Author: mrdon Date: Sat Jun 17 12:02:02 2006 New Revision: 415045 URL: http://svn.apache.org/viewvc?rev=415045&view=rev Log: Adding the ability to use a role-hint in the plexus configuration Patch provided by Emmanuel Venisse
WW-1329 Modified: struts/action2/trunk/core/src/main/java/org/apache/struts/action2/plexus/PlexusFilter.java struts/action2/trunk/core/src/main/java/org/apache/struts/action2/plexus/PlexusObjectFactory.java Modified: struts/action2/trunk/core/src/main/java/org/apache/struts/action2/plexus/PlexusFilter.java URL: http://svn.apache.org/viewvc/struts/action2/trunk/core/src/main/java/org/apache/struts/action2/plexus/PlexusFilter.java?rev=415045&r1=415044&r2=415045&view=diff ============================================================================== --- struts/action2/trunk/core/src/main/java/org/apache/struts/action2/plexus/PlexusFilter.java (original) +++ struts/action2/trunk/core/src/main/java/org/apache/struts/action2/plexus/PlexusFilter.java Sat Jun 17 12:02:02 2006 @@ -31,6 +31,7 @@ */ public class PlexusFilter implements Filter { private static final Log log = LogFactory.getLog(PlexusObjectFactory.class); + private static final String CHILD_CONTAINER_NAME = "request"; public static boolean loaded = false; @@ -44,33 +45,41 @@ public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException { PlexusContainer child = null; try { - HttpServletRequest request = (HttpServletRequest) req; - HttpSession session = request.getSession(false); - PlexusContainer parent; - if (session != null) { - parent = (PlexusContainer) session.getAttribute(PlexusLifecycleListener.KEY); - } else { - parent = (PlexusContainer) ctx.getAttribute(PlexusLifecycleListener.KEY); + try { + HttpServletRequest request = (HttpServletRequest) req; + HttpSession session = request.getSession(false); + PlexusContainer parent; + if (session != null) { + parent = (PlexusContainer) session.getAttribute(PlexusLifecycleListener.KEY); + } else { + parent = (PlexusContainer) ctx.getAttribute(PlexusLifecycleListener.KEY); + } + + if (parent.hasChildContainer(CHILD_CONTAINER_NAME)) { + log.warn("Plexus container (scope: request) alredy exist."); + child = parent.getChildContainer(CHILD_CONTAINER_NAME); + } else { + child = parent.createChildContainer(CHILD_CONTAINER_NAME, Collections.EMPTY_LIST, Collections.EMPTY_MAP); + PlexusUtils.configure(child, "plexus-request.xml"); + child.initialize(); + child.start(); + } + PlexusThreadLocal.setPlexusContainer(child); + } catch (Exception e) { + log.error("Error initializing plexus container (scope: request)", e); } - child = parent.createChildContainer("request", Collections.EMPTY_LIST, Collections.EMPTY_MAP); - PlexusUtils.configure(child, "plexus-request.xml"); - child.initialize(); - child.start(); - PlexusThreadLocal.setPlexusContainer(child); - } catch (Exception e) { - log.error("Error initializing plexus container (scope: request)", e); + chain.doFilter(req, res); } - - chain.doFilter(req, res); - - try { - if (child != null) { - child.dispose(); + finally { + try { + if (child != null) { + child.dispose(); + } + PlexusThreadLocal.setPlexusContainer(null); + } catch (Exception e) { + log.error("Error disposing plexus container (scope: request)", e); } - PlexusThreadLocal.setPlexusContainer(null); - } catch (Exception e) { - log.error("Error disposing plexus container (scope: request)", e); } } Modified: struts/action2/trunk/core/src/main/java/org/apache/struts/action2/plexus/PlexusObjectFactory.java URL: http://svn.apache.org/viewvc/struts/action2/trunk/core/src/main/java/org/apache/struts/action2/plexus/PlexusObjectFactory.java?rev=415045&r1=415044&r2=415045&view=diff ============================================================================== --- struts/action2/trunk/core/src/main/java/org/apache/struts/action2/plexus/PlexusObjectFactory.java (original) +++ struts/action2/trunk/core/src/main/java/org/apache/struts/action2/plexus/PlexusObjectFactory.java Sat Jun 17 12:02:02 2006 @@ -17,21 +17,31 @@ */ package org.apache.struts.action2.plexus; -import org.apache.struts.action2.util.ObjectFactoryInitializable; +import com.opensymphony.xwork.Action; import com.opensymphony.xwork.ObjectFactory; +import com.opensymphony.xwork.Result; +import com.opensymphony.xwork.config.ConfigurationException; +import com.opensymphony.xwork.config.entities.ActionConfig; +import com.opensymphony.xwork.config.entities.InterceptorConfig; +import com.opensymphony.xwork.config.entities.ResultConfig; +import com.opensymphony.xwork.interceptor.Interceptor; +import com.opensymphony.xwork.util.OgnlUtil; +import com.opensymphony.xwork.validator.Validator; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; +import org.apache.struts.action2.util.ObjectFactoryInitializable; import org.codehaus.plexus.PlexusContainer; import javax.servlet.ServletContext; +import java.util.HashMap; import java.util.Map; /** * Plexus integartion. You need three optional files: plexus-request.xml, plexus-session.xml, and * plexus-application.xml. - * + * <p/> * The syntax of these files is: - * + * <p/> * <pre> * <plexus> * <components> @@ -52,12 +62,24 @@ * </components> * </plexus> * </pre> + * + * @author <a href="mailto:[EMAIL PROTECTED]">Emmanuel Venisse</a> */ public class PlexusObjectFactory extends ObjectFactory implements ObjectFactoryInitializable { private static final Log log = LogFactory.getLog(PlexusObjectFactory.class); + private static final String PLEXUS_COMPONENT_TYPE = "plexus.component.type"; + + // ---------------------------------------------------------------------- + // Privates + // ---------------------------------------------------------------------- + private PlexusContainer base; + // ---------------------------------------------------------------------- + // ObjectFactory overrides + // ---------------------------------------------------------------------- + public void init(ServletContext servletContext) { if (!PlexusLifecycleListener.loaded || !PlexusFilter.loaded) { // uh oh! looks like the lifecycle listener wasn't installed. Let's inform the user @@ -91,16 +113,164 @@ base = (PlexusContainer) servletContext.getAttribute(PlexusLifecycleListener.KEY); } - public Object buildBean(String className, Map extraContext) throws Exception { + public Object buildAction(String actionName, String namespace, ActionConfig config, Map extraContext) + throws Exception { + if (extraContext == null) { + extraContext = new HashMap(); + } + + extraContext.put(PLEXUS_COMPONENT_TYPE, Action.class.getName()); + + return super.buildAction(actionName, namespace, config, extraContext); + } + + public Interceptor buildInterceptor(InterceptorConfig interceptorConfig, Map interceptorRefParams) + throws ConfigurationException { + String interceptorClassName = interceptorConfig.getClassName(); + Map thisInterceptorClassParams = interceptorConfig.getParams(); + Map params = (thisInterceptorClassParams == null) ? new HashMap() : new HashMap(thisInterceptorClassParams); + params.putAll(interceptorRefParams); + + String message; + Throwable cause; + + try { + Map extraContext = new HashMap(); + extraContext.put(PLEXUS_COMPONENT_TYPE, Interceptor.class.getName()); + Interceptor interceptor = (Interceptor) buildBean(interceptorClassName, extraContext); + OgnlUtil.setProperties(params, interceptor); + interceptor.init(); + + return interceptor; + } + catch (InstantiationException e) { + cause = e; + message = "Unable to instantiate an instance of Interceptor class [" + interceptorClassName + "]."; + } + catch (IllegalAccessException e) { + cause = e; + message = "IllegalAccessException while attempting to instantiate an instance of Interceptor class [" + interceptorClassName + "]."; + } + catch (ClassCastException e) { + cause = e; + message = "Class [" + interceptorClassName + "] does not implement com.opensymphony.xwork.interceptor.Interceptor"; + } + catch (Exception e) { + cause = e; + message = "Caught Exception while registering Interceptor class " + interceptorClassName; + } + catch (NoClassDefFoundError e) { + cause = e; + message = "Could not load class " + interceptorClassName + ". Perhaps it exists but certain dependencies are not available?"; + } + + throw new ConfigurationException(message, cause); + } + + public Result buildResult(ResultConfig resultConfig, Map extraContext) + throws Exception { + if (extraContext == null) { + extraContext = new HashMap(); + } + + extraContext.put(PLEXUS_COMPONENT_TYPE, Result.class.getName()); + + return super.buildResult(resultConfig, extraContext); + } + + public Validator buildValidator(String className, Map params, Map extraContext) + throws Exception { + Map context = new HashMap(); + context.put(PLEXUS_COMPONENT_TYPE, Validator.class.getName()); + Validator validator = (Validator) buildBean(className, context); + OgnlUtil.setProperties(params, validator); + + return validator; + } + + public Object buildBean(Class clazz, Map extraContext) + throws Exception { + try { + return lookup(clazz.getName(), extraContext); + } + catch (Exception e) { + if (extraContext != null) { + String type = (String) extraContext.get(PLEXUS_COMPONENT_TYPE); + + if (type != null) { + return lookup(type, clazz.getName(), extraContext); + } + } + + throw e; + } + } + + public Class getClassInstance(String className) + throws ClassNotFoundException { PlexusContainer pc = PlexusThreadLocal.getPlexusContainer(); + if (pc == null) { pc = base; } try { - return pc.lookup(className); - } catch (Exception e) { - Object o = super.buildBean(className, extraContext); + return pc.lookup(className).getClass(); + } + catch (Exception e1) { + try { + return pc.lookup(Action.class.getName(), className).getClass(); + } + catch (Exception e2) { + try { + return pc.lookup(Interceptor.class.getName(), className).getClass(); + } + catch (Exception e3) { + try { + return pc.lookup(Validator.class.getName(), className).getClass(); + } + catch (Exception e4) { + try { + return pc.lookup(Result.class.getName(), className).getClass(); + } + catch (Exception e5) { + return super.getClassInstance(className); + } + } + } + } + } + } + + private Object lookup(String role) + throws Exception { + return lookup(role, null, null); + } + + private Object lookup(String role, Map extraContext) + throws Exception { + return lookup(role, null, extraContext); + } + + private Object lookup(String role, String roleHint) + throws Exception { + return lookup(role, roleHint, null); + } + + private Object lookup(String role, String roleHint, Map extraContext) + throws Exception { + PlexusContainer pc = PlexusThreadLocal.getPlexusContainer(); + + if (pc == null) { + pc = base; + } + + try { + return pc.lookup(role, roleHint); + } + catch (Exception e) { + log.debug("Can't load component (" + role + "/" + roleHint + ") with plexus, try now with webwork.", e); + Object o = super.buildBean(super.getClassInstance(role), extraContext); pc.autowire(o); return o; }