示例#1
0
  /**
   * Returns a new injection point for the injectable constructor of {@code type}.
   *
   * @param type a concrete type with exactly one constructor annotated {@literal @}{@link Inject},
   *     or a no-arguments constructor that is not private.
   * @throws ConfigurationException if there is no injectable constructor, more than one injectable
   *     constructor, or if parameters of the injectable constructor are malformed, such as a
   *     parameter with multiple binding annotations.
   */
  public static InjectionPoint forConstructorOf(TypeLiteral<?> type) {
    Class<?> rawType = getRawType(type.getType());
    Errors errors = new Errors(rawType);

    Constructor<?> injectableConstructor = null;
    for (Constructor<?> constructor : rawType.getDeclaredConstructors()) {

      boolean optional;
      Inject guiceInject = constructor.getAnnotation(Inject.class);
      if (guiceInject == null) {
        javax.inject.Inject javaxInject = constructor.getAnnotation(javax.inject.Inject.class);
        if (javaxInject == null) {
          continue;
        }
        optional = false;
      } else {
        optional = guiceInject.optional();
      }

      if (optional) {
        errors.optionalConstructor(constructor);
      }

      if (injectableConstructor != null) {
        errors.tooManyConstructors(rawType);
      }

      injectableConstructor = constructor;
      checkForMisplacedBindingAnnotations(injectableConstructor, errors);
    }

    errors.throwConfigurationExceptionIfErrorsExist();

    if (injectableConstructor != null) {
      return new InjectionPoint(type, injectableConstructor);
    }

    // If no annotated constructor is found, look for a no-arg constructor instead.
    try {
      Constructor<?> noArgConstructor = rawType.getDeclaredConstructor();

      // Disallow private constructors on non-private classes (unless they have @Inject)
      if (Modifier.isPrivate(noArgConstructor.getModifiers())
          && !Modifier.isPrivate(rawType.getModifiers())) {
        errors.missingConstructor(rawType);
        throw new ConfigurationException(errors.getMessages());
      }

      checkForMisplacedBindingAnnotations(noArgConstructor, errors);
      return new InjectionPoint(type, noArgConstructor);
    } catch (NoSuchMethodException e) {
      errors.missingConstructor(rawType);
      throw new ConfigurationException(errors.getMessages());
    }
  }
示例#2
0
  private void checkCompoundIds(Class<?> javaClass) throws IOException {
    String javaClassName = javaClass.getCanonicalName();
    PsiClass psiClass =
        myJavaPsiFacade.findClass(
            javaClassName, GlobalSearchScope.moduleWithLibrariesScope(myModule));
    assertNotNull(psiClass);

    for (java.lang.reflect.Method javaMethod : javaClass.getDeclaredMethods()) {
      Method method =
          new Method(
              Type.getType(javaClass).getInternalName(),
              javaMethod.getName(),
              Type.getMethodDescriptor(javaMethod));
      boolean noKey = javaMethod.getAnnotation(ExpectNoPsiKey.class) != null;
      PsiMethod psiMethod = psiClass.findMethodsByName(javaMethod.getName(), false)[0];
      checkCompoundId(method, psiMethod, noKey);
    }

    for (Constructor<?> constructor : javaClass.getDeclaredConstructors()) {
      Method method =
          new Method(
              Type.getType(javaClass).getInternalName(),
              "<init>",
              Type.getConstructorDescriptor(constructor));
      boolean noKey = constructor.getAnnotation(ExpectNoPsiKey.class) != null;
      PsiMethod[] constructors = psiClass.getConstructors();
      PsiMethod psiMethod = constructors[0];
      checkCompoundId(method, psiMethod, noKey);
    }
  }
示例#3
0
  @Test(groups = "unit", timeOut = 1000)
  public void test() throws ClassNotFoundException {
    final Collection<Class<?>> descriptionClasses = Lists.newArrayList();
    final URL url =
        AnnotationTests.class.getClassLoader().getResource("META-INF/jobs/persistence.xml");
    final String jpaConfigContents = InputContexts.toString(InputContexts.forUrl(url));
    final List<Class<? extends ActivityDescription>> activityDescriptionsMapped =
        Lists.newArrayList();
    for (final Class<? extends ActivityFactory<?>> factoryClass : FACTORIES) {
      // Make sure the class is make as a ManageBean to DI context picks it up.
      assert factoryClass.getAnnotation(ManagedBean.class) != null
          : "Factory class " + factoryClass + " is not annotated with @ManagedBean";

      // assert factoryClass.getDeclaredConstructors().length == 1;
      boolean foundInjectedConstructor = false;
      for (Constructor<?> constructor : factoryClass.getDeclaredConstructors()) {
        if (constructor.getParameterTypes().length == 0
            || constructor.getAnnotation(Inject.class) != null) {
          foundInjectedConstructor = true;
        }
      }
      assert foundInjectedConstructor;

      final ActivityFactoryFor factoryAnnotation =
          factoryClass.getAnnotation(ActivityFactoryFor.class);
      // Make sure this class specifies which ActivityDescription it acts an ActivityFactory for.
      assert factoryAnnotation != null;
      final Class<? extends ActivityDescription> descriptionClass = factoryAnnotation.value();
      activityDescriptionsMapped.add(descriptionClass);
      assert ActivityDescription.class.isAssignableFrom(descriptionClass);
      // Make sure there are not multiple descriptions per factory
      assert !descriptionClasses.contains(descriptionClass);

      // Make sure the description can be persisted
      assert descriptionClass.getAnnotation(Entity.class) != null
          : descriptionClass + " is not annotated with entity.";
      assert jpaConfigContents.contains(descriptionClass.getCanonicalName())
          : "Class " + descriptionClass.getCanonicalName() + " not found in JPA configuration.";
    }

    final Pattern pattern = Pattern.compile("\\<class\\>.*\\<");
    final Matcher matcher = pattern.matcher(jpaConfigContents);
    int start = 0;
    while (matcher.find(start)) {
      final int startIdx = matcher.start() + "<class>".length();
      final int endIdx = jpaConfigContents.indexOf("<", startIdx);
      final String classStr = jpaConfigContents.substring(startIdx, endIdx);
      final Class<?> clazz = Class.forName(classStr);
      if (ActivityDescription.class.isAssignableFrom(clazz)) {
        if (!Modifier.isAbstract(clazz.getModifiers())) {
          assert activityDescriptionsMapped.contains(clazz)
              : "No activity factory found for description class " + clazz;
        }
      }
      start = endIdx;
    }
  }
 @Test
 public void javaLangAnnotationTypeViaFindMergedAnnotation() throws Exception {
   Constructor<?> deprecatedCtor = Date.class.getConstructor(String.class);
   assertEquals(
       deprecatedCtor.getAnnotation(Deprecated.class),
       findMergedAnnotation(deprecatedCtor, Deprecated.class));
   assertEquals(
       Date.class.getAnnotation(Deprecated.class),
       findMergedAnnotation(Date.class, Deprecated.class));
 }
  private EnumSet<ExecutableType> executableTypesDefinedOnConstructor(Constructor<?> constructor) {
    ValidateOnExecution validateOnExecutionAnnotation =
        constructor.getAnnotation(ValidateOnExecution.class);
    EnumSet<ExecutableType> executableTypes =
        commonExecutableTypeChecks(validateOnExecutionAnnotation);

    if (executableTypes.contains(ExecutableType.IMPLICIT)) {
      executableTypes.add(ExecutableType.CONSTRUCTORS);
    }

    return executableTypes;
  }
  static int examine(Class enclosedClass, String constructorSig) {
    Constructor c = enclosedClass.getEnclosingConstructor();
    if (c == null && constructorSig == null) return 0;

    if (c != null && c.getAnnotation(ConstructorDescriptor.class).value().equals(constructorSig))
      return 0; // everything is okay
    else {
      System.err.println(
          "\nUnexpected constructor value; expected:\t" + constructorSig + "\ngot:\t" + c);
      return 1;
    }
  }
 /**
  * Finds the conversion method.
  *
  * @param <T> the type of the converter
  * @param cls the class to find a method for, not null
  * @return the method to call, null means use {@code toString}
  * @throws RuntimeException if invalid
  */
 private <T> Constructor<T> findFromStringConstructor(Class<T> cls) {
   Constructor<T> con;
   try {
     con = cls.getDeclaredConstructor(String.class);
   } catch (NoSuchMethodException ex) {
     try {
       con = cls.getDeclaredConstructor(CharSequence.class);
     } catch (NoSuchMethodException ex2) {
       return null;
     }
   }
   FromString fromString = con.getAnnotation(FromString.class);
   return fromString != null ? con : null;
 }
示例#8
0
  private void initProperties(Class<?> clazz, Set<Class<?>> visited) {
    if (visited.add(clazz)) {
      CssDocProperty property = clazz.getAnnotation(CssDocProperty.class);

      if (property != null) {
        properties.add(new DocProperty(this, property, clazz));
      }
      for (Constructor<?> constructor : clazz.getDeclaredConstructors()) {
        property = constructor.getAnnotation(CssDocProperty.class);
        if (property != null) {
          properties.add(new DocProperty(this, property, clazz));
        }
      }

      for (Field field : clazz.getDeclaredFields()) {
        property = field.getAnnotation(CssDocProperty.class);
        if (property != null) {
          properties.add(new DocProperty(this, property, field.getType()));
        }
      }

      for (Method method : clazz.getDeclaredMethods()) {
        property = method.getAnnotation(CssDocProperty.class);
        if (property != null) {
          properties.add(new DocProperty(this, property, method.getReturnType()));
        }
      }

      Collections.sort(
          properties,
          new Comparator<DocProperty>() {
            private Collator collator = Collator.getInstance();

            @Override
            public int compare(DocProperty a, DocProperty b) {
              return collator.compare(a.getName(), b.getName());
            }
          });

      CssDocSeeAlso seeAlso = clazz.getAnnotation(CssDocSeeAlso.class);
      if (seeAlso != null) {
        for (Class<?> next : seeAlso.value()) {
          initProperties(next, visited);
        }
      }
    }
  }
 public static String[] evaluate(Constructor<?> candidate, int paramCount) {
   ConstructorProperties cp = candidate.getAnnotation(ConstructorProperties.class);
   if (cp != null) {
     String[] names = cp.value();
     if (names.length != paramCount) {
       throw new IllegalStateException(
           "Constructor annotated with @ConstructorProperties but not "
               + "corresponding to actual number of parameters ("
               + paramCount
               + "): "
               + candidate);
     }
     return names;
   } else {
     return null;
   }
 }
示例#10
0
  private void initPaths() {
    paths = new HashMap<String, CssDocPath>();

    addPath(clazz.getAnnotation(CssDocPath.class));
    for (Constructor<?> constructor : clazz.getDeclaredConstructors()) {
      addPath(constructor.getAnnotation(CssDocPath.class));
    }
    for (Field field : clazz.getDeclaredFields()) {
      addPath(field.getAnnotation(CssDocPath.class));
    }
    for (Method method : clazz.getDeclaredMethods()) {
      addPath(method.getAnnotation(CssDocPath.class));
    }
    for (DocProperty property : this) {
      addPath(property.getAnnotation().path());
    }
  }
示例#11
0
  /**
   * Return true if the type is not abstract and not an interface, and has a constructor annotated
   * with {@link Inject} or its only constructor is the default constructor.
   *
   * @param type A class type
   * @return True if the class type is instantiable
   */
  public static boolean isInstantiable(Class<?> type) {
    if (!Modifier.isAbstract(type.getModifiers()) && !type.isInterface()) {
      // first check for a constructor annotated with @Inject,
      //  - this doesn't care how many we'll let the injector complain
      //    if there are more than one
      for (Constructor<?> c : type.getDeclaredConstructors()) {
        if (c.getAnnotation(Inject.class) != null) {
          return true;
        }
      }

      // check if we only have the public default constructor
      if (type.getConstructors().length == 1
          && type.getConstructors()[0].getParameterTypes().length == 0) {
        return true;
      }
    }

    // no constructor available
    return false;
  }
示例#12
0
 private static Collection<? extends MockBinder> createMockBinders(Constructor<?> constructor) {
   if (constructor.getAnnotation(Inject.class) != null) {
     HashSet<MockBinder> mockBinders = new HashSet<MockBinder>();
     for (int parameterIndex = 0;
         parameterIndex < constructor.getParameterTypes().length;
         parameterIndex++) {
       for (Annotation annotation : constructor.getParameterAnnotations()[parameterIndex]) {
         if (annotation.annotationType() == Mock.class) {
           Class<?> mockClass = constructor.getParameterTypes()[parameterIndex];
           String mockName =
               defaultIfEmpty(
                   ((Mock) annotation).value(), uncapitalize(mockClass.getSimpleName()));
           mockBinders.add(new SimpleMockBinder(mockClass, mockName));
         }
       }
     }
     return mockBinders;
   } else {
     return Collections.emptyList();
   }
 }
示例#13
0
    private void fillCat2Funs(final Map<String, FunctionInfo> funs) {
      for (Entry<String, FunctionInfo> e : funs.entrySet()) {

        Class<?> funClass = e.getValue().getFunction().getClass();
        assert (funClass.getConstructors().length == 1);
        Constructor<?> cons = funClass.getConstructors()[0];

        String name = e.getKey();
        String constructorDescription = null;

        Description consAnno = cons.getAnnotation(Description.class);
        if (consAnno != null) {
          constructorDescription = consAnno.description();
        }

        HashMap<Category, ArrayList<SignatureInfo>> cat2sig = new HashMap<>();
        int methodCount = e.getValue().signatures.length;
        for (int i = 0; i < methodCount; i++) {
          createSigInfo(e, consAnno, cat2sig, i);
        }

        for (Category cat : cat2sig.keySet()) {
          SortedMap<String, AnnotationInfo> m = cat2funs.get(cat);
          if (m == null) {
            m = new TreeMap<>();
            cat2funs.put(cat, m);
          }
          AnnotationInfo aninfo = new AnnotationInfo();
          aninfo.name = name;
          aninfo.constructorDescription = constructorDescription;
          aninfo.signatureInfos = cat2sig.get(cat).toArray(new SignatureInfo[] {});
          m.put(aninfo.name, aninfo);
          cat2funs.put(cat, m);
        }
      }
    }
示例#14
0
  private final void init(E instance) {

    // Arrays can be mapped easily
    if (type.isArray()) {
      delegate = new ArrayMapper(instance);
      return;
    }

    // [#3212] "Value types" can be mapped from single-field Record1 types for convenience
    if (type.isPrimitive() || DefaultDataType.types().contains(type)) {
      delegate = new ValueTypeMapper();
      return;
    }

    // [#1470] Return a proxy if the supplied type is an interface
    if (Modifier.isAbstract(type.getModifiers())) {
      delegate = new ProxyMapper();
      return;
    }

    // [#2989] [#2836] Records are mapped
    if (AbstractRecord.class.isAssignableFrom(type)) {
      delegate = (RecordMapper<R, E>) new RecordToRecordMapper();
      return;
    }

    // [#1340] Allow for using non-public default constructors
    try {
      delegate = new MutablePOJOMapper(type.getDeclaredConstructor(), instance);
      return;
    } catch (NoSuchMethodException ignore) {
    }

    // [#1336] If no default constructor is present, check if there is a
    // "matching" constructor with the same number of fields as this record
    Constructor<E>[] constructors = (Constructor<E>[]) type.getDeclaredConstructors();

    // [#1837] If any java.beans.ConstructorProperties annotations are
    // present use those rather than matching constructors by the number of
    // arguments
    for (Constructor<E> constructor : constructors) {
      ConstructorProperties properties = constructor.getAnnotation(ConstructorProperties.class);

      if (properties != null) {
        delegate = new ImmutablePOJOMapperWithConstructorProperties(constructor, properties);
        return;
      }
    }

    // [#1837] Without ConstructorProperties, match constructors by matching
    // argument length
    for (Constructor<E> constructor : constructors) {
      Class<?>[] parameterTypes = constructor.getParameterTypes();

      // Match the first constructor by parameter length
      if (parameterTypes.length == fields.length) {
        delegate = new ImmutablePOJOMapper(constructor, parameterTypes);
        return;
      }
    }

    throw new MappingException(
        "No matching constructor found on type " + type + " for record " + this);
  }
示例#15
0
  @SuppressWarnings("unchecked")
  public static <T> JsapResultsWithObject<T> constructObject(
      Class<T> clazz, String[] rawArguments, String mainHelp, Parameter[] otherParameters)
      throws JSAPException, IOException, IllegalArgumentException, ReflectiveOperationException {
    Constructor<T> constructor = null;
    for (Constructor<?> constr : clazz.getConstructors()) {
      boolean annotationPresent = constr.isAnnotationPresent(CommandLine.class);
      if (annotationPresent) {
        constructor = (Constructor<T>) constr;
        break;
      }
    }
    if (constructor == null)
      throw new IllegalAccessError(
          "Class " + clazz + " must have a constructor annotated with @CommandLine");

    String[] argNames = constructor.getAnnotation(CommandLine.class).argNames();
    if (argNames.length != constructor.getParameterCount())
      throw new IllegalAnnotationException(
          "Annotation @CommandLine argNames are out of sync with the constructor arguments.");

    boolean[] isSerializedFile = new boolean[argNames.length];

    SimpleJSAP jsap = new SimpleJSAP(clazz.getName(), mainHelp, otherParameters);
    int i = 0;
    for (java.lang.reflect.Parameter x : constructor.getParameters()) {
      Parameter option;
      if (x.getType().equals(boolean.class)) {
        isSerializedFile[i] = false;
        option =
            new Switch(
                argNames[i],
                JSAP.NO_SHORTFLAG,
                argNames[i],
                "Set the value of " + argNames[i] + " for " + clazz.getSimpleName() + " as true.");
      } else {
        StringParser parser;
        String help;
        try {
          parser = getParserFor(x.getType());
          isSerializedFile[i] = false;
          help = "The " + x.getType().getSimpleName() + " value of " + argNames[i];
        } catch (NoJSAPParserForThisTypeException e) {
          parser = JSAP.STRING_PARSER;
          isSerializedFile[i] = true;
          help =
              "A serialized " + x.getType().getSimpleName() + " file to initialize " + argNames[i];
        }
        option = new UnflaggedOption(argNames[i], parser, JSAP.REQUIRED, help);
      }

      jsap.registerParameter(option);

      i++;
    }

    JSAPResult args = jsap.parse(rawArguments);
    if (jsap.messagePrinted()) System.exit(1);

    LOGGER.info("Initializing...");
    Object[] arguments = new Object[argNames.length];
    i = 0;
    for (String argName : argNames) {
      if (isSerializedFile[i]) arguments[i] = SerializationUtils.read(args.getString(argName));
      else arguments[i] = args.getObject(argName);
      i++;
    }
    T object = constructor.newInstance(arguments);
    LOGGER.info("Ready.");

    return new JsapResultsWithObject<T>(args, object);
  }
示例#16
0
    public final String getHtmlDescription() {
      StringBuilder sb = new StringBuilder();
      sb.append("<html><body><p>GReQL function <font color=\"blue\"><strong>")
          .append(name)
          .append("</strong></font></p><dl>");
      assert (functionClass.getConstructors().length == 1);
      Constructor<?> cons = functionClass.getConstructors()[0];

      Description consDesc = cons.getAnnotation(Description.class);

      for (Signature sig : signatures) {
        Description funDesc = sig.evaluateMethod.getAnnotation(Description.class);
        if (funDesc == null) {
          funDesc = consDesc;
        }
        if (funDesc == null) {
          continue;
        }
        Class<?> ret = sig.evaluateMethod.getReturnType();
        String returnType = Types.getGreqlTypeName(ret);

        boolean acceptsType =
            sig.parameterTypes[sig.parameterTypes.length - 1] == TypeCollection.class;
        sb.append("<dt><strong><font color=\"purple\">")
            .append(returnType)
            .append(" <font color=\"blue\">")
            .append(name)
            .append("</font></strong>");
        if (acceptsType) {
          sb.append(" { <font color=\"#008000\">types...</font> } ");
        }
        sb.append("(");
        String delim = "";
        int i = 0;
        for (String p : funDesc.params()) {
          if ((i == 0) && needsGraphArgument) {
            // don't show Graph argument
            ++i;
            continue;
          }
          if ((i == 0) && needsEvaluatorArgument) {
            // don't show evaluator argument
            ++i;
            continue;
          }
          if ((i == (sig.parameterTypes.length - 1)) && acceptsType) {
            // don't show TypeCollection argument
            ++i;
            continue;
          }
          Class<?> cls = sig.parameterTypes[i++];
          String type = Types.getGreqlTypeName(cls);
          sb.append(delim)
              .append("<strong><font color=\"purple\">")
              .append(type)
              .append("</font></strong> ")
              .append(p);
          delim = ", ";
        }
        sb.append(")</dt><dd>").append(funDesc.description()).append("</dd>");
      }
      sb.append("</dl></body></html>");
      return sb.toString();
    }