/** * Inject extra bound fields into a classInfo. * * @param extraBoundFields a list that represents the extra fields defined inside a @{@link * BoundBox} annotation. * @param classInfo representation of the class whose BoundBox will receive the extra fields. */ private void injectExtraBoundFields( List<? extends AnnotationValue> extraBoundFields, ClassInfo classInfo) { if (extraBoundFields == null || extraBoundFields.isEmpty()) { return; } List<FieldInfo> listFieldInfos = classInfo.getListFieldInfos(); TypeMirror fieldClass = null; String fieldName = null; for (AnnotationValue annotationValue : extraBoundFields) { AnnotationMirror annotationMirror = (AnnotationMirror) annotationValue.getValue(); log.info("mirror " + annotationMirror.getAnnotationType()); Map<? extends ExecutableElement, ? extends AnnotationValue> mapExecutableElementToAnnotationValue = annotationMirror.getElementValues(); for (Map.Entry<? extends ExecutableElement, ? extends AnnotationValue> entry : mapExecutableElementToAnnotationValue.entrySet()) { if (BOUNDBOX_ANNOTATION_PARAMETER_EXTRA_BOUND_FIELDS_FIELD_NAME.equals( entry.getKey().getSimpleName().toString())) { fieldName = getAnnotationValueAsString(entry.getValue()); // TODO shoot an error if its null or not a valid field name in java } if (BOUNDBOX_ANNOTATION_PARAMETER_EXTRA_BOUND_FIELDS_FIELD_CLASS.equals( entry.getKey().getSimpleName().toString())) { fieldClass = (TypeMirror) entry.getValue().getValue(); } } FieldInfo fieldInfo = new FieldInfo(fieldName, fieldClass); // TODO we should add a warning to the developer here. // TODO there can even be an error if a field of the same name but with a different type // exists. if (!listFieldInfos.contains(fieldInfo)) { listFieldInfos.add(fieldInfo); } } }
@Override public boolean process( final Set<? extends TypeElement> annotations, final RoundEnvironment roundEnvironment) { // Get all classes that has the annotation Set<? extends Element> classElements = roundEnvironment.getElementsAnnotatedWith(BoundBox.class); // For each class that has the annotation for (final Element classElement : classElements) { // Get the annotation information TypeElement boundClass = null; String maxSuperClass = null; String[] prefixes = null; String boundBoxPackageName = null; List<? extends AnnotationValue> extraBoundFields = null; List<? extends AnnotationMirror> listAnnotationMirrors = classElement.getAnnotationMirrors(); if (listAnnotationMirrors == null) { messager.printMessage(Kind.WARNING, "listAnnotationMirrors is null", classElement); return true; } StringBuilder message = new StringBuilder(); for (AnnotationMirror annotationMirror : listAnnotationMirrors) { log.info("mirror " + annotationMirror.getAnnotationType()); Map<? extends ExecutableElement, ? extends AnnotationValue> map = annotationMirror.getElementValues(); for (Map.Entry<? extends ExecutableElement, ? extends AnnotationValue> entry : map.entrySet()) { message.append(entry.getKey().getSimpleName().toString()); message.append("\n"); message.append(entry.getValue().toString()); if (BOUNDBOX_ANNOTATION_PARAMETER_BOUND_CLASS.equals( entry.getKey().getSimpleName().toString())) { boundClass = getAnnotationValueAsTypeElement(entry.getValue()); } if (BOUNDBOX_ANNOTATION_PARAMETER_MAX_SUPER_CLASS.equals( entry.getKey().getSimpleName().toString())) { maxSuperClass = getAnnotationValueAsTypeElement(entry.getValue()).asType().toString(); } if (BOUNDBOX_ANNOTATION_PARAMETER_EXTRA_BOUND_FIELDS.equals( entry.getKey().getSimpleName().toString())) { extraBoundFields = getAnnotationValueAsAnnotationValueList(entry.getValue()); } if (BOUNDBOX_ANNOTATION_PARAMETER_PREFIXES.equals( entry.getKey().getSimpleName().toString())) { List<? extends AnnotationValue> listPrefixes = getAnnotationValueAsAnnotationValueList(entry.getValue()); prefixes = new String[listPrefixes.size()]; for (int indexAnnotation = 0; indexAnnotation < listPrefixes.size(); indexAnnotation++) { prefixes[indexAnnotation] = getAnnotationValueAsString(listPrefixes.get(indexAnnotation)); } } if (BOUNDBOX_ANNOTATION_PARAMETER_PACKAGE.equals( entry.getKey().getSimpleName().toString())) { boundBoxPackageName = getAnnotationValueAsString(entry.getValue()); } } } if (boundClass == null) { messager.printMessage(Kind.WARNING, "BoundClass is null : " + message, classElement); return true; } if (maxSuperClass != null) { boundClassVisitor.setMaxSuperClassName(maxSuperClass); } if (prefixes != null && prefixes.length != 2 && prefixes.length != 1) { error( classElement, "You must provide 1 or 2 prefixes. The first one for class names, the second one for methods."); return true; } if (prefixes != null && prefixes.length == 1) { String[] newPrefixes = new String[] {prefixes[0], prefixes[0].toLowerCase(Locale.US)}; prefixes = newPrefixes; } boundboxWriter.setPrefixes(prefixes); if (boundBoxPackageName == null) { String boundClassFQN = boundClass.getQualifiedName().toString(); if (boundClassFQN.contains(PACKAGE_SEPARATOR)) { boundBoxPackageName = StringUtils.substringBeforeLast(boundClassFQN, PACKAGE_SEPARATOR); } else { boundBoxPackageName = StringUtils.EMPTY; } } boundClassVisitor.setBoundBoxPackageName(boundBoxPackageName); boundboxWriter.setBoundBoxPackageName(boundBoxPackageName); ClassInfo classInfo = boundClassVisitor.scan(boundClass); injectExtraBoundFields(extraBoundFields, classInfo); listClassInfo.add(classInfo); // perform some computations on meta model inheritanceComputer.computeInheritanceAndHidingFields(classInfo.getListFieldInfos()); inheritanceComputer.computeInheritanceAndOverridingMethods( classInfo.getListMethodInfos(), boundClass, elements); inheritanceComputer.computeInheritanceAndHidingInnerClasses( classInfo.getListInnerClassInfo()); inheritanceComputer.computeInheritanceInInnerClasses(classInfo, elements); // write meta model to java class file Writer sourceWriter = null; try { String boundBoxClassName = boundboxWriter.getNamingGenerator().createBoundBoxName(classInfo); String boundBoxClassFQN = boundBoxPackageName.isEmpty() ? boundBoxClassName : boundBoxPackageName + PACKAGE_SEPARATOR + boundBoxClassName; JavaFileObject sourceFile = filer.createSourceFile(boundBoxClassFQN, (Element[]) null); sourceWriter = sourceFile.openWriter(); boundboxWriter.writeBoundBox(classInfo, sourceWriter); } catch (IOException e) { e.printStackTrace(); error(classElement, e.getMessage()); } finally { if (sourceWriter != null) { IOUtils.closeQuietly(sourceWriter); } } } return true; }