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 super X> 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