All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.apache.wink.common.internal.utils.GenericsUtils Maven / Gradle / Ivy

There is a newer version: 1.4
Show newest version
/*******************************************************************************
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *  
 *   http://www.apache.org/licenses/LICENSE-2.0
 *  
 *  Unless required by applicable law or agreed to in writing,
 *  software distributed under the License is distributed on an
 *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 *  KIND, either express or implied.  See the License for the
 *  specific language governing permissions and limitations
 *  under the License.
 *  
 *******************************************************************************/
package org.apache.wink.common.internal.utils;

import java.lang.reflect.GenericArrayType;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;

import org.apache.wink.common.internal.i18n.Messages;
import org.apache.wink.common.internal.type.TypeFactory;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class GenericsUtils {

    private static final Logger logger = LoggerFactory.getLogger(GenericsUtils.class);

    private GenericsUtils() {
        // prevents creating this class
    }

    /**
     * 

* Returns true if the cls is assignable from the generic interface * of the assignable of the specific raw type. *

* E.g. Let A be class that implements List<String>. Calling * * isGenericInterfaceAssignableFrom(String.class, A.class, List.class) * will return true. * * @param cls * @param assignable * @param rawType * @return */ public static boolean isGenericInterfaceAssignableFrom(Class cls, Class assignable, Class rawType) { Type genericType = GenericsUtils.getGenericInterfaceParamType(assignable, rawType); // if genericType == null, assume developer did something like forgot to parameterize // their interface, in which case the genericType is indeed assignable from cls return (genericType == null) || isAssignableFrom(genericType, cls); } /** *

* Checks if the cls is assignable of from the type * assignable. *

* For arrays, checks that types of the arrays are assignable. *

* For parameterized types, checks only the raw type and doesn't check the * parameters. * * @param cls * @param assignable * @return */ public static boolean isAssignableFrom(Type type, Class cls) { if (cls.isArray()) { if (type instanceof GenericArrayType) { GenericArrayType genericArray = (GenericArrayType)type; Class componentType = cls.getComponentType(); return isAssignableFrom(genericArray.getGenericComponentType(), componentType); } } else { if (type instanceof GenericArrayType == false) { Class classType = getClassType(type, null); if (classType == Object.class || classType.isAssignableFrom(cls)) { return true; } } } return false; } /** * Returns the Type of parameter of the generic interface of the class. *

* E.g. Let A be class that implements List<String>. Calling * getGenericInterfaceType(A.class, List.class) will return * String.class. *

* In case the interface has more than one parameter, only the type of the * first parameter is returned by this method. * * @param cls * @param rawType * @return java.lang.reflect.Type */ public static Type getGenericInterfaceParamType(Class cls, Class rawType) { while (cls != null) { Type[] interfaces = cls.getGenericInterfaces(); for (Type type : interfaces) { if (type instanceof ParameterizedType) { ParameterizedType pType = (ParameterizedType)type; if (pType.getRawType() == rawType) { return pType.getActualTypeArguments()[0]; } else { continue; } } // look through the base interfaces of the current interface Type interfaceType = getGenericInterfaceParamType((Class)type, rawType); if (interfaceType != null) { return interfaceType; } } cls = cls.getSuperclass(); } // if we're done with the recursive calls, perhaps developer // did not parameterize their interface return null; } /** * Get the class type of the provided type. If the type is a Class, then * type is returned. If the type is ParameterizedType, then the Raw type is * returned. *

* E.g. if type is String.class, then String.class * is returned. If type is List<String>, then * List.class is returned. * * @param type the type to return the class type for * @param context The class that owns the member * @return the class type of type */ public static Class getClassType(Type type, Class context) { if (type == null) { return null; } Class cls = context == null ? TypeFactory.type(type).getRawClass() : TypeFactory.type(type, context).getRawClass(); /* if (type instanceof Class) { return (Class)type; } if (type instanceof ParameterizedType) { ParameterizedType parameterizedType = (ParameterizedType)type; return (Class)parameterizedType.getRawType(); } if (type instanceof GenericArrayType) { GenericArrayType genericArray = (GenericArrayType)type; Class classType = getClassType(genericArray.getGenericComponentType(), context); return Array.newInstance(classType, 0).getClass(); } if (type instanceof TypeVariable) { return getClassType(((TypeVariable)type).getBounds()[0], context); } if (type instanceof WildcardType) { return getClassType(((WildcardType)type).getUpperBounds()[0], context); } */ if (cls != null) { return cls; } logger.error(Messages.getMessage("methodCannotHandleType", String.valueOf(type))); //$NON-NLS-1$ return null; } /** * Get the class of the parameter of the provided parameterized type. If the * type is a Class, then null is returned. If the type is * ParameterizedType, then the actual type argument is returned. *

* E.g. if type is String.class, then null is * returned. If type is List<String>, then * String.class is returned. *

* In case the type has more than one parameter, only the type of the first * parameter is returned by this method. * * @param type the type to return the class of the parameter for * @return the class of the generic parameter of type */ public static Class getGenericParamType(Type type) { Class generic = null; if (type instanceof ParameterizedType) { ParameterizedType parameterizedType = (ParameterizedType)type; Type[] actualTypeArguments = parameterizedType.getActualTypeArguments(); generic = (Class)actualTypeArguments[0]; } return generic; } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy