Main.java Source code

Java tutorial

Introduction

Here is the source code for Main.java

Source

//package com.java2s;
//License from project: Apache License 

import java.lang.reflect.Array;
import java.lang.reflect.Constructor;
import java.lang.reflect.GenericArrayType;
import java.lang.reflect.GenericDeclaration;
import java.lang.reflect.Method;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.lang.reflect.TypeVariable;
import java.lang.reflect.WildcardType;

public class Main {
    public final static Class<?> getRawClass(Type type) {
        if (type instanceof Class<?>)
            return (Class<?>) type;
        else if (type instanceof ParameterizedType) {
            ParameterizedType pType = (ParameterizedType) type;
            return (Class<?>) pType.getRawType();
        } else if (type instanceof GenericArrayType) {
            Type componentType = ((GenericArrayType) type).getGenericComponentType();
            return Array.newInstance(getRawClass(componentType), 0).getClass();
        } else
            return getRawClass(expand(type, null));
    }

    final static Type expand(Type type, Class<?> inClass) {
        Type expandedType = null;
        if (type instanceof TypeVariable) {
            @SuppressWarnings("unchecked")
            // for the moment we assume it is a class, we can later handle ctr and methods
            TypeVariable<GenericDeclaration> tvType = (TypeVariable<GenericDeclaration>) type;
            if (inClass == null)
                inClass = genericDeclarationToClass(tvType.getGenericDeclaration());
            expandedType = resolveTypeVariable(tvType, inClass);
            if (type.equals(expandedType))
                expandedType = tvType.getBounds()[0];
        } else if (type instanceof WildcardType) {
            WildcardType wType = (WildcardType) type;
            expandedType = wType.getUpperBounds().length > 0 ? expand(wType.getUpperBounds()[0], inClass)
                    : Object.class;
        } else
            return type;

        return expandedType == null || type.equals(expandedType) ? Object.class : expandedType;
    }

    private static Class<?> genericDeclarationToClass(GenericDeclaration declaration) {
        if (declaration instanceof Class)
            return (Class<?>) declaration;
        if (declaration instanceof Method)
            return ((Method) declaration).getDeclaringClass();
        if (declaration instanceof Constructor)
            return ((Constructor<?>) declaration).getDeclaringClass();
        throw new UnsupportedOperationException();
    }

    /**
     * Searches for the typevariable definition in the inClass hierarchy.
     * 
     * @param type
     * @param inClass
     * @return the resolved type or type if unable to resolve it.
     */
    public final static Type resolveTypeVariable(TypeVariable<? extends GenericDeclaration> type,
            Class<?> inClass) {
        return resolveTypeVariable(type, genericDeclarationToClass(type.getGenericDeclaration()), inClass);
    }

    private final static Type resolveTypeVariable(TypeVariable<? extends GenericDeclaration> type,
            Class<?> declaringClass, Class<?> inClass) {

        if (inClass == null)
            return null;

        Class<?> superClass = null;
        Type resolvedType = null;
        Type genericSuperClass = null;

        if (!declaringClass.equals(inClass)) {
            if (declaringClass.isInterface()) {
                // the declaringClass is an interface
                Class<?>[] interfaces = inClass.getInterfaces();
                for (int i = 0; i < interfaces.length && resolvedType == null; i++) {
                    superClass = interfaces[i];
                    resolvedType = resolveTypeVariable(type, declaringClass, superClass);
                    genericSuperClass = inClass.getGenericInterfaces()[i];
                }
            }

            if (resolvedType == null) {
                superClass = inClass.getSuperclass();
                resolvedType = resolveTypeVariable(type, declaringClass, superClass);
                genericSuperClass = inClass.getGenericSuperclass();
            }
        } else {
            resolvedType = type;
            genericSuperClass = superClass = inClass;

        }

        if (resolvedType != null) {
            // if its another type this means we have finished
            if (resolvedType instanceof TypeVariable<?>) {
                type = (TypeVariable<?>) resolvedType;
                TypeVariable<?>[] parameters = superClass.getTypeParameters();
                int positionInClass = 0;
                for (; positionInClass < parameters.length
                        && !type.equals(parameters[positionInClass]); positionInClass++) {
                }

                // we located the position of the typevariable in the superclass
                if (positionInClass < parameters.length) {
                    // let's look if we have type specialization information in the current class
                    if (genericSuperClass instanceof ParameterizedType) {
                        ParameterizedType pGenericType = (ParameterizedType) genericSuperClass;
                        Type[] args = pGenericType.getActualTypeArguments();
                        return positionInClass < args.length ? args[positionInClass] : null;
                    }
                }

                // we didnt find typevariable specialization in the class, so it's the best we can
                // do, lets return the resolvedType...
            }
        }

        return resolvedType;
    }
}