001: /*
002: * Copyright (c) 2002-2006 by OpenSymphony
003: * All rights reserved.
004: */
005:
006: package com.opensymphony.xwork.spring.interceptor;
007:
008: import com.opensymphony.xwork.ActionContext;
009: import com.opensymphony.xwork.ActionInvocation;
010: import com.opensymphony.xwork.interceptor.AroundInterceptor;
011: import com.opensymphony.xwork.spring.SpringObjectFactory;
012: import org.apache.commons.logging.Log;
013: import org.apache.commons.logging.LogFactory;
014: import org.springframework.beans.BeansException;
015: import org.springframework.context.ApplicationContext;
016: import org.springframework.context.ApplicationContextAware;
017: import org.springframework.web.context.WebApplicationContext;
018:
019: /**
020: * <!-- START SNIPPET: description -->
021: * TODO: Give a description of the Interceptor.
022: * <!-- END SNIPPET: description -->
023: *
024: * <!-- START SNIPPET: parameters -->
025: * TODO: Describe the paramters for this Interceptor.
026: * <!-- END SNIPPET: parameters -->
027: *
028: * <!-- START SNIPPET: extending -->
029: * TODO: Discuss some possible extension of the Interceptor.
030: * <!-- END SNIPPET: extending -->
031: *
032: * <pre>
033: * <!-- START SNIPPET: example -->
034: * <!-- TODO: Describe how the Interceptor reference will effect execution -->
035: * <action name="someAction" class="com.examples.SomeAction">
036: * TODO: fill in the interceptor reference.
037: * <interceptor-ref name=""/>
038: * <result name="success">good_result.ftl</result>
039: * </action>
040: * <!-- END SNIPPET: example -->
041: * </pre>
042: *
043: * Autowires action classes to Spring beans. The strategy for autowiring the beans can be configured
044: * by setting the parameter on the interceptor. Actions that need access to the <code>ActionContext</code>
045: * can implements the <code>ApplicationContextAware</code> interface. The context will also be placed on
046: * the action context under the APPLICATION_CONTEXT attribute.
047: *
048: * @author Simon Stewart
049: * @author Eric Hauser
050: */
051: public class ActionAutowiringInterceptor extends AroundInterceptor
052: implements ApplicationContextAware {
053: private static final Log log = LogFactory
054: .getLog(ActionAutowiringInterceptor.class);
055:
056: public static final String APPLICATION_CONTEXT = "com.opensymphony.xwork.spring.interceptor.ActionAutowiringInterceptor.applicationContext";
057:
058: private boolean initialized = false;
059: private ApplicationContext context;
060: private SpringObjectFactory factory;
061: private Integer autowireStrategy;
062:
063: /**
064: * @param autowireStrategy
065: */
066: public void setAutowireStrategy(Integer autowireStrategy) {
067: this .autowireStrategy = autowireStrategy;
068: }
069:
070: /**
071: * @param dispatcher
072: * @param result
073: * @throws Exception
074: */
075: protected void after(ActionInvocation dispatcher, String result)
076: throws Exception {
077: // Empty
078: }
079:
080: /**
081: * Looks for the <code>ApplicationContext</code> under the attribute that the Spring listener sets in
082: * the servlet context. The configuration is done the first time here instead of in init() since the
083: * <code>ActionContext</code> is not available during <code>Interceptor</code> initialization.
084: * <p/>
085: * Autowires the action to Spring beans and places the <code>ApplicationContext</code>
086: * on the <code>ActionContext</code>
087: * <p/>
088: * TODO Should this check to see if the <code>SpringObjectFactory</code> has already been configured
089: * instead of instantiating a new one? Or is there a good reason for the interceptor to have it's own
090: * factory?
091: *
092: * @param invocation
093: * @throws Exception
094: */
095: protected void before(ActionInvocation invocation) throws Exception {
096: if (!initialized) {
097: ApplicationContext applicationContext = (ApplicationContext) ActionContext
098: .getContext()
099: .getApplication()
100: .get(
101: WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE);
102:
103: if (applicationContext == null) {
104: log
105: .warn("ApplicationContext could not be found. Action classes will not be autowired.");
106: } else {
107: setApplicationContext(applicationContext);
108: factory = new SpringObjectFactory();
109: factory.setApplicationContext(getApplicationContext());
110: if (autowireStrategy != null) {
111: factory.setAutowireStrategy(autowireStrategy
112: .intValue());
113: }
114: }
115: initialized = true;
116: }
117:
118: if (factory == null)
119: return;
120:
121: Object bean = invocation.getAction();
122: factory.autoWireBean(bean);
123:
124: ActionContext.getContext().put(APPLICATION_CONTEXT, context);
125: }
126:
127: /**
128: * @param applicationContext
129: * @throws BeansException
130: */
131: public void setApplicationContext(
132: ApplicationContext applicationContext)
133: throws BeansException {
134: context = applicationContext;
135: }
136:
137: /**
138: * @return context
139: */
140: protected ApplicationContext getApplicationContext() {
141: return context;
142: }
143:
144: }
|