动态创建 ParameterizedType

@param ownerType0           ParameterizedType 的 ownerType
@param rawType0             ParameterizedType 的 rawType
@param actualTypeArguments0 ParameterizedType 的 actualTypeArguments

@return Type
191923
public static Type createParameterizedType(final Type ownerType0, final Type rawType0, final Type... actualTypeArguments0) {
        if (ownerType0 == null && rawType0 instanceof Class) {
            int count = 0;
            for (Type t : actualTypeArguments0) {
                if (isClassType(t)) count++;
            }
            if (count == actualTypeArguments0.length) return createParameterizedType((Class) rawType0, actualTypeArguments0);
        }
        return new ParameterizedType() {
            private final Class<?> rawType = (Class<?>) rawType0;

            private final Type ownerType = ownerType0;

            private final Type[] actualTypeArguments = actualTypeArguments0;

            @Override
            public Type[] getActualTypeArguments() {
                return actualTypeArguments.clone();
            }

            @Override
            public Type getRawType() {
                return rawType;
            }

            @Override
            public Type getOwnerType() {
                return ownerType;
            }

            @Override
            public int hashCode() {
                return Arrays.hashCode(actualTypeArguments) ^ Objects.hashCode(rawType) ^ Objects.hashCode(ownerType);
            }

            @Override
            public boolean equals(Object o) {
                if (!(o instanceof ParameterizedType)) return false;
                final ParameterizedType that = (ParameterizedType) o;
                if (this == that) return true;
                return Objects.equals(ownerType, that.getOwnerType())
                    && Objects.equals(rawType, that.getRawType())
                    && Arrays.equals(actualTypeArguments, that.getActualTypeArguments());
            }

            @Override
            public String toString() {
                StringBuilder sb = new StringBuilder();
                if (ownerType != null) sb.append((ownerType instanceof Class) ? (((Class) ownerType).getName()) : ownerType.toString()).append(".");
                sb.append(rawType.getName());

                if (actualTypeArguments != null && actualTypeArguments.length > 0) {
                    sb.append("<");
                    boolean first = true;
                    for (Type t : actualTypeArguments) {
                        if (!first) sb.append(", ");
                        sb.append(t);
                        first = false;
                    }
                    sb.append(">");
                }
                return sb.toString();
            }
        };
    }
589167
public static Type[] getTypeArguments(Type type) {
        if (!(type instanceof ParameterizedType)) {
            return new Type[0];
        }
        return ((ParameterizedType) type).getActualTypeArguments();
    }
380923
@Deprecated
	public final LightweightTypeReference getCommonParameterSuperType(List<LightweightTypeReference> types, List<LightweightTypeReference> initiallyRequested, ITypeReferenceOwner owner) {
		CommonSuperTypeFinder typeFinder = newCommonSuperTypeFinder(owner);
		typeFinder.requestsInProgress = Lists.newArrayList();
		typeFinder.requestsInProgress.add(initiallyRequested);
		return typeFinder.getCommonParameterSuperType(types);
	}
172401
@Override
    @Path("/{ownerType}/{ownerId}")
    @ApiOperation(value="Update values for an ownerType and ownerId", response=StatusMessage.class)
    @ApiImplicitParams({
        @ApiImplicitParam(name="Values", paramType="body")})
    public JSONObject put(String path, JSONObject content, Map<String,String> headers)
    throws ServiceException, JSONException {
        Map<String,String> parameters = getParameters(headers);
        String ownerType = getSegment(path, 1);
        if (ownerType == null)
            ownerType = parameters.get("ownerType");
        if (ownerType == null)
            throw new ServiceException("Missing parameter: ownerType");
        String ownerId = getSegment(path, 2);
        if (ownerId == null)
            ownerId = parameters.get("ownerId");
        if (ownerId == null)
            throw new ServiceException("Missing parameter: ownerId");
        String updateOnly = getSegment(path, 3);
        if (updateOnly == null)
            updateOnly = parameters.get("updateOnly");
        if (content == null)
            throw new ServiceException("Missing JSON object: attributes");

        try {
            Map<String,String> values = new HashMap<String,String>();
            String[] names = JSONObject.getNames(content);
            if (names != null) {
                for (String name : names)
                    values.put(name, content.getString(name));
            }
            WorkflowServices workflowServices = ServiceLocator.getWorkflowServices();

            if (updateOnly != null) {
                // update values, without deleting all other values for that ownerId
                workflowServices.updateValues(ownerType, ownerId, values);
            } else {
                workflowServices.setValues(ownerType, ownerId, values);
            }
            return null;
        }
        catch (JSONException ex) {
            throw new ServiceException(ex.getMessage(), ex);
        }
    }
871819
public static Type narrowestParameterizedType(Class<?> subClass, ParameterizedType parameterizedType) {
        Validate.notNull(parameterizedType, "ParameterizedType must not be null");
        if (subClass == null) {
            return parameterizedType;
        }
        final Class<?> rawType = (Class<?>) parameterizedType.getRawType();
        Validate.isAssignableFrom(rawType, subClass);

        final Map<TypeVariable<?>, Type> typeArguments = TypeUtils.getTypeArguments(subClass, rawType);

        hierarchy: for (Class<?> t : ClassUtils.hierarchy(subClass, Interfaces.INCLUDE)) {
            if (t.equals(rawType)) {
                break;
            }
            if (!rawType.isAssignableFrom(t)) {
                continue;
            }
            if (t.getTypeParameters().length > 0) {
                // try to parameterize raw runtime type:
                try {
                    final Map<TypeVariable<?>, Type> typeArgMappings =
                        TypeUtils.determineTypeArguments(t, parameterizedType);
                    return TypeUtils.parameterize(t, typeArgMappings);
                } catch (Exception e) {
                    // use basic parameterized source type
                }
            } else {
                for (TypeVariable<?> v : rawType.getTypeParameters()) {
                    final Type arg = typeArguments.get(v);
                    if (arg == null || arg instanceof TypeVariable<?>) {
                        continue hierarchy;
                    }
                }
                // if we are here, we have determined that rt explicitly binds all type params of the declared type
                // of pos:
                return t;
            }
        }
        return parameterizedType;
    }
1302739
public static Set<Type> getTypedTypes(Map<Class<?>, Type> typeClosure, Class<?> rawType, Typed typed) {
        Set<Type> types = new HashSet<Type>();
        for (Class<?> specifiedClass : typed.value()) {
            Type tmp = typeClosure.get(specifiedClass);
            if (tmp != null) {
                types.add(tmp);
            } else {
                throw BeanLogger.LOG.typedClassNotInHierarchy(specifiedClass.getName(), rawType, Formats.formatTypes(typeClosure.values()));
            }
        }
        types.add(Object.class);
        return types;
    }
840265
public static Class<?> getGenericTypeArgument(Field field) {
        // TODO Might this better be located under SPI in an "InjectionUtil" class or something?
        Type genericType = field.getGenericType();
        if (genericType instanceof ParameterizedType) {
            ParameterizedType parameterizedType = (ParameterizedType) genericType;
            Type[] actualTypeArguments = parameterizedType.getActualTypeArguments();
            if (actualTypeArguments.length == 1) {
                Type type = actualTypeArguments[0];
                if (type instanceof Class<?>) {
                    Class<?> realClass = (Class<?>) type;
                    return realClass;
                } else {
                    throw new IllegalArgumentException(
                        "only direct class types are allowed for generic parameter on field " + field.getName()
                                + " of type "
                                + genericType.getClass().getName() + "<T>, but " + type
                                + " was given!");
                }
            } else {
                throw new IllegalArgumentException("only one type parameter expected for field " + field.getName()
                        + " but " + actualTypeArguments.length
                        + " where found!");
            }
        } else {
            throw new IllegalArgumentException(
                "The field '" + field.getName()
                        + "' is not a ParameterizedType but this is required for type inferrence!");
        }
    }
716484
public static final ParameterizedType parameterizeWithOwner(final Type owner, final Class<?> raw,
        final Type... typeArguments) {
        Validate.notNull(raw, "raw class is null");
        final Type useOwner;
        if (raw.getEnclosingClass() == null) {
            Validate.isTrue(owner == null, "no owner allowed for top-level %s", raw);
            useOwner = null;
        } else if (owner == null) {
            useOwner = raw.getEnclosingClass();
        } else {
            Validate.isTrue(TypeUtils.isAssignable(owner, raw.getEnclosingClass()),
                "%s is invalid owner type for parameterized %s", owner, raw);
            useOwner = owner;
        }
        Validate.noNullElements(typeArguments, "null type argument at index %s");
        Validate.isTrue(raw.getTypeParameters().length == typeArguments.length,
            "invalid number of type parameters specified: expected %d, got %d", raw.getTypeParameters().length,
            typeArguments.length);

        return new ParameterizedTypeImpl(raw, useOwner, typeArguments);
    }
765958
private static void populateTypeArgs(ParameterizedType type, Map<TypeVariable<?>, Type> map, boolean depthFirst) {
    if (type.getRawType() instanceof Class) {
      TypeVariable<?>[] typeVariables = ((Class<?>) type.getRawType()).getTypeParameters();
      Type[] typeArguments = type.getActualTypeArguments();

      if (type.getOwnerType() != null) {
        Type owner = type.getOwnerType();
        if (owner instanceof ParameterizedType)
          populateTypeArgs((ParameterizedType) owner, map, depthFirst);
      }

      for (int i = 0; i < typeArguments.length; i++) {
        TypeVariable<?> variable = typeVariables[i];
        Type typeArgument = typeArguments[i];

        if (typeArgument instanceof Class) {
          map.put(variable, typeArgument);
        } else if (typeArgument instanceof GenericArrayType) {
          map.put(variable, typeArgument);
        } else if (typeArgument instanceof ParameterizedType) {
          map.put(variable, typeArgument);
        } else if (typeArgument instanceof TypeVariable) {
          TypeVariable<?> typeVariableArgument = (TypeVariable<?>) typeArgument;
          if (depthFirst) {
            Type existingType = map.get(variable);
            if (existingType != null) {
              map.put(typeVariableArgument, existingType);
              continue;
            }
          }

          Type resolvedType = map.get(typeVariableArgument);
          if (resolvedType == null)
            resolvedType = resolveBound(typeVariableArgument);
          map.put(variable, resolvedType);
        }
      }
    }
  }
1076914
public static Type resolveType(Type targetType, Type rootType)
    {
        Type resolvedType;

        if (targetType instanceof ParameterizedType && rootType instanceof ParameterizedType) {
            ParameterizedType parameterizedType = (ParameterizedType) targetType;

            resolvedType =
                resolveType((Class<?>) parameterizedType.getRawType(), parameterizedType.getActualTypeArguments(),
                    getTypeClass(rootType));
        } else {
            resolvedType = resolveType(getTypeClass(rootType), null, getTypeClass(targetType));
        }

        return resolvedType;
    }
645845
public static <X> String createTypeId(AnnotatedType<X> annotatedType) {
        String id = createTypeId(annotatedType.getJavaClass(), annotatedType.getAnnotations(), annotatedType.getMethods(), annotatedType.getFields(), annotatedType.getConstructors());
        String hash = hash(id);
        MetadataLogger.LOG.tracef("Generated AnnotatedType id hash for %s: %s", id, hash);
        return hash;
    }
547149
@Programmatic
    public List<CommunicationChannelOwnerLink> findByOwner(final CommunicationChannelOwner owner) {
        if(owner == null) {
            return null;
        }
        final Bookmark bookmark = bookmarkService.bookmarkFor(owner);
        if(bookmark == null) {
            return null;
        }
        return container.allMatches(
                new QueryDefault<>(CommunicationChannelOwnerLink.class,
                        "findByOwner",
                        "ownerObjectType", bookmark.getObjectType(),
                        "ownerIdentifier", bookmark.getIdentifier()));
    }
148841
protected <Type extends JvmType> Type findDeclaredType(String clazzName, ITypeReferenceOwner owner) {
		@SuppressWarnings("unchecked")
		Type result = (Type) services.getTypeReferences().findDeclaredType(clazzName, owner.getContextResourceSet());
		return result;
	}
1073837
private static String parameterizedTypeToString(final ParameterizedType p) {
        final StringBuilder buf = new StringBuilder();

        final Type useOwner = p.getOwnerType();
        final Class<?> raw = (Class<?>) p.getRawType();

        if (useOwner == null) {
            buf.append(raw.getName());
        } else {
            if (useOwner instanceof Class<?>) {
                buf.append(((Class<?>) useOwner).getName());
            } else {
                buf.append(useOwner.toString());
            }
            buf.append('.').append(raw.getSimpleName());
        }

        final int[] recursiveTypeIndexes = findRecursiveTypes(p);

        if (recursiveTypeIndexes.length > 0) {
            appendRecursiveTypes(buf, recursiveTypeIndexes, p.getActualTypeArguments());
        } else {
            appendAllTo(buf.append('<'), ", ", p.getActualTypeArguments()).append('>');
        }

        return buf.toString();
    }
1171213
public static Type resolveGenericType(Type initialType, Class<?> targetType) {
        Class<?> rawType;
        if (initialType instanceof ParameterizedType)
            rawType = (Class<?>) ((ParameterizedType) initialType).getRawType();
        else
            rawType = (Class<?>) initialType;

        if (targetType.equals(rawType))
            return initialType;

        Type result;
        if (targetType.isInterface()) {
            for (Type superInterface : rawType.getGenericInterfaces())
                if (superInterface != null && !superInterface.equals(Object.class))
                    if ((result = resolveGenericType(superInterface, targetType)) != null)
                        return result;
        }

        Type superType = rawType.getGenericSuperclass();
        if (superType != null && !superType.equals(Object.class))
            if ((result = resolveGenericType(superType, targetType)) != null)
                return result;

        return null;
    }
627192
public static Type capture(Type type) {
		VarMap varMap = new VarMap();
		List<CaptureTypeImpl> toInit = new ArrayList<>();
		if (type instanceof ParameterizedType) {
			ParameterizedType pType = (ParameterizedType)type;
			Class<?> clazz = (Class<?>)pType.getRawType();
			Type[] arguments = pType.getActualTypeArguments();
			TypeVariable<?>[] vars = clazz.getTypeParameters();
			Type[] capturedArguments = new Type[arguments.length];
			assert arguments.length == vars.length;
			for (int i = 0; i < arguments.length; i++) {
				Type argument = arguments[i];
				if (argument instanceof WildcardType) {
					CaptureTypeImpl captured = new CaptureTypeImpl((WildcardType)argument, vars[i]);
					argument = captured;
					toInit.add(captured);
				}
				capturedArguments[i] = argument;
				varMap.add(vars[i], argument);
			}
			for (CaptureTypeImpl captured : toInit) {
				captured.init(varMap);
			}
			Type ownerType = (pType.getOwnerType() == null) ? null : capture(pType.getOwnerType());
			return new ParameterizedTypeImpl(clazz, capturedArguments, ownerType);
		} else {
			return type;
		}
	}
49816
private TypeVarToTypeMap mapTypes( TypeVarToTypeMap actualParamByVarName, IType... types )
  {
    for( int i = 0; i < types.length; i++ )
    {
      IType type = types[i];
      if( type instanceof ITypeVariableType )
      {
        actualParamByVarName.put( (ITypeVariableType)types[i], types[i] );
      }
      if( type instanceof ITypeVariableArrayType )
      {
        mapTypes( actualParamByVarName, type.getComponentType() );
      }
      if( type.isParameterizedType() )
      {
        IType[] parameters = type.getTypeParameters();
        mapTypes( actualParamByVarName, parameters );
      }
      if( type instanceof IFunctionType )
      {
        IFunctionType funType = (IFunctionType)type;
        mapTypes( actualParamByVarName, funType.getReturnType() );
        IType[] paramTypes = funType.getParameterTypes();
        for( IType paramType : paramTypes )
        {
          mapTypes( actualParamByVarName, paramType );
        }
      }
    }
    return actualParamByVarName;
  }