/**
* Copyright (C) 2010-2016 eBusiness Information, Excilys Group
* Copyright (C) 2016-2017 the AndroidAnnotations project
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License. You may obtain a copy of
* the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed To in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations under
* the License.
*/
package org.androidannotations.internal.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.internal.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/androidannotations/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) {
// ignored
} finally {
if (in != null) {
try {
in.close();
} catch (IOException e) {
// cannot help this
}
}
}
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();
}
}