net.smartlab.web.DynaAction Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of smartweb Show documentation
Show all versions of smartweb Show documentation
SmartWeb is a web application development meta framework based on Jakarta Struts, Hibernate and other open source frameworks and libraries.
/*
* The SmartWeb Framework
* Copyright (C) 2004-2006
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*
* For further informations on the SmartWeb Framework please visit
*
* http://smartweb.sourceforge.net
*/
package net.smartlab.web;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Locale;
import java.util.Map;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.commons.collections.FastHashMap;
import org.apache.struts.Globals;
import org.apache.struts.action.ActionForm;
import org.apache.struts.action.ActionForward;
import org.apache.struts.action.ActionMapping;
import org.apache.struts.config.MessageResourcesConfig;
import org.apache.struts.config.ModuleConfig;
import org.apache.struts.util.MessageResources;
/**
* This class represent the dynamic version of the basic Action class allowing
* a single class to define multiple actions.
*
* Each declared method respecting the PARAMETERS
signature and
* returning a String
or an ActionMapping
will be
* available as an action mapping in Struts.
*
* As an example both the following methods can be used in the struts
* configuration file as valid mappings.
*
*
* - public String myMethod (ActionForm form, HttpServletRequest request, HttpServletResponse response, ActionMapping mapping) throws Exception
* - public ActionMapping myOtherMethod (ActionForm form, HttpServletRequest request, HttpServletResponse response, ActionMapping mapping) throws Exception
*
*
* In addition this class supports the same features providen by the
* org.apache.struts.actions.LookupDispatchAction
but to distinguish
* between direct method naming and reverse lookup naming you have to prefix
* the reverse lookup mapping parameter with @
(at) character.
*
* @author rlogiacco
*/
public abstract class DynaAction extends Action {
/**
* Standard dynamic method parameters.
*/
public final static Class[] PARAMETERS = new Class[] {ActionForm.class, HttpServletRequest.class, HttpServletResponse.class, ActionMapping.class};
/**
* Mapping of exposed methods.
*/
private final Map methods = new FastHashMap();
/**
* Mapping of locales to resource messages for reverse lookup.
*/
private final Map locales = new HashMap();
/**
* Default constructor.
*/
public DynaAction() {
Method[] methods = this.getClass().getMethods();
for (int i = 0; i < methods.length; i++) {
if (Arrays.equals(methods[i].getParameterTypes(), PARAMETERS)) {
this.methods.put(methods[i].getName(), methods[i]);
}
}
((FastHashMap)this.methods).setFast(true);
}
/**
* @see net.smartlab.web.Action#execute(org.apache.struts.action.ActionForm,
* javax.servlet.http.HttpServletRequest,
* javax.servlet.http.HttpServletResponse, ActionMapping)
*/
protected ActionForward execute(ActionForm form, HttpServletRequest request, HttpServletResponse response, ActionMapping mapping) throws Exception {
if (logger.isDebugEnabled()) {
logger.debug("execute(" + mapping.getPath() + ") - start");
}
String method = mapping.getParameter();
if (mapping == null) {
throw new ActionException("action.parameter.null");
}
if (method.startsWith("@")) {
// Strip the leading char
method = method.substring(1);
// Dynamically find the method using the request parameter value
method = request.getParameter(method);
if (!methods.containsKey(method)) {
// Try to reverse resolve using the resource bundle
// Based on this request's Locale get the lookupMap
Map lookup = null;
Locale locale = request.getLocale();
boolean exists = true;
synchronized (locales) {
lookup = (Map)this.locales.get(locale);
if (lookup == null) {
exists = false;
lookup = new HashMap();
locales.put(locale, lookup);
}
}
if (!exists) {
synchronized (lookup) {
/*
* This is the first time this Locale is used so build
* the reverse lookup Map. Search for message keys in
* all configured MessageResources for the current
* module.
*/
ModuleConfig module = (ModuleConfig)request.getAttribute(Globals.MODULE_KEY);
MessageResourcesConfig[] messages = module.findMessageResourcesConfigs();
// Look through all module's MessageResources
for (int i = 0; i < messages.length; i++) {
MessageResources resources = this.getResources(request, messages[i].getKey());
// Look for method name in Messages
Iterator names = this.methods.keySet().iterator();
while (names.hasNext()) {
String name = (String)names.next();
String message = resources.getMessage(locale, name);
if ((message != null) && !lookup.containsKey(message)) {
// Found method name and haven't added to
// Map yet, so add the text
if (name.indexOf('.') > -1) {
// Strip out any dot
name = name.substring(name.lastIndexOf('.') + 1);
}
if (methods.containsKey(name)) {
lookup.put(message, name);
}
}
}
}
}
}
// Find the method
method = (String)lookup.get(method);
}
}
// Execute the specified method
if (logger.isTraceEnabled()) {
logger.trace(" method = " + method);
}
try {
Object forward = ((Method)methods.get(method)).invoke(this, new Object[] {form, request, response, mapping});
if (forward instanceof String) {
return mapping.findForward((String)forward);
} else {
return (ActionForward)forward;
}
} catch (InvocationTargetException ite) {
Throwable cause = ite.getTargetException();
if (cause instanceof Exception) {
throw (Exception)cause;
} else {
logger.debug("execute( " + mapping.getPath() + ") - error", cause);
throw new ActionException("action.error.method", cause);
}
} catch (Exception e) {
logger.debug("execute( " + mapping.getPath() + ") - error", e);
throw new ActionException("action.error.method.unknown", method);
}
}
/**
* Default method action used to simply forward requests to the resource mapped as success
.
*
* @return success
*/
public final String forward(ActionForm form, HttpServletRequest request, HttpServletResponse response, ActionMapping mapping) {
return "success";
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy