package org.wikbook.template.processing; import org.wikbook.template.freemarker.FreemarkerRenderer; import org.wikbook.template.processing.metamodel.MetaModel; import org.wikbook.template.processing.metamodel.ModelContext; import org.wikbook.template.processing.metamodel.TemplateElement; import javax.annotation.processing.AbstractProcessor; import javax.annotation.processing.Filer; import javax.annotation.processing.RoundEnvironment; import javax.lang.model.element.Element; import javax.lang.model.element.TypeElement; import javax.lang.model.util.Elements; import javax.lang.model.util.Types; import javax.tools.FileObject; import javax.tools.StandardLocation; import java.io.IOException; import java.io.ObjectOutputStream; import java.io.OutputStream; import java.util.ArrayList; import java.util.List; import java.util.Set; /** * @author <a href="mailto:alain.defrance@exoplatform.com">Alain Defrance</a> * @version $Revision$ */ public abstract class AbstractTemplateProcessor extends AbstractProcessor { private Class[] annotations; private Filer filer; private Elements elementsUtils; private Types typesUtils; private String templateName; private String generatedDirectory; private String ext; private MetaModel metaModel; protected AbstractTemplateProcessor() { this.metaModel = new MetaModel(); } @Override public boolean process(Set<? extends TypeElement> typeElements, RoundEnvironment roundEnvironment) { // annotations = annotations(); if (annotations == null) { throw new NullPointerException(); } // ext = ext(); if (ext == null || ext.length() == 0) { throw new NullPointerException(); } else { ext = "." + ext; } // templateName = templateName(); if (templateName == null) { throw new NullPointerException(); } // generatedDirectory = generatedDirectory(); if (generatedDirectory == null) { throw new NullPointerException(); } // if (annotations.length == 0) return false; // List<Element> done = new ArrayList<Element>(); this.filer = processingEnv.getFiler(); this.elementsUtils = processingEnv.getElementUtils(); this.typesUtils = processingEnv.getTypeUtils(); // ModelContext ctx = new ModelContext(); ctx.setClasses(annotations); ctx.setElementsUtils(elementsUtils); ctx.setTypesUtils(typesUtils); // for (Class clazz : annotations) { Set<? extends Element> elements = roundEnvironment.getElementsAnnotatedWith(clazz); for (Element element : elements) { if (done.contains(element)) { continue; } switch (element.getKind()) { case CLASS: case PACKAGE: List<TemplateElement> built = buildElements(element, ctx); metaModel.addAll(built); break; } done.add(element); } } if (roundEnvironment.processingOver() && metaModel.getElements().size() > 0) { try { if (globalTemplate()) { writeGlobalFile(); } else { writeFiles(); } } catch (IOException e) { throw new RuntimeException(e); } } return false; } private void writeFiles() throws IOException { String fileName; for (TemplateElement el : metaModel.getElements()) { // if (el.getType() != null) { fileName = el.getType().getFqn(); } else { fileName = el.getName(); } OutputStream os = createdFileOS(fileName); // new FreemarkerRenderer().render(metaModel, templateName, el, os, filer); // finalizeWriting(fileName); } } private void writeGlobalFile() throws IOException { // String fileName = getClass().getName(); OutputStream os = createdFileOS(fileName); // new FreemarkerRenderer().render(metaModel, templateName, os, filer); // finalizeWriting(fileName); } private void finalizeWriting(String fileName) { if (writeModel()) { writeState(metaModel, fileName + ext); } } private OutputStream createdFileOS(String name) throws IOException { FileObject file = filer.createResource(StandardLocation.SOURCE_OUTPUT, generatedDirectory, "" + name + ext, null); return file.openOutputStream(); } private List<TemplateElement> buildElements(Element el, ModelContext ctx) { TemplateElementVisitor visitor = new TemplateElementVisitor(); List<TemplateElement> elements = el.accept(visitor, ctx); return elements; } private void writeState(MetaModel metaModel, String name) { try { FileObject servicesfile = filer.createResource(StandardLocation.SOURCE_OUTPUT, generatedDirectory, name + ".model", null); ObjectOutputStream oos = new ObjectOutputStream(servicesfile.openOutputStream()); oos.writeObject(metaModel); oos.flush(); oos.close(); } catch (IOException e) { throw new RuntimeException(e); } } protected boolean writeModel() { return false; } protected boolean globalTemplate() { return false; } protected abstract Class[] annotations(); protected abstract String templateName(); protected abstract String generatedDirectory(); protected abstract String ext(); }