Package com.asakusafw.utils.java.internal.model.util

Source Code of com.asakusafw.utils.java.internal.model.util.ReflectionTypeMapper

/**
* Copyright 2011-2014 Asakusa Framework Team.
*
* 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.asakusafw.utils.java.internal.model.util;

import java.lang.reflect.GenericArrayType;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.TypeVariable;
import java.lang.reflect.WildcardType;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import com.asakusafw.utils.java.model.syntax.BasicTypeKind;
import com.asakusafw.utils.java.model.syntax.ModelFactory;
import com.asakusafw.utils.java.model.syntax.Type;
import com.asakusafw.utils.java.model.syntax.WildcardBoundKind;
import com.asakusafw.utils.java.model.util.Models;
import com.asakusafw.utils.java.model.util.NoThrow;

/**
* {@link java.lang.reflect.Type}をモデルに変換する。
*/
public class ReflectionTypeMapper
        extends ReflectionTypeVisitor<Type, ModelFactory, NoThrow> {

    private static final Map<Class<?>, BasicTypeKind> BASIC_TYPES;
    static {
        Map<Class<?>, BasicTypeKind> map =
            new HashMap<Class<?>, BasicTypeKind>();
        for (BasicTypeKind kind : BasicTypeKind.values()) {
            map.put(
                kind.getJavaRepresentation(),
                kind);
        }
        BASIC_TYPES = Collections.unmodifiableMap(map);
    }

    @Override
    protected Type visitClass(Class<?> type, ModelFactory context) {
        if (BASIC_TYPES.containsKey(type)) {
            return context.newBasicType(BASIC_TYPES.get(type));
        }
        if (type.isArray()) {
            return context.newArrayType(visitClass(type.getComponentType(), context));
        }
        String name = type.getName().replace('$', '.');
        return context.newNamedType(Models.toName(context, name));
    }

    @Override
    protected Type visitGenericArrayType(
            GenericArrayType type,
            ModelFactory context) {
        Type component = dispatch(type.getGenericComponentType(), context);
        return context.newArrayType(component);
    }

    @Override
    protected Type visitParameterizedType(
            ParameterizedType type,
            ModelFactory context) {
        java.lang.reflect.Type owner = type.getOwnerType();
        java.lang.reflect.Type rawType = type.getRawType();
        Type candidate;
        if (owner == null || owner instanceof Class<?>) {
            candidate = dispatch(rawType, context);
        } else {
            Type enclosing = dispatch(owner, context);
            assert rawType instanceof Class<?> : rawType;
            candidate = context.newQualifiedType(
                enclosing,
                context.newSimpleName(((Class<?>) rawType).getSimpleName()));
        }

        List<Type> typeArguments = new ArrayList<Type>();
        for (java.lang.reflect.Type t : type.getActualTypeArguments()) {
            typeArguments.add(dispatch(t, context));
        }
        return context.newParameterizedType(candidate, typeArguments);
    }

    @Override
    protected Type visitTypeVariable(TypeVariable<?> type, ModelFactory context) {
        return context.newNamedType(context.newSimpleName(type.getName()));
    }

    @Override
    protected Type visitWildcardType(WildcardType type, ModelFactory context) {
        java.lang.reflect.Type[] lower = type.getLowerBounds();
        if (lower.length == 1) {
            return context.newWildcard(
                WildcardBoundKind.LOWER_BOUNDED,
                dispatch(lower[0], context));
        }
        java.lang.reflect.Type[] upper = type.getUpperBounds();
        if (upper.length == 1 && upper[0] != Object.class) {
            return context.newWildcard(
                WildcardBoundKind.UPPER_BOUNDED,
                dispatch(upper[0], context));
        }

        return context.newWildcard(
            WildcardBoundKind.UNBOUNDED,
            null);
    }
}
TOP

Related Classes of com.asakusafw.utils.java.internal.model.util.ReflectionTypeMapper

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.