All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.apache.webbeans.portable.AnnotatedElementFactory Maven / Gradle / Ivy

/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements. See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership. The ASF licenses this file
 * to you 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.apache.webbeans.portable;

import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
import java.util.logging.Level;
import java.util.logging.Logger;

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

import org.apache.webbeans.config.OWBLogConst;
import org.apache.webbeans.config.WebBeansContext;
import org.apache.webbeans.logger.WebBeansLoggerFacade;
import org.apache.webbeans.util.Asserts;

/**
 * Factory for {@link javax.enterprise.inject.spi.Annotated} elements.
 * 
 * @version $Rev: 1526251 $ $Date: 2013-09-25 20:14:58 +0200 (Wed, 25 Sep 2013) $
 */
public final class AnnotatedElementFactory
{
    
    public static final String OWB_DEFAULT_KEY = "OWB_DEFAULT_KEY";

    // Logger instance
    private final static Logger logger = WebBeansLoggerFacade.getLogger(AnnotatedElementFactory.class);

    //Cache of the AnnotatedType
    private ConcurrentMap, ConcurrentMap>> annotatedTypeCache =
        new ConcurrentHashMap, ConcurrentMap>>();
    
    //Cache of AnnotatedConstructor
    private ConcurrentMap, AnnotatedConstructor> annotatedConstructorCache =
        new ConcurrentHashMap, AnnotatedConstructor>();
    
    //Cache of AnnotatedMethod
    private ConcurrentMap> annotatedMethodCache =
        new ConcurrentHashMap>();
    
    //Cache of AnnotatedField
    private ConcurrentMap> annotatedFieldCache =
        new ConcurrentHashMap>();

    private WebBeansContext webBeansContext;
    
    /**
     * No instantiate.
     */
    public AnnotatedElementFactory(WebBeansContext webBeansContext)
    {
        this.webBeansContext = webBeansContext;
    }

    /**
     * Get an already registered AnnotatedType. This will NOT create a new one!
     * @param annotatedClass
     * @param 
     * @return AnnotatedType
     */
    public  AnnotatedType getAnnotatedType(Class annotatedClass)
    {
        return getAnnotatedTypeCache(annotatedClass).get(OWB_DEFAULT_KEY);
    }

    /**
     * Get all already registered AnnotatedTypes of the specified type. This will NOT create a new one!
     * @param annotatedClass
     * @param 
     * @return AnnotatedType
     */
    public  Iterable> getAnnotatedTypes(Class annotatedClass)
    {
        return getAnnotatedTypeCache(annotatedClass).values();
    }
    
    /**
     * This method will get used to manually add AnnoatedTypes to our storage.
     * Those AnnotatedTypes are coming from Extensions and get registered e.g. via
     * {@link javax.enterprise.inject.spi.BeforeBeanDiscovery#addAnnotatedType(AnnotatedType)}
     *
     * Sets the annotatedType and replace the given one.
     * @param annotatedType
     * @param 
     * @return the previously registered AnnotatedType or null if not previously defined.
     */
    public  AnnotatedType setAnnotatedType(AnnotatedType annotatedType)
    {
        return setAnnotatedType(annotatedType, OWB_DEFAULT_KEY);
    }

    public  AnnotatedType setAnnotatedType(AnnotatedType annotatedType, String id)
    {
        ConcurrentMap> annotatedTypes = getAnnotatedTypeCache(annotatedType.getJavaClass());
        return (AnnotatedType) annotatedTypes.put(id, annotatedType);
    }

    /**
     * Creates and configures new annotated type.
     * 
     * @param  class info
     * @param annotatedClass annotated class
     * @return new annotated type
     */
    public  AnnotatedType newAnnotatedType(Class annotatedClass)
    {
        Asserts.assertNotNull(annotatedClass, "annotatedClass is null");
        ConcurrentMap> annotatedTypes = getAnnotatedTypeCache(annotatedClass);
        AnnotatedType annotatedType = annotatedTypes.get(OWB_DEFAULT_KEY);
        if(annotatedType == null)
        {
            try
            {
                AnnotatedType supertype = null;
                if (annotatedClass.getSuperclass() != null && !annotatedClass.getSuperclass().equals(Object.class))
                {
                    supertype = newAnnotatedType(annotatedClass.getSuperclass());
                }
                annotatedType = new AnnotatedTypeImpl(webBeansContext, annotatedClass, supertype);

                AnnotatedType oldType = annotatedTypes.putIfAbsent(OWB_DEFAULT_KEY, annotatedType);
                if(oldType != null)
                {
                    annotatedType = oldType;
                }
            }
            catch (Exception e)
            {
                if (e instanceof ClassNotFoundException || e instanceof ArrayStoreException)
                {
                    if (logger.isLoggable(Level.SEVERE))
                    {
                        logger.log(Level.SEVERE, WebBeansLoggerFacade.constructMessage(OWBLogConst.ERROR_0027, annotatedClass.getName(), e.getCause()), e);
                    }

                    annotatedType = null;
                } 
                else
                {
                    throw new RuntimeException(e);
                }
            } 
            catch (NoClassDefFoundError ncdfe)
            {
                if (logger.isLoggable(Level.SEVERE))
                {
                    logger.log(Level.SEVERE, WebBeansLoggerFacade.constructMessage(OWBLogConst.ERROR_0027, annotatedClass.getName(), ncdfe.getCause()), ncdfe);
                }

                annotatedType = null;
            }
        }
                
        return annotatedType;
    }

    /**
     * Creates and configures new annotated constructor.
     * 
     * @param  declaring class
     * @param constructor constructor
     * @return new annotated constructor
     */
    @SuppressWarnings("unchecked")
    public  AnnotatedConstructor newAnnotatedConstructor(Constructor constructor, AnnotatedType declaringClass)
    {
        Asserts.assertNotNull(constructor, "constructor is null");
        Asserts.assertNotNull(declaringClass, "declaringClass is null");
        
        AnnotatedConstructorImpl annConstructor;
        if(annotatedConstructorCache.containsKey(constructor))
        {
            annConstructor = (AnnotatedConstructorImpl)annotatedConstructorCache.get(constructor);
        }
        else
        {
            annConstructor = new AnnotatedConstructorImpl(webBeansContext, constructor, declaringClass);
            AnnotatedConstructorImpl old = (AnnotatedConstructorImpl)annotatedConstructorCache.putIfAbsent(constructor, annConstructor);
            if(old != null)
            {
                annConstructor = old;
            }
        }
        
        return annConstructor;
    }

    /**
     * Creates and configures new annotated field.
     * 
     * @param  declaring class
     * @param field field instance
     * @param declaringClass declaring class
     * @return new annotated field
     */
    @SuppressWarnings("unchecked")
    public  AnnotatedField newAnnotatedField(Field field, AnnotatedType declaringClass)
    {
        Asserts.assertNotNull(field, "field is null");
        Asserts.assertNotNull(declaringClass, "declaringClass is null");
        
        AnnotatedFieldImpl annotField;
        if(annotatedFieldCache.containsKey(field))
        {
            annotField = (AnnotatedFieldImpl)annotatedFieldCache.get(field);
        }
        else
        {
            annotField = new AnnotatedFieldImpl(webBeansContext, field, declaringClass);
            AnnotatedFieldImpl old = (AnnotatedFieldImpl) annotatedFieldCache.putIfAbsent(field, annotField);
            if(old != null)
            {
                annotField = old;
            }
        }
        
        return annotField; 
    }

    /**
     * Creates and configures new annotated method.
     * 
     * @param  declaring class
     * @param method annotated method
     * @param declaringType declaring class info
     * @return new annotated method
     */
    @SuppressWarnings("unchecked")
    public  AnnotatedMethod newAnnotatedMethod(Method method, AnnotatedType declaringType)
    {
        Asserts.assertNotNull(method, "method is null");
        Asserts.assertNotNull(declaringType, "declaringType is null");
        
        AnnotatedMethodImpl annotMethod;
        if(annotatedMethodCache.containsKey(method))
        {
            annotMethod = (AnnotatedMethodImpl)annotatedMethodCache.get(method);
        }
        else
        {
            annotMethod = new AnnotatedMethodImpl(webBeansContext, method, declaringType);
            AnnotatedMethodImpl old = (AnnotatedMethodImpl) annotatedMethodCache.putIfAbsent(method, annotMethod);
            if(old != null)
            {
                annotMethod = old;
            }
        }
        
        return annotMethod;          
    }
    
    /**
     * Clear caches.
     */
    public void clear()
    {
        annotatedTypeCache.clear();
        annotatedConstructorCache.clear();
        annotatedFieldCache.clear();
        annotatedMethodCache.clear();
    }
    
    private  ConcurrentMap> getAnnotatedTypeCache(Class type)
    {
        ConcurrentMap> annotatedTypes = annotatedTypeCache.get(type);
        if (annotatedTypes == null)
        {
            annotatedTypes = new ConcurrentHashMap>();
            ConcurrentMap> oldAnnotatedTypes = annotatedTypeCache.putIfAbsent(type, annotatedTypes);
            if (oldAnnotatedTypes != null)
            {
                annotatedTypes = oldAnnotatedTypes;
            }
        }
        return (ConcurrentMap>)(ConcurrentMap)annotatedTypes;
    }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy