001 /*******************************************************************************
002 * Copyright (c) PicoContainer Organization. All rights reserved.
003 * ---------------------------------------------------------------------------
004 * The software in this package is published under the terms of the BSD style
005 * license a copy of which has been included with this distribution in the
006 * LICENSE.txt file.
007 ******************************************************************************/
008
009 package org.picocontainer.web.struts2;
010
011 import java.util.Map;
012 import java.util.Collection;
013 import java.util.Iterator;
014
015 import org.picocontainer.ComponentAdapter;
016 import org.picocontainer.MutablePicoContainer;
017 import org.picocontainer.injectors.AbstractInjector;
018 import org.picocontainer.web.PicoServletContainerFilter;
019
020 import com.opensymphony.xwork2.ObjectFactory;
021 import com.opensymphony.xwork2.config.ConfigurationException;
022 import com.opensymphony.xwork2.config.entities.InterceptorConfig;
023 import com.opensymphony.xwork2.interceptor.Interceptor;
024
025 /**
026 * XWork2 ObjectFactory implementation to delegate action/component/bean lookups
027 * to PicoContainer.
028 *
029 * @author Paul Hammant
030 * @author Mauro Talevi
031 */
032 @SuppressWarnings("serial")
033 public class PicoObjectFactory extends ObjectFactory {
034
035 private static ThreadLocal<MutablePicoContainer> currentRequestContainer = new ThreadLocal<MutablePicoContainer>();
036 private static ThreadLocal<MutablePicoContainer> currentSessionContainer = new ThreadLocal<MutablePicoContainer>();
037 private static ThreadLocal<MutablePicoContainer> currentAppContainer = new ThreadLocal<MutablePicoContainer>();
038
039 public static class ServletFilter extends PicoServletContainerFilter {
040 protected void setAppContainer(MutablePicoContainer container) {
041 currentAppContainer.set(container);
042 }
043 protected void setRequestContainer(MutablePicoContainer container) {
044 currentRequestContainer.set(container);
045 }
046 protected void setSessionContainer(MutablePicoContainer container) {
047 currentSessionContainer.set(container);
048 }
049 }
050
051 @SuppressWarnings("unchecked")
052 public Class getClassInstance(String name) throws ClassNotFoundException {
053 Class clazz = super.getClassInstance(name);
054 synchronized (this) {
055 MutablePicoContainer reqContainer = currentRequestContainer.get();
056 if (reqContainer != null) {
057 // forces a registration via noComponentFound()
058 reqContainer.getComponentAdapter(clazz);
059 }
060 }
061 return clazz;
062 }
063
064 @SuppressWarnings("unchecked")
065 public Object buildBean(Class clazz, Map extraContext) throws Exception {
066
067 MutablePicoContainer requestContainer = currentRequestContainer.get();
068 if (requestContainer == null) {
069 MutablePicoContainer appContainer = currentAppContainer.get();
070 Object comp = appContainer.getComponent(clazz);
071 if (comp == null) {
072 appContainer.addComponent(clazz);
073 comp = appContainer.getComponent(clazz);
074 }
075 return comp;
076
077 }
078 return requestContainer.getComponent(clazz);
079 }
080
081 @SuppressWarnings("unchecked")
082 public Interceptor buildInterceptor(InterceptorConfig config, Map params) throws ConfigurationException {
083 return super.buildInterceptor(config, params);
084 }
085
086 public boolean isNoArgConstructorRequired() {
087 return false;
088 }
089
090 }