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

xapi.dev.gwtc.impl.UiTemplateGenerator Maven / Gradle / Ivy

Go to download

Everything needed to run a comprehensive dev environment. Just type X_ and pick a service from autocomplete; new dev modules will be added as they are built. The only dev service not included in the uber jar is xapi-dev-maven, as it includes all runtime dependencies of maven, adding ~4 seconds to build time, and 6 megabytes to the final output jar size (without xapi-dev-maven, it's ~1MB).

The newest version!
package xapi.dev.gwtc.impl;

import java.io.InputStream;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;

import xapi.annotation.ui.UiTemplate;
import xapi.annotation.ui.UiTemplate.EmbedStrategy;
import xapi.annotation.ui.UiTemplate.Location;
import xapi.collect.api.Fifo;
import xapi.collect.impl.LazyList;
import xapi.dev.gwtc.impl.GwtcContext.GwtcUnit;
import xapi.dev.source.PrintBuffer;
import xapi.dev.source.XmlBuffer;
import xapi.file.X_File;
import xapi.inject.X_Inject;
import xapi.io.X_IO;
import xapi.log.X_Log;
import xapi.util.X_Util;


@SuppressWarnings("unused")
public class UiTemplateGenerator {

  protected static interface WrapElements{
    GwtcUnitType type();
    boolean wrapsAll();
  }
  protected static class WrapsElements implements WrapElements {

    private final GwtcUnitType type;

    public WrapsElements(final GwtcUnitType type) {
      this.type = type;
    }

    @Override
    public GwtcUnitType type() {
      return type;
    }

    @Override
    public boolean wrapsAll() {
      return false;
    }
  }
  protected static class WrapsAllElements extends WrapsElements {

    public WrapsAllElements(final GwtcUnitType type) {
      super(type);
    }

    @Override
    public boolean wrapsAll() {
      return true;
    }
  }
  protected static class WrapsAllPackages extends WrapsAllElements {
    public WrapsAllPackages() {
      super(GwtcUnitType.Package);
    }
  }
  protected static class WrapsAllClasses extends WrapsAllElements {
    public WrapsAllClasses() {
      super(GwtcUnitType.Class);
    }
  }
  protected static class WrapsAllMethods extends WrapsAllElements {
    public WrapsAllMethods() {
      super(GwtcUnitType.Class);
    }
  }
  protected static class WrapsPackages extends WrapsElements {
    public WrapsPackages() {
      super(GwtcUnitType.Package);
    }
  }
  protected static class WrapsClasses extends WrapsElements {
    public WrapsClasses() {
      super(GwtcUnitType.Class);
    }
  }
  protected static class WrapsMethods extends WrapsElements {
    public WrapsMethods() {
      super(GwtcUnitType.Class);
    }
  }

  protected class UiContext {

    private final EmbedStrategy strategy;
    WrapsAllElements all;
    WrapsElements each;


    public UiContext(final EmbedStrategy strategy) {
      this.strategy = strategy;
    }

    private final StringBuilder before = new StringBuilder();
    private final StringBuilder after = new StringBuilder();
    private final List children = new ArrayList();

    protected void addBefore(final String txt) {
      before.append(txt);
    }

    protected UiContext wrap(final UiTemplateGenerator generator) {
      final UiContext ctx = generator.new UiContext(strategy);
      if (matchesStrategy(generator)) {
        // When our UiContext matches for a supplied child,
        // we should return a new UiContext which wraps this child.

        ctx.addBefore(before.toString());
        ctx.addAfter(after.toString());
        children.add(ctx);
      }
      return ctx;
    }

    private boolean matchesStrategy(final UiTemplateGenerator generator) {
      switch (strategy) {
        case Insert:
          return false;
        case WrapAllClasses:
          return generator.type == GwtcUnitType.Class &&
            (generator.parent == null || generator.parent.type == GwtcUnitType.Package);
        case WrapAllPackages:
          if (parent != null) {
            return false;
          }
        case WrapEachPackage:
          return generator.type == GwtcUnitType.Package;
        case WrapEachClass:
          return generator.type == GwtcUnitType.Class;
        case WrapEachMethod:
          return generator.type == GwtcUnitType.Method;
      }
      return false;
    }

    protected void addAfter(final String txt) {
      after.append(txt);
    }

    @Override
    public String toString() {
      if (children.isEmpty()) {
        return before + after.toString();
      } else {
        final StringBuilder b = new StringBuilder();
        for (final UiContext child : children) {
          b.append(child.toString());
        }
        return b.toString();
      }
    }

  }

  protected UiTemplateGenerator parent;

  private final Fifo children = X_Inject.instance(Fifo.class);

  // Rather than null-check all six insertion points, we just use lazy providers
  // which will create collections only on demand.
  LazyList
    htmlBodyBefore = newList(),
    htmlBody = newList(),
    htmlBodyAfter = newList(),
    htmlHeadBefore = newList(),
    htmlHead = newList(),
    htmlHeadAfter = newList();

  protected final GwtcUnitType type;

  private final WrapsAllPackages allPackages = new WrapsAllPackages();
  private final WrapsAllClasses allClasses = new WrapsAllClasses();
  private final WrapsAllMethods allMethods = new WrapsAllMethods();
  private final WrapsPackages packages = new WrapsPackages();
  private final WrapsClasses classes = new WrapsClasses();
  private final WrapsMethods methods = new WrapsMethods();

  public UiTemplateGenerator(final GwtcUnit root) {
    this.type = root.getType();
    for (final UiTemplate template : root.gwtc.includeHostHtml()) {
      switch (template.location()) {
        case Body_Prefix:
        case Body_Insert:
        case Body_Suffix:
        case Head_Prefix:
        case Head_Insert:
        case Head_Suffix:
      }
      addTemplate(template);
    }
    for (final GwtcUnit child : root.getChildren()) {
      addChild(new UiTemplateGenerator(child));
    }
  }




  private final LazyList newList() {
    return new LazyList();
  }




  public UiTemplateGenerator addTemplate(final UiTemplate template) {
    final ArrayList list;
    switch (template.location()) {
      case Body_Insert:
        list = htmlBody.get();
        break;
      case Body_Prefix:
        list = htmlBodyBefore.get();
        break;
      case Body_Suffix:
        list = htmlBodyAfter.get();
        break;
      case Head_Insert:
        list = htmlHeadBefore.get();
        break;
      case Head_Prefix:
        list = htmlHead.get();
        break;
      case Head_Suffix:
        list = htmlHeadAfter.get();
        break;
      default:
        throw new IllegalStateException("Unhanded location type "+template.location());//impossible
    }
    list.add(template);
    return this;
  }

  protected void addChild(final UiTemplateGenerator child) {
    children.give(child);
  }

  public void generate(final XmlBuffer head, final XmlBuffer body) {
    final PrintBuffer headBefore = new PrintBuffer();
    final PrintBuffer headInsert = new PrintBuffer();
    final PrintBuffer headAfter = new PrintBuffer();
    final PrintBuffer bodyBefore = new PrintBuffer();
    final PrintBuffer bodyInsert = new PrintBuffer();
    final PrintBuffer bodyAfter = new PrintBuffer();


    doGenerate(new HashSet(), headBefore, headInsert, headAfter,
        bodyBefore, bodyInsert, bodyAfter);


    if (!headBefore.isEmpty()) {
      head.addToBeginning(headBefore);
    }
    if (!headInsert.isEmpty()) {
      head.addToEnd(headInsert);
    }
    if (!headAfter.isEmpty()) {
      head.addToEnd(headAfter);
    }
    if (!bodyBefore.isEmpty()) {
      body.addToBeginning(headBefore);
    }
    if (!bodyInsert.isEmpty()) {
      body.addToEnd(bodyInsert);
    }
    if (!bodyAfter.isEmpty()) {
      body.addToEnd(headAfter);
    }

  }
  public void doGenerate(final HashSet finished,
      final PrintBuffer headBefore, final PrintBuffer head, final PrintBuffer headAfter,
      final PrintBuffer bodyBefore, final PrintBuffer body, final PrintBuffer bodyAfter) {

    if (htmlHeadBefore.isSet()) {
      for (final UiTemplate headResource : htmlHeadBefore.get()) {
        printResource(headBefore, headResource);
      }
    }
    if (htmlHead.isSet()) {
      for (final UiTemplate headResource : htmlHead.get()) {
        printResource(head, headResource);
      }
    }
    if (htmlBodyBefore.isSet()) {
      for (final UiTemplate headResource : htmlBodyBefore.get()) {
        printResource(bodyBefore, headResource);
      }
    }
    if (htmlBody.isSet()) {
      for (final UiTemplate headResource : htmlBody.get()) {
        printResource(body, headResource);
      }
    }

    for (final UiTemplateGenerator child : children.forEach()) {
      if (finished.add(child)) {
        child.doGenerate(finished, headBefore, head, headAfter, bodyBefore, body, bodyAfter);
      }
    }

    if (htmlHeadAfter.isSet()) {
      for (final UiTemplate headResource : htmlHeadAfter.get()) {
        printResource(headAfter, headResource);
      }
    }
    if (htmlBodyAfter.isSet()) {
      for (final UiTemplate headResource : htmlBodyAfter.get()) {
        printResource(bodyAfter, headResource);
      }
    }
  }

  protected String getResource(final UiTemplate body) {
    final String value = body.value();
    final String contents;
    try {
      InputStream resource;
      switch (body.type()) {
        case Literal:
          contents = body.value();
          break;
        case File:
          resource = X_File.unzipFile(value);
          contents = X_IO.toStringUtf8(resource);
          break;
        case Resource:
          resource = X_File.unzipResource(value, Thread.currentThread().getContextClassLoader());
          contents = X_IO.toStringUtf8(resource);
          break;
        default:
          throw new UnsupportedOperationException(getClass()+" does not support "+body.type());
      }
      return contents;
    } catch (final Exception e) {
      X_Log.warn(getClass(), e, "failure while loading resource",body);
      if (body.required()) {
        throw X_Util.rethrow(e);
      }
      return value;
    }

  }
  @SuppressWarnings("incomplete-switch")
  public void printResource(final PrintBuffer el, final UiTemplate body) {// TODO
    final String contents = resolveTemplate(getResource(body), body);
    switch(body.embedStrategy()) {
      case Insert:
        break;
    }
//    UiContext ctx = new UiContext(body.embedStrategy());
//    Template t = new Template(contents, body.keys());
//    Object[] values = getValues(ctx, body.location(), body.keys());
//    X_Log.error(getClass(), "Test render\n\n",t.apply(values));
    el.println(contents);
  }


  private Object[] getValues(final UiContext ctx, final Location location, final String[] keys) {
    int i = keys.length;
    final Object[] values = new Object[i];
    while (i-->0) {
      values[i] = keys[i];
      switch (keys[i]) {
        case UiTemplate.$child:
          // The value to use is the resolved children
        case UiTemplate.$class:
        case UiTemplate.$id:
        case UiTemplate.$method:
        case UiTemplate.$package:
      }
    }
    return values;
  }
  /**
   * A hook used to allow subclasses to perform custom manipulations on a given template.
   *
   * @param contents - The resolved plaintext UTF-8 encoded text content of the supplied {@link UiTemplate}
   * @param body  - The {@link UiTemplate} from which the contents were resolved
   * @return - A manipulated form of the contents
   */
  protected String resolveTemplate(final String contents, final UiTemplate body) {
    return contents;
  }

}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy