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

org.jamon.codegen.ImplGenerator Maven / Gradle / Ivy

/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

package org.jamon.codegen;

import java.io.OutputStream;

import org.jamon.compiler.ParserErrorImpl;
import org.jamon.compiler.ParserErrorsImpl;

public class ImplGenerator extends AbstractSourceGenerator {
  public ImplGenerator(TemplateDescriber describer, TemplateUnit templateUnit) {
    super(describer, templateUnit);
  }

  @Override
  public void generateSource(OutputStream out) throws java.io.IOException {
    writer = new CodeWriter(out, templateUnit.getEncoding());
    try {
      generateHeader();
      generatePrologue();
      generateImports();
      generateDeclaration();
      generateSetOptionalArguments();
      generateConstructor();
      generateRender();
      generateDefs();
      generateMethods();
      generateEpilogue();
      writer.finish();
    }
    catch (ParserErrorImpl e) {
      throw new ParserErrorsImpl(e);
    }
  }

  private final String getPath() {
    return templateUnit.getName();
  }

  private String getClassName() {
    return PathUtils.getImplClassName(getPath());
  }

  private void generateHeader() {
    writer.println("// Autogenerated Jamon implementation");
    writer.println("// " + describer.getExternalIdentifier(getPath()).replace('\\', '/'));
    writer.println();
  }

  private void generateDeclaration() {
    generateCustomAnnotations(templateUnit.getAnnotations(), AnnotationType.IMPL);
    writer.print("public");
    if (templateUnit.isParent()) {
      writer.print(" abstract");
    }
    writer.println(" class " + getClassName()
      + templateUnit.getGenericParams().generateGenericsDeclaration());
    writer.println("  extends " + (templateUnit.hasParentPath()
        ? PathUtils.getFullyQualifiedImplClassName(templateUnit.getParentPath())
        : ClassNames.BASE_TEMPLATE));
    writer.println("  implements " + getProxyClassName() + ".Intf"
      + templateUnit.getGenericParams().generateGenericParamsList());
    writer.println();
    writer.openBlock();
    if (templateUnit.getJamonContextType() != null) {
      writer.println("protected final " + templateUnit.getJamonContextType() + " jamonContext;");
    }
    for (AbstractArgument arg : templateUnit.getVisibleArgs()) {
      writer.println("private final " + arg.getFullyQualifiedType() + " " + arg.getName() + ";");
    }
    templateUnit.printClassContent(writer);
  }

  private void generateSetOptionalArguments() {
    writer.println("protected static "
      + templateUnit.getGenericParams().generateGenericsDeclaration() + getImplDataClassName()
      + " " + SET_OPTS + "(" + getImplDataClassName() + " p_implData)");
    writer.openBlock();
    for (OptionalArgument arg : templateUnit.getSignatureOptionalArgs()) {
      String value = templateUnit.getOptionalArgDefault(arg);
      if (value != null) {
        writer.println("if(! p_implData." + arg.getIsNotDefaultName() + "())");
        writer.openBlock();
        writer.println("p_implData." + arg.getSetterName() + "(" + value + ");");
        writer.closeBlock();
      }
    }
    if (templateUnit.hasParentPath()) {
      writer.println(getParentImplClassName() + "." + SET_OPTS + "(p_implData);");
    }
    writer.println("return p_implData;");
    writer.closeBlock();
  }

  private void generateConstructor() {
    writer.println("public " + getClassName() + "(" + ClassNames.TEMPLATE_MANAGER
      + " p_templateManager, " + getImplDataClassName() + " p_implData)");
    writer.openBlock();
    writer.println("super(p_templateManager, " + SET_OPTS + "(p_implData));");
    if (templateUnit.getJamonContextType() != null) {
      writer.println("jamonContext = p_implData.getJamonContext();");
    }
    for (AbstractArgument arg : templateUnit.getVisibleArgs()) {
      writer.println(arg.getName() + " = p_implData." + arg.getGetterName() + "();");
    }
    writer.closeBlock();
    writer.println();
  }

  private void generatePrologue() {
    String pkgName = PathUtils.getImplPackageName(getPath());
    if (pkgName.length() > 0) {
      writer.println("package " + pkgName + ";");
      writer.println();
    }
  }

  private void generateInnerUnitFargInterface(FragmentUnit fragmentUnit, boolean isPrivate) {
    writer.println();
    writer.printLocation(fragmentUnit.getLocation());
    fragmentUnit.printInterface(
      writer,
      isPrivate ? "private" : "protected", false);
  }

  private void generateDefs() throws ParserErrorImpl {
    for (DefUnit defUnit : templateUnit.getDefUnits()) {
      for (FragmentArgument frag : defUnit.getFragmentArgs()) {
        generateInnerUnitFargInterface(frag.getFragmentUnit(), true);
      }

      writer.println();
      writer.printLocation(defUnit.getLocation());
      writer.print("private void __jamon_innerUnit__");
      writer.print(defUnit.getName());
      writer.openList();
      writer.printListElement(ArgNames.WRITER_DECL);
      defUnit.printRenderArgsDecl(writer);
      writer.closeList();
      writer.println();
      if (defUnit.doesIO()) {
        writer.println("  throws " + ClassNames.IOEXCEPTION);
      }
      defUnit.generateRenderBody(writer, describer);
      writer.println();
    }
  }

  private void generateMethods() throws ParserErrorImpl {
    for (MethodUnit methodUnit : templateUnit.getDeclaredMethodUnits()) {
      generateMethodIntf(methodUnit);
    }
    for (MethodUnit methodUnit : templateUnit.getImplementedMethodUnits()) {
      generateMethodImpl(methodUnit);
    }
  }

  private void generateMethodIntf(MethodUnit methodUnit) {
    writer.println();
    for (FragmentArgument frag : methodUnit.getFragmentArgs()) {
      generateInnerUnitFargInterface(frag.getFragmentUnit(), false);
    }

  }

  private void generateMethodImpl(MethodUnit methodUnit) throws ParserErrorImpl {
    // FIXME - cut'n'pasted from generateDefs
    writer.println();
    generateJavadoc();
    writer.printLocation(methodUnit.getLocation());
    if (methodUnit.isOverride()) {
      writer.print("@Override ");
    }

    writer.print("protected " + (methodUnit.isAbstract()
        ? "abstract "
        : "") + "void __jamon_innerUnit__");
    writer.print(methodUnit.getName());
    writer.openList();
    writer.printListElement(ArgNames.WRITER_DECL);
    methodUnit.printRenderArgsDecl(writer);
    writer.closeList();
    writer.println();
    writer.println("  throws " + ClassNames.IOEXCEPTION);
    if (methodUnit.isAbstract()) {
      writer.println("  ;");
    }
    else {
      methodUnit.generateRenderBody(writer, describer);
    }
    writer.println();

    for (OptionalArgument arg : methodUnit.getOptionalArgsWithDefaults()) {
      if (methodUnit.isOverride()) {
        writer.print("@Override ");
      }
      writer.println("protected " + arg.getType() + " "
        + methodUnit.getOptionalArgDefaultMethod(arg) + "()");
      writer.openBlock();
      writer.println("return " + methodUnit.getDefaultForArg(arg) + ";");
      writer.closeBlock();
    }
  }

  /**
   * Generate javadoc to avoid warnings about unused parameters or unthrown exceptions
   */
  private void generateJavadoc() {
    writer.println("/**");
    writer.println(" * @param jamonWriter");
    writer.println(" * @throws " + ClassNames.IOEXCEPTION);
    writer.println(" */");
  }

  private void generateRender() throws ParserErrorImpl {
    if (templateUnit.hasParentPath()) {
      writer.println("@Override protected void child_render_" + templateUnit.getInheritanceDepth()
        + "(" + ArgNames.WRITER_DECL + ")");
    }
    else {
      if (!templateUnit.isParent()) {
        writer.print("@Override ");
      }
      writer.println("public void renderNoFlush(" + ArgNames.WRITER_DECL + ")");
    }
    if (templateUnit.doesIO()) {
      writer.println("  throws " + ClassNames.IOEXCEPTION);
    }
    templateUnit.generateRenderBody(writer, describer);

    writer.println();
    if (templateUnit.isParent()) {
      writer.println("protected abstract void child_render_"
        + (templateUnit.getInheritanceDepth() + 1) + "(" + ArgNames.WRITER_DECL + ") throws "
        + ClassNames.IOEXCEPTION + ";");
      writer.println();
    }
  }

  private void generateEpilogue() {
    writer.println();
    writer.closeBlock();
  }

  private void generateImports() {
    templateUnit.printImports(writer);
  }

  private String getProxyClassName() {
    return PathUtils.getFullyQualifiedIntfClassName(getPath());
  }

  private String getImplDataClassName() {
    return getProxyClassName() + ".ImplData"
      + templateUnit.getGenericParams().generateGenericParamsList();
  }

  private String getParentImplClassName() {
    return PathUtils.getFullyQualifiedImplClassName(templateUnit.getParentPath());
  }

  private final static String SET_OPTS = "__jamon_setOptionalArguments";
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy