Package com.alibaba.citrus.generictype.impl

Source Code of com.alibaba.citrus.generictype.impl.ArrayTypeImpl$SupertypesLoader

/*
* Copyright 2010 Alibaba Group Holding Limited.
* All rights reserved.
*
* 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.alibaba.citrus.generictype.impl;

import static com.alibaba.citrus.util.Assert.*;
import static com.alibaba.citrus.util.CollectionUtil.*;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

import com.alibaba.citrus.generictype.ArrayTypeInfo;
import com.alibaba.citrus.generictype.GenericDeclarationInfo;
import com.alibaba.citrus.generictype.TypeInfo;
import com.alibaba.citrus.util.ClassUtil;
import com.alibaba.citrus.util.internal.LazyLoader;
import com.alibaba.citrus.util.internal.LazyLoader.Loader;

/**
* ��{@link ArrayTypeInfo}��ʵ�֡�
*
* @author Michael Zhou
*/
class ArrayTypeImpl implements ArrayTypeInfo {
    private final Class<?> rawType;
    private final TypeInfo componentType;
    private final TypeInfo directComponentType;
    private final int dimension;
    private final LazyLoader<Supertypes, Object> supertypesLoader;

    ArrayTypeImpl(TypeInfo componentType, TypeInfo directComponentType, int dimension, Class<?> rawType) {
        this.componentType = assertNotNull(componentType, "componentType");
        this.directComponentType = assertNotNull(directComponentType, "directComponentType");
        this.dimension = dimension;

        assertTrue(dimension > 0, "dimension: %d", dimension);

        if (rawType == null) {
            this.rawType = ClassUtil.getArrayClass(componentType.getRawType(), dimension);
        } else {
            this.rawType = rawType;
        }

        this.supertypesLoader = LazyLoader.getDefault(new SupertypesLoader());
    }

    public Class<?> getRawType() {
        return rawType;
    }

    public String getName() {
        return rawType.getName();
    }

    public String getSimpleName() {
        return rawType.getSimpleName();
    }

    public boolean isPrimitive() {
        return false;
    }

    public boolean isArray() {
        return true;
    }

    public boolean isInterface() {
        return false;
    }

    public TypeInfo getPrimitiveWrapperType() {
        return this;
    }

    public TypeInfo getComponentType() {
        return componentType;
    }

    public TypeInfo getDirectComponentType() {
        return directComponentType;
    }

    public int getDimension() {
        return dimension;
    }

    public List<TypeInfo> getInterfaces() {
        return supertypesLoader.getInstance().interfaces;
    }

    public List<TypeInfo> getSuperclasses() {
        return supertypesLoader.getInstance().superclasses;
    }

    public List<TypeInfo> getSupertypes() {
        return supertypesLoader.getInstance().supertypes;
    }

    public TypeInfo getSupertype(Class<?> equivalentClass) {
        return TypeInfoFactory.findSupertype(this, equivalentClass);
    }

    // Implementation of TypeInfo.resolve
    public TypeInfo resolve(GenericDeclarationInfo context) {
        return resolve(context, true);
    }

    // Implementation of TypeInfo.resolve
    public TypeInfo resolve(GenericDeclarationInfo context, boolean includeBaseType) {
        TypeInfo resolvedComponentType = componentType.resolve(context, includeBaseType);

        if (resolvedComponentType == componentType) {
            return this;
        } else {
            return factory.getArrayType(resolvedComponentType, dimension);
        }
    }

    /**
     * ȡ��hashֵ��
     */
    @Override
    public int hashCode() {
        return getClass().hashCode() ^ componentType.hashCode() ^ dimension;
    }

    /**
     * �ж����������Ƿ���ͬ��
     */
    @Override
    public boolean equals(Object other) {
        if (other == this) {
            return true;
        }

        if (other == null || !other.getClass().equals(getClass())) {
            return false;
        }

        ArrayTypeImpl otherType = (ArrayTypeImpl) other;

        return dimension == otherType.dimension && componentType.equals(otherType.componentType);
    }

    /**
     * ȡ���ַ�����ʾ��
     */
    @Override
    public String toString() {
        StringBuilder buf = new StringBuilder();

        buf.append(getComponentType());

        for (int i = 0; i < dimension; i++) {
            buf.append("[]");
        }

        return buf.toString();
    }

    /**
     * ���ࡢ�ӿڵ���Ϣ��
     */
    private static class Supertypes {
        private static final TypeInfo[] ARRAY_SUPERTYPES;
        private final List<TypeInfo> supertypes;
        private final List<TypeInfo> interfaces;
        private final List<TypeInfo> superclasses;

        static {
            TypeInfo[] interfaces = factory.getTypes(Object[].class.getInterfaces());
            TypeInfo[] arraySupertypes = new TypeInfo[interfaces.length + 1];

            System.arraycopy(interfaces, 0, arraySupertypes, 0, interfaces.length);
            arraySupertypes[interfaces.length] = TypeInfo.OBJECT;

            ARRAY_SUPERTYPES = arraySupertypes;
        }

        private Supertypes(ArrayTypeImpl arrayType) {
            TypeInfo componentType = arrayType.componentType;
            List<TypeInfo> componentSupertypes = componentType.getSupertypes();
            ArrayList<TypeInfo> supertypes = createArrayList(componentSupertypes.size() * 2);
            ArrayList<TypeInfo> interfaces = createArrayList();
            ArrayList<TypeInfo> superclasses = createArrayList();

            for (TypeInfo componentSupertype : componentSupertypes) {
                supertypes.add(factory.getArrayType(componentSupertype, arrayType.dimension));
            }

            for (int dim = arrayType.dimension - 1; dim > 0; dim--) {
                for (TypeInfo arraySupertype : ARRAY_SUPERTYPES) {
                    supertypes.add(factory.getArrayType(arraySupertype, dim));
                }
            }

            for (TypeInfo arraySupertype : ARRAY_SUPERTYPES) {
                supertypes.add(arraySupertype);
            }

            // ����lists
            for (TypeInfo supertype : supertypes) {
                if (supertype.getRawType().isInterface()) {
                    interfaces.add(supertype);
                } else {
                    superclasses.add(supertype);
                }
            }

            supertypes.trimToSize();
            interfaces.trimToSize();
            superclasses.trimToSize();

            this.supertypes = Collections.unmodifiableList(supertypes);
            this.interfaces = Collections.unmodifiableList(interfaces);
            this.superclasses = Collections.unmodifiableList(superclasses);
        }
    }

    /**
     * ����supertypes��װ������
     */
    private class SupertypesLoader implements Loader<Supertypes, Object> {
        public Supertypes load(Object context) {
            return new Supertypes(ArrayTypeImpl.this);
        }
    }
}
TOP

Related Classes of com.alibaba.citrus.generictype.impl.ArrayTypeImpl$SupertypesLoader

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.