Hello,
In need of a way to execute my actions in a non-servlet environment, I created the following class:
<x-tad-bigger>import</x-tad-bigger><x-tad-bigger> java.io.IOException;
</x-tad-bigger><x-tad-bigger>import</x-tad-bigger><x-tad-bigger> java.io.InputStream;
</x-tad-bigger><x-tad-bigger>import</x-tad-bigger><x-tad-bigger> java.util.HashMap;
</x-tad-bigger><x-tad-bigger>import</x-tad-bigger><x-tad-bigger> org.apache.log4j.Logger;
</x-tad-bigger><x-tad-bigger>import</x-tad-bigger><x-tad-bigger> org.xml.sax.SAXException;
</x-tad-bigger><x-tad-bigger>import</x-tad-bigger><x-tad-bigger> com.opensymphony.xwork.ActionContext;
</x-tad-bigger><x-tad-bigger>import</x-tad-bigger><x-tad-bigger> com.opensymphony.xwork.ActionProxy;
</x-tad-bigger><x-tad-bigger>import</x-tad-bigger><x-tad-bigger> com.opensymphony.xwork.Action;
</x-tad-bigger><x-tad-bigger>import</x-tad-bigger><x-tad-bigger> com.opensymphony.xwork.ActionProxyFactory;
</x-tad-bigger><x-tad-bigger>import</x-tad-bigger><x-tad-bigger> com.opensymphony.xwork.ActionSupport;
</x-tad-bigger><x-tad-bigger>import</x-tad-bigger><x-tad-bigger> com.opensymphony.xwork.interceptor.component.ComponentConfiguration;
</x-tad-bigger><x-tad-bigger>import</x-tad-bigger><x-tad-bigger> com.opensymphony.xwork.interceptor.component.ComponentManager;
</x-tad-bigger><x-tad-bigger>import</x-tad-bigger><x-tad-bigger> com.opensymphony.xwork.interceptor.component.DefaultComponentManager;
</x-tad-bigger><x-tad-bigger>/**</x-tad-bigger><x-tad-bigger>
</x-tad-bigger><x-tad-bigger>*</x-tad-bigger><x-tad-bigger> </x-tad-bigger><x-tad-bigger>@author</x-tad-bigger><x-tad-bigger> </x-tad-bigger><x-tad-bigger>pat</x-tad-bigger><x-tad-bigger>
</x-tad-bigger><x-tad-bigger>*</x-tad-bigger><x-tad-bigger>
</x-tad-bigger><x-tad-bigger>*/</x-tad-bigger><x-tad-bigger>
</x-tad-bigger><x-tad-bigger>public</x-tad-bigger><x-tad-bigger> </x-tad-bigger><x-tad-bigger>class</x-tad-bigger><x-tad-bigger> ActionExecution {
</x-tad-bigger><x-tad-bigger>private</x-tad-bigger><x-tad-bigger> </x-tad-bigger><x-tad-bigger>static</x-tad-bigger><x-tad-bigger> Logger LOG = Logger.getLogger(ActionExecution.</x-tad-bigger><x-tad-bigger>class</x-tad-bigger><x-tad-bigger>);
</x-tad-bigger><x-tad-bigger>public</x-tad-bigger><x-tad-bigger> </x-tad-bigger><x-tad-bigger>static</x-tad-bigger><x-tad-bigger> ComponentConfiguration APPLICATION_CONFIGURATION;
</x-tad-bigger><x-tad-bigger>public</x-tad-bigger><x-tad-bigger> </x-tad-bigger><x-tad-bigger>static</x-tad-bigger><x-tad-bigger> DefaultComponentManager APPLICATION_COMPONENT;
</x-tad-bigger><x-tad-bigger>private</x-tad-bigger><x-tad-bigger> </x-tad-bigger><x-tad-bigger>static</x-tad-bigger><x-tad-bigger> HashMap application;
</x-tad-bigger><x-tad-bigger>private</x-tad-bigger><x-tad-bigger> HashMap parameters;
</x-tad-bigger><x-tad-bigger>private</x-tad-bigger><x-tad-bigger> HashMap session;
</x-tad-bigger><x-tad-bigger>private</x-tad-bigger><x-tad-bigger> ActionProxy proxy;
</x-tad-bigger><x-tad-bigger>private</x-tad-bigger><x-tad-bigger> </x-tad-bigger><x-tad-bigger>boolean</x-tad-bigger><x-tad-bigger> executed=</x-tad-bigger><x-tad-bigger>false</x-tad-bigger><x-tad-bigger>;
</x-tad-bigger><x-tad-bigger>static</x-tad-bigger><x-tad-bigger>{
APPLICATION_CONFIGURATION=loadConfiguration();
APPLICATION_COMPONENT=</x-tad-bigger><x-tad-bigger>new</x-tad-bigger><x-tad-bigger> DefaultComponentManager();
APPLICATION_CONFIGURATION.configure(APPLICATION_COMPONENT,</x-tad-bigger><x-tad-bigger>"application"</x-tad-bigger><x-tad-bigger>);
</x-tad-bigger><x-tad-bigger>//Is this really necessary in a servlet environment?</x-tad-bigger><x-tad-bigger>
application=</x-tad-bigger><x-tad-bigger>new</x-tad-bigger><x-tad-bigger> HashMap();
application.put(</x-tad-bigger><x-tad-bigger>"config"</x-tad-bigger><x-tad-bigger>,APPLICATION_CONFIGURATION);
application.put(</x-tad-bigger><x-tad-bigger>"DefaultComponentManager"</x-tad-bigger><x-tad-bigger>,APPLICATION_COMPONENT);
}
</x-tad-bigger><x-tad-bigger>public</x-tad-bigger><x-tad-bigger> ActionExecution(SdbUser user){
session=</x-tad-bigger><x-tad-bigger>new</x-tad-bigger><x-tad-bigger> HashMap();
DefaultComponentManager container = </x-tad-bigger><x-tad-bigger>new</x-tad-bigger><x-tad-bigger> DefaultComponentManager();
container.setFallback(APPLICATION_COMPONENT);
APPLICATION_CONFIGURATION.configure(container, </x-tad-bigger><x-tad-bigger>"session"</x-tad-bigger><x-tad-bigger>);
session.put(</x-tad-bigger><x-tad-bigger>"DefaultComponentManager"</x-tad-bigger><x-tad-bigger>, container);
</x-tad-bigger><x-tad-bigger>null</x-tad-bigger><x-tad-bigger>){
session.put(SdbUser.SESSION_KEY,user);
}
}
</x-tad-bigger><x-tad-bigger>public</x-tad-bigger><x-tad-bigger> </x-tad-bigger><x-tad-bigger>void</x-tad-bigger><x-tad-bigger> addParameter(String key,Object value){
</x-tad-bigger><x-tad-bigger>null</x-tad-bigger><x-tad-bigger>){
parameters=</x-tad-bigger><x-tad-bigger>new</x-tad-bigger><x-tad-bigger> HashMap();
executed=</x-tad-bigger><x-tad-bigger>false</x-tad-bigger><x-tad-bigger>;
}
parameters.put(key,value);
}
</x-tad-bigger><x-tad-bigger>public</x-tad-bigger><x-tad-bigger> String execute(String actionName) </x-tad-bigger><x-tad-bigger>throws</x-tad-bigger><x-tad-bigger> Exception{
DefaultComponentManager container = </x-tad-bigger><x-tad-bigger>new</x-tad-bigger><x-tad-bigger> DefaultComponentManager();
ComponentManager fallback = (ComponentManager) session.get(</x-tad-bigger><x-tad-bigger>"DefaultComponentManager"</x-tad-bigger><x-tad-bigger>);
</x-tad-bigger><x-tad-bigger>try</x-tad-bigger><x-tad-bigger>{
container.setFallback(fallback);
APPLICATION_CONFIGURATION.configure(container, </x-tad-bigger><x-tad-bigger>"request"</x-tad-bigger><x-tad-bigger>);
HashMap extraContext = </x-tad-bigger><x-tad-bigger>new</x-tad-bigger><x-tad-bigger> HashMap();
</x-tad-bigger><x-tad-bigger>if</x-tad-bigger><x-tad-bigger>(parameters != </x-tad-bigger><x-tad-bigger>null</x-tad-bigger><x-tad-bigger>){
</x-tad-bigger><x-tad-bigger>// get a shallow copy of the params map</x-tad-bigger><x-tad-bigger>
HashMap requestParameters=(HashMap)parameters.clone();
parameters=</x-tad-bigger><x-tad-bigger>null</x-tad-bigger><x-tad-bigger>;
extraContext.put(ActionContext.PARAMETERS, requestParameters);
}
extraContext.put(ActionContext.SESSION, session);
extraContext.put(ActionContext.APPLICATION, application);
extraContext.put(ActionContext.LOCALE, Main.getLocale());
extraContext.put(</x-tad-bigger><x-tad-bigger>"com.opensymphony.xwork.interceptor.component.ComponentManager"</x-tad-bigger><x-tad-bigger>,container);
proxy=ActionProxyFactory.getFactory().createActionProxy(</x-tad-bigger><x-tad-bigger>"default"</x-tad-bigger><x-tad-bigger>,actionName,extraContext);
String ret=proxy.execute();
executed=</x-tad-bigger><x-tad-bigger>true</x-tad-bigger><x-tad-bigger>;
</x-tad-bigger><x-tad-bigger>return</x-tad-bigger><x-tad-bigger>(ret);
}</x-tad-bigger><x-tad-bigger>finally</x-tad-bigger><x-tad-bigger>{
container.dispose();
}
}
</x-tad-bigger><x-tad-bigger>public</x-tad-bigger><x-tad-bigger> Action getAction(){
</x-tad-bigger><x-tad-bigger>if</x-tad-bigger><x-tad-bigger>(!executed){
</x-tad-bigger><x-tad-bigger>return</x-tad-bigger><x-tad-bigger> </x-tad-bigger><x-tad-bigger>null</x-tad-bigger><x-tad-bigger>;
}
</x-tad-bigger><x-tad-bigger>return</x-tad-bigger><x-tad-bigger>(proxy.getInvocation().getAction());
}
</x-tad-bigger><x-tad-bigger>private</x-tad-bigger><x-tad-bigger> </x-tad-bigger><x-tad-bigger>static</x-tad-bigger><x-tad-bigger> ComponentConfiguration loadConfiguration() {
ComponentConfiguration config = </x-tad-bigger><x-tad-bigger>new</x-tad-bigger><x-tad-bigger> ComponentConfiguration();
InputStream configXml = Thread.currentThread().getContextClassLoader().getResourceAsStream(</x-tad-bigger><x-tad-bigger>"components.xml"</x-tad-bigger><x-tad-bigger>);
</x-tad-bigger><x-tad-bigger>if</x-tad-bigger><x-tad-bigger> (configXml == </x-tad-bigger><x-tad-bigger>null</x-tad-bigger><x-tad-bigger>) {
</x-tad-bigger><x-tad-bigger>final</x-tad-bigger><x-tad-bigger> String message = </x-tad-bigger><x-tad-bigger>"Unable to find the file components.xml in the classpath."</x-tad-bigger><x-tad-bigger>;
LOG.error(message);
</x-tad-bigger><x-tad-bigger>throw</x-tad-bigger><x-tad-bigger> </x-tad-bigger><x-tad-bigger>new</x-tad-bigger><x-tad-bigger> RuntimeException(message);
}
</x-tad-bigger><x-tad-bigger>try</x-tad-bigger><x-tad-bigger> {
config.loadFromXml(configXml);
} </x-tad-bigger><x-tad-bigger>catch</x-tad-bigger><x-tad-bigger> (IOException ioe) {
LOG.error(ioe);
</x-tad-bigger><x-tad-bigger>throw</x-tad-bigger><x-tad-bigger> </x-tad-bigger><x-tad-bigger>new</x-tad-bigger><x-tad-bigger> RuntimeException(</x-tad-bigger><x-tad-bigger>"Unable to load component configuration"</x-tad-bigger><x-tad-bigger>);
} </x-tad-bigger><x-tad-bigger>catch</x-tad-bigger><x-tad-bigger> (SAXException sae) {
LOG.error(sae);
</x-tad-bigger><x-tad-bigger>throw</x-tad-bigger><x-tad-bigger> </x-tad-bigger><x-tad-bigger>new</x-tad-bigger><x-tad-bigger> RuntimeException(</x-tad-bigger><x-tad-bigger>"Unable to load component configuration"</x-tad-bigger><x-tad-bigger>);
}
</x-tad-bigger><x-tad-bigger>return</x-tad-bigger><x-tad-bigger> config;
}
}
That way, to execute an action, all I have to do is the following:
ActionExecution exec=</x-tad-bigger><x-tad-bigger>new</x-tad-bigger><x-tad-bigger> ActionExecution(myUser);
exec.addParameter(</x-tad-bigger><x-tad-bigger>"some param"</x-tad-bigger><x-tad-bigger>,</x-tad-bigger><x-tad-bigger>"some value"</x-tad-bigger><x-tad-bigger>);
exec.addParameter(</x-tad-bigger><x-tad-bigger>"some other param"</x-tad-bigger><x-tad-bigger>,</x-tad-bigger><x-tad-bigger>"some value"</x-tad-bigger><x-tad-bigger>);
String result=exec.execute("myAction");
Later on, if I want to use the same user session, I re-use the same exec object.
In my case, I'm in a mix environment, where some requests will be served by the ServletDispatcher in WW2. In that case, instead of using WW2's ApplicationLifecycleListener, I use the following one:
</x-tad-bigger><x-tad-bigger>import</x-tad-bigger><x-tad-bigger> javax.servlet.ServletContext;
</x-tad-bigger><x-tad-bigger>import</x-tad-bigger><x-tad-bigger> javax.servlet.ServletContextEvent;
</x-tad-bigger><x-tad-bigger>import</x-tad-bigger><x-tad-bigger> javax.servlet.ServletContextListener;
</x-tad-bigger><x-tad-bigger>import</x-tad-bigger><x-tad-bigger> org.apache.log4j.Logger;
</x-tad-bigger><x-tad-bigger>import</x-tad-bigger><x-tad-bigger> com.opensymphony.xwork.interceptor.component.ComponentConfiguration;
</x-tad-bigger><x-tad-bigger>import</x-tad-bigger><x-tad-bigger> com.opensymphony.xwork.interceptor.component.ComponentManager;
</x-tad-bigger><x-tad-bigger>import</x-tad-bigger><x-tad-bigger> ....ActionExecution;
</x-tad-bigger><x-tad-bigger>/**</x-tad-bigger><x-tad-bigger>
</x-tad-bigger><x-tad-bigger>*</x-tad-bigger><x-tad-bigger> </x-tad-bigger><x-tad-bigger>@author</x-tad-bigger><x-tad-bigger> </x-tad-bigger><x-tad-bigger>pat</x-tad-bigger><x-tad-bigger>
</x-tad-bigger><x-tad-bigger>*</x-tad-bigger><x-tad-bigger>
</x-tad-bigger><x-tad-bigger>*/</x-tad-bigger><x-tad-bigger>
</x-tad-bigger><x-tad-bigger>public</x-tad-bigger><x-tad-bigger> </x-tad-bigger><x-tad-bigger>class</x-tad-bigger><x-tad-bigger> ApplicationLifecycleListener </x-tad-bigger><x-tad-bigger>implements</x-tad-bigger><x-tad-bigger> ServletContextListener{
</x-tad-bigger><x-tad-bigger>protected</x-tad-bigger><x-tad-bigger> </x-tad-bigger><x-tad-bigger>static</x-tad-bigger><x-tad-bigger> </x-tad-bigger><x-tad-bigger>final</x-tad-bigger><x-tad-bigger> Logger LOG = Logger.getLogger(ApplicationLifecycleListener.</x-tad-bigger><x-tad-bigger>class</x-tad-bigger><x-tad-bigger>);
</x-tad-bigger><x-tad-bigger>public</x-tad-bigger><x-tad-bigger> </x-tad-bigger><x-tad-bigger>void</x-tad-bigger><x-tad-bigger> contextInitialized(ServletContextEvent event) {
ServletContext application = event.getServletContext();
ComponentManager container = ActionExecution.APPLICATION_COMPONENT;
ComponentConfiguration config = ActionExecution.APPLICATION_CONFIGURATION;
config.configure(container, </x-tad-bigger><x-tad-bigger>"application"</x-tad-bigger><x-tad-bigger>);
application.setAttribute(</x-tad-bigger><x-tad-bigger>"DefaultComponentManager"</x-tad-bigger><x-tad-bigger>, container);
application.setAttribute(</x-tad-bigger><x-tad-bigger>"ComponentConfiguration"</x-tad-bigger><x-tad-bigger>, config);
}
</x-tad-bigger><x-tad-bigger>public</x-tad-bigger><x-tad-bigger> </x-tad-bigger><x-tad-bigger>void</x-tad-bigger><x-tad-bigger> contextDestroyed(ServletContextEvent event) {
ServletContext application = event.getServletContext();
ComponentManager container = (ComponentManager) application.getAttribute(</x-tad-bigger><x-tad-bigger>"DefaultComponentManager"</x-tad-bigger><x-tad-bigger>);
</x-tad-bigger><x-tad-bigger>if</x-tad-bigger><x-tad-bigger> (container != </x-tad-bigger><x-tad-bigger>null</x-tad-bigger><x-tad-bigger>) {
container.dispose();
}
}
}
That's it.
Did you plan to implement such classes in xwork and webwork2? Do you have any comment about it?
Cheers and thanks
Patrick
</x-tad-bigger>