Skip to content
This repository was archived by the owner on Feb 26, 2023. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ eclipse.preferences.version=1
encoding//src/main/java=UTF-8
encoding//src/main/java/rebel.xml=UTF-8
encoding//src/main/resources=UTF-8
encoding//src/main/resources/androidannotations-version.properties=utf-8
encoding//src/main/resources/rebel.xml=UTF-8
encoding//src/test/java=UTF-8
encoding//src/test/resources=UTF-8
Expand Down
18 changes: 17 additions & 1 deletion AndroidAnnotations/androidannotations/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,16 @@
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-resources-plugin</artifactId>
<version>2.5</version>
<configuration>
<encoding>${project.build.sourceEncoding}</encoding>
</configuration>
</plugin>
</plugins>

<resources>
<resource>
<directory>src/main/resources</directory>
Expand All @@ -88,7 +97,14 @@
<resource>
<directory>src/main/java</directory>
<includes>
<include>org/androidannotations/api/**</include>
<include>org/androidannotations/api/**</include>
</includes>
</resource>
<resource>
<directory>src/main/resources</directory>
<filtering>true</filtering>
<includes>
<include>**/*.properties</include>
</includes>
</resource>
</resources>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,11 +21,11 @@
import static org.androidannotations.helper.ModelConstants.TRACE_OPTION;

import java.io.IOException;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.net.URL;
import java.util.Collections;
import java.util.HashSet;
import java.util.Map;
import java.util.Properties;
import java.util.Set;

import javax.annotation.processing.AbstractProcessor;
Expand Down Expand Up @@ -117,9 +117,11 @@
import org.androidannotations.annotations.rest.RestService;
import org.androidannotations.annotations.sharedpreferences.Pref;
import org.androidannotations.annotations.sharedpreferences.SharedPref;
import org.androidannotations.exception.ProcessingException;
import org.androidannotations.generation.CodeModelGenerator;
import org.androidannotations.helper.AndroidManifest;
import org.androidannotations.helper.AndroidManifestFinder;
import org.androidannotations.helper.ErrorHelper;
import org.androidannotations.helper.Option;
import org.androidannotations.helper.TimeStats;
import org.androidannotations.model.AndroidRes;
Expand Down Expand Up @@ -270,7 +272,10 @@
@SupportedOptions({ TRACE_OPTION, ANDROID_MANIFEST_FILE_OPTION })
public class AndroidAnnotationProcessor extends AbstractProcessor {

private final Properties properties = new Properties();
private final TimeStats timeStats = new TimeStats();
private final ErrorHelper errorHelper = new ErrorHelper();

private Set<String> supportedAnnotationNames;

@Override
Expand All @@ -279,6 +284,8 @@ public synchronized void init(ProcessingEnvironment processingEnv) {

Messager messager = processingEnv.getMessager();

loadPropertyFile();

timeStats.setMessager(messager);

messager.printMessage(Diagnostic.Kind.NOTE, "Starting AndroidAnnotations annotation processing");
Expand All @@ -290,16 +297,34 @@ public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment
timeStats.start("Whole Processing");
try {
processThrowing(annotations, roundEnv);
} catch (Exception e) {
} catch (ProcessingException e) {
handleException(annotations, roundEnv, e);
} catch (Exception e) {
handleException(annotations, roundEnv, new ProcessingException(e, null));
}
timeStats.stop("Whole Processing");
timeStats.logStats();
return true;
}

private void processThrowing(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) throws Exception {
private void loadPropertyFile() {
String filename = "androidannotations-version.properties";
try {
URL url = getClass().getClassLoader().getResource(filename);
properties.load(url.openStream());
} catch (Exception e) {
e.printStackTrace();

Messager messager = processingEnv.getMessager();
messager.printMessage(Diagnostic.Kind.NOTE, "AndroidAnnotations processing failed because " + filename + " couldn't be parsed : " + e.getLocalizedMessage());
}
}

private String getAAProcessorVersion() {
return properties.getProperty("version", "3.0+");
}

private void processThrowing(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) throws ProcessingException, Exception {
if (nothingToDo(annotations, roundEnv)) {
return;
}
Expand Down Expand Up @@ -372,7 +397,7 @@ private Option<IRClass> findRClasses(AndroidManifest androidManifest) throws IOE
return Option.of(coumpoundRClass);
}

private AnnotationElements validateAnnotations(AnnotationElementsHolder extractedModel, IRClass rClass, AndroidSystemServices androidSystemServices, AndroidManifest androidManifest) {
private AnnotationElements validateAnnotations(AnnotationElementsHolder extractedModel, IRClass rClass, AndroidSystemServices androidSystemServices, AndroidManifest androidManifest) throws ProcessingException, Exception {
timeStats.start("Validate Annotations");
ModelValidator modelValidator = buildModelValidator(rClass, androidSystemServices, androidManifest);
AnnotationElements validatedAnnotations = modelValidator.validate(extractedModel);
Expand Down Expand Up @@ -468,7 +493,7 @@ private boolean traceActivated() {
}
}

private ProcessResult processAnnotations(AnnotationElements validatedModel, IRClass rClass, AndroidSystemServices androidSystemServices, AndroidManifest androidManifest) throws Exception {
private ProcessResult processAnnotations(AnnotationElements validatedModel, IRClass rClass, AndroidSystemServices androidSystemServices, AndroidManifest androidManifest) throws ProcessingException, Exception {
timeStats.start("Process Annotations");
ModelProcessor modelProcessor = buildModelProcessor(rClass, androidSystemServices, androidManifest, validatedModel);
ProcessResult processResult = modelProcessor.process(validatedModel);
Expand Down Expand Up @@ -559,13 +584,13 @@ private void generateSources(ProcessResult processResult) throws IOException {
timeStats.start("Generate Sources");
Messager messager = processingEnv.getMessager();
messager.printMessage(Diagnostic.Kind.NOTE, "Number of files generated by AndroidAnnotations: " + processResult.codeModel.countArtifacts());
CodeModelGenerator modelGenerator = new CodeModelGenerator(processingEnv.getFiler(), messager);
CodeModelGenerator modelGenerator = new CodeModelGenerator(processingEnv.getFiler(), messager, getAAProcessorVersion());
modelGenerator.generate(processResult);
timeStats.stop("Generate Sources");
}

private void handleException(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv, Exception e) {
String errorMessage = "Unexpected error. Please report an issue on AndroidAnnotations, with the following content: " + stackTraceToString(e);
private void handleException(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv, ProcessingException e) {
String errorMessage = errorHelper.getErrorMessage(processingEnv, e, getAAProcessorVersion());

Messager messager = processingEnv.getMessager();
messager.printMessage(Diagnostic.Kind.ERROR, errorMessage);
Expand All @@ -580,13 +605,6 @@ private void handleException(Set<? extends TypeElement> annotations, RoundEnviro
messager.printMessage(Diagnostic.Kind.ERROR, errorMessage, element);
}

private String stackTraceToString(Throwable e) {
StringWriter writer = new StringWriter();
PrintWriter pw = new PrintWriter(writer);
e.printStackTrace(pw);
return writer.toString();
}

@Override
public Set<String> getSupportedAnnotationTypes() {
if (supportedAnnotationNames == null) {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
package org.androidannotations.exception;

import javax.lang.model.element.Element;

public class ProcessingException extends Exception {

private static final long serialVersionUID = -1282996599471872615L;

private Element element;

public ProcessingException(Throwable cause, Element element) {
super(cause);
this.element = element;
}

public ProcessingException(String message, Throwable cause, Element element) {
super(message, cause);
this.element = element;
}

public Element getElement() {
return element;
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -28,10 +28,12 @@ public class CodeModelGenerator {

private final Filer filer;
private final Messager messager;
private final String aaVersion;

public CodeModelGenerator(Filer filer, Messager messager) {
public CodeModelGenerator(Filer filer, Messager messager, String aaVersion) {
this.filer = filer;
this.messager = messager;
this.aaVersion = aaVersion;
}

public void generate(ProcessResult processResult) throws IOException {
Expand All @@ -41,7 +43,7 @@ public void generate(ProcessResult processResult) throws IOException {

SourceCodewriter sourceCodeWriter = new SourceCodewriter(filer, messager, processResult.originatingElements);

PrologCodeWriter prologCodeWriter = new PrologCodeWriter(sourceCodeWriter, "DO NOT EDIT THIS FILE, IT HAS BEEN GENERATED USING AndroidAnnotations.\n");
PrologCodeWriter prologCodeWriter = new PrologCodeWriter(sourceCodeWriter, "DO NOT EDIT THIS FILE, IT HAS BEEN GENERATED USING AndroidAnnotations " + aaVersion + ".\n");

processResult.codeModel.build(prologCodeWriter, new ResourceCodeWriter(filer));
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
package org.androidannotations.helper;

import java.io.BufferedReader;
import java.io.CharArrayWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;

import javax.annotation.processing.ProcessingEnvironment;
import javax.lang.model.element.Element;
import javax.lang.model.util.Elements;

import org.androidannotations.exception.ProcessingException;

public class ErrorHelper {

public String getErrorMessage(ProcessingEnvironment processingEnv, ProcessingException e, String aaVersion) {
String errorMessage = "Unexpected error in AndroidAnnotations " + aaVersion + "!\n" //
+ "You should check if there is already an issue about it on https://github.com/excilys/androidannotations/search?q=" + urlEncodedErrorMessage(e) + "&type=Issues\n" //
+ "If none exists, please open a new one with the following content and tell us if you can reproduce it or not. Don't forget to give us as much information as you can (like parts of your code in failure).\n";
errorMessage += "Java version: " + getJavaCompilerVersion() + "\n";
errorMessage += "Javac processors options: " + annotationProcessorOptions(processingEnv) + "\n";
errorMessage += "Stacktrace: " + stackTraceToString(e.getCause());

Element element = e.getElement();
if (element != null) {
errorMessage += "Thrown from: " + elementContainer(element) + "\n";
errorMessage += "Element (" + element.getClass().getSimpleName() + "): " + elementFullString(processingEnv, element) + "\n";
}

return errorMessage;
}

private String elementFullString(ProcessingEnvironment processingEnv, Element element) {
Elements elementUtils = processingEnv.getElementUtils();
CharArrayWriter writer = new CharArrayWriter();
elementUtils.printElements(writer, element);
return writer.toString();
}

private String elementContainer(Element element) {
Element enclosingElement = element.getEnclosingElement();
return enclosingElement != null ? enclosingElement.toString() : "";
}

private String annotationProcessorOptions(ProcessingEnvironment processingEnv) {
Map<String, String> options = processingEnv.getOptions();
Set<Entry<String, String>> optionsEntries = options.entrySet();

String result = "";
for (Entry<String, String> optionEntry : optionsEntries) {
result += optionEntry.getKey() + "=" + optionEntry.getValue() + ", ";
}
return result.length() > 2 ? result.substring(0, result.length() - 2) : result;
}

private String getJavaCompilerVersion() {
ProcessBuilder pb = new ProcessBuilder("javac", "-version");
pb.redirectErrorStream(true);

BufferedReader in = null;
try {
Process process = pb.start();
in = new BufferedReader(new InputStreamReader(process.getInputStream()));
String buffer = in.readLine();
process.waitFor();
return buffer;
} catch (Exception e) {
} finally {
if (in != null) {
try {
in.close();
} catch (IOException e) {
}
}
}
return "unknown";
}

private String urlEncodedErrorMessage(Throwable e) {
try {
return URLEncoder.encode(e.getCause().getClass().getName(), "UTF-8");
} catch (UnsupportedEncodingException e1) {
return "";
}
}

private String stackTraceToString(Throwable e) {
StringWriter writer = new StringWriter();
PrintWriter pw = new PrintWriter(writer);
e.printStackTrace(pw);
return writer.toString();
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
import javax.lang.model.element.Modifier;
import javax.lang.model.element.TypeElement;

import org.androidannotations.exception.ProcessingException;
import org.androidannotations.model.AnnotationElements;
import org.androidannotations.model.AnnotationElements.AnnotatedAndRootElements;

Expand Down Expand Up @@ -59,7 +60,7 @@ public void register(GeneratingElementProcessor processor) {
typeProcessors.add(processor);
}

public ProcessResult process(AnnotationElements validatedModel) throws Exception {
public ProcessResult process(AnnotationElements validatedModel) throws ProcessingException, Exception {

JCodeModel codeModel = new JCodeModel();

Expand All @@ -75,7 +76,7 @@ public ProcessResult process(AnnotationElements validatedModel) throws Exception
* extend them).
*/
if (!isAbstractClass(annotatedElement)) {
processor.process(annotatedElement, codeModel, eBeansHolder);
processThrowing(processor, annotatedElement, codeModel, eBeansHolder);
}
}
/*
Expand All @@ -99,7 +100,7 @@ public ProcessResult process(AnnotationElements validatedModel) throws Exception
* elements that are not validated, and therefore not available.
*/
if (holder != null) {
processor.process(elements.annotatedElement, codeModel, holder);
processThrowing(processor, elements.annotatedElement, codeModel, holder);
}
}

Expand All @@ -120,7 +121,7 @@ public ProcessResult process(AnnotationElements validatedModel) throws Exception
*/
if (!isAbstractClass(enclosingElement)) {
EBeanHolder holder = eBeansHolder.getEBeanHolder(enclosingElement);
processor.process(annotatedElement, codeModel, holder);
processThrowing(processor, annotatedElement, codeModel, holder);
}
}

Expand All @@ -132,6 +133,22 @@ public ProcessResult process(AnnotationElements validatedModel) throws Exception
eBeansHolder.getApiClassesToGenerate());
}

private void processThrowing(GeneratingElementProcessor processor, Element element, JCodeModel codeModel, EBeansHolder eBeansHolder) throws Exception, ProcessingException {
try {
processor.process(element, codeModel, eBeansHolder);
} catch (Exception e) {
throw new ProcessingException(e, element);
}
}

private void processThrowing(DecoratingElementProcessor processor, Element element, JCodeModel codeModel, EBeanHolder eBeanHolder) throws Exception, ProcessingException {
try {
processor.process(element, codeModel, eBeanHolder);
} catch (Exception e) {
throw new ProcessingException(e, element);
}
}

private boolean isAbstractClass(Element annotatedElement) {
if (annotatedElement instanceof TypeElement) {
TypeElement typeElement = (TypeElement) annotatedElement;
Expand Down
Loading