blob: 3e5434b1ecc59b289ce74d321c81219b18fd021b [file] [log] [blame]
/*
* $Id$
*
* Copyright 2001-2004 The Apache Software Foundation.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.struts.scaffold;
import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.Map;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.commons.beanutils.PropertyUtils;
import org.apache.struts.action.ActionForm;
import org.apache.struts.action.ActionMapping;
import org.apache.commons.scaffold.lang.Log;
import org.apache.commons.scaffold.lang.Tokens;
import org.apache.commons.scaffold.util.ProcessBean;
import org.apache.commons.scaffold.util.ProcessResult;
import org.apache.commons.scaffold.util.ProcessResultBase;
import org.apache.commons.scaffold.util.ResultList;
import org.apache.commons.scaffold.util.ResultListBase;
/**
* ProcessFormAction that accepts the name of a class and a method
* with the signature "Object method(Object)" as the parameter.
* [org.apache.cerebus.Account;store].
*
* @version $Rev$ $Date$
*/
public class ProcessDispatchAction extends ProcessFormAction {
/**
* The set of argument type classes for the reflected method call.
* These are the same for all calls, so calculate them only once.
*/
private static final Class types[] = { Object.class };
/**
* Error handler.
* Posts a message template and two parameters in a ProcessResult.
*/
public void processError(ProcessResult result, String template,
ActionMapping mapping) {
result = new ProcessResultBase(this);
result.addMessage(template);
result.addMessage(mapping.getPath());
result.addMessage(mapping.getParameter());
}
// --------------------------------------------------------- Public Methods
/**
* Instantiate helper object from the type given as the
* first ActionMapping parameter and execute the method given
* as the second parameter (delimited with semicolons).
* <p>
* Otherwise operates as a ProcessAction.
*
* @param mapping The ActionMapping used to select this instance
* @param form The ActionForm
* @param request The HTTP request we are processing
* @param response The HTTP response we are creating
* <p>
* @exception IOException if an input/output error occurs
* @exception ServletException if a servlet exception occurs
* @todo Refactor so both Process*Actions can call core logic
* @todo Add support for mutliple object/methods
*/
public void executeLogic(
ActionMapping mapping,
ActionForm form,
HttpServletRequest request,
HttpServletResponse response)
throws Exception {
// Retrieve user profile, if any
BaseForm userBean =
getUserProfile(mapping,form,request,response);
Map properties = null;
// Munge the parameter property
String[] tokens = tokenize(mapping.getParameter());
// Create our ProcessBean helper
Object helper = createHelperObject(request,tokens[0]);
ProcessBean dataBean = (ProcessBean) helper;
// Pass along the helper's parameter, if any
if (tokens.length>2) {
dataBean.setParameter(tokens[2]);
}
properties = null;
if (null!=form) {
if (form instanceof BaseForm) {
BaseForm formBean = (BaseForm) form;
// Merge user profile (if found)
// and our form into a single map
properties = formBean.merge(userBean);
// Pass up the Locale and RemoteServer (if any)
dataBean.setLocale(formBean.getSessionLocale());
dataBean.setRemoteServer(getRemoteServer());
}
else {
properties = PropertyUtils.describe(form);
}
} // end null form
else if (null!=userBean) {
// if no form, but is profile, still use profile
properties = PropertyUtils.describe(userBean);
}
// Execute business logic, using values from map
Method method = dataBean.getClass().getMethod(tokens[1],types);
Object args[] = { properties };
ProcessResult result = null;
try {
result = (ProcessResult) method.invoke(dataBean,args);
}
catch (ClassCastException e) {
processError(result,Tokens.ERROR_DISPATCH_RETURN,mapping);
}
catch (IllegalAccessException e) {
processError(result,Tokens.ERROR_DISPATCH_RETURN,mapping);
}
catch (InvocationTargetException e) {
// Rethrow the target exception if possible so that the
// exception handling machinery can deal with it
Throwable t = e.getTargetException();
if (t instanceof Exception) {
throw ((Exception) t);
} else {
processError(result,Tokens.ERROR_DISPATCH,mapping);
}
}
// Execute business logic, using map
checkOutcome(mapping,request,response,result);
}
} // end ProcessDispatchAction