📄 run.java
字号:
/**
* Copyright (c) 2005-2007, Paul Tuckey
* All rights reserved.
* ====================================================================
* Licensed under the BSD License. Text as follows.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* - Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimer in the documentation and/or other materials provided
* with the distribution.
* - Neither the name tuckey.org nor the names of its contributors
* may be used to endorse or promote products derived from this
* software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
* ====================================================================
*/
package org.tuckey.web.filters.urlrewrite;
import org.tuckey.web.filters.urlrewrite.extend.RewriteMatch;
import org.tuckey.web.filters.urlrewrite.utils.Log;
import org.tuckey.web.filters.urlrewrite.utils.StringMatchingMatcher;
import org.tuckey.web.filters.urlrewrite.utils.StringUtils;
import org.tuckey.web.filters.urlrewrite.utils.TypeUtils;
import org.tuckey.web.filters.urlrewrite.json.JsonRewriteMatch;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletConfig;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.Hashtable;
/**
* Defines a run element, the ability to run a methodStr
* (eg, xx(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse))
*
* @author Paul Tuckey
* @version $Revision: 43 $ $Date: 2006-10-31 17:29:59 +1300 (Tue, 31 Oct 2006) $
*/
public class Run {
private static Log log = Log.getLog(Run.class);
/**
* Weather or not the user wants the classStr created for each run.
*/
private boolean newEachTime = false;
private boolean jsonHandler = false;
private String classStr;
private static final String DEAULT_METHOD_STR = "run";
private String methodStr = DEAULT_METHOD_STR;
/**
* Used to identify the condition.
*/
private int id = 0;
private String error = null;
private boolean valid = false;
private boolean initialised = false;
/**
* The instance of the classStr to run. Note, will be null if newEachTime is true.
*/
private Object runClassInstance;
/**
* handles to the methods we are going to run.
*/
private Constructor runConstructor;
private Method initMethod;
private Method filterInitMethod;
private Method runMethod;
private Class[] runMethodParams;
private String[] runMethodParamNames;
private boolean runMethodUseDefaultParams = true;
private Method destroyMethod;
/**
* The config that we pass to the objectwe are trying to run.
*/
private RunConfig runServletConfig;
private Hashtable initParams = new Hashtable();
private static boolean loadClass = true;
private static Class[][] runMethodPossibleSignatures = {
{ServletRequest.class, ServletResponse.class},
{ServletRequest.class},
{ServletResponse.class},
{HttpServletRequest.class, HttpServletResponse.class},
{HttpServletRequest.class},
{HttpServletResponse.class}
};
private boolean filter = false;
/**
* @see #initialise(ServletContext,Class) initialise
*/
public boolean initialise(ServletContext context) {
return initialise(context, null);
}
/**
* Initialise the Run, this will check specified classStr, constructor and methodStr exist.
*/
public boolean initialise(ServletContext context, Class extraParam) {
log.debug("initialising run");
runServletConfig = new RunConfig(context, initParams);
initialised = true;
valid = false;
if (StringUtils.isBlank(classStr)) {
setError("cannot initialise run " + id + " value is empty");
return valid;
}
if (methodStr == null) {
methodStr = DEAULT_METHOD_STR;
}
log.debug("methodStr: " + methodStr);
String rawMethodStr = methodStr;
int bkStart = rawMethodStr.indexOf('(');
int bkEnd = rawMethodStr.indexOf(')');
if (bkStart != -1 && bkEnd != -1 && (bkEnd - bkStart) > 0) {
runMethodUseDefaultParams = false;
// set method str back to just method name
methodStr = rawMethodStr.substring(0, bkStart);
// get the list of params ie, "String name, int id"
String paramsList = rawMethodStr.substring(bkStart + 1, bkEnd);
paramsList = StringUtils.trimToNull(paramsList);
if (paramsList != null) {
String[] params = paramsList.split(",");
// validate and clean the incoming params list
Class[] paramClasses = new Class[params.length];
String[] paramNames = new String[params.length];
for (int i = 0; i < params.length; i++) {
String param = StringUtils.trimToNull(params[i]);
if (param == null) continue;
if (param.contains(" ")) {
String paramName = StringUtils.trimToNull(param.substring(param.indexOf(" ")));
if (paramName != null) {
log.debug("param name: " + paramName);
paramNames[i] = paramName;
}
param = param.substring(0, param.indexOf(' '));
}
Class clazz = parseClass(param);
if (clazz == null) return valid;
paramClasses[i] = clazz;
}
runMethodParams = paramClasses;
runMethodParamNames = paramNames;
}
}
if (loadClass) {
prepareRunObject(extraParam);
} else {
valid = true;
}
return valid;
}
/**
* Turns a class or language keyword name into the Class object, works with short names, ie, L - Long.
* <p/>
* boolean Z
* byte B
* char C
* class or interface Lclassname;
* double D
* float F
* int I
* long J
* short S
*
* @see Class
*/
private Class parseClass(String param) {
// do shortcuts
Class paramClass = TypeUtils.findClass(param);
if ("javax.servlet.FilterChain".equalsIgnoreCase(param) || "FilterChain".equalsIgnoreCase(param)
|| "chain".equalsIgnoreCase(param)) {
filter = true;
paramClass = FilterChain.class;
}
if (loadClass) {
if (paramClass == null) {
try {
paramClass = Class.forName(param);
} catch (ClassNotFoundException e) {
setError("could not find " + param + " got a " + e.toString(), e);
return null;
} catch (NoClassDefFoundError e) {
setError("could not find " + param + " got a " + e.toString(), e);
return null;
}
}
if (paramClass == null) {
setError("could not find class of type " + param);
return null;
}
}
if (log.isDebugEnabled()) {
log.debug("parseClass found class " + paramClass + " for " + param);
}
return paramClass;
}
/**
* Prepare the object for running by constructing and setting up method handles.
*/
private void prepareRunObject(Class extraParam) {
if (log.isDebugEnabled()) {
log.debug("looking for class " + classStr);
}
Class runClass;
try {
runClass = Class.forName(classStr);
} catch (ClassNotFoundException e) {
setError("could not find " + classStr + " got a " + e.toString(), e);
return;
} catch (NoClassDefFoundError e) {
setError("could not find " + classStr + " got a " + e.toString(), e);
return;
}
try {
runConstructor = runClass.getConstructor((Class[]) null);
} catch (NoSuchMethodException e) {
setError("could not get constructor for " + classStr, e);
return;
}
if (!runMethodUseDefaultParams) {
if (log.isDebugEnabled()) {
log.debug("looking for " + methodStr + " with specific params");
}
try {
runMethod = runClass.getMethod(methodStr, runMethodParams);
} catch (NoSuchMethodException e) {
// do nothing
}
} else {
if (log.isDebugEnabled()) {
log.debug("looking for " + methodStr + "(ServletRequest, ServletResponse)");
}
for (int i = 0; i < runMethodPossibleSignatures.length; i++) {
Class[] runMethodPossibleSignature = runMethodPossibleSignatures[i];
if (extraParam != null) {
if (runMethodPossibleSignature.length == 2) {
runMethodPossibleSignature = new Class[]{runMethodPossibleSignature[0],
runMethodPossibleSignature[1], extraParam};
}
if (runMethodPossibleSignature.length == 1) {
runMethodPossibleSignature = new Class[]{runMethodPossibleSignature[0], extraParam};
}
}
if (log.isDebugEnabled()) {
StringBuffer possible = new StringBuffer();
for (int j = 0; j < runMethodPossibleSignature.length; j++) {
if (j > 0) possible.append(",");
possible.append(runMethodPossibleSignature[j].getName());
}
log.debug("looking for " + methodStr + "(" + possible + ")");
}
try {
runMethod = runClass.getMethod(methodStr, runMethodPossibleSignature);
runMethodParams = runMethodPossibleSignature;
break;
} catch (NoSuchMethodException e) {
// do nothing except be paranoid about resetting runMethodParams
runMethodParams = null;
}
}
if (runMethod == null) {
setError("could not find method with the name " + methodStr + " on " + classStr);
return;
}
}
Method[] methods = runClass.getMethods();
for (int i = 0; i < methods.length; i++) {
Method method = methods[i];
if ("destroy".equals(method.getName()) && method.getParameterTypes().length == 0) {
log.debug("found destroy methodStr");
destroyMethod = method;
}
if ("init".equals(method.getName()) && method.getParameterTypes().length == 1 &&
ServletConfig.class.getName().equals(method.getParameterTypes()[0].getName())) {
log.debug("found init methodStr");
initMethod = method;
}
if ("init".equals(method.getName()) && method.getParameterTypes().length == 1 &&
FilterConfig.class.getName().equals(method.getParameterTypes()[0].getName())) {
log.debug("found filter init methodStr");
filterInitMethod = method;
}
if (initMethod != null && destroyMethod != null) break;
}
if (!newEachTime) {
runClassInstance = fetchNewInstance();
}
valid = true;
}
private void invokeDestroy(Object runClassInstanceToDestroy) {
if (runClassInstanceToDestroy != null && destroyMethod != null) {
if (log.isDebugEnabled()) {
log.debug("running " + classStr + ".destroy()");
}
try {
destroyMethod.invoke(runClassInstanceToDestroy, (Object[]) null);
} catch (IllegalAccessException e) {
logInvokeException("destroy()", e);
} catch (InvocationTargetException e) {
logInvokeException("destroy()", e);
}
}
}
/**
* Invokes the run method.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -