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;
}
}
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());
}
}
}
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);
}
Aggregations