⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 run.java

📁 UrlRewriteFilter 是一个不错的URL转换工具
💻 JAVA
📖 第 1 页 / 共 2 页
字号:
/**
 * 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 + -