
org.apache.geronimo.j2ee.annotation.Holder Maven / Gradle / Ivy
The newest version!
/*
* 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.geronimo.j2ee.annotation;
import java.io.Serializable;
import java.lang.reflect.InvocationTargetException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.CopyOnWriteArrayList;
import javax.naming.Context;
import javax.naming.NamingException;
import org.apache.xbean.recipe.ConstructionException;
import org.apache.xbean.recipe.ObjectRecipe;
import org.apache.xbean.recipe.Option;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* @version $Rev: 1379359 $ $Date: 2012-08-31 16:35:57 +0800 (Fri, 31 Aug 2012) $
*/
public class Holder implements Serializable {
private static final Logger log = LoggerFactory.getLogger(Holder.class);
public static final Holder EMPTY = new Holder() {
};
private Map> injectionMap;
private Map postConstruct;
private Map preDestroy;
private List interceptors = new CopyOnWriteArrayList();
public Holder() {
}
public Holder(Holder source) {
if (source.getInjectionMap() != null) {
this.injectionMap = new HashMap>();
addInjectionMap(source.getInjectionMap());
}
if (source.getPostConstruct() != null) {
this.postConstruct = new HashMap();
addPostConstructs(source.getPostConstruct());
}
if (source.getPreDestroy() != null) {
this.preDestroy = new HashMap();
addPreDestroys(source.getPreDestroy());
}
}
private Set getInjectionList(String className) {
if (injectionMap == null) {
injectionMap = new HashMap>();
}
Set injections = injectionMap.get(className);
if (injections == null) {
injections = new HashSet();
injectionMap.put(className, injections);
}
return injections;
}
public void addInjection(String className, Injection newInjection) {
Set injections = getInjectionList(className);
injections.add(newInjection);
}
public void addInjections(String className, Collection newInjections) {
Set injections = getInjectionList(className);
for (Injection injection : newInjections) {
injections.add(injection);
}
}
public void addPostConstructs(Map newPostConstructs) {
this.postConstruct = merge(postConstruct, newPostConstructs);
}
public void addPreDestroys(Map newPreDestroys) {
this.preDestroy = merge(preDestroy, newPreDestroys);
}
private Map merge(Map old, Map additional) {
if (old == null) {
return additional;
}
if (additional == null) {
return old;
}
old.putAll(additional);
return old;
}
public void addInjectionMap(Map> injectionMap) {
if (injectionMap == null) {
return;
}
for (Map.Entry> entry : injectionMap.entrySet()) {
String className = entry.getKey();
Set injections = entry.getValue();
addInjections(className, injections);
}
}
public List getInjections(String className) {
if (injectionMap != null) {
Set injections = injectionMap.get(className);
if (injections != null) {
return new ArrayList(injections);
}
}
return null;
}
public Map> getInjectionMap() {
return injectionMap;
}
public Map getPostConstruct() {
return postConstruct;
}
public Map getPreDestroy() {
return preDestroy;
}
public boolean isEmpty() {
return (injectionMap == null || injectionMap.isEmpty()) && (postConstruct == null || postConstruct.isEmpty()) && (preDestroy == null || preDestroy.isEmpty());
}
public Object newInstanceWithoutPostConstruct(String className, ClassLoader classLoader, Context context) throws IllegalAccessException, InstantiationException {
ObjectRecipe objectRecipe = new ObjectRecipe(className);
objectRecipe.allow(Option.FIELD_INJECTION);
objectRecipe.allow(Option.PRIVATE_PROPERTIES);
Class> clazz;
try {
clazz = classLoader.loadClass(className);
} catch (ClassNotFoundException e) {
throw (InstantiationException) new InstantiationException("Can't load class " + className + " in classloader: " + classLoader).initCause(e);
}
List problems = new ArrayList();
while (clazz != Object.class) {
addInjections(clazz.getName(), context, objectRecipe, problems);
clazz = clazz.getSuperclass();
}
if (!problems.isEmpty()) {
throw new InstantiationException("Some objects to be injected were not found in jndi: " + problems);
}
Object result;
try {
result = objectRecipe.create(classLoader);
} catch (ConstructionException e) {
throw (InstantiationException) new InstantiationException("Could not construct object").initCause(e);
}
InvocationContext invocationContext = new InvocationContext(context, result);
try {
for (Interceptor interceptor : interceptors) {
interceptor.instancerCreated(invocationContext);
}
} catch (InterceptorException e) {
throw (InstantiationException) new InstantiationException("Interceptor invocation failed").initCause(e);
}
return result;
}
public Object newInstance(String className, ClassLoader classLoader, Context context) throws IllegalAccessException, InstantiationException {
Object result = this.newInstanceWithoutPostConstruct(className, classLoader, context);
if (getPostConstruct() != null) {
try {
apply(result, null, postConstruct);
} catch (InvocationTargetException e) {
Throwable cause = e.getCause();
throw (InstantiationException) new InstantiationException("Could not call postConstruct method").initCause(cause);
}
}
return result;
}
private void addInjections(String className, Context context, ObjectRecipe objectRecipe, List problems) {
List callbackHandlerinjections = getInjections(className);
if (callbackHandlerinjections != null) {
for (Injection injection : callbackHandlerinjections) {
try {
String jndiName = injection.getJndiName();
Object object = context.lookup(jndiName);
objectRecipe.setProperty(injection.getTargetName(), object);
} catch (NamingException e) {
//Per EE 5.4.1.3, if no value is configured for environment entry, it will be ignored
//In the past, we skip this in the EnvironmentEntryBuilder, while in Java EE 6, there are some sharable JNDI name spaces are added
//So, in some scenarios, it is impossible to know whether the environment entry is available in the deploying process.
if (injection.getType() != ReferenceType.ENV_ENTRY) {
problems.add(e);
}
log.info("Could not look up " + injection.getJndiName(), e);
}
}
}
}
public void destroyInstance(Object o) throws Exception {
Class> clazz = o.getClass();
Map preDestroy = getPreDestroy();
if (preDestroy != null) {
apply(o, clazz, preDestroy);
}
}
public static void apply(Object o, Class> clazz, Map map) throws IllegalAccessException, InvocationTargetException {
if (clazz == null) {
clazz = o.getClass();
}
ArrayList> classes = new ArrayList>();
while (clazz != null && clazz != Object.class) {
classes.add(clazz);
clazz = clazz.getSuperclass();
}
for (int i = classes.size() - 1; i > -1; i--) {
Class> clazz1 = classes.get(i);
LifecycleMethod m = map.get(clazz1.getName());
if (m != null) {
m.call(o, clazz1);
}
}
}
public boolean addInterceptor(Interceptor interceptor) {
return interceptors.add(interceptor);
}
public boolean removeInterceptor(Interceptor interceptor) {
return interceptors.remove(interceptor);
}
public static interface Interceptor {
public void instancerCreated(InvocationContext context) throws InterceptorException;
public void instanceDestoryed(InvocationContext context) throws InterceptorException;
public void postConstructInvoked(InvocationContext context) throws InterceptorException;
}
public static class InterceptorException extends Exception {
public InterceptorException(Throwable cause) {
super(cause);
}
public InterceptorException(String message) {
super(message);
}
public InterceptorException(String message, Throwable cause) {
super(message, cause);
}
}
public static class InvocationContext {
private final Context context;
private final Object instance;
public InvocationContext(Context context, Object instance) {
this.context = context;
this.instance = instance;
}
public Context getContext() {
return context;
}
public Object getInstance() {
return instance;
}
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy