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

📄 rulebase.java

📁 urlrewritefilter-2.6-src.zip
💻 JAVA
字号:
/**
 * Copyright (c) 2005, Paul Tuckey
 * All rights reserved.
 *
 * Each copy or derived work must preserve the copyright notice and this
 * notice unmodified.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program 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 General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 *
 */
package org.tuckey.web.filters.urlrewrite;

import org.tuckey.web.filters.urlrewrite.utils.Log;
import org.tuckey.web.filters.urlrewrite.utils.StringUtils;

import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.regex.PatternSyntaxException;

/**
 * Defines a rule that can be run against an incoming request.
 *
 * @author Paul Tuckey
 * @version $Revision: 1.10 $ $Date: 2005/12/07 10:27:03 $
 */
public class RuleBase {

    private static Log log = Log.getLog(RuleBase.class);

    protected int id;

    private boolean enabled = true;

    private boolean fromCaseSensitive;
    protected boolean initialised;
    protected boolean valid;

    protected String name;
    private String note;
    protected String from;
    protected String to;
    private boolean toEmpty;
    private boolean last = false;
    protected boolean encodeToUrl;
    private int conditionIdCounter;
    private int runIdCounter;

    private Pattern pattern;
    protected final List errors = new ArrayList(5);
    private final List conditions = new ArrayList(5);
    private final List runs = new ArrayList(2);
    protected final List setAttributes = new ArrayList(2);
    private boolean stopFilterChainOnMatch = false;
    protected static final String STOP_FILTER_CHANGE_MATCH_VALUE = "__STOP_FILTER_CHANGE_MATCH_VALUE__";

    private boolean toContainsVariable = false;
    private boolean toContainsBackReference = false;


    /**
     * Constructor.
     */
    public RuleBase() {
        super();
        // empty
    }

    /**
     * Will run the rule against the uri and perform action required will return false is not matched
     * otherwise true.
     *
     * @param url
     * @param hsRequest
     * @return String of the rewritten url or the same as the url passed in if no match was made
     */
    protected RuleExecutionOutput executeBase(final String url, final HttpServletRequest hsRequest,
                                              final HttpServletResponse hsResponse) throws IOException, ServletException {
        // make sure all the conditions match
        if (log.isDebugEnabled()) {
            String displayName = getDisplayName();
            log.debug(displayName + " run called with " + url);
        }
        if (!initialised) {
            log.debug("not initialised, skipping");
            return null;
        }
        if (!valid) {
            log.debug("not valid, skipping");
            return null;
        }
        if (!enabled) {
            log.debug("not enabled, skipping");
            return null;
        }

        Matcher matcher = pattern.matcher(url);
        boolean performToReplacement = false;
        if (toEmpty || stopFilterChainOnMatch) {
            // to is empty this must be an attempt to "set" and/or "run"
            if (!matcher.find()) {
                if (log.isTraceEnabled()) {
                    log.trace("no match on \"from\" (to is empty)");
                }
                return null;
            }
        } else {
            if (!matcher.find()) {
                if (log.isTraceEnabled()) {
                    log.trace("no match on \"from\" for " + from + " and " + url);
                }
                return null;
            }
            if (!toEmpty) {
                performToReplacement = true;
            }
        }
        if (log.isDebugEnabled()) {
            log.debug("matched \"from\"");
        }

        int conditionsSize = conditions.size();
        ConditionMatch lastConditionMatch = null;
        if (conditionsSize > 0) {
            boolean processNextOr = false;
            boolean currentResult = true;
            for (int i = 0; i < conditionsSize; i++) {
                final Condition condition = (Condition) conditions.get(i);
                ConditionMatch conditionMatch = condition.getConditionMatch(hsRequest);
                if (conditionMatch != null) {
                    lastConditionMatch = conditionMatch;
                }
                boolean conditionMatches = conditionMatch != null;
                if (processNextOr) {
                    currentResult |= conditionMatches;
                } else {
                    // must be and
                    currentResult &= conditionMatches;
                }
                processNextOr = condition.isProcessNextOr();
            }
            if (!currentResult) {
                log.debug("conditions do not match");
                return null;
            } else {
                log.debug("conditions match");
            }
        }
        String replacedTo = null;
        if (performToReplacement) {
            // replace back ref eg, %3 items
            // replace vars eg, %{txt}
            replacedTo = to;
            if (replacedTo != null) {
                // do variable replacement
                if (toContainsVariable) {
                    replacedTo = VariableReplacer.replace(replacedTo, hsRequest);
                }
                // perform backref replacement
                if (toContainsBackReference) {
                    replacedTo = BackReferenceReplacer.replace(lastConditionMatch, replacedTo);
                }
            }

            // get existing eg, $1 items
            replacedTo = matcher.replaceAll(replacedTo);
        }

        RuleExecutionOutput ruleExecutionOutput = new RuleExecutionOutput(replacedTo, true);

        // make sure the setAttributes are handled
        int setAttributesSize = setAttributes.size();
        if (setAttributesSize > 0) {
            log.trace("setting sttributes");
            for (int i = 0; i < setAttributesSize; i++) {
                SetAttribute setAttribute = (SetAttribute) setAttributes.get(i);
                setAttribute.execute(lastConditionMatch, matcher, hsRequest, hsResponse);
            }
        }

        // make sure the runs are handled
        int runsSize = runs.size();
        if (runsSize > 0) {
            log.trace("performing runs");
            for (int i = 0; i < runsSize; i++) {
                Run run = (Run) runs.get(i);
                run.execute(hsRequest, hsResponse);
            }
        }

        // check for empty to element (valid when only set's)
        if (toEmpty) {
            log.debug("'to' is empty, no rewrite, only 'set' and or 'run'");
            return null;
        }

        // when match found but need to stop filter chain
        if (stopFilterChainOnMatch) {
            ruleExecutionOutput.setStopFilterMatch(true);
            ruleExecutionOutput.setReplacedUrl(null);
        }
        // the rewritten URL is unchanged if there was no <to> element.
        return ruleExecutionOutput;
    }


    public String getDisplayName() {
        return null;
    }


    /**
     * Will initialise the rule.
     *
     * @return true on success
     */
    public boolean initialise(ServletContext context) {
        // check all the conditions
        initialised = true;
        boolean ok = true;
        for (int i = 0; i < conditions.size(); i++) {
            final Condition condition = (Condition) conditions.get(i);
            if (!condition.initialise()) {
                ok = false;
            }
        }
        for (int i = 0; i < runs.size(); i++) {
            final Run run = (Run) runs.get(i);
            if (!run.initialise(context)) {
                ok = false;
            }
        }
        for (int i = 0; i < setAttributes.size(); i++) {
            final SetAttribute setAttribute = (SetAttribute) setAttributes.get(i);
            if (!setAttribute.initialise()) {
                ok = false;
            }
        }
        // compile the from regexp
        if (StringUtils.isBlank(from)) {
            addError("from is not valid because it is blank");
        } else {
            try {
                if (fromCaseSensitive) {
                    pattern = Pattern.compile(from);
                } else {
                    pattern = Pattern.compile(from, Pattern.CASE_INSENSITIVE);
                }
            } catch (PatternSyntaxException e) {
                addError("from (" + from + ") is an invalid regular expression - " + e.getMessage());
            }
        }
        // set the substitution
        if (StringUtils.isBlank(to) && setAttributes.size() == 0 && runs.size() == 0) {
            addError("to is not valid because it is blank");
        } else if ("null".equalsIgnoreCase(to)) {
            stopFilterChainOnMatch = true;
        } else if (StringUtils.isBlank(to)) {
            toEmpty = true;
        } else if (!StringUtils.isBlank(to)) {
            // check for back refs
            if (BackReferenceReplacer.containsBackRef(to)) {
                toContainsBackReference = true;
            }
            // look for vars
            if (VariableReplacer.containsVariable(to)) {
                toContainsVariable = true;
            }
        }
        if (ok) {
            log.debug("loaded rule " + getFullDisplayName());
        } else {
            log.debug("failed to load rule");
        }
        if (errors.size() > 0) {
            ok = false;
        }
        valid = ok;
        return ok;
    }

    public boolean isToContainsBackReference() {
        return toContainsBackReference;
    }

    public boolean isToContainsVariable() {
        return toContainsVariable;
    }

    public String getFullDisplayName() {
        return null;
    }

    protected void addError(String s) {
        errors.add(s);
        log.error(s);
    }

    /**
     * Destroy the rule gracefully.
     */
    public void destroy() {
        for (int i = 0; i < runs.size(); i++) {
            final Run run = (Run) runs.get(i);
            run.destroy();
        }
    }

    /**
     * Will get the contents of the from element.
     *
     * @return the contents of the from element
     */
    public String getFrom() {
        return from;
    }

    protected boolean isReadyToProcess() {
        if (!valid) {
            log.debug("not valid, skipping");
            return false;
        }
        if (!initialised) {
            log.debug("not initialised, skipping");
            return false;
        }
        if (!enabled) {
            log.debug("not enabled, skipping");
            return false;
        }
        return true;
    }

    /**
     * Will set from, usually called by Digester.
     *
     * @param from the url to match from
     */
    public void setFrom(final String from) {
        this.from = from;
    }

    /**
     * Will set the to, usually called by Digester.
     *
     * @param to url for redirecting/passing through to
     */
    public void setTo(final String to) {
        if (!StringUtils.isBlank(to)) {
            this.to = to;
        }
    }

    /**
     * Set to type. note, it will default to false.
     *
     * @param lastStr true or false
     */
    public void setToLast(final String lastStr) {
        last = "true".equalsIgnoreCase(lastStr);
    }

    /**
     * Is this rule last?.
     *
     * @return boolean
     */
    public boolean isLast() {
        return last;
    }

    public boolean isStopFilterChainOnMatch() {
        return stopFilterChainOnMatch;
    }

    /**
     * Get to.
     *
     * @return String
     */
    public String getTo() {
        return to;
    }

    /**
     * Will get the rule's id.
     *
     * @return int
     */
    public int getId() {
        return id;
    }


    /**
     * Will get the list of errors.
     *
     * @return the list of errors
     */
    public List getErrors() {
        return errors;
    }

    /**
     * Will add the condition to the List.
     *
     * @param condition The Condition object to add
     */
    public void addCondition(final Condition condition) {
        conditions.add(condition);
        condition.setId(conditionIdCounter++);
    }

    /**
     * Will add the run to the List.
     *
     * @param run The Run object to add
     */
    public void addRun(final Run run) {
        runs.add(run);
        run.setId(runIdCounter++);
    }

    /**
     * Will add the SetAttribute to the List.
     *
     * @param setAttribute The SetAttribute object to add
     */
    public void addSetAttribute(final SetAttribute setAttribute) {
        setAttributes.add(setAttribute);
    }

    public List getSetAttributes() {
        return setAttributes;
    }

    /**
     * Will get the List of conditions.
     *
     * @return the List of Condition objects
     */
    public List getConditions() {
        return conditions;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getNote() {
        return note;
    }

    public void setNote(String note) {
        this.note = note;
    }

    public boolean isEnabled() {
        return enabled;
    }

    public void setEnabled(boolean enabled) {
        this.enabled = enabled;
    }

    public void setId(int id) {
        this.id = id;
    }

    public boolean isFromCaseSensitive() {
        return fromCaseSensitive;
    }

    public void setFromCaseSensitive(boolean fromCaseSensitive) {
        this.fromCaseSensitive = fromCaseSensitive;
    }

    public List getRuns() {
        return runs;
    }

    public boolean isValid() {
        return valid;
    }


}



⌨️ 快捷键说明

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