Search in sources :

Example 1 with MainInfo

use of com.predic8.membrane.annot.model.MainInfo in project service-proxy by membrane.

the class SpringConfigurationXSDGeneratingAnnotationProcessor method process.

@Override
public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) {
    // * in the last round, "roundEnv.processingOver()" is true
    try {
        String status = "process() a=" + annotations.size() + " r=" + roundEnv.getRootElements().size() + " h=" + hashCode() + (roundEnv.processingOver() ? " processing-over" : " ");
        log(status);
        read();
        if (roundEnv.processingOver())
            write();
        if (annotations.size() > 0) {
            // a class with one of our annotation needs to be compiled
            status = "working with " + getCachedElementsAnnotatedWith(roundEnv, MCMain.class).size() + " and " + getCachedElementsAnnotatedWith(roundEnv, MCElement.class).size();
            log(status);
            Model m = new Model();
            Set<? extends Element> mcmains = getCachedElementsAnnotatedWith(roundEnv, MCMain.class);
            if (mcmains.isEmpty()) {
                processingEnv.getMessager().printMessage(Kind.WARNING, "@MCMain was nowhere found.");
                return true;
            }
            for (Element element : mcmains) {
                MainInfo main = new MainInfo();
                main.setElement((TypeElement) element);
                main.setAnnotation(element.getAnnotation(MCMain.class));
                m.getMains().add(main);
            }
            for (Element e : getCachedElementsAnnotatedWith(roundEnv, MCElement.class)) {
                ElementInfo ii = new ElementInfo();
                ii.setElement((TypeElement) e);
                ii.setAnnotation(e.getAnnotation(MCElement.class));
                MainInfo main = ii.getMain(m);
                main.getIis().add(ii);
                main.getElements().put(ii.getElement(), ii);
                if (main.getGlobals().containsKey(ii.getAnnotation().name()))
                    throw new ProcessingException("Duplicate global @MCElement name.", main.getGlobals().get(ii.getAnnotation().name()).getElement(), ii.getElement());
                if (main.getIds().containsKey(ii.getId()))
                    throw new ProcessingException("Duplicate element id \"" + ii.getId() + "\". Please assign one using @MCElement(id=\"...\").", e, main.getIds().get(ii.getId()).getElement());
                main.getIds().put(ii.getId(), ii);
                scan(m, main, ii);
                if (ii.getTci() != null && !ii.getAnnotation().mixed())
                    throw new ProcessingException("@MCTextContent requires @MCElement(..., mixed=true) on the class.", ii.getElement());
                if (ii.getTci() == null && ii.getAnnotation().mixed())
                    throw new ProcessingException("@MCElement(..., mixed=true) requires @MCTextContent on a property.", ii.getElement());
            }
            for (MainInfo main : m.getMains()) {
                for (Map.Entry<TypeElement, ChildElementDeclarationInfo> f : main.getChildElementDeclarations().entrySet()) {
                    ChildElementDeclarationInfo cedi = f.getValue();
                    ElementInfo ei = main.getElements().get(f.getKey());
                    if (ei != null)
                        cedi.getElementInfo().add(ei);
                    else {
                        for (Map.Entry<TypeElement, ElementInfo> e : main.getElements().entrySet()) if (processingEnv.getTypeUtils().isAssignable(e.getKey().asType(), f.getKey().asType()))
                            cedi.getElementInfo().add(e.getValue());
                    }
                    for (ElementInfo ei2 : cedi.getElementInfo()) ei2.addUsedBy(f.getValue());
                    if (cedi.getElementInfo().isEmpty() && cedi.isRaiseErrorWhenNoSpecimen()) {
                        processingEnv.getMessager().printMessage(Kind.ERROR, "@MCChildElement references " + f.getKey().getQualifiedName() + ", but there is no @MCElement among it and its subclasses.", f.getKey());
                        return true;
                    }
                }
            }
            if (mcmains.isEmpty()) {
                processingEnv.getMessager().printMessage(Kind.ERROR, "@MCMain but no @MCElement found.", mcmains.iterator().next());
                return true;
            }
            process(m);
        }
        return true;
    } catch (IOException e) {
        throw new RuntimeException(e);
    } catch (ProcessingException e1) {
        for (int i = 0; i < e1.getElements().length; i++) processingEnv.getMessager().printMessage(Kind.ERROR, i == 0 ? e1.getMessage() : "also here", e1.getElements()[i]);
        return true;
    }
}
Also used : ElementInfo(com.predic8.membrane.annot.model.ElementInfo) ChildElementInfo(com.predic8.membrane.annot.model.ChildElementInfo) IOException(java.io.IOException) MainInfo(com.predic8.membrane.annot.model.MainInfo) Model(com.predic8.membrane.annot.model.Model) ChildElementDeclarationInfo(com.predic8.membrane.annot.model.ChildElementDeclarationInfo)

Example 2 with MainInfo

use of com.predic8.membrane.annot.model.MainInfo in project service-proxy by membrane.

the class BlueprintParsers method writeParsers.

public void writeParsers(Model m) throws IOException {
    for (MainInfo main : m.getMains()) {
        for (ElementInfo ii : main.getIis()) {
            List<Element> sources = new ArrayList<Element>();
            sources.add(main.getElement());
            sources.add(ii.getElement());
            String interceptorClassName = ii.getElement().getQualifiedName().toString();
            try {
                FileObject o = processingEnv.getFiler().createSourceFile(main.getAnnotation().outputPackage() + ".blueprint" + "." + ii.getParserClassSimpleName(), sources.toArray(new Element[0]));
                BufferedWriter bw = new BufferedWriter(o.openWriter());
                try {
                    bw.write("/* Copyright 2014 predic8 GmbH, www.predic8.com\r\n" + "\r\n" + "   Licensed under the Apache License, Version 2.0 (the \"License\");\r\n" + "   you may not use this file except in compliance with the License.\r\n" + "   You may obtain a copy of the License at\r\n" + "\r\n" + "   http://www.apache.org/licenses/LICENSE-2.0\r\n" + "\r\n" + "   Unless required by applicable law or agreed to in writing, software\r\n" + "   distributed under the License is distributed on an \"AS IS\" BASIS,\r\n" + "   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r\n" + "   See the License for the specific language governing permissions and\r\n" + "   limitations under the License. */\r\n" + "\r\n" + "package " + main.getAnnotation().outputPackage() + ".blueprint;\r\n" + "\r\n" + "import com.predic8.membrane.annot.parser.BlueprintElementParser;\r\n" + "import com.predic8.membrane.annot.parser.BlueprintParser;\r\n" + "import org.apache.aries.blueprint.ParserContext;\r\n" + "import org.osgi.service.blueprint.reflect.Metadata;\r\n" + "import org.apache.aries.blueprint.mutable.MutableBeanMetadata;\r\n" + "import org.osgi.service.blueprint.reflect.BeanMetadata;\r\n" + "import org.w3c.dom.Element;\r\n" + "");
                    bw.write("\r\n" + "/**\r\n" + "  * Automatically generated by " + BlueprintParsers.class.getName() + ".\r\n" + "  */\r\n" + "public class " + ii.getParserClassSimpleName() + " extends BlueprintElementParser {\r\n" + "	public Metadata parse(BlueprintParser globalParser, Element element, ParserContext context) {\r\n" + "		MutableBeanMetadata mcm = context.createMetadata(MutableBeanMetadata.class);\r\n" + "		mcm.setId(context.generateId());\r\n" + "		mcm.setScope(BeanMetadata.SCOPE_SINGLETON);\r\n" + "		mcm.setRuntimeClass(" + interceptorClassName + ".class);\r\n" + "		applySpringInterfacePatches(context, " + interceptorClassName + ".class, mcm);\r\n" + "\r\n");
                    if (ii.isHasIdField())
                        bw.write("		setPropertyIfSet(context, \"id\", element, mcm);\r\n");
                    bw.write("		setIdIfNeeded(element, context, \"" + ii.getAnnotation().name() + "\");\r\n");
                    for (AttributeInfo ai : ii.getAis()) {
                        if (ai.getXMLName().equals("id"))
                            continue;
                        if (ai.isBeanReference(processingEnv.getTypeUtils())) {
                            if (!ai.isRequired())
                                bw.write("		if (element.hasAttribute(\"" + ai.getXMLName() + "\"))\r\n");
                            bw.write("		setPropertyReference(context, \"" + ai.getSpringName() + "\", element.getAttribute(\"" + ai.getXMLName() + "\"), mcm);\r\n");
                        } else {
                            bw.write("		setProperty" + (ai.isRequired() ? "" : "IfSet") + "(context, \"" + ai.getXMLName() + "\", \"" + ai.getSpringName() + "\", element, mcm" + (ai.isEnum(processingEnv.getTypeUtils()) ? ", true" : "") + ");\r\n");
                        }
                        if (ai.getXMLName().equals("name"))
                            bw.write("		element.removeAttribute(\"name\");\r\n");
                    }
                    if (ii.getOai() != null) {
                        bw.write("		setProperties(context, \"" + ii.getOai().getSpringName() + "\", element, mcm);\r\n");
                    }
                    if (ii.getTci() != null)
                        bw.write("		setProperty(context, mcm, \"" + ii.getTci().getPropertyName() + "\", element.getTextContent());\r\n");
                    else
                        bw.write("		parseChildren(element, context, mcm, globalParser);\r\n");
                    for (ChildElementInfo cei : ii.getCeis()) if (cei.isList() && cei.isRequired()) {
                        bw.write("		if (!isPropertySet(mcm, \"" + cei.getPropertyName() + "\"))\r\n");
                        bw.write("			throw new RuntimeException(\"Property '" + cei.getPropertyName() + "' is required, but none was defined (empty list).\");\r\n");
                    }
                    bw.write("" + "		return mcm;\r\n");
                    bw.write("	}\r\n");
                    bw.write("	@Override\r\n" + "	protected void handleChildObject(Element ele, ParserContext context, MutableBeanMetadata mcm, Class<?> clazz, Object child) {\r\n");
                    for (ChildElementInfo cei : ii.getCeis()) {
                        bw.write("		if (" + cei.getTypeDeclaration().getQualifiedName() + ".class.isAssignableFrom(clazz)) {\r\n");
                        if (cei.isList())
                            bw.write("			appendToListProperty(context, mcm, \"" + cei.getPropertyName() + "\"" + ", child);\r\n");
                        else
                            bw.write("			setProperty(context, mcm, \"" + cei.getPropertyName() + "\"" + ", child);\r\n");
                        bw.write("		} else \r\n");
                    }
                    bw.write("		{\r\n" + "			throw new RuntimeException(\"Unknown child class \\\"\" + clazz + \"\\\".\");\r\n" + "		}\r\n");
                    bw.write("	}\r\n");
                    bw.write("}\r\n" + "");
                } finally {
                    bw.close();
                }
            } catch (FilerException e) {
                if (e.getMessage().contains("Source file already created"))
                    return;
                throw e;
            }
        }
    }
}
Also used : AttributeInfo(com.predic8.membrane.annot.model.AttributeInfo) MainInfo(com.predic8.membrane.annot.model.MainInfo) ElementInfo(com.predic8.membrane.annot.model.ElementInfo) ChildElementInfo(com.predic8.membrane.annot.model.ChildElementInfo) Element(javax.lang.model.element.Element) TypeElement(javax.lang.model.element.TypeElement) ArrayList(java.util.ArrayList) FileObject(javax.tools.FileObject) FilerException(javax.annotation.processing.FilerException) ChildElementInfo(com.predic8.membrane.annot.model.ChildElementInfo) BufferedWriter(java.io.BufferedWriter)

Example 3 with MainInfo

use of com.predic8.membrane.annot.model.MainInfo in project service-proxy by membrane.

the class NamespaceInfo method writeInfo.

public void writeInfo(Model m) {
    try {
        FileObject o = processingEnv.getFiler().createResource(StandardLocation.CLASS_OUTPUT, "", "META-INF/membrane.namespaces");
        OutputStream oo = o.openOutputStream();
        BufferedOutputStream bos = new BufferedOutputStream(oo);
        try {
            Properties p = new Properties();
            int i = 1;
            for (MainInfo mi : m.getMains()) {
                String key = "schema" + (i++);
                p.put(key + "-targetNamespace", mi.getAnnotation().targetNamespace());
                p.put(key + "-outputPackage", mi.getAnnotation().outputPackage());
                p.put(key + "-outputName", mi.getAnnotation().outputName());
            }
            p.store(bos, "Autogenerated by " + getClass().getName());
        } finally {
            bos.close();
        }
    } catch (IOException e) {
        throw new RuntimeException(e);
    }
}
Also used : MainInfo(com.predic8.membrane.annot.model.MainInfo) OutputStream(java.io.OutputStream) BufferedOutputStream(java.io.BufferedOutputStream) FileObject(javax.tools.FileObject) IOException(java.io.IOException) Properties(java.util.Properties) BufferedOutputStream(java.io.BufferedOutputStream)

Example 4 with MainInfo

use of com.predic8.membrane.annot.model.MainInfo in project service-proxy by membrane.

the class HelpReference method handle.

private void handle(Model m, MainInfo main, ElementInfo ei) throws XMLStreamException {
    xew.writeStartElement("element");
    xew.writeAttribute("name", ei.getAnnotation().name());
    if (ei.getAnnotation().mixed())
        xew.writeAttribute("mixed", "true");
    xew.writeAttribute("topLevel", Boolean.toString(ei.getAnnotation().topLevel()));
    xew.writeAttribute("id", ei.getId());
    if (!ei.getAnnotation().topLevel()) {
        String primaryParentId = getPrimaryParentId(m, main, ei);
        if (primaryParentId != null)
            xew.writeAttribute("primaryParentId", primaryParentId);
    }
    handleDoc(ei);
    List<AttributeInfo> ais = ei.getAis();
    Collections.sort(ais, new Comparator<AttributeInfo>() {

        @Override
        public int compare(AttributeInfo o1, AttributeInfo o2) {
            return o1.getXMLName().compareTo(o2.getXMLName());
        }
    });
    OtherAttributesInfo oai = ei.getOai();
    if (ais.size() > 0 && ais.get(0).getXMLName().equals("id"))
        ais.remove(0);
    if (ais.size() > 0 || oai != null) {
        xew.writeStartElement("attributes");
        for (AttributeInfo ai : ais) handle(ai);
        if (oai != null) {
            xew.writeStartElement("any");
            handleDoc(oai);
            xew.writeEndElement();
        }
        xew.writeEndElement();
    }
    List<ChildElementInfo> ceis = ei.getCeis();
    if (ceis.size() > 0) {
        xew.writeStartElement("children");
        for (ChildElementInfo cei : ceis) handle(m, main, cei);
        xew.writeEndElement();
    }
    xew.writeEndElement();
}
Also used : AttributeInfo(com.predic8.membrane.annot.model.AttributeInfo) OtherAttributesInfo(com.predic8.membrane.annot.model.OtherAttributesInfo) ChildElementInfo(com.predic8.membrane.annot.model.ChildElementInfo)

Example 5 with MainInfo

use of com.predic8.membrane.annot.model.MainInfo in project service-proxy by membrane.

the class HelpReference method getPrimaryParentId.

private String getPrimaryParentId(Model m, MainInfo mi, ElementInfo ei) {
    // choose a random parent (TODO: choose a better one)
    Set<ElementInfo> possibleParents = new HashSet<ElementInfo>();
    for (Map.Entry<TypeElement, ChildElementDeclarationInfo> e : mi.getChildElementDeclarations().entrySet()) if (e.getValue().getElementInfo().contains(ei)) {
        for (ChildElementInfo usedBy : e.getValue().getUsedBy()) {
            ElementInfo e2 = mi.getElements().get(usedBy.getEi().getElement());
            if (e2 != null)
                possibleParents.add(e2);
        }
    }
    for (ElementInfo ei2 : possibleParents) if (ei2.getAnnotation().topLevel())
        return ei2.getId();
    possibleParents.remove(ei);
    if (possibleParents.size() > 0)
        return possibleParents.iterator().next().getId();
    return null;
}
Also used : ElementInfo(com.predic8.membrane.annot.model.ElementInfo) ChildElementInfo(com.predic8.membrane.annot.model.ChildElementInfo) TypeElement(javax.lang.model.element.TypeElement) Map(java.util.Map) ChildElementInfo(com.predic8.membrane.annot.model.ChildElementInfo) ChildElementDeclarationInfo(com.predic8.membrane.annot.model.ChildElementDeclarationInfo) HashSet(java.util.HashSet)

Aggregations

ChildElementInfo (com.predic8.membrane.annot.model.ChildElementInfo)11 ElementInfo (com.predic8.membrane.annot.model.ElementInfo)9 MainInfo (com.predic8.membrane.annot.model.MainInfo)9 ArrayList (java.util.ArrayList)6 FileObject (javax.tools.FileObject)6 AttributeInfo (com.predic8.membrane.annot.model.AttributeInfo)5 ChildElementDeclarationInfo (com.predic8.membrane.annot.model.ChildElementDeclarationInfo)5 BufferedWriter (java.io.BufferedWriter)5 FilerException (javax.annotation.processing.FilerException)5 Element (javax.lang.model.element.Element)5 TypeElement (javax.lang.model.element.TypeElement)5 OtherAttributesInfo (com.predic8.membrane.annot.model.OtherAttributesInfo)2 IOException (java.io.IOException)2 Model (com.predic8.membrane.annot.model.Model)1 TextContentInfo (com.predic8.membrane.annot.model.TextContentInfo)1 BufferedOutputStream (java.io.BufferedOutputStream)1 OutputStream (java.io.OutputStream)1 HashSet (java.util.HashSet)1 Map (java.util.Map)1 Properties (java.util.Properties)1