Пример #1
0
  @Nullable
  public InstanceFactory findInstanceFactory(@Nonnull Type mockedType) {
    InstanceFactory instanceFactory = mockedTypesAndInstances.get(mockedType);

    if (instanceFactory != null) {
      return instanceFactory;
    }

    Class<?> mockedClass = getClassType(mockedType);
    //noinspection ReuseOfLocalVariable
    instanceFactory = mockedTypesAndInstances.get(mockedClass);

    if (instanceFactory != null) {
      return instanceFactory;
    }

    boolean abstractType = mockedClass.isInterface() || isAbstract(mockedClass.getModifiers());

    for (Entry<Type, InstanceFactory> entry : mockedTypesAndInstances.entrySet()) {
      Type registeredMockedType = entry.getKey();
      Class<?> registeredMockedClass = getClassType(registeredMockedType);

      if (abstractType) {
        registeredMockedClass = getMockedClassOrInterfaceType(registeredMockedClass);
      }

      if (mockedClass.isAssignableFrom(registeredMockedClass)) {
        instanceFactory = entry.getValue();
        break;
      }
    }

    return instanceFactory;
  }
Пример #2
0
 public boolean conformsTo(Type t) {
   if (t instanceof ClassAny) {
     ClassAny ca = (ClassAny) t;
     Class otherClass = ca.c;
     return otherClass.isAssignableFrom(c);
   } else {
     return false;
   }
 }
Пример #3
0
  public static int nextDelegate(Object[] beans, Class<?>[] apis, int index) {
    for (index--; index >= 0; index--) {
      for (Class<?> api : apis) {
        if (api.isAssignableFrom(beans[index].getClass())) return index;
      }
    }

    return index;
  }
  public static Field findAssignableField(Class clazz, Class type, String name)
      throws NoSuchFieldException {
    final ArrayList<Field> fields = collectFields(clazz);
    for (Field each : fields) {
      if (name.equals(each.getName()) && type.isAssignableFrom(each.getType())) return each;
    }

    throw new NoSuchFieldException("Class: " + clazz + " name: " + name + " type: " + type);
  }
 public void mapToType(Class<?> type) {
   if (!targetType.isAssignableFrom(type)) {
     throw new IllegalArgumentException(
         String.format(
             "requested wrapper type '%s' is not assignable to target type '%s'.",
             type.getSimpleName(), targetType.getSimpleName()));
   }
   wrapperType = type;
 }
Пример #6
0
  /**
   * Determine which of two signatures is the closer fit. Returns one of PREFERENCE_EQUAL,
   * PREFERENCE_FIRST_ARG, PREFERENCE_SECOND_ARG, or PREFERENCE_AMBIGUOUS.
   */
  private static int preferSignature(
      Object[] args, Class<?>[] sig1, boolean vararg1, Class<?>[] sig2, boolean vararg2) {
    int totalPreference = 0;
    for (int j = 0; j < args.length; j++) {
      Class<?> type1 = vararg1 && j >= sig1.length ? sig1[sig1.length - 1] : sig1[j];
      Class<?> type2 = vararg2 && j >= sig2.length ? sig2[sig2.length - 1] : sig2[j];
      if (type1 == type2) {
        continue;
      }
      Object arg = args[j];

      // Determine which of type1, type2 is easier to convert from arg.

      int rank1 = NativeJavaObject.getConversionWeight(arg, type1);
      int rank2 = NativeJavaObject.getConversionWeight(arg, type2);

      int preference;
      if (rank1 < rank2) {
        preference = PREFERENCE_FIRST_ARG;
      } else if (rank1 > rank2) {
        preference = PREFERENCE_SECOND_ARG;
      } else {
        // Equal ranks
        if (rank1 == NativeJavaObject.CONVERSION_NONTRIVIAL) {
          if (type1.isAssignableFrom(type2)) {
            preference = PREFERENCE_SECOND_ARG;
          } else if (type2.isAssignableFrom(type1)) {
            preference = PREFERENCE_FIRST_ARG;
          } else {
            preference = PREFERENCE_AMBIGUOUS;
          }
        } else {
          preference = PREFERENCE_AMBIGUOUS;
        }
      }

      totalPreference |= preference;

      if (totalPreference == PREFERENCE_AMBIGUOUS) {
        break;
      }
    }
    return totalPreference;
  }
Пример #7
0
 private static boolean typeMatches(Class<?> foundType, Class<?> expectedType) {
   if (foundType == null) return true;
   if (expectedType.isAssignableFrom(foundType)) return true;
   if (isPrimitiveType(expectedType.getName())
       && foundType.equals(getWrapper(expectedType.getName()))) return true;
   if (isPrimitiveType(foundType.getName())
       && expectedType.equals(getWrapper(foundType.getName()))) return true;
   if (isNumberType(foundType) && isNumberType(expectedType)) return true;
   return false;
 }
Пример #8
0
  /**
   * Return the type distance between the child and parent types. The child type must be a subtype
   * of the parent. The type distance between a class and itself is 0; the distance from a class to
   * one of its immediate supertypes (superclass or a directly implemented interface) is 1; deeper
   * distances are computed recursively.
   *
   * @param child The child type
   * @param parent The parent type
   * @return The type distance
   * @throws IllegalArgumentException if {@code child} is not a subtype of {@code parent}.
   */
  public static int getTypeDistance(@Nonnull Class<?> child, @Nonnull Class<?> parent) {
    Preconditions.notNull("child class", child);
    Preconditions.notNull("parent class", parent);

    if (child.equals(parent)) {
      // fast-path same-class tests
      return 0;
    } else if (!parent.isAssignableFrom(child)) {
      // if child does not extend from the parent, return -1
      throw new IllegalArgumentException("child not a subclass of parent");
    } else if (!parent.isInterface()) {
      // if the parent is not an interface, we only need to follower superclasses
      int distance = 0;
      Class<?> cur = child;
      while (!cur.equals(parent)) {
        distance++;
        cur = cur.getSuperclass();
      }
      return distance;
    } else {
      // worst case, recursively compute the type
      // recursion is safe, as types aren't too deep except in crazy-land
      int minDepth = Integer.MAX_VALUE;
      Class<?> sup = child.getSuperclass();
      if (sup != null && parent.isAssignableFrom(sup)) {
        minDepth = getTypeDistance(sup, parent);
      }
      for (Class<?> iface : child.getInterfaces()) {
        if (parent.isAssignableFrom(iface)) {
          int d = getTypeDistance(iface, parent);
          if (d < minDepth) {
            minDepth = d;
          }
        }
      }
      // minDepth now holds the depth of the superclass with shallowest depth
      return minDepth + 1;
    }
  }
Пример #9
0
 public <T> T nodeByTypeElement(Class<T> baseType) {
   int len = children.size();
   for (int i = 0; i < len; i++) {
     Child child = children.get(i);
     if (child instanceof NodeChild) {
       NodeChild nc = (NodeChild) child;
       if (model.elements.containsKey(nc.name)) continue; // match with named
       if (baseType.isAssignableFrom(nc.dom.getImplementationClass()))
         return baseType.cast(nc.dom.get());
     }
   }
   return null;
 }
 private Object replace(Class<?> type, ApplicableGenerator generator, boolean alternative) {
   for (Creator<?> creator : creators) {
     ParameterizedType generic =
         (ParameterizedType) creator.getClass().getGenericInterfaces()[0];
     Class<?> restrained =
         generic.getActualTypeArguments()[0] instanceof ParameterizedType
             ? (Class<?>) ((ParameterizedType) generic.getActualTypeArguments()[0]).getRawType()
             : (Class<?>) generic.getActualTypeArguments()[0];
     if (type.isAssignableFrom(restrained)) {
       return creator.create();
     }
   }
   return generator.generate(type, alternative);
 }
 private Object generate(Class<?> type, boolean alternative) {
   for (Generator<?> generator : generators) {
     ParameterizedType generic =
         (ParameterizedType) generator.getClass().getGenericInterfaces()[0];
     Class<?> restrained =
         generic.getActualTypeArguments()[0] instanceof ParameterizedType
             ? (Class<?>) ((ParameterizedType) generic.getActualTypeArguments()[0]).getRawType()
             : (Class<?>) generic.getActualTypeArguments()[0];
     if (type.isAssignableFrom(restrained)) {
       type = generator.generate();
     }
   }
   return type == String.class ? alternative ? OTHER_STRING : DEFAULT_STRING : mock(type);
 }
Пример #12
0
  /**
   * Picks up all node elements that are assignable to the given type, except those who are matched
   * by other named elements in the model.
   *
   * <p>Used to implement {@code FromElement("*")}.
   */
  public List<Dom> domNodeByTypeElements(Class baseType) {
    List<Dom> r = new ArrayList<Dom>();

    int len = children.size();
    for (int i = 0; i < len; i++) {
      Child child = children.get(i);
      if (child instanceof NodeChild) {
        NodeChild nc = (NodeChild) child;
        if (model.elements.containsKey(nc.name)) continue; // match with named
        if (baseType.isAssignableFrom(nc.dom.getImplementationClass())) r.add(nc.dom);
      }
    }
    return r;
  }
Пример #13
0
 public static Class<?> commonSubType(Collection<?> objects) {
   Iterator<?> iterator = objects.iterator();
   if (!iterator.hasNext()) return null;
   Class<?> result = null;
   while (iterator.hasNext()) {
     Object candidate = iterator.next();
     if (candidate != null) {
       Class<?> candidateClass = candidate.getClass();
       if (result == null) result = candidateClass;
       else if (candidateClass != result && result.isAssignableFrom(candidateClass))
         result = candidateClass;
     }
   }
   return result;
 }
Пример #14
0
 /** Check if the given collection is a uniform collection of the given type. */
 public static boolean isUniformCollection(Collection<?> c, Class<?> e) {
   if (e == null) {
     throw new IllegalArgumentException("Null reference type");
   }
   if (c == null) {
     throw new IllegalArgumentException("Null collection");
   }
   if (c.isEmpty()) {
     return false;
   }
   for (Object o : c) {
     if (o == null || !e.isAssignableFrom(o.getClass())) {
       return false;
     }
   }
   return true;
 }
Пример #15
0
 public static void setPropertyValue(
     Object bean,
     String propertyName,
     Object propertyValue,
     boolean required,
     boolean autoConvert) {
   Method writeMethod = null;
   try {
     Class<?> beanClass = bean.getClass();
     PropertyDescriptor propertyDescriptor = getPropertyDescriptor(beanClass, propertyName);
     if (propertyDescriptor == null)
       if (required)
         throw new ConfigurationError(
             beanClass + " does not have a property '" + propertyName + "'");
       else return;
     writeMethod = propertyDescriptor.getWriteMethod();
     if (writeMethod == null)
       throw new UnsupportedOperationException(
           "Cannot write read-only property '"
               + propertyDescriptor.getName()
               + "' of "
               + beanClass);
     Class<?> propertyType = propertyDescriptor.getPropertyType();
     if (propertyValue != null) {
       Class<?> argType = propertyValue.getClass();
       if (!propertyType.isAssignableFrom(argType)
           && !isWrapperTypeOf(propertyType, propertyValue)
           && !autoConvert)
         throw new IllegalArgumentException(
             "ArgumentType mismatch: expected "
                 + propertyType.getName()
                 + ", found "
                 + propertyValue.getClass().getName());
       else propertyValue = AnyConverter.convert(propertyValue, propertyType);
     }
     writeMethod.invoke(bean, propertyValue);
   } catch (IllegalAccessException e) {
     throw ExceptionMapper.configurationException(e, writeMethod);
   } catch (InvocationTargetException e) {
     throw ExceptionMapper.configurationException(e, writeMethod);
   }
 }
Пример #16
0
 /**
  * Get the type that is provided by a given implementation of {@link Provider}.
  *
  * @param providerClass The provider's class
  * @return The provided class type
  * @throws IllegalArgumentException if the class doesn't actually implement Provider
  */
 public static Class<?> getProvidedType(Class<? extends Provider<?>> providerClass) {
   com.google.common.base.Preconditions.checkArgument(
       Provider.class.isAssignableFrom(providerClass), "class is not Provider class");
   Map<TypeVariable<?>, Type> bindings = TypeUtils.getTypeArguments(providerClass, Provider.class);
   if (!bindings.containsKey(PROVIDER_TYPE_VAR)) {
     throw new IllegalArgumentException(
         "Class provided by " + providerClass.getName() + " is generic");
   }
   final Class<?> inferredType = TypeUtils.getRawType(bindings.get(PROVIDER_TYPE_VAR), null);
   try {
     final Class<?> observedType = providerClass.getMethod("get").getReturnType();
     if (inferredType != null && inferredType.isAssignableFrom(observedType)) {
       return observedType;
     } else {
       return inferredType;
     }
   } catch (NoSuchMethodException e) {
     throw new IllegalArgumentException("Class does not implement get()");
   }
 }
Пример #17
0
  /**
   * This method returns a <tt>Class</tt> for a helper which can handle the list of distributions
   * specified by <tt>seq1</tt>. We maintain a cache of recently-loaded helpers, so check the cache
   * before going to the trouble of searching for a helper. The cache is blown away every
   * <tt>HELPER_CACHE_REFRESH</tt> seconds.
   *
   * <p>If we can't find a helper in the cache, we must search through the list of available helpers
   * to find an appropriate one. First try to find helper using class sequence as specified by
   * <tt>seq</tt>. Whether or not that succeeds, promote any <tt>Gaussian</tt> in the sequence to
   * <tt>MixGaussians</tt>, and try again. If we get a better match on the second try, return the
   * helper thus found.
   */
  public static Class find_helper_class(Vector seq1, String helper_type)
      throws ClassNotFoundException {
    // Let's see if an appropriate helper is in the cache.
    // If the cache is too old, empty it and search for the helper anew.

    if (System.currentTimeMillis() - cache_timestamp > HELPER_CACHE_REFRESH) {
      helper_cache = new Hashtable();
      cache_timestamp = System.currentTimeMillis();
      // Go on and search for appropriate helper.
    } else {
      HelperCacheKey key = new HelperCacheKey(helper_type, seq1);
      Class helper_class = (Class) helper_cache.get(key);
      if (helper_class != null) {
        if (Global.debug > -1)
          System.err.println(
              "PiHelperLoader.find_helper_class: found helper class: "
                  + helper_class
                  + "; no need to search.");
        return helper_class;
      }
      // else no luck; we have to search for helper.
    }

    // Well, we didn't find a helper in the cache, so let's go to work.
    if (Global.debug > -1)
      System.err.println(
          "PiHelperLoader.find_helper_class: DID NOT FIND HELPER CLASS; NOW SEARCH.");

    Class c1 = null, c2 = null;
    ClassNotFoundException cnfe1 = null, cnfe2 = null;
    int[] class_score1 = new int[1], count_score1 = new int[1];
    int[] class_score2 = new int[1], count_score2 = new int[1];

    try {
      c1 = find_helper_class1(seq1, helper_type, class_score1, count_score1);
    } catch (ClassNotFoundException e) {
      cnfe1 = e;
    } // hang on, we may need to re-throw later.

    Class gaussian_class = Class.forName("riso.distributions.Gaussian");
    MixGaussians mog = new MixGaussians(1, 1);

    Vector seq2 = new Vector(seq1.size());
    for (int i = 0; i < seq1.size(); i++)
      if (gaussian_class.isAssignableFrom((Class) seq1.elementAt(i)))
        seq2.addElement(mog.getClass());
      else seq2.addElement(seq1.elementAt(i));

    try {
      c2 = find_helper_class1(seq2, helper_type, class_score2, count_score2);
    } catch (ClassNotFoundException e) {
      cnfe2 = e;
    }

    if (cnfe1 == null && cnfe2 == null) {
      // Both matched; see which one fits better.
      // Break ties in favor of the helper for non-promoted messages.

      if (class_score1[0] >= class_score2[0]
          || (class_score1[0] == class_score2[0] && count_score1[0] >= count_score2[0])) {
        if (Global.debug > 1)
          System.err.println(
              "\taccept helper " + c1 + " for non-promoted classes instead of " + c2);
        if (Global.debug > 1)
          System.err.println(
              "\t\t"
                  + class_score1[0]
                  + ", "
                  + class_score2[0]
                  + "; "
                  + count_score1[0]
                  + ", "
                  + count_score2[0]);
        helper_cache.put(new HelperCacheKey(helper_type, seq1), c1);
        return c1;
      } else {
        if (Global.debug > 1)
          System.err.println("\taccept helper " + c2 + " for promoted classes instead of " + c1);
        if (Global.debug > 1)
          System.err.println(
              "\t\t"
                  + class_score1[0]
                  + ", "
                  + class_score2[0]
                  + "; "
                  + count_score1[0]
                  + ", "
                  + count_score2[0]);
        helper_cache.put(new HelperCacheKey(helper_type, seq1), c2);
        return c2;
      }
    } else if (cnfe1 == null && cnfe2 != null) {
      // Only the first try matched, return it.
      helper_cache.put(new HelperCacheKey(helper_type, seq1), c1);
      return c1;
    } else if (cnfe1 != null && cnfe2 == null) {
      // Only the second try matched, return it.
      helper_cache.put(new HelperCacheKey(helper_type, seq1), c2);
      return c2;
    } else {
      // Neither try matched. Re-throw the exception generated by the first try.
      throw cnfe1;
    }
  }
Пример #18
0
  protected void _resolveBindings(Type t) {
    if (t == null) return;

    Class<?> raw;
    if (t instanceof ParameterizedType) {
      ParameterizedType pt = (ParameterizedType) t;
      Type[] args = pt.getActualTypeArguments();
      if (args != null && args.length > 0) {
        Class<?> rawType = (Class<?>) pt.getRawType();
        TypeVariable<?>[] vars = rawType.getTypeParameters();
        if (vars.length != args.length) {
          throw new IllegalArgumentException(
              "Strange parametrized type (in class "
                  + rawType.getName()
                  + "): number of type arguments != number of type parameters ("
                  + args.length
                  + " vs "
                  + vars.length
                  + ")");
        }
        for (int i = 0, len = args.length; i < len; ++i) {
          TypeVariable<?> var = vars[i];
          String name = var.getName();
          if (_bindings == null) {
            _bindings = new LinkedHashMap<String, JavaType>();
          } else {
            /* 24-Mar-2010, tatu: Better ensure that we do not overwrite something
             *  collected earlier (since we descend towards super-classes):
             */
            if (_bindings.containsKey(name)) continue;
          }
          // first: add a placeholder to prevent infinite loops
          _addPlaceholder(name);
          // then resolve type
          _bindings.put(name, _typeFactory._constructType(args[i], this));
        }
      }
      raw = (Class<?>) pt.getRawType();
    } else if (t instanceof Class<?>) {
      raw = (Class<?>) t;
      /* [JACKSON-677]: If this is an inner class then the generics are defined on the
       * enclosing class so we have to check there as well.  We don't
       * need to call getEnclosingClass since anonymous classes declare
       * generics
       */
      _resolveBindings(raw.getDeclaringClass());
      /* 24-Mar-2010, tatu: Can not have true generics definitions, but can
       *   have lower bounds ("<T extends BeanBase>") in declaration itself
       */
      TypeVariable<?>[] vars = raw.getTypeParameters();
      if (vars != null && vars.length > 0) {
        JavaType[] typeParams = null;

        if (_contextType != null && raw.isAssignableFrom(_contextType.getRawClass())) {
          typeParams = _typeFactory.findTypeParameters(_contextType, raw);
        }

        for (int i = 0; i < vars.length; i++) {
          TypeVariable<?> var = vars[i];

          String name = var.getName();
          Type varType = var.getBounds()[0];
          if (varType != null) {
            if (_bindings == null) {
              _bindings = new LinkedHashMap<String, JavaType>();
            } else { // and no overwriting...
              if (_bindings.containsKey(name)) continue;
            }
            _addPlaceholder(name); // to prevent infinite loops

            if (typeParams != null) {
              _bindings.put(name, typeParams[i]);
            } else {
              _bindings.put(name, _typeFactory._constructType(varType, this));
            }
          }
        }
      }
    } else { // probably can't be any of these... so let's skip for now
      // if (type instanceof GenericArrayType) {
      // if (type instanceof TypeVariable<?>) {
      // if (type instanceof WildcardType) {
      return;
    }
    // but even if it's not a parameterized type, its super types may be:
    _resolveBindings(raw.getGenericSuperclass());
    for (Type intType : raw.getGenericInterfaces()) {
      _resolveBindings(intType);
    }
  }
Пример #19
0
  /**
   * Aspect implementation which executes grid-enabled methods on remote nodes.
   *
   * @param invoc Method invocation instance provided by JBoss AOP framework.
   * @return Method execution result.
   * @throws Throwable If method execution failed.
   */
  @SuppressWarnings({
    "ProhibitedExceptionDeclared",
    "ProhibitedExceptionThrown",
    "CatchGenericClass",
    "unchecked"
  })
  @Bind(
      pointcut = "execution(* *->@org.gridgain.grid.gridify.Gridify(..))",
      cflow = "org.gridgain.grid.gridify.aop.jboss.GridifyJbossAspect.CFLOW_STACK")
  public Object gridify(MethodInvocation invoc) throws Throwable {
    Method mtd = invoc.getMethod();

    Gridify ann = mtd.getAnnotation(Gridify.class);

    assert ann != null : "Intercepted method does not have gridify annotation.";

    // Since annotations in Java don't allow 'null' as default value
    // we have accept an empty string and convert it here.
    // NOTE: there's unintended behavior when user specifies an empty
    // string as intended grid name.
    // NOTE: the 'ann.gridName() == null' check is added to mitigate
    // annotation bugs in some scripting languages (e.g. Groovy).
    String gridName = F.isEmpty(ann.gridName()) ? null : ann.gridName();

    if (G.state(gridName) != STARTED) {
      throw new GridException("Grid is not locally started: " + gridName);
    }

    // Initialize defaults.
    GridifyArgument arg =
        new GridifyArgumentAdapter(
            mtd.getDeclaringClass(),
            mtd.getName(),
            mtd.getParameterTypes(),
            invoc.getArguments(),
            invoc.getTargetObject());

    if (!ann.interceptor().equals(GridifyInterceptor.class)) {
      // Check interceptor first.
      if (!ann.interceptor().newInstance().isGridify(ann, arg)) {
        return invoc.invokeNext();
      }
    }

    if (!ann.taskClass().equals(GridifyDefaultTask.class) && ann.taskName().length() > 0) {
      throw new GridException(
          "Gridify annotation must specify either Gridify.taskName() or "
              + "Gridify.taskClass(), but not both: "
              + ann);
    }

    try {
      Grid grid = G.grid(gridName);

      // If task class was specified.
      if (!ann.taskClass().equals(GridifyDefaultTask.class)) {
        return grid.execute(
                (Class<? extends GridTask<GridifyArgument, Object>>) ann.taskClass(),
                arg,
                ann.timeout())
            .get();
      }

      // If task name was not specified.
      if (ann.taskName().length() == 0) {
        return grid.execute(
                new GridifyDefaultTask(invoc.getActualMethod().getDeclaringClass()),
                arg,
                ann.timeout())
            .get();
      }

      // If task name was specified.
      return grid.execute(ann.taskName(), arg, ann.timeout()).get();
    } catch (Throwable e) {
      for (Class<?> ex : invoc.getMethod().getExceptionTypes()) {
        // Descend all levels down.
        Throwable cause = e.getCause();

        while (cause != null) {
          if (ex.isAssignableFrom(cause.getClass())) {
            throw cause;
          }

          cause = cause.getCause();
        }

        if (ex.isAssignableFrom(e.getClass())) {
          throw e;
        }
      }

      throw new GridifyRuntimeException("Undeclared exception thrown: " + e.getMessage(), e);
    }
  }
Пример #20
0
  private Object getParam(
      final Class<?> pClass,
      final String pName,
      final ParamType pType,
      final String pXpath,
      final HttpMessage pMessage)
      throws XmlException {
    Object result = null;
    switch (pType) {
      case GET:
        result = getParamGet(pName, pMessage);
        break;
      case POST:
        result = getParamPost(pName, pMessage);
        break;
      case QUERY:
        result = getParamGet(pName, pMessage);
        if (result == null) {
          result = getParamPost(pName, pMessage);
        }
        break;
      case VAR:
        result = mPathParams.get(pName);
        break;
      case XPATH:
        result = getParamXPath(pClass, pXpath, pMessage.getBody());
        break;
      case BODY:
        result = getBody(pClass, pMessage);
        break;
      case ATTACHMENT:
        result = getAttachment(pClass, pName, pMessage);
        break;
      case PRINCIPAL:
        {
          final Principal principal = pMessage.getUserPrincipal();
          if (pClass.isAssignableFrom(String.class)) {
            result = principal.getName();
          } else {
            result = principal;
          }
          break;
        }
    }
    // XXX generizice this and share the same approach to unmarshalling in ALL code
    // TODO support collection/list parameters
    if ((result != null) && (!pClass.isInstance(result))) {
      if ((Types.isPrimitive(pClass) || (Types.isPrimitiveWrapper(pClass)))
          && (result instanceof String)) {
        try {
          result = Types.parsePrimitive(pClass, ((String) result));
        } catch (NumberFormatException e) {
          throw new HttpResponseException(
              HttpServletResponse.SC_BAD_REQUEST, "The argument given is invalid", e);
        }
      } else if (Enum.class.isAssignableFrom(pClass)) {
        @SuppressWarnings({"rawtypes"})
        final Class clazz = pClass;
        @SuppressWarnings("unchecked")
        final Enum<?> tmpResult = Enum.valueOf(clazz, result.toString());
        result = tmpResult;
      } else if (result instanceof Node) {
        XmlDeserializer factory = pClass.getAnnotation(XmlDeserializer.class);
        if (factory != null) {
          try {
            result =
                factory
                    .value()
                    .newInstance()
                    .deserialize(XmlStreaming.newReader(new DOMSource((Node) result)));
          } catch (IllegalAccessException | InstantiationException e) {
            throw new XmlException(e);
          }
        } else {
          result = JAXB.unmarshal(new DOMSource((Node) result), pClass);
        }
      } else {
        final String s = result.toString();
        // Only wrap when we don't start with <
        final char[] requestBody =
            (s.startsWith("<") ? s : "<wrapper>" + s + "</wrapper>").toCharArray();
        if (requestBody.length > 0) {
          result = JAXB.unmarshal(new CharArrayReader(requestBody), pClass);
        } else {
          result = null;
        }
      }
    }

    return result;
  }
Пример #21
0
  /**
   * Determines if the suspected super type is assignable from the suspected sub type.
   *
   * @param suspectedSuperType e.g. {@code GenericDAO<Pet, String>}
   * @param suspectedSubType e.g. {@code PetDAO extends GenericDAO<Pet,String>}
   * @return true if (sourceType)targetClass is a valid cast
   */
  public static boolean isAssignableFrom(Type suspectedSuperType, Type suspectedSubType) {
    final Class suspectedSuperClass = asClass(suspectedSuperType);
    final Class suspectedSubClass = asClass(suspectedSubType);

    // The raw types need to be compatible.
    if (!suspectedSuperClass.isAssignableFrom(suspectedSubClass)) {
      return false;
    }

    // From this point we know that the raw types are assignable.
    // We need to figure out what the generic parameters in the targetClass are
    // as they pertain to the sourceType.

    if (suspectedSuperType instanceof WildcardType) {
      // ? extends Number
      // needs to match all the bounds (there will only be upper bounds or lower bounds
      for (Type t : ((WildcardType) suspectedSuperType).getUpperBounds()) {
        if (!isAssignableFrom(t, suspectedSubType)) return false;
      }
      for (Type t : ((WildcardType) suspectedSuperType).getLowerBounds()) {
        if (!isAssignableFrom(suspectedSubType, t)) return false;
      }
      return true;
    }

    Type curType = suspectedSubType;
    Class curClass;

    while (curType != null && !curType.equals(Object.class)) {
      curClass = asClass(curType);

      if (curClass.equals(suspectedSuperClass)) {
        final Type resolved = resolve(curType, suspectedSubType);

        if (suspectedSuperType instanceof Class) {
          if (resolved instanceof Class) return suspectedSuperType.equals(resolved);

          // They may represent the same class, but the suspectedSuperType is not parameterized. The
          // parameter
          // types default to Object so they must be a match.
          // e.g. Pair p = new StringLongPair();
          //      Pair p = new Pair<? extends Number, String>

          return true;
        }

        if (suspectedSuperType instanceof ParameterizedType) {
          if (resolved instanceof ParameterizedType) {
            final Type[] type1Arguments =
                ((ParameterizedType) suspectedSuperType).getActualTypeArguments();
            final Type[] type2Arguments = ((ParameterizedType) resolved).getActualTypeArguments();
            if (type1Arguments.length != type2Arguments.length) return false;

            for (int i = 0; i < type1Arguments.length; ++i) {
              if (!isAssignableFrom(type1Arguments[i], type2Arguments[i])) return false;
            }
            return true;
          }
        } else if (suspectedSuperType instanceof GenericArrayType) {
          if (resolved instanceof GenericArrayType) {
            return isAssignableFrom(
                ((GenericArrayType) suspectedSuperType).getGenericComponentType(),
                ((GenericArrayType) resolved).getGenericComponentType());
          }
        }

        return false;
      }

      final Type[] types = curClass.getGenericInterfaces();
      for (Type t : types) {
        final Type resolved = resolve(t, suspectedSubType);
        if (isAssignableFrom(suspectedSuperType, resolved)) return true;
      }

      curType = curClass.getGenericSuperclass();
    }
    return false;
  }