Example #1
0
  /**
   * 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);
      }
    }
  }
Example #2
0
  @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;
  }