Package org.jboss.weld.resources

Source Code of org.jboss.weld.resources.MemberTransformer$EnhancedConstructorLoader

/*
* JBoss, Home of Professional Open Source
* Copyright 2010, Red Hat, Inc., and individual contributors
* by the @authors tag. See the copyright.txt in the distribution for a
* full listing of individual contributors.
*
* 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 org.jboss.weld.resources;

import static org.jboss.weld.util.reflection.Reflections.cast;

import java.lang.reflect.Member;
import java.util.Collection;
import java.util.Objects;
import java.util.function.Function;

import javax.enterprise.inject.spi.AnnotatedConstructor;
import javax.enterprise.inject.spi.AnnotatedField;
import javax.enterprise.inject.spi.AnnotatedMember;
import javax.enterprise.inject.spi.AnnotatedMethod;
import javax.enterprise.inject.spi.AnnotatedParameter;

import org.jboss.weld.annotated.enhanced.EnhancedAnnotatedCallable;
import org.jboss.weld.annotated.enhanced.EnhancedAnnotatedConstructor;
import org.jboss.weld.annotated.enhanced.EnhancedAnnotatedField;
import org.jboss.weld.annotated.enhanced.EnhancedAnnotatedMember;
import org.jboss.weld.annotated.enhanced.EnhancedAnnotatedMethod;
import org.jboss.weld.annotated.enhanced.EnhancedAnnotatedParameter;
import org.jboss.weld.annotated.enhanced.EnhancedAnnotatedType;
import org.jboss.weld.annotated.slim.backed.BackedAnnotatedMember;
import org.jboss.weld.annotated.slim.unbacked.UnbackedAnnotatedMember;
import org.jboss.weld.annotated.slim.unbacked.UnbackedAnnotatedType;
import org.jboss.weld.annotated.slim.unbacked.UnbackedMemberIdentifier;
import org.jboss.weld.bootstrap.api.BootstrapService;
import org.jboss.weld.logging.BeanLogger;
import org.jboss.weld.util.AnnotatedTypes;
import org.jboss.weld.util.cache.ComputingCache;
import org.jboss.weld.util.cache.ComputingCacheBuilder;
import org.jboss.weld.util.reflection.Reflections;

/**
* Serves several functions. Firstly, transforms a given {@link AnnotatedMember} into its richer counterpart
* {@link EnhancedAnnotatedMember}. Secondly, a {@link BackedAnnotatedMember} or {@link UnbackedAnnotatedMember} can be looked
* up.
*
* @author Jozef Hartinger
*
*/
public class MemberTransformer implements BootstrapService {

    private static class MemberKey<X, A extends AnnotatedMember<X>> {
        private final EnhancedAnnotatedType<X> type;
        private final A member;
        private final int hashCode;

        public MemberKey(EnhancedAnnotatedType<X> type, A member) {
            this.type = type;
            this.member = member;
            this.hashCode = Objects.hash(type, member);
        }

        @Override
        public int hashCode() {
            return hashCode;
        }

        @Override
        public boolean equals(Object obj) {
            if (obj instanceof MemberKey) {
                MemberKey<?, ?> that = (MemberKey<?, ?>) obj;
                return Objects.equals(this.type, that.type) && Objects.equals(this.member, that.member);
            }
            return false;
        }
    }

    private final ClassTransformer transformer;

    private final ComputingCache<UnbackedMemberIdentifier<?>, UnbackedAnnotatedMember<?>> unbackedAnnotatedMembersById;

    private final ComputingCache<MemberKey<?, ?>, EnhancedAnnotatedMember<?, ?, ?>> enhancedMemberCache;
    private final EnhancedFieldLoader enhancedFieldLoader;
    private final EnhancedMethodLoader enhancedMethodLoader;
    private final EnhancedConstructorLoader enhancedConstructorLoader;

    public MemberTransformer(ClassTransformer transformer) {
        ComputingCacheBuilder cacheBuilder = ComputingCacheBuilder.newBuilder();
        this.transformer = transformer;
        this.unbackedAnnotatedMembersById = cacheBuilder.build(new UnbackedMemberById());
        this.enhancedFieldLoader = new EnhancedFieldLoader();
        this.enhancedMethodLoader = new EnhancedMethodLoader();
        this.enhancedConstructorLoader = new EnhancedConstructorLoader();
        this.enhancedMemberCache = cacheBuilder.build(new EnhancedMemberLoaderFunction());
    }

    // Unbacked members

    public <X> UnbackedAnnotatedMember<X> getUnbackedMember(UnbackedMemberIdentifier<X> identifier) {
        return unbackedAnnotatedMembersById.getCastValue(identifier);
    }

    /**
     * If an unbacked member is being deserialized it is looked in all the members of the declaring type and cached.
     */
    private static class UnbackedMemberById implements Function<UnbackedMemberIdentifier<?>, UnbackedAnnotatedMember<?>> {

        @Override
        public UnbackedAnnotatedMember<?> apply(UnbackedMemberIdentifier<?> identifier) {
            return findMatchingMember(identifier.getType(), identifier.getMemberId());
        }

        private <T> UnbackedAnnotatedMember<T> findMatchingMember(UnbackedAnnotatedType<T> type, String id) {
            for (AnnotatedField<? super T> field : type.getFields()) {
                if (id.equals(AnnotatedTypes.createFieldId(field))) {
                    return cast(field);
                }
            }
            for (AnnotatedMethod<? super T> method : type.getMethods()) {
                if (id.equals(AnnotatedTypes.createMethodId(method.getJavaMember(), method.getAnnotations(), method.getParameters()))) {
                    return Reflections.cast(method);
                }
            }
            for (AnnotatedConstructor<T> constructor : type.getConstructors()) {
                if (id.equals(AnnotatedTypes.createConstructorId(constructor.getJavaMember(), constructor.getAnnotations(), constructor.getParameters()))) {
                    return cast(constructor);
                }
            }
            throw BeanLogger.LOG.unableToLoadMember(id);
        }
    }

    // Enhanced members

    public <X, A extends EnhancedAnnotatedMember<?, X, ? extends Member>> A loadEnhancedMember(AnnotatedMember<X> member, String bdaId) {
        if (member instanceof EnhancedAnnotatedMember<?, ?, ?>) {
            return Reflections.cast(member);
        }
        EnhancedAnnotatedType<X> declaringType = transformer.getEnhancedAnnotatedType(member.getDeclaringType(), bdaId);
        return enhancedMemberCache.getCastValue(new MemberKey<X, AnnotatedMember<X>>(declaringType, member));
    }

    public <X> EnhancedAnnotatedParameter<?, X> loadEnhancedParameter(AnnotatedParameter<X> parameter, String bdaId) {
        if (parameter instanceof EnhancedAnnotatedParameter<?, ?>) {
            return Reflections.cast(parameter);
        }
        EnhancedAnnotatedCallable<?, X, Member> callable = loadEnhancedMember(parameter.getDeclaringCallable(), bdaId);
        return callable.getEnhancedParameters().get(parameter.getPosition());
    }

    private class EnhancedMemberLoaderFunction implements Function<MemberKey<?, ?>, EnhancedAnnotatedMember<?, ?, ?>> {
        @Override
        public EnhancedAnnotatedMember<?, ?, ?> apply(MemberKey<?, ?> from) {
            if (from.member instanceof AnnotatedField<?>) {
                return enhancedFieldLoader.load(Reflections.<MemberKey<?, AnnotatedField<?>>> cast(from));
            }
            if (from.member instanceof AnnotatedMethod<?>) {
                return enhancedMethodLoader.load(Reflections.<MemberKey<?, AnnotatedMethod<?>>> cast(from));
            }
            if (from.member instanceof AnnotatedConstructor<?>) {
                return enhancedConstructorLoader.load(Reflections.<MemberKey<?, AnnotatedConstructor<?>>> cast(from));
            }
            throw BeanLogger.LOG.invalidAnnotatedMember(from);
        }
    }

    private abstract class AbstractEnhancedMemberLoader<A extends AnnotatedMember<?>, W extends EnhancedAnnotatedMember<?, ?, ?>> {

        public W load(MemberKey<?, A> source) {
            return findMatching(getMembersOfDeclaringType(source), source.member);
        }

        public W findMatching(Collection<W> members, A source) {
            for (W member : members) {
                if (equals(member, source)) {
                    return member;
                }
            }
            throw BeanLogger.LOG.unableToLoadMember(source);
        }

        public abstract boolean equals(W member1, A member2);

        public abstract Collection<W> getMembersOfDeclaringType(MemberKey<?, A> source);
    }

    private class EnhancedFieldLoader extends AbstractEnhancedMemberLoader<AnnotatedField<?>, EnhancedAnnotatedField<?, ?>> {
        @Override
        public boolean equals(EnhancedAnnotatedField<?, ?> member1, AnnotatedField<?> member2) {
            return AnnotatedTypes.compareAnnotatedField(member1, member2);
        }

        @Override
        public Collection<EnhancedAnnotatedField<?, ?>> getMembersOfDeclaringType(MemberKey<?, AnnotatedField<?>> source) {
            return cast(source.type.getFields());
        }
    }

    private class EnhancedMethodLoader extends AbstractEnhancedMemberLoader<AnnotatedMethod<?>, EnhancedAnnotatedMethod<?, ?>> {
        @Override
        public boolean equals(EnhancedAnnotatedMethod<?, ?> member1, AnnotatedMethod<?> member2) {
            return AnnotatedTypes.compareAnnotatedCallable(member1, member2);
        }

        @Override
        public Collection<EnhancedAnnotatedMethod<?, ?>> getMembersOfDeclaringType(MemberKey<?, AnnotatedMethod<?>> source) {
            return cast(source.type.getMethods());
        }
    }

    private class EnhancedConstructorLoader extends AbstractEnhancedMemberLoader<AnnotatedConstructor<?>, EnhancedAnnotatedConstructor<?>> {
        @Override
        public boolean equals(EnhancedAnnotatedConstructor<?> member1, AnnotatedConstructor<?> member2) {
            return AnnotatedTypes.compareAnnotatedCallable(member1, member2);
        }

        @Override
        public Collection<EnhancedAnnotatedConstructor<?>> getMembersOfDeclaringType(MemberKey<?, AnnotatedConstructor<?>> source) {
            return cast(source.type.getConstructors());
        }
    }

    public void cleanupAfterBoot() {
        enhancedMemberCache.clear();
    }

    @Override
    public void cleanup() {
        cleanupAfterBoot();
        unbackedAnnotatedMembersById.clear();
    }
}
TOP

Related Classes of org.jboss.weld.resources.MemberTransformer$EnhancedConstructorLoader

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.