Package com.alibaba.citrus.service.requestcontext.rewrite.impl

Source Code of com.alibaba.citrus.service.requestcontext.rewrite.impl.RewriteSubstitution$Parameter

/*
* Copyright (c) 2002-2012 Alibaba Group Holding Limited.
* All rights reserved.
*
* 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.alibaba.citrus.service.requestcontext.rewrite.impl;

import static com.alibaba.citrus.service.requestcontext.rewrite.impl.RewriteUtil.*;
import static com.alibaba.citrus.util.ArrayUtil.*;
import static com.alibaba.citrus.util.Assert.*;
import static com.alibaba.citrus.util.BasicConstant.*;
import static com.alibaba.citrus.util.StringUtil.*;

import java.util.regex.MatchResult;
import javax.servlet.http.HttpServletResponse;

import com.alibaba.citrus.service.requestcontext.parser.ParameterParser;
import com.alibaba.citrus.util.ArrayUtil;
import com.alibaba.citrus.util.ObjectUtil;
import com.alibaba.citrus.util.StringEscapeUtil;
import com.alibaba.citrus.util.StringUtil;
import com.alibaba.citrus.util.ToStringBuilder;
import com.alibaba.citrus.util.ToStringBuilder.MapBuilder;
import com.alibaba.citrus.util.regex.MatchResultSubstitution;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.InitializingBean;

public class RewriteSubstitution implements InitializingBean {
    private static final Logger log = LoggerFactory.getLogger(RewriteSubstitution.class);
    private String            uri;
    private SubstitutionFlags flags;
    private Parameter[]       parameters;

    public void setUri(String uri) {
        this.uri = StringUtil.trimToNull(uri);
    }

    public SubstitutionFlags getFlags() {
        return flags;
    }

    public void setFlags(String[] flags) {
        this.flags = new SubstitutionFlags(flags);
    }

    public void setParameters(Parameter[] params) {
        this.parameters = params;
    }

    public void afterPropertiesSet() throws Exception {
        // flags
        if (flags == null) {
            flags = new SubstitutionFlags();
        }

        // params
        if (parameters == null) {
            parameters = new Parameter[0];
        }
    }

    public String substitute(String path, MatchResultSubstitution resultSubs) {
        if (uri == null) {
            if (log.isTraceEnabled()) {
                log.trace("No substitution applied to path: \"{}\"", StringEscapeUtil.escapeJava(path));
            }

            return path;
        }

        String subsPath = resultSubs.substitute(uri);

        if (!isFullURL(subsPath)) {
            MatchResult ruleMatchResult = resultSubs.getMatch();

            subsPath = path.substring(0, ruleMatchResult.start()) // before match
                       + subsPath // match
                       + path.substring(ruleMatchResult.end()); // after match
        }

        if (log.isDebugEnabled()) {
            log.debug("Rewriting \"{}\" to \"{}\"", StringEscapeUtil.escapeJava(path),
                      StringEscapeUtil.escapeJava(subsPath));
        }

        return subsPath;
    }

    public boolean substituteParameters(ParameterParser params, MatchResultSubstitution resultSubs) {
        boolean parameterSubstituted = false;

        if (!params.isEmpty()) {
            if (!flags.hasQSA()) {
                params.clear();
                parameterSubstituted = true;

                log.debug("All parameters have been cleared.  To prevent from clearing the parameters, "
                          + "just specify \"QSA\" or \"qsappend\"(query string append) flag to the substitution");
            }
        }

        for (Parameter param : parameters) {
            String key = param.getKey(resultSubs);
            String[] values = param.getValues(resultSubs);

            if (!StringUtil.isEmpty(key)) {
                if (ArrayUtil.isEmptyArray(values) || values.length == 1 && StringUtil.isEmpty(values[0])) {
                    params.remove(key);

                    if (log.isDebugEnabled()) {
                        log.debug("Removed parameter: \"{}\"", StringEscapeUtil.escapeJava(key));
                    }
                } else {
                    params.setStrings(key, values);

                    if (log.isDebugEnabled()) {
                        log.debug("Set parameter: \"{}\"=\"{}\"", StringEscapeUtil.escapeJava(key),
                                  ObjectUtil.toString(values));
                    }
                }

                parameterSubstituted = true;
            }
        }

        return parameterSubstituted;
    }

    @Override
    public String toString() {
        MapBuilder mb = new MapBuilder();

        if (uri != null) {
            mb.append("uri", uri);
        }

        if (!isEmptyArray(parameters)) {
            mb.append("params", parameters);
        }

        if (!flags.isEmpty()) {
            mb.append("flags", flags);
        }

        return new ToStringBuilder().append("Substitution").append(mb).toString();
    }

    /** 代表substitution的标志位。 */
    public static class SubstitutionFlags extends Flags {
        public SubstitutionFlags() {
            super();
        }

        public SubstitutionFlags(String... flags) {
            super(flags);
        }

        /** 标志位:保留所有GET、POST、UPLOAD所得的参数。 */
        public boolean hasQSA() {
            return hasFlags("QSA", "qsappend");
        }

        /** 标志位:如果一个规则被匹配,则继续处理其后继规则;如果该规则不被匹配,则其后继规则将被跳过。 */
        public boolean hasC() {
            return hasFlags("C", "chain");
        }

        /** 标志位:如果一个规则被匹配,并指明该参数,则立即结束。 */
        public boolean hasL() {
            return hasFlags("L", "last");
        }

        /**
         * 标志位:重定向,并取得redirect code。如果未指定重定向,则返回<code>0</code>
         * <p>
         * 默认为<code>302 moved temporarily</code>。如指定<code>R=301</code>则表示
         * <code>301 moved permanently</code>
         * </p>
         */
        public int getRedirectCode() {
            String value = getFlagValue("R", "redirect");
            int defaultStatusCode = HttpServletResponse.SC_MOVED_TEMPORARILY;

            if (value == null) {
                return 0;
            } else if (value.length() == 0) {
                return defaultStatusCode;
            } else {
                try {
                    return Integer.parseInt(value);
                } catch (NumberFormatException e) {
                    return defaultStatusCode;
                }
            }
        }
    }

    public static class Parameter implements InitializingBean {
        private String   key;
        private String[] values;

        public void setKey(String key) {
            this.key = trimToNull(key);
        }

        public void setValue(String value) {
            this.values = new String[] { value };
        }

        public void setValues(String[] values) {
            this.values = values;
        }

        public void afterPropertiesSet() throws Exception {
            assertNotNull(key, "missing key attribute for parameter");

            if (values == null) {
                values = EMPTY_STRING_ARRAY;
            }
        }

        public String getKey(MatchResultSubstitution resultSubs) {
            return resultSubs.substitute(key);
        }

        public String[] getValues(MatchResultSubstitution resultSubs) {
            String[] subsValues = new String[values.length];

            for (int i = 0; i < values.length; i++) {
                subsValues[i] = resultSubs.substitute(values[i]);
            }

            return subsValues;
        }

        @Override
        public String toString() {
            ToStringBuilder buf = new ToStringBuilder().append(key).append(" = ");

            if (values.length == 1) {
                buf.append(values[0]);
            } else {
                buf.appendArray(values);
            }

            return buf.toString();
        }
    }
}
TOP

Related Classes of com.alibaba.citrus.service.requestcontext.rewrite.impl.RewriteSubstitution$Parameter

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.