All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.google.sitebricks.rendering.control.WidgetWrapper Maven / Gradle / Ivy

The newest version!
package com.google.sitebricks.rendering.control;

import com.google.common.base.Objects;
import com.google.sitebricks.Evaluator;
import com.google.sitebricks.Renderable;
import com.google.sitebricks.rendering.SelfRendering;
import com.google.sitebricks.routing.PageBook;

import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;

/**
 * @author Dhanji R. Prasanna (dhanji@gmail com)
 */
class WidgetWrapper {
  private final Class clazz;
  private final Constructor constructor;
  private final String key;
  private final boolean selfRendering;
  private final WidgetKind kind;

  private WidgetWrapper(Class clazz,
      Constructor constructor, WidgetKind kind, String key) {
    this.kind = kind;
    this.clazz = clazz;
    this.constructor = constructor;
    this.key = key;

    selfRendering = clazz.isAnnotationPresent(SelfRendering.class);
  }

  public Renderable newWidget(WidgetChain widgetChain, String expression, Evaluator evaluator,
                              PageBook pageBook) {
    try {
      return WidgetKind.NORMAL.equals(kind) ?
          constructor.newInstance(widgetChain, expression, evaluator) :
          constructor.newInstance(toArguments(widgetChain), expression, evaluator, pageBook, key);

    } catch (IllegalAccessException e) {
      throw new IllegalStateException("Malformed Widget (this should never happen): " + clazz);
    } catch (InvocationTargetException e) {
      throw new IllegalStateException("Could not construct an instance of " + clazz, e);
    } catch (InstantiationException e) {
      throw new IllegalStateException("Could not construct an instance of : " + clazz, e);
    }
  }

  private static Map toArguments(WidgetChain widgetChain) {
    Set arguments = widgetChain.collect(ArgumentWidget.class);
    Map map = new HashMap();

    for (ArgumentWidget argument : arguments) {
      map.put(argument.getName(), argument);
    }

    return map;
  }

  public static WidgetWrapper forWidget(String key, Class widgetClass) {
    WidgetKind kind = EmbedWidget.class.isAssignableFrom(widgetClass)
        ? WidgetKind.EMBED
        : WidgetKind.NORMAL;
    Constructor constructor;

    try {
      switch (kind) {
        case EMBED:
          constructor = widgetClass.getConstructor(Map.class, String.class, Evaluator.class,
              PageBook.class, String.class);
          break;

        case NORMAL:
        default:
          constructor = widgetClass.getConstructor(WidgetChain.class, String.class,
              Evaluator.class);
      }
    } catch (NoSuchMethodException e) {
      throw new IllegalStateException("Malformed Widget (this should never happen): "
          + widgetClass);
    }


    // Ugh...
    if (!constructor.isAccessible())
      constructor.setAccessible(true);

    return new WidgetWrapper(widgetClass, constructor, kind, key);
  }

  /**
   * Returns true if this widget will render an outer, containing tag,
   * discarding the annotated tag.
   */
  public boolean isSelfRendering() {
    return selfRendering;
  }

  @Override
  public String toString() {
    return Objects.toStringHelper(WidgetWrapper.class)
        .add("key", key)
        .add("class", clazz)
        .add("kind", kind)
        .toString();
  }

  private static enum WidgetKind {
    NORMAL, EMBED
  }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy