Package org.jboss.weld.annotated.slim.backed

Source Code of org.jboss.weld.annotated.slim.backed.BackedAnnotatedType$BackedAnnotatedFields

package org.jboss.weld.annotated.slim.backed;

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

import java.io.ObjectInputStream;
import java.io.ObjectStreamException;
import java.io.Serializable;
import java.lang.annotation.Annotation;
import java.lang.reflect.AnnotatedElement;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.lang.reflect.Type;
import java.security.AccessController;
import java.util.Objects;
import java.util.Set;

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

import org.jboss.weld.annotated.slim.AnnotatedTypeIdentifier;
import org.jboss.weld.annotated.slim.SlimAnnotatedType;
import org.jboss.weld.exceptions.InvalidObjectException;
import org.jboss.weld.logging.BeanLogger;
import org.jboss.weld.resources.ReflectionCache;
import org.jboss.weld.resources.SharedObjectCache;
import org.jboss.weld.security.GetDeclaredConstructorsAction;
import org.jboss.weld.security.GetDeclaredFieldsAction;
import org.jboss.weld.security.GetDeclaredMethodsAction;
import org.jboss.weld.util.LazyValueHolder;
import org.jboss.weld.util.Types;
import org.jboss.weld.util.collections.ImmutableSet;
import org.jboss.weld.util.reflection.Formats;
import org.jboss.weld.util.reflection.Reflections;

import edu.umd.cs.findbugs.annotations.SuppressWarnings;
@SuppressWarnings(value = { "SE_BAD_FIELD", "SE_NO_SUITABLE_CONSTRUCTOR", "SE_BAD_FIELD_STORE", "SE_NO_SERIALVERSIONID" }, justification = "False positive from FindBugs - serialization is handled by SerializationProxy.")
public class BackedAnnotatedType<X> extends BackedAnnotated implements SlimAnnotatedType<X>, Serializable {

    public static <X> BackedAnnotatedType<X> of(Class<X> javaClass, SharedObjectCache sharedObjectCache, ReflectionCache reflectionCache, String contextId, String bdaId) {
        return of(javaClass, javaClass, sharedObjectCache, reflectionCache, contextId, bdaId);
    }

    public static <X> BackedAnnotatedType<X> of(Class<X> javaClass, Type baseType, SharedObjectCache sharedObjectCache, ReflectionCache reflectionCache, String contextId, String bdaId) {
        return new BackedAnnotatedType<X>(javaClass, baseType, sharedObjectCache, reflectionCache, contextId, bdaId);
    }

    private final Class<X> javaClass;
    private final LazyValueHolder<Set<AnnotatedConstructor<X>>> constructors;
    private final LazyValueHolder<Set<AnnotatedMethod<? super X>>> methods;
    private final LazyValueHolder<Set<AnnotatedField<? super X>>> fields;
    private final SharedObjectCache sharedObjectCache;
    private final ReflectionCache reflectionCache;
    private final AnnotatedTypeIdentifier identifier;

    private BackedAnnotatedType(Class<X> rawType, Type baseType, SharedObjectCache sharedObjectCache, ReflectionCache reflectionCache, String contextId, String bdaId) {
        super(baseType, sharedObjectCache);
        this.javaClass = rawType;
        this.sharedObjectCache = sharedObjectCache;
        this.reflectionCache = reflectionCache;

        this.constructors = new BackedAnnotatedConstructors();
        this.fields = new BackedAnnotatedFields();
        this.methods = new BackedAnnotatedMethods();
        this.identifier = AnnotatedTypeIdentifier.forBackedAnnotatedType(contextId, rawType, baseType, bdaId);
    }

    @Override
    protected LazyValueHolder<Set<Type>> initTypeClosure(Type baseType, SharedObjectCache cache) {
        return cache.getTypeClosureHolder(Types.getCanonicalType(baseType));
    }

    @Override
    protected AnnotatedElement getAnnotatedElement() {
        return javaClass;
    }

    public Class<X> getJavaClass() {
        return javaClass;
    }

    public Set<AnnotatedConstructor<X>> getConstructors() {
        return constructors.get();
    }

    public Set<AnnotatedMethod<? super X>> getMethods() {
        return methods.get();
    }

    public Set<AnnotatedField<? super X>> getFields() {
        return fields.get();
    }

    public <T extends Annotation> T getAnnotation(Class<T> annotationType) {
        for (Annotation annotation : getAnnotations()) {
            if (annotation.annotationType().equals(annotationType)) {
                return annotationType.cast(annotation);
            }
        }
        return null;
    }

    public boolean isAnnotationPresent(Class<? extends Annotation> annotationType) {
        return getAnnotation(annotationType) != null;
    }

    @Override
    public Set<Annotation> getAnnotations() {
        return reflectionCache.getBackedAnnotatedTypeAnnotationSet(javaClass);
    }

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

    @Override
    public boolean equals(Object obj) {
        if (this == obj) {
            return true;
        }
        if (obj instanceof BackedAnnotatedType<?>) {
            BackedAnnotatedType<?> that = cast(obj);
            return Objects.equals(this.identifier, that.identifier);
        }
        return false;
    }

    @Override
    public String toString() {
        return Formats.formatAnnotatedType(this);
    }

    @Override
    public void clear() {
        this.constructors.clear();
        this.fields.clear();
        this.methods.clear();
    }

    // Serialization

    private Object writeReplace() throws ObjectStreamException {
        return new SerializationProxy<X>(getIdentifier());
    }

    private void readObject(ObjectInputStream stream) throws InvalidObjectException {
        throw BeanLogger.LOG.proxyRequired();
    }

    // Lazy initialization

    // Initialize eagerly since we want to discover CNFE at bootstrap
    // After bootstrap, these holders are reset to conserve memory
    private abstract class EagerlyInitializedLazyValueHolder<T> extends LazyValueHolder<T> {
        public EagerlyInitializedLazyValueHolder() {
            this.get();
        }
    }

    private class BackedAnnotatedConstructors extends EagerlyInitializedLazyValueHolder<Set<AnnotatedConstructor<X>>> {
        @Override
        protected Set<AnnotatedConstructor<X>> computeValue() {
            Constructor<?>[] declaredConstructors = AccessController.doPrivileged(new GetDeclaredConstructorsAction(javaClass));
            ImmutableSet.Builder<AnnotatedConstructor<X>> constructors = ImmutableSet.builder();
            for (Constructor<?> constructor : declaredConstructors) {
                Constructor<X> c = Reflections.cast(constructor);
                constructors.add(BackedAnnotatedConstructor.of(c, BackedAnnotatedType.this, sharedObjectCache));
            }
            return constructors.build();
        }
    }

    private class BackedAnnotatedFields extends EagerlyInitializedLazyValueHolder<Set<AnnotatedField<? super X>>> {
        @Override
        protected Set<AnnotatedField<? super X>> computeValue() {
            ImmutableSet.Builder<AnnotatedField<? super X>> fields = ImmutableSet.builder();
            Class<? super X> clazz = javaClass;
            while (clazz != Object.class && clazz != null) {
                for (Field field : AccessController.doPrivileged(new GetDeclaredFieldsAction(clazz))) {
                    fields.add(BackedAnnotatedField.of(field, BackedAnnotatedType.this, sharedObjectCache));
                }
                clazz = clazz.getSuperclass();
            }
            return fields.build();
        }
    }

    private class BackedAnnotatedMethods extends EagerlyInitializedLazyValueHolder<Set<AnnotatedMethod<? super X>>> {
        @Override
        protected Set<AnnotatedMethod<? super X>> computeValue() {
            ImmutableSet.Builder<AnnotatedMethod<? super X>> methods = ImmutableSet.builder();
            Class<? super X> clazz = javaClass;
            while (clazz != Object.class && clazz != null) {
                for (Method method : AccessController.doPrivileged(new GetDeclaredMethodsAction(clazz))) {
                    methods.add(BackedAnnotatedMethod.of(method, BackedAnnotatedType.this, sharedObjectCache));
                }
                clazz = clazz.getSuperclass();
            }
            return methods.build();
        }
    }

    public ReflectionCache getReflectionCache() {
        return reflectionCache;
    }

    @Override
    public AnnotatedTypeIdentifier getIdentifier() {
        return identifier;
    }
}
TOP

Related Classes of org.jboss.weld.annotated.slim.backed.BackedAnnotatedType$BackedAnnotatedFields

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.