package restx.exceptions.processor; import com.google.common.base.CharMatcher; import com.google.common.base.Joiner; import com.google.common.collect.ImmutableMap; import com.google.common.collect.Lists; import com.samskivert.mustache.Template; import restx.common.Mustaches; import restx.common.processor.RestxAbstractProcessor; import restx.exceptions.ErrorCode; import restx.exceptions.ErrorField; import javax.annotation.processing.RoundEnvironment; import javax.annotation.processing.SupportedAnnotationTypes; import javax.annotation.processing.SupportedOptions; import javax.lang.model.element.Element; import javax.lang.model.element.ElementKind; import javax.lang.model.element.TypeElement; import java.util.List; import java.util.Locale; import java.util.Set; /** * User: xavierhanin * Date: 3/19/13 * Time: 10:20 PM */ @SupportedAnnotationTypes({ "restx.exceptions.ErrorCode" }) @SupportedOptions({ "debug" }) public class ErrorAnnotationProcessor extends RestxAbstractProcessor { final Template errorDescriptorTpl; public ErrorAnnotationProcessor() { errorDescriptorTpl = Mustaches.compile(ErrorAnnotationProcessor.class, "ErrorDescriptor.mustache"); } @Override protected boolean processImpl(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) throws Exception{ for (Element elem : roundEnv.getElementsAnnotatedWith(ErrorCode.class)) { try { ErrorCode errorCode = elem.getAnnotation(ErrorCode.class); TypeElement typeElement = (TypeElement) elem; String fqcn = typeElement.getQualifiedName().toString(); int i = CharMatcher.JAVA_UPPER_CASE.indexIn(fqcn); String pack = fqcn.substring(0, i - 1); String name = fqcn.substring(i).replace(".", ""); String descriptor = name + "Descriptor"; List<String> fields = Lists.newArrayList(); for (Element element : typeElement.getEnclosedElements()) { if (element.getKind() == ElementKind.ENUM_CONSTANT) { String field = element.getSimpleName().toString(); ErrorField errorField = element.getAnnotation(ErrorField.class); String description = errorField == null ? field.replace("_", " ").toLowerCase(Locale.ENGLISH) : errorField.value(); fields.add(String.format(".put(\"%s\", new ErrorDescriptor.ErrorFieldDescriptor(\"%s\", \"%s\"))", field, field, description)); } } ImmutableMap<String, Object> ctx = ImmutableMap.<String, Object>builder() .put("package", pack) .put("descriptor", descriptor) .put("errorStatus", String.valueOf(errorCode.status().getCode())) .put("errorCode", errorCode.code()) .put("description", errorCode.description()) .put("fields", Joiner.on("\n").join(fields)).build(); generateJavaClass(pack + "." + descriptor, errorDescriptorTpl, ctx, elem); } catch (Exception e) { fatalError("error when processing " + elem, e, elem); } } return true; } }