/** * Validates that a type is extendable, i.e. is not an array, a primitive type or a {@code final} * type. * * @param typeDescription The type to validate. * @param <T> The actual type of the validated instance. * @return The input value. */ public static <T extends GenericTypeDescription> T isExtendable(T typeDescription) { if (!EXTENDABLE_TYPES.contains(typeDescription.getSort())) { throw new IllegalArgumentException("Cannot extend generic type: " + typeDescription); } else if (isDefineable(typeDescription.asErasure()).isFinal()) { throw new IllegalArgumentException("Cannot extend a final type: " + typeDescription); } return typeDescription; }
/** * Joins two collections where the left collection must only contain unique elements. If two * elements represent the same type erasure but are not equal, an exception is thrown- * * @param left The left collection. * @param right The right collection. * @param <T> The element type. * @return A joined list of both given lists. */ public static <T extends GenericTypeDescription> List<T> joinUniqueRaw( Collection<? extends T> left, Collection<? extends T> right) { List<T> result = new ArrayList<T>(left.size() + right.size()); Map<TypeDescription, GenericTypeDescription> types = new HashMap<TypeDescription, GenericTypeDescription>(); for (T typeDescription : left) { types.put(typeDescription.asErasure(), typeDescription); result.add(typeDescription); } for (T typeDescription : right) { GenericTypeDescription conflictingType = types.put(typeDescription.asErasure(), typeDescription); if (conflictingType != null && !conflictingType.equals(typeDescription)) { throw new IllegalArgumentException( "Conflicting type erasures: " + conflictingType + " and " + typeDescription); } else if (conflictingType == null) { result.add(typeDescription); } } return result; }