Search in sources :

Example 1 with NgModelSourceLink

use of com.github.davityle.ngprocessor.source.links.NgModelSourceLink in project ngAndroid by davityle.

the class NgProcessor method process.

@Override
public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) {
    this.roundEnv = roundEnv;
    if (annotations.size() == 0)
        return false;
    try {
        this.dependencyComponent = dependencyComponentBuilder.environmentModule(new EnvironmentModule(envModule.getOrElse(new ResolverImpl()))).build();
        final MessageUtils messageUtils = dependencyComponent.createMessageUtils();
        messageUtils.note(Option.<Element>absent(), ":NgAndroid:processing");
        Option<String> manifestPackageName = getPackageNameFromAndroidManifest();
        if (manifestPackageName.isAbsent()) {
            messageUtils.error(Option.<Element>absent(), ":NgAndroid:Unable to find android manifest.");
            return false;
        }
        Set<Scope> scopes = getScopeSet(annotations);
        Map<Layout, Collection<XmlScope>> xmlScopes = getXmlScopes();
        if (messageUtils.hasErrors())
            return false;
        Map<Layout, Collection<Scope>> layoutsWScopes = mapLayoutsToScopes(scopes, xmlScopes);
        Collection<LayoutSourceLink> layoutSourceLinks = getLayoutSourceLinks(layoutsWScopes, manifestPackageName.get());
        Collection<ScopeSourceLink> scopeSourceLinks = getScopeSourceLinks(scopes, manifestPackageName.get());
        List<NgModelSourceLink> modelSourceLinks = getModelSourceLinks(getModels(annotations));
        createSourceFiles(modelSourceLinks, layoutSourceLinks, scopeSourceLinks);
        messageUtils.note(Option.<Element>absent(), ":NgAndroid:finished");
        return true;
    } catch (Throwable t) {
        StringWriter sw = new StringWriter();
        t.printStackTrace(new PrintWriter(sw));
        processingEnv.getMessager().printMessage(Diagnostic.Kind.ERROR, "There was an error compiling your ngAttributes: " + sw.toString().replace('\n', ' '), null);
        return false;
    }
}
Also used : LayoutSourceLink(com.github.davityle.ngprocessor.source.links.LayoutSourceLink) NgModelSourceLink(com.github.davityle.ngprocessor.source.links.NgModelSourceLink) ScopeSourceLink(com.github.davityle.ngprocessor.source.links.ScopeSourceLink) XmlScope(com.github.davityle.ngprocessor.xml.XmlScope) Scope(com.github.davityle.ngprocessor.model.Scope) StringWriter(java.io.StringWriter) Layout(com.github.davityle.ngprocessor.model.Layout) Collection(java.util.Collection) MessageUtils(com.github.davityle.ngprocessor.util.MessageUtils) PrintWriter(java.io.PrintWriter)

Example 2 with NgModelSourceLink

use of com.github.davityle.ngprocessor.source.links.NgModelSourceLink in project ngAndroid by davityle.

the class SourceCreator method createSourceFiles.

public void createSourceFiles() {
    Properties props = new Properties();
    props.setProperty("runtime.log.logsystem.class", "org.apache.velocity.runtime.log.SystemLogChute");
    props.setProperty("resource.loader", "classpath");
    props.setProperty("classpath.resource.loader.class", "org.apache.velocity.runtime.resource.loader.ClasspathResourceLoader");
    VelocityEngine ve = new VelocityEngine(props);
    ve.init();
    Template vtModel = ve.getTemplate("templates/ngmodel.vm");
    Template vtScope = ve.getTemplate("templates/scope.vm");
    Template vtLayout = ve.getTemplate("templates/layout.vm");
    for (NgModelSourceLink ms : modelSourceLinks) {
        try {
            JavaFileObject jfo = filer.createSourceFile(ms.getSourceFileName(), ms.getElements());
            Writer writer = jfo.openWriter();
            vtModel.merge(ms.getVelocityContext(), writer);
            writer.flush();
            writer.close();
        } catch (IOException e) {
            messageUtils.error(Option.of(ms.getElements()[0]), e.getMessage());
        }
    }
    for (ScopeSourceLink ss : scopeSourceLinks) {
        try {
            JavaFileObject jfo = filer.createSourceFile(ss.getSourceFileName(), ss.getElements());
            Writer writer = jfo.openWriter();
            vtScope.merge(ss.getVelocityContext(), writer);
            writer.flush();
            writer.close();
        } catch (IOException e) {
            messageUtils.error(Option.of(ss.getElements()[0]), e.getMessage());
        }
    }
    for (LayoutSourceLink lsl : layoutSourceLinks) {
        try {
            JavaFileObject jfo = filer.createSourceFile(lsl.getSourceFileName(), lsl.getElements());
            Writer writer = jfo.openWriter();
            vtLayout.merge(lsl.getVelocityContext(), writer);
            writer.flush();
            writer.close();
        } catch (IOException e) {
            messageUtils.error(Option.<Element>absent(), e.getMessage());
        }
    }
}
Also used : VelocityEngine(org.apache.velocity.app.VelocityEngine) JavaFileObject(javax.tools.JavaFileObject) ScopeSourceLink(com.github.davityle.ngprocessor.source.links.ScopeSourceLink) Element(javax.lang.model.element.Element) LayoutSourceLink(com.github.davityle.ngprocessor.source.links.LayoutSourceLink) IOException(java.io.IOException) Properties(java.util.Properties) Writer(java.io.Writer) Template(org.apache.velocity.Template) NgModelSourceLink(com.github.davityle.ngprocessor.source.links.NgModelSourceLink)

Example 3 with NgModelSourceLink

use of com.github.davityle.ngprocessor.source.links.NgModelSourceLink in project ngAndroid by davityle.

the class ModelSourceLinker method getSourceLink.

private NgModelSourceLink getSourceLink(Element element) {
    TypeMirror fieldType = element.asType();
    TypeElement typeElement = typeUtils.asTypeElement(fieldType);
    Option<String> packageName = elementUtils.getPackageName(typeElement);
    String fullName = elementUtils.getFullName(typeElement);
    List<SourceField> fields = new ArrayList<>();
    String modelName = elementUtils.stripClassName(fieldType);
    List<? extends Element> enclosedElements = typeElement.getEnclosedElements();
    boolean isInterface = typeElement.getKind().isInterface();
    if (isInterface) {
        messageUtils.error(Option.of(typeElement), "Model must be a class");
    }
    Set<String> duplicateCheck = new HashSet<>();
    for (int index = 0; index < enclosedElements.size(); index++) {
        Element enclosedElement = enclosedElements.get(index);
        if (elementUtils.isSetter(enclosedElement)) {
            ExecutableElement setter = (ExecutableElement) enclosedElement;
            if (!elementUtils.returnsVoid(setter)) {
                messageUtils.error(Option.of(element), "Setter '%s' must not return a value", element.toString());
                continue;
            }
            Set<Modifier> modifiers = setter.getModifiers();
            if (modifiers.contains(Modifier.PRIVATE) || modifiers.contains(Modifier.PROTECTED)) {
                messageUtils.error(Option.of(setter), "Unable to access field '%s' from scope '%s'. Must have default or public access", element.toString(), element.getEnclosingElement().toString());
                continue;
            }
            String fName = setter.getSimpleName().toString().substring(3).toLowerCase();
            if (duplicateCheck.contains(fName)) {
                messageUtils.error(Option.of(setter), "Field '%s' in model '%s' is a duplicate.", setter.getSimpleName().toString().substring(3), fullName);
                continue;
            }
            duplicateCheck.add(fName);
            TypeMirror typeMirror = setter.getParameters().get(0).asType();
            String type = typeMirror.toString();
            SourceField sourceField = new SourceField(fName, type, primitiveUtils);
            sourceField.setSetter(setter.getSimpleName().toString());
            // TODO O(n^2) is the best
            boolean getterFound = false;
            for (Element possGetter : enclosedElements) {
                if (elementUtils.isGetterForField(possGetter, fName, typeMirror.getKind())) {
                    sourceField.setGetter(possGetter.getSimpleName().toString());
                    getterFound = true;
                    break;
                }
            }
            if (!getterFound) {
                messageUtils.error(Option.of(setter), "Field '%s' is missing a corresponding getter", fName);
            }
            fields.add(sourceField);
        }
    }
    return new NgModelSourceLink(modelName, packageName, fullName, isInterface, fields, element);
}
Also used : TypeElement(javax.lang.model.element.TypeElement) SourceField(com.github.davityle.ngprocessor.source.SourceField) ExecutableElement(javax.lang.model.element.ExecutableElement) Element(javax.lang.model.element.Element) TypeElement(javax.lang.model.element.TypeElement) ExecutableElement(javax.lang.model.element.ExecutableElement) ArrayList(java.util.ArrayList) NgModelSourceLink(com.github.davityle.ngprocessor.source.links.NgModelSourceLink) TypeMirror(javax.lang.model.type.TypeMirror) Modifier(javax.lang.model.element.Modifier) HashSet(java.util.HashSet)

Aggregations

NgModelSourceLink (com.github.davityle.ngprocessor.source.links.NgModelSourceLink)3 LayoutSourceLink (com.github.davityle.ngprocessor.source.links.LayoutSourceLink)2 ScopeSourceLink (com.github.davityle.ngprocessor.source.links.ScopeSourceLink)2 Element (javax.lang.model.element.Element)2 Layout (com.github.davityle.ngprocessor.model.Layout)1 Scope (com.github.davityle.ngprocessor.model.Scope)1 SourceField (com.github.davityle.ngprocessor.source.SourceField)1 MessageUtils (com.github.davityle.ngprocessor.util.MessageUtils)1 XmlScope (com.github.davityle.ngprocessor.xml.XmlScope)1 IOException (java.io.IOException)1 PrintWriter (java.io.PrintWriter)1 StringWriter (java.io.StringWriter)1 Writer (java.io.Writer)1 ArrayList (java.util.ArrayList)1 Collection (java.util.Collection)1 HashSet (java.util.HashSet)1 Properties (java.util.Properties)1 ExecutableElement (javax.lang.model.element.ExecutableElement)1 Modifier (javax.lang.model.element.Modifier)1 TypeElement (javax.lang.model.element.TypeElement)1