private void checkExtends(
     ClassDeclaration classDeclaration, PackageDeclaration packageDeclaration) {
   String scName = classDeclaration.getSuperclass().toString();
   int lt = scName.indexOf('<');
   if (lt != -1) {
     scName = scName.substring(0, lt);
   }
   int dot = scName.lastIndexOf('.');
   if (dot != -1) {
     String superClassPackageName = scName.substring(0, dot);
     if (!superClassPackageName.equals(packageDeclaration.getQualifiedName())) {
       scName = ""; // force error below
     } else {
       scName = scName.substring(dot + 1);
     }
   }
   if (!scName.equals(classDeclaration.getSimpleName() + "Gen")) {
     error(
         classDeclaration,
         classDeclaration.getQualifiedName()
             + " must extend "
             + classDeclaration.getQualifiedName()
             + "Gen for @Bean to work properly");
   }
 }
 private boolean checkInheritedMethod(
     Thing data,
     String methodName,
     String returnType,
     ClassDeclaration superclass,
     boolean finalOk,
     InheritCheck inheritCheck) {
   if (inheritCheck != null) {
     if (inheritCheck.isInherited(data, superclass)) {
       return true;
     }
   }
   for (MethodDeclaration methodDeclaration : superclass.getMethods()) {
     if (methodName.equals(methodDeclaration.getSimpleName())
         && methodDeclaration.getParameters().isEmpty()
         && returnType.equals(methodDeclaration.getReturnType().toString())) {
       data.put(methodName + "Inherited", true);
       Collection<Modifier> modifiers = methodDeclaration.getModifiers();
       if ((modifiers.contains(Modifier.FINAL) || modifiers.contains(Modifier.PRIVATE))
           && !finalOk) {
         // TBD TBD TBD - ERROR!!! cannot extend class with superclass method like this - how to
         // report?
       } else if (modifiers.contains(Modifier.PROTECTED)) {
         data.put(methodName + "Modifiers", "protected");
       } else if (modifiers.contains(Modifier.PUBLIC)) {
         data.put(methodName + "Modifiers", "public");
       } else {
         data.put(methodName + "Modifiers", "");
       }
       return true;
     }
   }
   if (superclass.getSuperclass() != null) {
     if (superclass.getSuperclass().getDeclaration() != null) {
       if (checkInheritedMethod(
           data,
           methodName,
           returnType,
           superclass.getSuperclass().getDeclaration(),
           finalOk,
           inheritCheck)) {
         return true;
       }
     }
   }
   return false;
 }
  /**
   * Visits a class declaration.
   *
   * @param d the declaration to visit
   */
  public void visitClassDeclaration(ClassDeclaration d) {
    d.accept(pre);

    SortedSet<Declaration> decls = new TreeSet<Declaration>(SourceOrderDeclScanner.comparator);

    for (TypeParameterDeclaration tpDecl : d.getFormalTypeParameters()) {
      decls.add(tpDecl);
    }

    for (FieldDeclaration fieldDecl : d.getFields()) {
      decls.add(fieldDecl);
    }

    for (MethodDeclaration methodDecl : d.getMethods()) {
      decls.add(methodDecl);
    }

    for (TypeDeclaration typeDecl : d.getNestedTypes()) {
      decls.add(typeDecl);
    }

    for (ConstructorDeclaration ctorDecl : d.getConstructors()) {
      decls.add(ctorDecl);
    }

    for (Declaration decl : decls) decl.accept(this);

    d.accept(post);
  }
  public static boolean checkIfAnnotationValueAttributeIsEntity(
      AnnotationMirror mirror, String attributeName, EclipseMessager messager) {
    Map<AnnotationTypeElementDeclaration, AnnotationValue> valueMap = mirror.getElementValues();
    Set<Map.Entry<AnnotationTypeElementDeclaration, AnnotationValue>> valueSet =
        valueMap.entrySet();

    for (Map.Entry<AnnotationTypeElementDeclaration, AnnotationValue> annoKeyValue : valueSet) {
      if (annoKeyValue.getKey().getSimpleName().equals(attributeName)) {
        ClassDeclaration annoValue = (ClassDeclaration) annoKeyValue.getValue().getValue();
        Entity entityAnnotation = annoValue.getAnnotation(Entity.class);
        if (entityAnnotation == null) {
          SourcePosition pos = annoKeyValue.getValue().getPosition();
          messager.printError(
              pos,
              "'"
                  + attributeName
                  + "' attribute value class should be annotated with 'javax.persistence.Entity'");
          return false;
        }
      }
    }
    return true;
  }
Example #5
0
 @Test(result = "T")
 Collection<TypeParameterDeclaration> getFormalTypeParameters2() {
   return nested.getFormalTypeParameters();
 }
Example #6
0
 @Test(result = {"m1()", "m2()", "m2(int)"})
 Collection<MethodDeclaration> getMethods() {
   return nested.getMethods();
 }
Example #7
0
 @Test(result = {"null"})
 ClassType objectHasNoSuperclass() {
   return object.getSuperclass();
 }
Example #8
0
 @Test(result = "java.io.Serializable")
 Collection<InterfaceType> getSuperinterfaces() {
   return nested.getSuperinterfaces();
 }
Example #9
0
 // Check for default constructor.
 // 4997614: visitConstructionDeclaration reports info when there is no ctor
 @Test(result = {"NestedClass()"})
 Collection<ConstructorDeclaration> getConstructors2() {
   return nested.getConstructors();
 }
Example #10
0
 @Test(result = "ClassDecl.NestedClass")
 String getQualifiedName2() {
   return nested.getQualifiedName();
 }
Example #11
0
 @Test(result = "java.lang.Object")
 String getQualifiedName3() {
   return object.getQualifiedName();
 }
  @Override
  public void process() {
    final AnnotationTypeDeclaration beanAnn =
        (AnnotationTypeDeclaration) env_.getTypeDeclaration(Bean.class.getName());
    for (Declaration declaration : env_.getDeclarationsAnnotatedWith(beanAnn)) {
      try {
        if (!(declaration instanceof ClassDeclaration)) {
          error(declaration, "You can only annotate class declarations with @Bean");
          return;
        }

        Thing data = new Thing("data");

        ClassDeclaration classDeclaration = (ClassDeclaration) declaration;
        PackageDeclaration packageDeclaration = classDeclaration.getPackage();

        Map<String, AnnotationValue> beanValues =
            getAnnotationValues(classDeclaration, "com.javadude.annotation.Bean");

        checkExtends(classDeclaration, packageDeclaration); // check that the class extends XXXGen
        processSuperclass(data, beanValues); // process the superclass attribute
        processProperties(data, beanValues);
        processObservers(data, beanValues);
        processNullObjects(data, beanValues);
        processDelegates(data, beanValues);
        processDefaultMethods(data, classDeclaration);

        setValue(data, beanValues, "cloneable", false);
        setValue(data, beanValues, "defineEqualsAndHashCode", false);
        setValue(data, beanValues, "equalsAndHashCodeCallSuper", false);
        setValue(data, beanValues, "definePropertyNameConstants", false);
        setValue(data, beanValues, "defineCreatePropertyMap", false);
        data.put("date", new Date());
        data.put("year", Calendar.getInstance().get(Calendar.YEAR));
        data.put("className", classDeclaration.getSimpleName());
        data.put("packageName", packageDeclaration.getQualifiedName());

        data.checkAllValuesSet(declaration, this);

        Filer f = env_.getFiler();
        PrintWriter pw = f.createSourceFile(classDeclaration.getQualifiedName() + "Gen");

        if (nestedEclipse) {
          // debugging in eclipse -- reread the template each time
          FileReader fileReader =
              new FileReader(
                  workspace
                      + "/com.javadude.annotation/template/$packageName$/$className$Gen.java");
          template = new TemplateReader().readTemplate(fileReader);
        }
        int spacesForLeadingTabs = i(beanValues, "spacesForLeadingTabs", -1);
        String padding = null;
        if (spacesForLeadingTabs != -1) {
          padding = "";
          for (int i = 0; i < spacesForLeadingTabs; i++) {
            padding += ' ';
          }
        }
        template.process(new Symbols(data), pw, -1, padding);
        pw.close();
      } catch (ThreadDeath e) {
        throw e;
      } catch (ExpressionException e) {
        error(declaration, "@Bean generator error: " + e.getMessage());
      } catch (Throwable t) {
        StringWriter stringWriter = new StringWriter();
        PrintWriter printWriter = new PrintWriter(stringWriter);
        t.printStackTrace(printWriter);
        printWriter.close();
        error(declaration, "Unexpected exception: " + stringWriter.toString());
      }
    }
  }
Example #13
0
 @Test(result = "java.lang")
 PackageDeclaration getPackage2() {
   return object.getPackage();
 }
Example #14
0
 @Test(result = "ClassDecl")
 TypeDeclaration getDeclaringType2() {
   return nested.getDeclaringType();
 }
Example #15
0
 @Test(result = "NestedClass")
 String getSimpleName2() {
   return nested.getSimpleName();
 }
Example #16
0
 // Check that static nested class has "static" modifier, even though
 // the VM doesn't set that bit.
 @Test(result = {"private", "static", "strictfp"})
 Collection<Modifier> getModifiers2() {
   return nested.getModifiers();
 }
  private void processSuperclass(Thing data, Map<String, AnnotationValue> beanValues) {
    AnnotationValue value = beanValues.get("superclass");
    data.put("superclass", null);
    data.put("genericDecls", "");
    data.put("classModifiers", "");
    data.put("propertyNameConstantsInherited", false);
    data.put("getPropertyChangeSupportInherited", false);
    data.put("getPropertyChangeSupportModifiers", "protected");
    data.put("paramStringInherited", false);
    data.put("paramStringModifiers", "protected");
    data.put("createPropertyMapInherited", false);
    data.put("createPropertyMapModifiers", "public");
    data.put("atLeastOneDouble", false);
    data.put("atLeastOneBound", false);
    data.put("atLeastOneObject", false);
    data.put("atLeastOneDefault", false);

    if (value == null) {
      data.setEmpty("superclassConstructors");
    } else {
      if (!(value.getValue() instanceof ClassDeclaration)) {
        error(value, "superclass must be a class");
        return;
      }
      ClassDeclaration superclass = (ClassDeclaration) value.getValue();
      data.put("superclass", superclass.getQualifiedName());
      boolean hasProperties = !l(beanValues, "properties").isEmpty();
      // check if getPropertyChangeSupport or some superclass defines bound properties in @Bean
      checkInheritedMethod(
          data,
          "getPropertyChangeSupport",
          "java.beans.PropertyChangeSupport",
          superclass,
          true,
          new InheritCheck() {
            @Override
            public boolean isInherited(Thing d, ClassDeclaration classDeclaration) {
              Bean beanAnn = classDeclaration.getAnnotation(Bean.class);
              if (beanAnn != null) {
                Property[] properties = beanAnn.properties();
                for (Property property : properties) {
                  if (property.bound()) {
                    d.put("getPropertyChangeSupportInherited", true);
                    d.put("getPropertyChangeSupportModifiers", "protected");
                    return true;
                  }
                }
              }
              return false;
            }
          });
      // check if paramString inherited or some superclass has @Bean
      checkInheritedMethod(
          data,
          "paramString",
          "java.lang.String",
          superclass,
          !hasProperties,
          new InheritCheck() {
            @Override
            public boolean isInherited(Thing d, ClassDeclaration classDeclaration) {
              if (classDeclaration.getAnnotation(Bean.class) != null) {
                d.put("paramStringInherited", true);
                d.put("paramStringModifiers", "protected");
                return true;
              }
              return false;
            }
          });
      // check if createPropertyMap inherited or some superclass has @Bean with
      // defineCreatePropertyMap
      checkInheritedMethod(
          data,
          "createPropertyMap",
          "java.lang.String",
          superclass,
          !hasProperties,
          new InheritCheck() {
            @Override
            public boolean isInherited(Thing d, ClassDeclaration classDeclaration) {
              Bean beanAnn = classDeclaration.getAnnotation(Bean.class);
              if (beanAnn != null && beanAnn.defineCreatePropertyMap()) {
                d.put("createPropertyMapInherited", true);
                d.put("createPropertyMapModifiers", "public");
                return true;
              }
              return false;
            }
          });

      String genericDecls = null;
      Collection<TypeParameterDeclaration> formalTypeParameters2 =
          superclass.getFormalTypeParameters();
      for (TypeParameterDeclaration typeParameterDeclaration : formalTypeParameters2) {
        genericDecls = addWithCommasBetween(genericDecls, typeParameterDeclaration);
      }
      if (genericDecls == null) {
        genericDecls = "";
      } else {
        genericDecls = '<' + genericDecls + '>';
      }
      data.put("genericDecls", genericDecls);

      String classModifiers = "";
      for (Modifier modifier : superclass.getModifiers()) {
        if (!"abstract".equals(modifier.toString())) {
          classModifiers += modifier.toString() + ' ';
        }
      }
      data.put("classModifiers", classModifiers);

      Collection<ConstructorDeclaration> constructors = superclass.getConstructors();
      if (constructors.isEmpty()) {
        data.setEmpty("superclassConstructors");
      } else {
        for (ConstructorDeclaration constructorDeclaration : constructors) {
          data.add("superclassConstructors", setupMethod(constructorDeclaration, false));
        }
      }

      boolean extendPropertyNameConstants = false;
      if (b(beanValues, "definePropertyNameConstants")) {
        // if superclass has a PropertyNameConstants interface or a Bean annotation with
        //     definePropertyNameConstants=true, we need to have our PropertyNameConstants
        //     extend it
        Collection<TypeDeclaration> nestedTypes = superclass.getNestedTypes();
        for (TypeDeclaration typeDeclaration : nestedTypes) {
          if ("PropertyNames".equals(typeDeclaration.getSimpleName())
              && (typeDeclaration instanceof InterfaceDeclaration)) {
            extendPropertyNameConstants = true;
          }
        }
        if (!extendPropertyNameConstants) {
          // check if the superclass is annotated with Bean
          Bean annotation = superclass.getAnnotation(Bean.class);
          if (annotation != null) {
            extendPropertyNameConstants = annotation.definePropertyNameConstants();
          }
        }
      }
      data.put("propertyNameConstantsInherited", extendPropertyNameConstants);
    }
  }
  private void processDefaultMethods(Thing data, ClassDeclaration classDeclaration) {
    // find any methods that have default parameters
    boolean error = false;
    for (ConstructorDeclaration constructorDeclaration : classDeclaration.getConstructors()) {
      Collection<ParameterDeclaration> parameters = constructorDeclaration.getParameters();
      for (ParameterDeclaration parameterDeclaration : parameters) {
        Default annotation = parameterDeclaration.getAnnotation(Default.class);
        if (annotation != null) {
          error(parameterDeclaration, "@Default is not legal in constructor parameters");
          error = true;
        }
      }
    }
    if (error) {
      return;
    }

    boolean atLeastOneDefault = false;
    methods:
    for (MethodDeclaration methodDeclaration : classDeclaration.getMethods()) {
      Collection<ParameterDeclaration> parameters = methodDeclaration.getParameters();
      boolean seenDefault = false;
      String[] names = new String[parameters.size()];
      String[] types = new String[parameters.size()];
      String[] defaults = new String[parameters.size()];
      int n = 0;
      for (ParameterDeclaration parameterDeclaration : parameters) {
        Default annotation = parameterDeclaration.getAnnotation(Default.class);
        names[n] = parameterDeclaration.getSimpleName();
        types[n] = parameterDeclaration.getType().toString();
        if (annotation != null) {
          seenDefault = true;
          if ("java.lang.String".equals(types[n])) {
            defaults[n] = '"' + annotation.value() + '"';
          } else {
            defaults[n] = annotation.value();
          }
        } else if (seenDefault) {
          error(
              parameterDeclaration,
              "All parameters after a parameter annotated with @Default must be annotated with @Default");
          continue methods;
        }
        n++;
      }

      if (seenDefault) {
        atLeastOneDefault = true;
        if (methodDeclaration.getModifiers().contains(Modifier.PRIVATE)) {
          error(methodDeclaration, "Private methods cannot use @Default parameters");
        }
        if (methodDeclaration.getModifiers().contains(Modifier.STATIC)) {
          error(methodDeclaration, "Static methods cannot use @Default parameters");
        }
        String modifiers3 = "";
        if (methodDeclaration.getModifiers().contains(Modifier.PUBLIC)) {
          modifiers3 = "public ";
        } else if (methodDeclaration.getModifiers().contains(Modifier.PROTECTED)) {
          modifiers3 = "protected ";
        }
        String throwsClause = getThrowsClause(methodDeclaration);
        String returnType = methodDeclaration.getReturnType().toString();
        String methodName = methodDeclaration.getSimpleName();
        String argDecl = "";
        String callArgs = "";
        for (int i = 0; i < n; i++) {
          if (defaults[i] != null) {
            String callArgsWithDefaults = callArgs;
            for (int j = i; j < n; j++) {
              if (j > 0) {
                callArgsWithDefaults += ", ";
              }
              callArgsWithDefaults += defaults[j];
            }
            Thing method = new Thing("method");
            method.put("name", methodName);
            method.put("returnType", returnType);
            method.put("throwsClause", throwsClause);
            method.put("argDecls", argDecl);
            method.put("modifiers", modifiers3);
            method.put("args", callArgsWithDefaults);
            data.add("defaultMethods", method);
          }
          if (i > 0) {
            argDecl += ", ";
            callArgs += ", ";
          }
          argDecl += types[i] + ' ' + names[i];
          callArgs += names[i];
        }
        Thing method = new Thing("method");
        method.put("name", methodName);
        method.put("returnType", returnType);
        method.put("throwsClause", throwsClause);
        method.put("modifiers", modifiers3);
        method.put("abstract", true);
        method.put("argDecls", argDecl);
        data.add("defaultMethods", method);
      }
    }
    data.put("atLeastOneDefault", atLeastOneDefault);
    if (!atLeastOneDefault) {
      data.setEmpty("defaultMethods");
    }
  }