com.link_intersystems.lang.reflect.Class2Test.java Source code

Java tutorial

Introduction

Here is the source code for com.link_intersystems.lang.reflect.Class2Test.java

Source

/**
 * Copyright 2011 Link Intersystems GmbH <rene.link@link-intersystems.com>
 *
 * Licensed 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 com.link_intersystems.lang.reflect;

import static junit.framework.Assert.assertTrue;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;

import java.lang.reflect.Type;
import java.lang.reflect.TypeVariable;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Locale;
import java.util.Map;

import org.apache.commons.lang3.SerializationUtils;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;

import com.link_intersystems.lang.ClassLoaderContextAware;
import com.link_intersystems.lang.reflect.testclasses.ArrayBoundType;
import com.link_intersystems.lang.reflect.testclasses.Class2ToStringBoundTypeNotClass;
import com.link_intersystems.lang.reflect.testclasses.Class2ToStringGeneric;
import com.link_intersystems.lang.reflect.testclasses.Class2ToStringGenericNoBounds;
import com.link_intersystems.lang.reflect.testclasses.Class2ToStringParameterizedTypeBoundType;
import com.link_intersystems.lang.reflect.testclasses.ConreteGenericClassWithBeanType;
import com.link_intersystems.lang.reflect.testclasses.CrazyParameterizedBoundType;
import com.link_intersystems.lang.reflect.testclasses.GenericBoundType;
import com.link_intersystems.lang.reflect.testclasses.GenericClassWithBeanType;
import com.link_intersystems.lang.reflect.testclasses.GenericClassWithGenericBeanType;
import com.link_intersystems.lang.reflect.testclasses.GenericClass_Types_A_B_C_D;
import com.link_intersystems.lang.reflect.testclasses.GenericClass_Types_D_C_Extends_GenericClass;
import com.link_intersystems.lang.reflect.testclasses.GenericInterface_Types_A_B_C;
import com.link_intersystems.lang.reflect.testclasses.GenericSubInterface;
import com.link_intersystems.lang.reflect.testclasses.GenericSubWithInterface;
import com.link_intersystems.lang.reflect.testclasses.OnlyGenericInterface;

public class Class2Test {

    private List<String> allContainerProperties;

    @SuppressWarnings("unused")
    private List<String> containerOnlyProperties;

    private ArrayList<String> allPanelProperties;

    @Before
    public void instantiate() {
        allContainerProperties = new ArrayList<String>(Arrays.asList("alignmentY", "component",
                "focusTraversalPolicyProvider", "layout", "containerListeners", "insets", "preferredSize",
                "minimumSize", "focusCycleRoot", "maximumSize", "foreground", "focusTraversalPolicy",
                "componentCount", "font", "components", "focusable", "enabled", "focusTraversalPolicySet",
                "visible", "background", "alignmentX", "name", "focusTraversalKeys"));
        containerOnlyProperties = new ArrayList<String>(Arrays.asList("alignmentY", "component",
                "focusTraversalPolicyProvider", "layout", "containerListeners", "insets", "preferredSize",
                "minimumSize", "focusCycleRoot", "maximumSize", "foreground", "focusTraversalPolicy",
                "componentCount", "font", "components", "focusable", "enabled", "focusTraversalPolicySet",
                "visible", "background", "alignmentX", "name", "focusTraversalKeys"));
        allPanelProperties = new ArrayList<String>(Arrays.asList("accessibleContext"));
        allPanelProperties.addAll(allContainerProperties);
    }

    @Test
    public void getClassLoaderForSystemClass() throws ClassNotFoundException {
        Class2<String> class2 = Class2.get(String.class);
        ClassLoader classLoader = class2.getType().getClassLoader();
        assertNull(classLoader);

        ClassLoader classLoader2 = class2.getClassLoader();
        assertEquals(ClassLoader.getSystemClassLoader(), classLoader2);

        Class2<Object> class2ByName = Class2.get(String.class.getCanonicalName());
        Assert.assertSame(class2, class2ByName);
    }

    @Test(expected = IllegalArgumentException.class)
    public void nullTypeVariableName() {
        Class2<?> genericSubClass = Class2.get(GenericClass_Types_D_C_Extends_GenericClass.class);
        genericSubClass.getTypeVariable(null);
    }

    @Test
    public void getNonExistentTypeVariable() {
        Class2<?> genericSubClass = Class2.get(GenericClass_Types_D_C_Extends_GenericClass.class);
        TypeVariable<?> typeVariable = genericSubClass.getTypeVariable("ABC");
        assertNull("Type variable should not exist", typeVariable);
    }

    @Test(expected = IllegalArgumentException.class)
    public void nullTypeVariable() {
        Class2<?> genericSubWithInterface = Class2.get(GenericSubWithInterface.class);
        genericSubWithInterface.getBoundType(null);
    }

    @Test
    public void simpleGenerics() {
        Class2<?> genericSubClass = Class2.get(GenericClass_Types_D_C_Extends_GenericClass.class);
        Class2<?> genericSubWithInterface = Class2.get(GenericSubWithInterface.class);
        TypeVariable<?> typeVariable = genericSubClass.getTypeVariable("C");
        Type type = genericSubWithInterface.getBoundType(typeVariable);
        assertEquals(Float.class, type);
    }

    @Test
    public void genericInterfaceSimpleHierarchy() {
        Class2<?> genericSubWithInterface = Class2.get(GenericSubWithInterface.class);
        Class2<?> genericInterface = Class2.get(GenericSubInterface.class);
        TypeVariable<?> typeVariable = genericInterface.getTypeVariable("B");
        Type boundType = genericSubWithInterface.getBoundType(typeVariable);
        assertEquals(Float.class, boundType);
    }

    @Test
    public void genericInterfaceKomplexHierarchy() {
        Class2<?> genericSubWithInterface = Class2.get(GenericSubWithInterface.class);
        Class2<?> genericInterface = Class2.get(GenericInterface_Types_A_B_C.class);
        TypeVariable<?> typeVariable = genericInterface.getTypeVariable("B");
        Type boundType = genericSubWithInterface.getBoundType(typeVariable);
        assertEquals(Double.class, boundType);
    }

    @Test
    public void convenienceMethodForBoundClass() {
        Class2<?> genericSubWithInterface = Class2.get(GenericClass_Types_D_C_Extends_GenericClass.class);
        Type boundType = genericSubWithInterface.getBoundClass("B");
        assertEquals(Integer.class, boundType);
    }

    @Test
    public void convenienceMethodForBoundInterfaceTypeVar() {
        Class2<?> genericSubWithInterface = Class2.get(OnlyGenericInterface.class);
        Type boundType = genericSubWithInterface.getBoundClass("C");
        assertEquals(Integer.class, boundType);
    }

    @Test(expected = IllegalArgumentException.class)
    public void convenienceMethodForBoundClassNoSuchTypeVariable() {
        Class2<?> genericSubWithInterface = Class2.get(GenericClass_Types_D_C_Extends_GenericClass.class);
        genericSubWithInterface.getBoundClass("X");
    }

    @Test
    public void genericClassKomplexHierarchy() {
        Class2<?> genericClass = Class2.get(GenericClass_Types_A_B_C_D.class);
        Class2<?> genericSubWithInterface = Class2.get(GenericSubWithInterface.class);
        TypeVariable<?> typeVariable = genericClass.getTypeVariable("C");
        Type boundType = genericSubWithInterface.getBoundType(typeVariable);
        assertEquals(Float.class, boundType);
    }

    @Test
    public void unboundTypeVariable() {
        Class2<?> genericClass = Class2.get(GenericClass_Types_A_B_C_D.class);
        Class2<?> genericSubClass = Class2.get(GenericClass_Types_D_C_Extends_GenericClass.class);
        TypeVariable<?> typeVariable = genericClass.getTypeVariable("C");
        Type boundType = genericSubClass.getBoundType(typeVariable);
        assertNull("type variable should not be bound", boundType);
    }

    @Test
    public void boundTypeClass() {
        Class2<?> genericDefinition = Class2.get(GenericClassWithBeanType.class);
        Class2<?> concrteGeneric = Class2.get(ConreteGenericClassWithBeanType.class);
        TypeVariable<?> typeVariable = genericDefinition.getTypeVariable("BEAN_TYPE");
        Class<ConreteGenericClassWithBeanType.SomeBean> boundClass = concrteGeneric.getBoundClass(typeVariable);
        assertNotNull(boundClass);
    }

    @Test
    public void boundTypeClassForNonExistingTypeVariable() {
        Class2<?> genericDefinition = Class2.get(GenericClassWithBeanType.class);
        TypeVariable<?> typeVariable = genericDefinition.getTypeVariable("BEAN_TYPE");
        Class<Object> boundClass = genericDefinition.getBoundClass(typeVariable);
        assertNull(boundClass);
    }

    @Test
    public void instantiateTypeVariable() {
        Class2<?> genericDefinition = Class2.get(GenericClassWithBeanType.class);
        Class2<?> concrteGeneric = Class2.get(ConreteGenericClassWithBeanType.class);
        TypeVariable<?> typeVariable = genericDefinition.getTypeVariable("BEAN_TYPE");
        Object boundTypeInstance = concrteGeneric.getBoundInstance(typeVariable);
        assertNotNull(boundTypeInstance);
        assertTrue(boundTypeInstance instanceof ConreteGenericClassWithBeanType.SomeBean);
    }

    @Test(expected = IllegalArgumentException.class)
    public void instantiateTypeVariableWrongConstructorArgs() {
        Class2<?> genericDefinition = Class2.get(GenericClassWithBeanType.class);
        Class2<?> concreteGeneric = Class2.get(ConreteGenericClassWithBeanType.class);
        TypeVariable<?> typeVariable = genericDefinition.getTypeVariable("BEAN_TYPE");
        concreteGeneric.getBoundInstance(typeVariable, new byte[0]);
    }

    @Test
    public void instantiateTypeVariableWithGenericBoundType() {
        Class2<?> genericDefinition = Class2.get(GenericClassWithBeanType.class);
        Class2<?> concrteGeneric = Class2.get(GenericClassWithGenericBeanType.class);
        TypeVariable<?> typeVariable = genericDefinition.getTypeVariable("BEAN_TYPE");
        Object boundTypeInstance = concrteGeneric.getBoundInstance(typeVariable);
        assertNotNull(boundTypeInstance);
        assertTrue(boundTypeInstance instanceof ArrayList);
    }

    @Test(expected = IllegalArgumentException.class)
    public void instantiateTypeVariableisAnInterface() {
        Class2<?> genericDefinition = Class2.get(GenericClassWithBeanType.class);
        Class2<?> concrteGeneric = Class2.get(CrazyParameterizedBoundType.class);
        TypeVariable<?> typeVariable = genericDefinition.getTypeVariable("BEAN_TYPE");
        concrteGeneric.getBoundInstance(typeVariable);
    }

    @Test
    public void parameterizedBoundType() {
        Class2<?> genericDefinition = Class2.get(GenericClassWithBeanType.class);
        Class2<?> concrteGeneric = Class2.get(CrazyParameterizedBoundType.class);
        TypeVariable<?> typeVariable = genericDefinition.getTypeVariable("BEAN_TYPE");
        Class<?> boundTypeClass = concrteGeneric.getBoundClass(typeVariable);
        assertNotNull(boundTypeClass);
        assertTrue(boundTypeClass.equals(List.class));
    }

    @Test
    public void arrayBoundType() {
        Class2<?> arrayBoundType = Class2.get(ArrayBoundType.class);
        Class<?> boundClass = arrayBoundType.getBoundClass("BEAN_TYPE");
        assertEquals(String[].class, boundClass);
    }

    @Test
    public void genericBoundType() {
        Class2<?> arrayBoundType = Class2.get(GenericBoundType.class);
        Class<?> boundClass = arrayBoundType.getBoundClass("BEAN_TYPE");
        assertEquals(List.class, boundClass);
    }

    @SuppressWarnings("rawtypes")
    @Test
    public void toStringForMultipleParameterizedType() {
        Class2<Map> forClass = Class2.get(Map.class);
        String string = forClass.toString();
        assertEquals("java.util.Map<K,V>", string);
    }

    @SuppressWarnings("rawtypes")
    @Test
    public void toStringForSimpleParameterizedType() {
        Class2<Class2> forClass = Class2.get(Class2.class);
        String string = forClass.toString();
        assertEquals("com.link_intersystems.lang.reflect.Class2<T>", string);
    }

    @Test
    public void applicableVarargsMethod() throws Exception {
        Class2<String> forClass = Class2.get(String.class);
        Method2 applicableMethod = forClass.getApplicableMethod("format", Locale.GERMAN, "Hello %s", "World");
        Invokable invokable = applicableMethod.getInvokable(String.class);
        String formatted = invokable.invoke(Locale.GERMAN, "Hello %s", "World");
        assertEquals("Hello World", formatted);
    }

    @SuppressWarnings("rawtypes")
    @Test
    public void toStringForBoundTypes() {
        Class2<Class2ToStringGeneric> forClass = Class2.get(Class2ToStringGeneric.class);
        String string = forClass.toString();
        assertEquals(
                "com.link_intersystems.lang.reflect.testclasses.Class2ToStringGeneric<A extends java.lang.annotation.Annotation,C extends java.lang.annotation.Annotation & java.io.Serializable,B extends java.io.Serializable,D>",
                string);
    }

    @SuppressWarnings("rawtypes")
    @Test
    public void toStringForUnboundTypes() {
        Class2<Class2ToStringGenericNoBounds> forClass = Class2.get(Class2ToStringGenericNoBounds.class);
        String string = forClass.toString();
        assertEquals("com.link_intersystems.lang.reflect.testclasses.Class2ToStringGenericNoBounds<A>", string);
    }

    @SuppressWarnings("rawtypes")
    @Test
    public void toStringForNoClassBoundTypes() {
        Class2<Class2ToStringBoundTypeNotClass> forClass = Class2.get(Class2ToStringBoundTypeNotClass.class);
        String string = forClass.toString();
        assertEquals(
                "com.link_intersystems.lang.reflect.testclasses.Class2ToStringBoundTypeNotClass<B extends java.io.Serializable,A extends B>",
                string);
    }

    @SuppressWarnings("rawtypes")
    @Test
    public void toStringForParameterizedTypeBoundTypes() {
        Class2<Class2ToStringParameterizedTypeBoundType> forClass = Class2
                .get(Class2ToStringParameterizedTypeBoundType.class);
        String string = forClass.toString();
        assertEquals(
                "com.link_intersystems.lang.reflect.testclasses.Class2ToStringParameterizedTypeBoundType<B extends java.io.Serializable,A extends java.util.List<B>>",
                string);
    }

    @SuppressWarnings("rawtypes")
    @Test
    public void contextClassLoaderAware() {
        ClassLoader contextClassLoader = Thread.currentThread().getContextClassLoader();
        try {
            Thread.currentThread().setContextClassLoader(null);
            Class2<Class2ToStringGeneric> forClass = Class2.get(Class2ToStringGeneric.class);
            final ClassLoader classLoader = Class2ToStringGeneric.class.getClassLoader();
            ClassLoaderContextAware classLoaderContext = forClass.getClassLoaderContextAware();
            classLoaderContext.runInContext(new Runnable() {

                public void run() {
                    ClassLoader contextClassLoader = Thread.currentThread().getContextClassLoader();
                    assertEquals(contextClassLoader, classLoader);
                }
            });
        } finally {
            Thread.currentThread().setContextClassLoader(contextClassLoader);
        }
    }

    @Test
    public void getPackage2() {
        Class2<?> genericDefinition = Class2.get(GenericClassWithBeanType.class);
        Package package1 = GenericClassWithBeanType.class.getPackage();
        Package2 package2 = genericDefinition.getPackage();
        assertEquals(package1.getName(), package2.getName());
    }

    @Test
    public void serializable() {
        Class2<?> genericDefinition = Class2.get(GenericClassWithBeanType.class);
        Class2<?> clone = (Class2<?>) SerializationUtils.clone(genericDefinition);
        TypeVariable<?> typeVariable = clone.getTypeVariable("BEAN_TYPE");
        assertNotNull(typeVariable);
    }

    @Test
    public void getArrayType() {
        Class2<?> objectType = Class2.get(Object.class);
        Class<?> asArrayType = objectType.getArrayType();
        assertEquals(Object[].class, asArrayType);
    }

    @Test
    public void getArrayTypeOfArrayType() {
        Class2<?> objectArrayType = Class2.get(Object[].class);
        Class<?> asArrayType = objectArrayType.getArrayType();
        assertEquals(Object[][].class, asArrayType);
    }

    @Test
    public void getArrayType2Cached() {
        Class2<?> genericDefinition = Class2.get(GenericClassWithBeanType.class);
        Class2<?> asArrayType1 = genericDefinition.getArrayType2();
        Class2<?> asArrayType2 = genericDefinition.getArrayType2();
        Assert.assertSame(asArrayType1, asArrayType2);
    }

    @Test
    public void getMultiDimensionArrayType() {
        Class2<Object> objectArrayType = Class2.get(Object.class);
        Class<Object[][][]> asArrayType = objectArrayType.getArrayType2().getArrayType2().getArrayType();
        assertEquals(Object[][][].class, asArrayType);
    }
}