Ejemplo n.º 1
0
  public void process(TemplateMetaModelPlugin plugin) throws ProcessingException {

    //
    TemplatesMetaModel metaModel = application.getChild(TemplatesMetaModel.KEY);

    // Evict templates that are out of date
    log.log("Synchronizing existing templates " + templates.keySet());
    for (Iterator<Template<?>> i = templates.values().iterator(); i.hasNext(); ) {
      Template<?> template = i.next();
      FileObject resource =
          application.resolveResource(TemplatesMetaModel.LOCATION, template.getRelativePath());
      if (resource == null) {
        // That will generate a template not found error
        i.remove();
        log.log("Detected template removal " + template.getRelativePath());
      } else if (resource.getLastModified() > template.getLastModified()) {
        // That will force the regeneration of the template
        i.remove();
        log.log("Detected stale template " + template.getRelativePath());
      } else {
        log.log("Template " + template.getRelativePath() + " is valid");
      }
    }

    // Build missing templates
    log.log("Building missing templates");
    Map<Path.Relative, Template<?>> copy = new HashMap<Path.Relative, Template<?>>(templates);
    for (TemplateMetaModel templateMeta : metaModel) {
      Template<?> template = copy.get(templateMeta.getPath());
      if (template == null) {
        log.log("Compiling template " + templateMeta.getPath());
        ModelTemplateProcessContext compiler =
            new ModelTemplateProcessContext(
                templateMeta,
                new HashMap<Path, Template<?>>(copy),
                application.getProcessingContext());
        Collection<Template<?>> resolved = compiler.resolve(templateMeta);
        for (Template<?> added : resolved) {
          copy.put(added.getRelativePath(), added);
        }
      }
    }
    templates = copy;

    // Generate missing files from template
    for (Template<?> template : templates.values()) {
      //
      Path originPath = template.getOrigin();
      TemplateMetaModel templateMeta = metaModel.get(originPath);

      //
      // We compute the class elements from the field elements (as eclipse will make the
      // relationship)
      Set<Name> types = new LinkedHashSet<Name>();
      for (TemplateRefMetaModel ref : templateMeta.getRefs()) {
        ElementHandle.Field handle = ref.getHandle();
        types.add(handle.getFQN());
      }
      final Element[] elements = new Element[types.size()];
      int index = 0;
      for (Name type : types) {
        elements[index++] = application.getProcessingContext().getTypeElement(type);
      }

      // If CCE that would mean there is an internal bug
      TemplateProvider<?> provider =
          (TemplateProvider<?>) plugin.providers.get(template.getRelativePath().getExt());

      // Resolve the qualified class
      resolvedQualified(provider, template, elements);

      //
      resolveScript(template, plugin, elements);
    }
  }
Ejemplo n.º 2
0
  private <M extends Serializable> void resolvedQualified(
      TemplateProvider<?> provider, Template<M> template, Element[] elements) {

    //
    TemplatesMetaModel metaModel = application.getChild(TemplatesMetaModel.KEY);

    //
    Path.Relative path = template.getRelativePath();
    if (classCache.containsKey(path)) {
      log.log("Template class " + path + " was found in cache");
      return;
    }

    //
    Path.Absolute resolvedPath = metaModel.resolvePath(path);

    //
    Writer writer = null;
    try {
      // Template qualified class
      FileObject classFile =
          application.getProcessingContext().createSourceFile(resolvedPath.getName(), elements);
      writer = classFile.openWriter();
      writer.append("package ").append(resolvedPath.getDirs()).append(";\n");
      writer.append("import ").append(TemplateDescriptor.class.getCanonicalName()).append(";\n");
      writer.append("import ").append(TemplatePlugin.class.getCanonicalName()).append(";\n");
      writer.append("@").append(Generated.class.getName()).append("({})\n");
      writer
          .append("@")
          .append(juzu.Path.class.getName())
          .append("(\"")
          .append(path.getValue())
          .append("\")\n");
      writer
          .append("public class ")
          .append(path.getRawName())
          .append(" extends ")
          .append(juzu.template.Template.class.getName())
          .append("\n");
      writer.append("{\n");
      writer.append("@javax.inject.Inject\n");
      writer
          .append("public ")
          .append(path.getRawName())
          .append("(")
          .append(TemplatePlugin.class.getSimpleName())
          .append(" templatePlugin")
          .append(")\n");
      writer.append("{\n");
      writer
          .append("super(templatePlugin, \"")
          .append(path.getValue())
          .append("\"")
          .append(", ")
          .append(provider.getTemplateStubType().getName())
          .append(".class);\n");
      writer.append("}\n");

      //
      writer
          .append("public static final ")
          .append(TemplateDescriptor.class.getName())
          .append(" DESCRIPTOR = new ")
          .append(TemplateDescriptor.class.getName())
          .append("(")
          .append(resolvedPath.getName())
          .append(".class,")
          .append(provider.getTemplateStubType().getName())
          .append(".class")
          .append(");\n");

      //
      String baseBuilderName = juzu.template.Template.Builder.class.getCanonicalName();
      if (template.getParameters() != null) {
        // Implement abstract method with this class Builder covariant return type
        writer.append("public Builder builder() {\n");
        writer.append("return new Builder();\n");
        writer.append("}\n");

        // Covariant return type of with()
        writer.append("public Builder with() {\n");
        writer.append("return (Builder)super.with();\n");
        writer.append("}\n");

        // Setters on builders
        writer.append("public class Builder extends ").append(baseBuilderName).append("\n");
        writer.append("{\n");
        for (String paramName : template.getParameters()) {
          writer
              .append("public Builder ")
              .append(paramName)
              .append("(Object ")
              .append(paramName)
              .append(") {\n");
          writer.append("set(\"").append(paramName).append("\",").append(paramName).append(");\n");
          writer.append("return this;\n");
          writer.append(("}\n"));
        }
        writer.append("}\n");
      } else {
        // Implement abstract factory method
        writer.append("public ").append(baseBuilderName).append(" builder() {\n");
        writer.append("return new ").append(baseBuilderName).append("();\n");
        writer.append("}\n");
      }

      // Close class
      writer.append("}\n");

      //
      classCache.put(path, classFile);

      //
      log.log(
          "Generated template class "
              + path
              + " as "
              + classFile.toUri()
              + " with originating elements "
              + Arrays.asList(elements));
    } catch (IOException e) {
      throw TemplateMetaModel.CANNOT_WRITE_TEMPLATE_CLASS.failure(e, elements[0], path);
    } finally {
      Tools.safeClose(writer);
    }
  }