private void readActualTypeParametersOnDeclaringClass() {
   registerTypeParametersOn(clazz.getTypeParameters());
   registerTypeVariablesOn(clazz.getGenericSuperclass());
   for (Type genericInterface : clazz.getGenericInterfaces()) {
     registerTypeVariablesOn(genericInterface);
   }
 }
  @SuppressWarnings("unchecked")
  @Override
  public <P> Getter<GettableByIndexData, P> newGetter(
      Type target, DatastaxColumnKey key, ColumnDefinition<?, ?> columnDefinition) {
    Class<?> targetClass = TypeHelper.toClass(target);
    if (Date.class.equals(targetClass)) {
      return (Getter<GettableByIndexData, P>) new DatastaxDateGetter(key.getIndex());
    }

    if (boolean.class.equals(targetClass) || Boolean.class.equals(targetClass)) {
      return (Getter<GettableByIndexData, P>) new DatastaxBooleanGetter(key.getIndex());
    }

    if (InetAddress.class.equals(targetClass)) {
      return (Getter<GettableByIndexData, P>) new DatastaxInetAddressGetter(key.getIndex());
    }

    if (TupleValue.class.equals(targetClass)) {
      return (Getter<GettableByIndexData, P>) new DatastaxTupleValueGetter(key.getIndex());
    }

    if (Collection.class.isAssignableFrom(targetClass)) {

      Type elementType = TypeHelper.getComponentTypeOfListOrArray(target);
      Class<?> dataTypeClass = Object.class;
      Class<?> dataTypeElt = null;
      DataType dtElt = null;
      if (key.getDataType() != null) {
        DataType dataType = key.getDataType();
        dataTypeClass = dataType.asJavaClass();
        if (dataType.isCollection()) {
          dtElt = key.getDataType().getTypeArguments().get(0);
          dataTypeElt = dtElt.asJavaClass();
        }
      } else {
        dataTypeElt = TypeHelper.toClass(elementType);
      }

      if (dataTypeElt != null) {
        if (TypeHelper.areEquals(elementType, dataTypeElt)) {
          if (Set.class.equals(dataTypeClass)) {
            if (targetClass.isAssignableFrom(dataTypeClass)) {
              return new DatastaxSetGetter(key.getIndex(), TypeHelper.toClass(elementType));
            }
          }
          if (List.class.equals(dataTypeClass)) {
            if (targetClass.isAssignableFrom(dataTypeClass)) {
              return new DatastaxListGetter(key.getIndex(), TypeHelper.toClass(elementType));
            }
          }
        } else {
          Converter<?, ?> converter = getConverter(elementType, dataTypeElt, dtElt);

          if (converter != null) {
            if (Set.class.equals(dataTypeClass)) {
              if (targetClass.isAssignableFrom(dataTypeClass)) {
                return new DatastaxSetWithConverterGetter(key.getIndex(), dataTypeElt, converter);
              }
            }
            if (List.class.equals(dataTypeClass)) {
              if (targetClass.isAssignableFrom(dataTypeClass)) {
                return new DatastaxListWithConverterGetter(key.getIndex(), dataTypeElt, converter);
              }
            }
          }
        }
      }
    }
    if (Map.class.equals(targetClass)) {
      Tuple2<Type, Type> keyValueTypeOfMap = TypeHelper.getKeyValueTypeOfMap(target);

      Class<?> dtKeyType = null;
      Class<?> dtValueType = null;
      DataType dtKey = null;
      DataType dtValue = null;
      if (key.getDataType() != null) {
        List<DataType> typeArguments = key.getDataType().getTypeArguments();
        if (typeArguments.size() == 2) {
          dtKey = typeArguments.get(0);
          dtKeyType = dtKey.asJavaClass();
          dtValue = typeArguments.get(1);
          dtValueType = dtValue.asJavaClass();
        }
      } else {
        dtKeyType = TypeHelper.toClass(keyValueTypeOfMap.first());
        dtValueType = TypeHelper.toClass(keyValueTypeOfMap.second());
      }
      if (dtKeyType != null && dtValueType != null) {
        if (TypeHelper.areEquals(keyValueTypeOfMap.first(), dtKeyType)
            && TypeHelper.areEquals(keyValueTypeOfMap.second(), dtValueType)) {
          return new DatastaxMapGetter(
              key.getIndex(),
              TypeHelper.toClass(keyValueTypeOfMap.first()),
              TypeHelper.toClass(keyValueTypeOfMap.second()));
        } else {
          Converter<?, ?> keyConverter = getConverter(keyValueTypeOfMap.first(), dtKeyType, dtKey);
          Converter<?, ?> valueConverter =
              getConverter(keyValueTypeOfMap.second(), dtValueType, dtValue);

          if (keyConverter != null && valueConverter != null) {
            return new DatastaxMapWithConverterGetter(
                key.getIndex(), dtKeyType, dtValueType, keyConverter, valueConverter);
          }
        }
      }
    }

    if (Tuples.isTuple(target)) {
      if (key.getDataType() != null && key.getDataType() instanceof TupleType) {
        TupleType tt = (TupleType) key.getDataType();

        List<DataType> typeArguments = tt.getTypeArguments();

        TypeVariable<? extends Class<?>>[] typeParameters = targetClass.getTypeParameters();

        if (typeArguments.size() <= typeParameters.length) {
          return (Getter<GettableByIndexData, P>)
              DatastaxTupleGetter.newInstance(datastaxMapperFactory, target, tt, key.getIndex());
        }
      }
    }

    if (TypeHelper.isEnum(target)) {
      final Getter<GettableByIndexData, ? extends Enum> getter =
          enumGetter(key, TypeHelper.toClass(target));
      if (getter != null) {
        return (Getter<GettableByIndexData, P>) getter;
      }
    }

    final GetterFactory<GettableByIndexData, DatastaxColumnKey> rowGetterFactory =
        getterFactories.get(targetClass);

    if (rowGetterFactory != null) {
      return rowGetterFactory.newGetter(target, key, columnDefinition);
    }

    final Getter<GettableByIndexData, P> getter =
        jodaTimeGetterFactory.newGetter(target, key, columnDefinition);

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

    if (key.getDataType() != null && key.getDataType() instanceof UserType) {
      UserType ut = (UserType) key.getDataType();
      return (Getter<GettableByIndexData, P>)
          DatastaxUDTGetter.newInstance(datastaxMapperFactory, target, ut, key.getIndex());
    }

    return null;
  }
Example #3
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);
    }
  }
Example #4
0
  /**
   * Gets the actual type arguments that are used in a given implementation of a given generic base
   * class or interface. (Based on code copyright 2007 by Ian Robertson).
   *
   * @param base the generic base class or interface
   * @param implementation the type (potentially) implementing the given base class or interface
   * @return a list of the raw classes for the actual type arguments.
   */
  @NotNull
  public static List<Class<?>> getTypeArguments(
      @NotNull Class<?> base, @NotNull Class<?> implementation) {
    Map<Type, Type> resolvedTypes = new HashMap<Type, Type>();

    // first we need to resolve all supertypes up to the required base class or interface
    // and find the right Type for it
    Type type;

    Queue<Type> toCheck = new LinkedList<Type>();
    toCheck.add(implementation);
    while (true) {
      // if we have checked everything and not found the base class we return an empty list
      if (toCheck.isEmpty()) return ImmutableList.of();

      type = toCheck.remove();
      Class<?> clazz;

      if (type instanceof Class) {
        // there is no useful information for us in raw types, so just keep going up the inheritance
        // chain
        clazz = (Class) type;
        if (base.isInterface()) {
          // if we are actually looking for the type parameters to an interface we also need to
          // look at all the ones implemented by the given current one
          toCheck.addAll(Arrays.asList(clazz.getGenericInterfaces()));
        }
      } else if (type instanceof ParameterizedType) {
        ParameterizedType parameterizedType = (ParameterizedType) type;
        clazz = (Class) parameterizedType.getRawType();

        // for instances of ParameterizedType we extract and remember all type arguments
        TypeVariable<?>[] typeParameters = clazz.getTypeParameters();
        Type[] actualTypeArguments = parameterizedType.getActualTypeArguments();
        for (int i = 0; i < actualTypeArguments.length; i++) {
          resolvedTypes.put(typeParameters[i], actualTypeArguments[i]);
        }
      } else {
        return ImmutableList.of();
      }

      // we can stop if we have reached the sought for base type
      if (base.equals(getClass(type))) break;

      toCheck.add(clazz.getGenericSuperclass());
    }

    // finally, for each actual type argument provided to baseClass,
    // determine (if possible) the raw class for that type argument.
    Type[] actualTypeArguments;
    if (type instanceof Class) {
      actualTypeArguments = ((Class) type).getTypeParameters();
    } else {
      actualTypeArguments = ((ParameterizedType) type).getActualTypeArguments();
    }
    List<Class<?>> typeArgumentsAsClasses = new ArrayList<Class<?>>();
    // resolve types by chasing down type variables.
    for (Type baseType : actualTypeArguments) {
      while (resolvedTypes.containsKey(baseType)) {
        baseType = resolvedTypes.get(baseType);
      }
      typeArgumentsAsClasses.add(getClass(baseType));
    }
    return typeArgumentsAsClasses;
  }