/**
   * Create a default object of the given type. Prefers constructors with as few arguments as
   * possible. Creates an empty proxy for interfaces.
   *
   * @param type type to instantiate
   * @return default instance
   * @throws Exception if the default instance could not be created
   */
  private static Object instantiateType(Class<?> type) throws Exception {
    if (type.isPrimitive()) return Defaults.defaultValue(type);
    else if (type == Void.class) return null;
    else if (type.isArray()) return Array.newInstance(type, 0);
    else if (type.isInterface())
      return Proxy.newProxyInstance(
          type.getClassLoader(),
          new Class[] {type},
          new InvocationHandler() {
            @Override
            public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
              return null;
            }
          });

    // Take a constructor with as few params as possible
    Constructor constructor = type.getDeclaredConstructors()[0];
    for (Constructor<?> c : type.getDeclaredConstructors()) {
      if (c.getParameterTypes().length < constructor.getParameterTypes().length) constructor = c;
    }

    Object[] params = new Object[constructor.getParameterTypes().length];
    for (int i = 0; i < constructor.getParameterTypes().length; i++) {
      params[i] = instantiateType(constructor.getParameterTypes()[i]);
    }
    return constructor.newInstance(params);
  }
Пример #2
0
 private Filter newInstance(API api) throws Exception {
   for (Constructor c : api.filter().getDeclaredConstructors()) {
     c.setAccessible(true);
     Class[] ps = c.getParameterTypes();
     if (ps.length == 1 && RequestArguments.class.isAssignableFrom(ps[0]))
       return (Filter) c.newInstance(this);
   }
   for (Constructor c : api.filter().getDeclaredConstructors()) {
     Class[] ps = c.getParameterTypes();
     if (ps.length == 0) return (Filter) c.newInstance();
   }
   throw new Exception("Class " + api.filter().getName() + " must have an empty constructor");
 }
Пример #3
0
  @SuppressWarnings("unchecked")
  private <T> T _get(Class<T> type, Set<Class<?>> seenTypes) {
    if (!seenTypes.add(type)) {
      throw new IllegalStateException("Cycle in dependencies for " + type);
    }

    Object singleton = singletons.get(type);
    if (singleton != null) {
      return (T) singleton;
    }

    try {
      Constructor<T> constructor = getConstructor(type);
      Class<?>[] parameterTypes = constructor.getParameterTypes();
      Object[] parameters = new Object[parameterTypes.length];
      for (int i = 0; i < parameterTypes.length; i++) {
        parameters[i] = _get(parameterTypes[i], seenTypes);
      }

      T instance = postProcess(constructor.newInstance(parameters));
      singletons.put(type, instance);
      return instance;
    } catch (InstantiationException | IllegalAccessException | InvocationTargetException e) {
      throw new IllegalStateException("Unable to create instance of " + type);
    }
  }
Пример #4
0
  protected void _addConstructorMixIns(Class<?> mixin) {
    MemberKey[] ctorKeys = null;
    int ctorCount = (_constructors == null) ? 0 : _constructors.size();
    for (Constructor<?> ctor : mixin.getDeclaredConstructors()) {
      switch (ctor.getParameterTypes().length) {
        case 0:
          if (_defaultConstructor != null) {
            _addMixOvers(ctor, _defaultConstructor, false);
          }
          break;
        default:
          if (ctorKeys == null) {
            ctorKeys = new MemberKey[ctorCount];
            for (int i = 0; i < ctorCount; ++i) {
              ctorKeys[i] = new MemberKey(_constructors.get(i).getAnnotated());
            }
          }
          MemberKey key = new MemberKey(ctor);

          for (int i = 0; i < ctorCount; ++i) {
            if (!key.equals(ctorKeys[i])) {
              continue;
            }
            _addMixOvers(ctor, _constructors.get(i), true);
            break;
          }
      }
    }
  }
Пример #5
0
  private void validateClass(Class<?> source, ValidationProblemCollector problems) {
    int modifiers = source.getModifiers();

    if (Modifier.isInterface(modifiers)) {
      problems.add("Must be a class, not an interface");
    }

    if (source.getEnclosingClass() != null) {
      if (Modifier.isStatic(modifiers)) {
        if (Modifier.isPrivate(modifiers)) {
          problems.add("Class cannot be private");
        }
      } else {
        problems.add("Enclosed classes must be static and non private");
      }
    }

    Constructor<?>[] constructors = source.getDeclaredConstructors();
    for (Constructor<?> constructor : constructors) {
      if (constructor.getParameterTypes().length > 0) {
        problems.add("Cannot declare a constructor that takes arguments");
        break;
      }
    }

    Field[] fields = source.getDeclaredFields();
    for (Field field : fields) {
      int fieldModifiers = field.getModifiers();
      if (!field.isSynthetic()
          && !(Modifier.isStatic(fieldModifiers) && Modifier.isFinal(fieldModifiers))) {
        problems.add(field, "Fields must be static final.");
      }
    }
  }
Пример #6
0
 @SuppressWarnings("unchecked")
 public static <T> Constructor<T> findConstructor(Class<T> type, Class<?>... paramTypes) {
   Constructor<T>[] ctors = (Constructor<T>[]) type.getConstructors();
   for (Constructor<T> ctor : ctors)
     if (typesMatch(paramTypes, ctor.getParameterTypes())) return ctor;
   return null;
 }
 public void apply()
     throws IllegalAccessException, InvocationTargetException, InstantiationException {
   if (type.isEnum()) {
     for (T instance : type.getEnumConstants()) {
       assertThat(
           instance.toString(),
           is(
               type.getCanonicalName().substring(type.getPackage().getName().length() + 1)
                   + "."
                   + ((Enum<?>) instance).name()));
     }
     return;
   }
   for (Constructor<?> constructor : type.getDeclaredConstructors()) {
     if (constructor.isSynthetic() && skipSynthetic) {
       continue;
     }
     constructor.setAccessible(true);
     Class<?>[] parameterTypes = constructor.getParameterTypes();
     Object[] actualArguments = new Object[parameterTypes.length];
     Object[] otherArguments = new Object[parameterTypes.length];
     int index = 0;
     for (Class<?> parameterType : parameterTypes) {
       putInstance(parameterType, actualArguments, otherArguments, index++);
     }
     int testIndex = 0;
     @SuppressWarnings("unchecked")
     T instance = (T) constructor.newInstance(actualArguments);
     assertThat(instance, is(instance));
     assertThat(instance, not(is((Object) null)));
     assertThat(instance, not(is(new Object())));
     Object similarInstance = constructor.newInstance(actualArguments);
     assertThat(instance.hashCode(), is(similarInstance.hashCode()));
     assertThat(instance, is(similarInstance));
     if (skipToString) {
       assertThat(instance.toString(), notNullValue());
     } else if (optionalToStringRegex == null) {
       checkString(instance);
     } else {
       assertThat(instance.toString(), new RegexMatcher(optionalToStringRegex));
     }
     for (Object otherArgument : otherArguments) {
       Object[] compareArguments = new Object[actualArguments.length];
       int argumentIndex = 0;
       for (Object actualArgument : actualArguments) {
         if (argumentIndex == testIndex) {
           compareArguments[argumentIndex] = otherArgument;
         } else {
           compareArguments[argumentIndex] = actualArgument;
         }
         argumentIndex++;
       }
       Object unlikeInstance = constructor.newInstance(compareArguments);
       assertThat(instance.hashCode(), not(is(unlikeInstance)));
       assertThat(instance, not(is(unlikeInstance)));
       testIndex++;
     }
   }
 }
Пример #8
0
 private Validator newValidator(API api) throws Exception {
   for (Constructor c : api.validator().getDeclaredConstructors()) {
     c.setAccessible(true);
     Class[] ps = c.getParameterTypes();
     return (Validator) c.newInstance();
   }
   return null;
 }
Пример #9
0
 /**
  * Finds the constructor of the given class that is compatible with the given arguments.
  *
  * @param type the class to find the constructor of
  * @param args the arguments
  * @return the constructor
  */
 public static Constructor findConstructor(Class<?> type, Object[] args) {
   outer:
   for (Constructor constructor : type.getConstructors()) {
     Class<?>[] paramTypes = constructor.getParameterTypes();
     if (paramTypes.length != args.length) continue;
     for (int i = 0; i < args.length; i++) {
       Object arg = args[i];
       if (arg != null && !paramTypes[i].isAssignableFrom(arg.getClass())) continue outer;
       if (arg == null && paramTypes[i].isPrimitive()) continue outer;
     }
     return constructor;
   }
   throw new GrammarException(
       "No constructor found for %s and the given %s arguments", type, args.length);
 }
Пример #10
0
 public static <T> T newInstance(
     Constructor<T> constructor, boolean strict, Object... parameters) {
   if (!strict) parameters = convertArray(parameters, constructor.getParameterTypes());
   Class<T> type = constructor.getDeclaringClass();
   if (deprecated(type))
     escalator.escalate(
         "Instantiating a deprecated class: " + type.getName(), BeanUtil.class, null);
   try {
     return constructor.newInstance(parameters);
   } catch (InstantiationException e) {
     throw ExceptionMapper.configurationException(e, type);
   } catch (IllegalAccessException e) {
     throw ExceptionMapper.configurationException(e, type);
   } catch (InvocationTargetException e) {
     throw ExceptionMapper.configurationException(e, type);
   }
 }
Пример #11
0
  private static Object createArgumentPlaceholderForUnknownClass(
      Class<?> clazz, Integer placeholderId) throws IllegalAccessException, InstantiationException {
    FinalClassArgumentCreator<?> creator = FINAL_CLASS_ARGUMENT_CREATORS.get(clazz);
    if (creator != null) return creator.createArgumentPlaceHolder(placeholderId);

    for (Constructor constructor : clazz.getConstructors()) {
      Class<?>[] params = constructor.getParameterTypes();
      if (params.length != 1) continue;
      try {
        if (params[0] == String.class)
          return constructor.newInstance(String.valueOf(placeholderId));
        if (isNumericClass(params[0])) return constructor.newInstance(placeholderId);
      } catch (IllegalAccessException e1) {
      } catch (InvocationTargetException e2) {
      }
    }
    return clazz.newInstance();
  }
Пример #12
0
  /**
   * Prints all constructors of a class
   *
   * @param cl a class
   */
  public static void printConstructors(Class cl) {
    Constructor[] constructors = cl.getDeclaredConstructors();

    for (Constructor c : constructors) {
      String name = c.getName();
      System.out.print("   ");
      String modifiers = Modifier.toString(c.getModifiers());
      if (modifiers.length() > 0) System.out.print(modifiers + " ");
      System.out.print(name + "(");

      // print parameter types
      Class[] paramTypes = c.getParameterTypes();
      for (int j = 0; j < paramTypes.length; j++) {
        if (j > 0) System.out.print(", ");
        System.out.print(paramTypes[j].getName());
      }
      System.out.println(");");
    }
  }
 public void applyBasic()
     throws IllegalAccessException, InvocationTargetException, InstantiationException {
   for (Constructor<?> constructor : type.getDeclaredConstructors()) {
     if (constructor.isSynthetic() && skipSynthetic) {
       continue;
     }
     constructor.setAccessible(true);
     Class<?>[] parameterTypes = constructor.getParameterTypes();
     Object[] actualArguments = new Object[parameterTypes.length];
     Object[] otherArguments = new Object[parameterTypes.length];
     int index = 0;
     for (Class<?> parameterType : parameterTypes) {
       putInstance(parameterType, actualArguments, otherArguments, index++);
     }
     @SuppressWarnings("unchecked")
     T instance = (T) constructor.newInstance(actualArguments);
     checkString(instance);
     assertThat(instance, is(instance));
     assertThat(instance, not(is((Object) null)));
     assertThat(instance, not(is(new Object())));
     assertThat(instance, not(is(constructor.newInstance(otherArguments))));
   }
 }
Пример #14
0
  /**
   * Initialization method that will find out all constructors and potential static factory methods
   * the class has.
   *
   * <p>Starting with 1.2, it will also apply mix-in annotations, as per [JACKSON-76]
   *
   * @param includeAll If true, includes all creator methods; if false, will only include the
   *     no-arguments "default" constructor
   */
  public void resolveCreators(boolean includeAll) {
    // Then see which constructors we have
    _constructors = null;
    for (Constructor<?> ctor : _class.getDeclaredConstructors()) {
      switch (ctor.getParameterTypes().length) {
        case 0:
          _defaultConstructor = _constructConstructor(ctor, true);
          break;
        default:
          if (includeAll) {
            if (_constructors == null) {
              _constructors = new ArrayList<AnnotatedConstructor>();
            }
            _constructors.add(_constructConstructor(ctor, false));
          }
      }
    }
    // and if need be, augment with mix-ins
    if (_primaryMixIn != null) {
      if (_defaultConstructor != null || _constructors != null) {
        _addConstructorMixIns(_primaryMixIn);
      }
    }

    /* And then... let's remove all constructors that are
     * deemed to be ignorable after all annotations have been
     * properly collapsed.
     */
    if (_defaultConstructor != null) {
      if (_annotationIntrospector.isIgnorableConstructor(_defaultConstructor)) {
        _defaultConstructor = null;
      }
    }
    if (_constructors != null) {
      // count down to allow safe removal
      for (int i = _constructors.size(); --i >= 0; ) {
        if (_annotationIntrospector.isIgnorableConstructor(_constructors.get(i))) {
          _constructors.remove(i);
        }
      }
    }

    _creatorMethods = null;

    if (includeAll) {
      /* Then static methods which are potential factory
       * methods
       */
      for (Method m : _class.getDeclaredMethods()) {
        if (!Modifier.isStatic(m.getModifiers())) {
          continue;
        }
        int argCount = m.getParameterTypes().length;
        // factory methods take at least one arg:
        if (argCount < 1) {
          continue;
        }
        if (_creatorMethods == null) {
          _creatorMethods = new ArrayList<AnnotatedMethod>();
        }
        _creatorMethods.add(_constructCreatorMethod(m));
      }
      // mix-ins to mix in?
      if (_primaryMixIn != null && _creatorMethods != null) {
        _addFactoryMixIns(_primaryMixIn);
      }
      // anything to ignore at this point?
      if (_creatorMethods != null) {
        // count down to allow safe removal
        for (int i = _creatorMethods.size(); --i >= 0; ) {
          if (_annotationIntrospector.isIgnorableMethod(_creatorMethods.get(i))) {
            _creatorMethods.remove(i);
          }
        }
      }
    }
  }
Пример #15
0
  private static void generateCtor(
      ClassFileWriter cfw, String adapterName, String superName, Constructor<?> superCtor) {
    short locals = 3; // this + factory + delegee
    Class<?>[] parameters = superCtor.getParameterTypes();

    // Note that we swapped arguments in app-facing constructors to avoid
    // conflicting signatures with serial constructor defined below.
    if (parameters.length == 0) {
      cfw.startMethod(
          "<init>",
          "(Laurora/javascript/Scriptable;" + "Laurora/javascript/ContextFactory;)V",
          ClassFileWriter.ACC_PUBLIC);

      // Invoke base class constructor
      cfw.add(ByteCode.ALOAD_0); // this
      cfw.addInvoke(ByteCode.INVOKESPECIAL, superName, "<init>", "()V");
    } else {
      StringBuilder sig =
          new StringBuilder(
              "(Laurora/javascript/Scriptable;" + "Laurora/javascript/ContextFactory;");
      int marker = sig.length(); // lets us reuse buffer for super signature
      for (Class<?> c : parameters) {
        appendTypeString(sig, c);
      }
      sig.append(")V");
      cfw.startMethod("<init>", sig.toString(), ClassFileWriter.ACC_PUBLIC);

      // Invoke base class constructor
      cfw.add(ByteCode.ALOAD_0); // this
      short paramOffset = 3;
      for (Class<?> parameter : parameters) {
        paramOffset += generatePushParam(cfw, paramOffset, parameter);
      }
      locals = paramOffset;
      sig.delete(1, marker);
      cfw.addInvoke(ByteCode.INVOKESPECIAL, superName, "<init>", sig.toString());
    }

    // Save parameter in instance variable "delegee"
    cfw.add(ByteCode.ALOAD_0); // this
    cfw.add(ByteCode.ALOAD_1); // first arg: Scriptable delegee
    cfw.add(ByteCode.PUTFIELD, adapterName, "delegee", "Laurora/javascript/Scriptable;");

    // Save parameter in instance variable "factory"
    cfw.add(ByteCode.ALOAD_0); // this
    cfw.add(ByteCode.ALOAD_2); // second arg: ContextFactory instance
    cfw.add(ByteCode.PUTFIELD, adapterName, "factory", "Laurora/javascript/ContextFactory;");

    cfw.add(ByteCode.ALOAD_0); // this for the following PUTFIELD for self
    // create a wrapper object to be used as "this" in method calls
    cfw.add(ByteCode.ALOAD_1); // the Scriptable delegee
    cfw.add(ByteCode.ALOAD_0); // this
    cfw.addInvoke(
        ByteCode.INVOKESTATIC,
        "aurora/javascript/JavaAdapter",
        "createAdapterWrapper",
        "(Laurora/javascript/Scriptable;"
            + "Ljava/lang/Object;"
            + ")Laurora/javascript/Scriptable;");
    cfw.add(ByteCode.PUTFIELD, adapterName, "self", "Laurora/javascript/Scriptable;");

    cfw.add(ByteCode.RETURN);
    cfw.stopMethod(locals);
  }
Пример #16
0
 @SuppressWarnings({"unchecked", "rawtypes"})
 public static <T> T newInstance(Class<T> type, boolean strict, Object... parameters) {
   if (parameters.length == 0) return newInstanceFromDefaultConstructor(type);
   Constructor<T> constructorToUse = null;
   try {
     Constructor<T>[] constructors = (Constructor<T>[]) type.getConstructors();
     List<Constructor<T>> candidates = new ArrayList<Constructor<T>>(constructors.length);
     int paramCount = parameters.length;
     for (Constructor<T> constructor : constructors)
       if (constructor.getParameterTypes().length == paramCount) candidates.add(constructor);
     if (candidates.size() == 1) constructorToUse = candidates.get(0);
     else if (candidates.size() == 0)
       throw new ConfigurationError(
           "No constructor with " + paramCount + " parameters found for " + type);
     else {
       // there are several candidates - find the first one with matching types
       Class<?>[] paramTypes = new Class[parameters.length];
       for (int i = 0; i < parameters.length; i++) paramTypes[i] = parameters[i].getClass();
       for (Constructor c : type.getConstructors()) {
         if (typesMatch(c.getParameterTypes(), paramTypes)) {
           constructorToUse = c;
           break;
         }
       }
       // there is no ideal match
       if (constructorToUse == null) {
         if (strict)
           throw new NoSuchMethodException(
               "No appropriate constructor found: "
                   + type
                   + '('
                   + ArrayFormat.format(", ", paramTypes)
                   + ')');
         Exception mostRecentException = null;
         for (Constructor<T> candidate : candidates) {
           try {
             return newInstance(candidate, strict, parameters);
           } catch (Exception e) {
             mostRecentException = e;
             logger.warn("Exception in constructor call: " + candidate, e);
             continue; // ignore exception and try next constructor
           }
         }
         // no constructor could be called without exception
         String errMsg =
             (mostRecentException != null
                 ? "None of these constructors could be called without exception: "
                     + candidates
                     + ", latest exception: "
                     + mostRecentException
                 : type
                     + " has no appropriate constructor for the arguments "
                     + ArrayFormat.format(", ", parameters));
         throw new ConfigurationError(errMsg);
       }
     }
     if (!strict) parameters = convertArray(parameters, constructorToUse.getParameterTypes());
     return newInstance(constructorToUse, parameters);
   } catch (SecurityException e) {
     throw ExceptionMapper.configurationException(e, constructorToUse);
   } catch (NoSuchMethodException e) {
     throw ExceptionMapper.configurationException(e, type);
   }
 }