actionconfigmatcher.java

来自「在Struts2中的jar包xwork的源代码.版本为2.0.7」· Java 代码 · 共 314 行

JAVA
314
字号
/* * $Id: ActionConfigMatcher.java 1223 2006-11-23 20:33:15Z rainerh $ * * Copyright 2003,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 com.opensymphony.xwork2.config.impl;import org.apache.commons.logging.Log;import org.apache.commons.logging.LogFactory;import com.opensymphony.xwork2.util.WildcardHelper;import com.opensymphony.xwork2.config.entities.ActionConfig;import com.opensymphony.xwork2.config.entities.ExceptionMappingConfig;import com.opensymphony.xwork2.config.entities.ResultConfig;import java.io.Serializable;import java.util.ArrayList;import java.util.HashMap;import java.util.Iterator;import java.util.LinkedHashMap;import java.util.List;import java.util.Map;/** * <p> Matches paths against pre-compiled wildcard expressions pulled from * action configs. It uses the wildcard matcher from the Apache Cocoon * project. Patterns will be matched in the order they exist in the  * config file. The first match wins, so more specific patterns should be * defined before less specific patterns. */public class ActionConfigMatcher implements Serializable {    /**     * <p> The logging instance </p>     */    private static final Log log = LogFactory.getLog(ActionConfigMatcher.class);    /**     * <p> Handles all wildcard pattern matching. </p>     */    private static final WildcardHelper wildcard = new WildcardHelper();    /**     * <p> The compiled paths and their associated ActionConfig's </p>     */    private List compiledPaths;    /**     * <p> Finds and precompiles the wildcard patterns from the ActionConfig     * "path" attributes. ActionConfig's will be evaluated in the order they     * exist in the config file. Only paths that actually contain a     * wildcard will be compiled. Patterns will matched strictly.</p>     *     * @param configs An array of ActionConfig's to process     */    public ActionConfigMatcher(Map<String, ActionConfig> configs) {        this(configs, false);    }        /**     * <p> Finds and precompiles the wildcard patterns from the ActionConfig     * "path" attributes. ActionConfig's will be evaluated in the order they     * exist in the config file. Only paths that actually contain a     * wildcard will be compiled. </p>     *      * <p>Patterns can optionally be matched "loosely".  When     * the end of the pattern matches \*[^*]\*$ (wildcard, no wildcard,     * wildcard), if the pattern fails, it is also matched as if the      * last two characters didn't exist.  The goal is to support the      * legacy "*!*" syntax, where the "!*" is optional.</p>      *     * @param configs An array of ActionConfig's to process     * @param looseMatch To loosely match wildcards or not     */    public ActionConfigMatcher(Map<String, ActionConfig> configs,            boolean looseMatch) {        compiledPaths = new ArrayList();        int[] pattern;        for (String name : configs.keySet()) {            if ((name != null) && (name.indexOf('*') > -1)) {                if ((name.length() > 0) && (name.charAt(0) == '/')) {                    name = name.substring(1);                }                if (log.isDebugEnabled()) {                    log.debug("Compiling action config path '" + name + "'");                }                pattern = wildcard.compilePattern(name);                compiledPaths.add(new Mapping(name, pattern, configs.get(name)));                                int lastStar = name.lastIndexOf('*');                if (lastStar > 1 && lastStar == name.length() - 1) {                    if (name.charAt(lastStar - 1) != '*') {                        pattern = wildcard.compilePattern(name.substring(0, lastStar - 1));                        compiledPaths.add(new Mapping(name, pattern, configs.get(name)));                    }                }            }        }    }    /**     * <p> Matches the path against the compiled wildcard patterns. </p>     *     * @param path The portion of the request URI for selecting a config.     * @return The action config if matched, else null     */    public ActionConfig match(String path) {        ActionConfig config = null;        if (compiledPaths.size() > 0) {            if (log.isDebugEnabled()) {                log.debug("Attempting to match '" + path                    + "' to a wildcard pattern, "+ compiledPaths.size()                    + " available");            }            Mapping m;            HashMap vars = new HashMap();            for (Iterator i = compiledPaths.iterator(); i.hasNext();) {                m = (Mapping) i.next();                if (wildcard.match(vars, path, m.getPattern())) {                    if (log.isDebugEnabled()) {                        log.debug("Path matches pattern '"                            + m.getOriginal() + "'");                    }                    config =                        convertActionConfig(path,                            (ActionConfig) m.getActionConfig(), vars);                    break;                }            }        }        return config;    }    /**     * <p> Clones the ActionConfig and its children, replacing various     * properties with the values of the wildcard-matched strings. </p>     *     * @param path The requested path     * @param orig The original ActionConfig     * @param vars A Map of wildcard-matched strings     * @return A cloned ActionConfig with appropriate properties replaced with     *         wildcard-matched values     */    protected ActionConfig convertActionConfig(String path, ActionConfig orig,        Map vars) {                String className = convertParam(orig.getClassName(), vars);        String methodName = convertParam(orig.getMethodName(), vars);        String pkgName = convertParam(orig.getPackageName(), vars);                Map<String,Object> params = replaceParameters(orig.getParams(), vars);                Map<String,ResultConfig> results = new LinkedHashMap<String,ResultConfig>();        for (String name : orig.getResults().keySet()) {            ResultConfig result = orig.getResults().get(name);            name = convertParam(name, vars);            String resultClassName = convertParam(result.getClassName(), vars);            Map<String,Object> resultParams = replaceParameters(result.getParams(), vars);            ResultConfig r = new ResultConfig(name, resultClassName, resultParams);            results.put(name, r);        }                List<ExceptionMappingConfig> exs = new ArrayList<ExceptionMappingConfig>();        for (ExceptionMappingConfig ex : orig.getExceptionMappings()) {            String name = convertParam(ex.getName(), vars);            String exClassName = convertParam(ex.getExceptionClassName(), vars);            String exResult = convertParam(ex.getResult(), vars);            Map<String,Object> exParams = replaceParameters(ex.getParams(), vars);            ExceptionMappingConfig e = new ExceptionMappingConfig(name, exClassName, exResult, exParams);            exs.add(e);        }                ActionConfig config = new ActionConfig(methodName, className, pkgName,                 params, results, orig.getInterceptors(), exs);        config.setLocation(orig.getLocation());                return config;    }    /**     * <p> Replaces parameter values     * </p>     *     * @param orig  The original parameters with placehold values     * @param vars  A Map of wildcard-matched strings     */    protected Map<String,Object> replaceParameters(Map<String, Object> orig, Map vars) {        Map<String,Object> map = new LinkedHashMap<String,Object>();        for (String key : orig.keySet()) {            map.put(key, convertParam(String.valueOf(orig.get(key)), vars));        }        return map;    }    /**     * <p> Inserts into a value wildcard-matched strings where specified     * with the {x} syntax.  If a wildcard-matched value isn't found, the     * replacement token is turned into an empty string.      * </p>     *     * @param val  The value to convert     * @param vars A Map of wildcard-matched strings     * @return The new value     */    protected String convertParam(String val, Map vars) {        if (val == null) {            return null;        }                 int len = val.length();        StringBuilder ret = new StringBuilder();        char c;        String varVal;        for (int x=0; x<len; x++) {            c = val.charAt(x);            if (x < len - 2 &&                     c == '{' && '}' == val.charAt(x+2)) {                varVal = (String)vars.get(String.valueOf(val.charAt(x + 1)));                if (varVal != null) {                    ret.append(varVal);                }                 x += 2;            } else {                ret.append(c);            }        }                return ret.toString();    }    /**     * <p> Stores a compiled wildcard pattern and the ActionConfig it came     * from. </p>     */    private class Mapping implements Serializable {        /**         * <p> The original pattern. </p>         */        private String original;                /**         * <p> The compiled pattern. </p>         */        private int[] pattern;        /**         * <p> The original ActionConfig. </p>         */        private ActionConfig config;        /**         * <p> Contructs a read-only Mapping instance. </p>         *         * @param original The original pattern         * @param pattern The compiled pattern         * @param config  The original ActionConfig         */        public Mapping(String original, int[] pattern, ActionConfig config) {            this.original = original;            this.pattern = pattern;            this.config = config;        }        /**         * <p> Gets the compiled wildcard pattern. </p>         *         * @return The compiled pattern         */        public int[] getPattern() {            return this.pattern;        }        /**         * <p> Gets the ActionConfig that contains the pattern. </p>         *         * @return The associated ActionConfig         */        public ActionConfig getActionConfig() {            return this.config;        }                /**         * <p> Gets the original wildcard pattern. </p>         *         * @return The original pattern         */        public String getOriginal() {            return this.original;        }    }}

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?