Package org.slim3.controller.router

Source Code of org.slim3.controller.router.Routing$PlaceHolderFragment

/*
* Copyright 2004-2010 the Seasar Foundation and the Others.
*
* 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 org.slim3.controller.router;

import java.io.UnsupportedEncodingException;
import java.net.URL;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import javax.servlet.http.HttpServletRequest;

import org.slim3.util.WrapRuntimeException;

/**
* A class to route a path.
*
* @author higa
* @since 1.0.0
*
*/
public class Routing {

    /**
     * The "from" path.
     */
    protected String from;

    /**
     * {@link Pattern} for "from".
     */
    protected Pattern fromPattern;

    /**
     * The list of place holders.
     */
    protected List<String> placeHolderList = new ArrayList<String>();

    /**
     * The "to" path.
     */
    protected String to;

    /**
     * The list of {@link ToFragment}s.
     */
    protected List<ToFragment> toFragmentList = new ArrayList<ToFragment>();

    /**
     * Constructor.
     *
     * @param from
     *            the "from" path
     * @param to
     *            the "to" path
     * @throws NullPointerException
     *             if the from parameter is null or if the to parameter is null
     */
    public Routing(String from, String to) throws NullPointerException {
        setFrom(from);
        setTo(to);
    }

    /**
     * Sets the "from" path.
     *
     * @param from
     *            the "from" path
     * @throws NullPointerException
     *             if the from parameter is null
     */
    protected void setFrom(String from) throws NullPointerException {
        if (from == null) {
            throw new NullPointerException("The from parameter is null.");
        }
        this.from = from;
        StringBuilder sb = new StringBuilder(50);
        char[] chars = from.toCharArray();
        int length = chars.length;
        int index = -1;
        for (int i = 0; i < length; i++) {
            if (chars[i] == '{') {
                if (index < 0) {
                    index = i;
                } else {
                    throw new IllegalArgumentException("The from path("
                        + from
                        + ") is invalid, because \"}\" is missing.");
                }
            } else if (chars[i] == '}') {
                if (index >= 0) {
                    sb.append("([^/]+)");
                    placeHolderList.add(from.substring(index + 1, i));
                    index = -1;
                } else {
                    throw new IllegalArgumentException("The from path("
                        + from
                        + ") is invalid, because \"{\" is missing.");
                }
            } else if (index < 0) {
                sb.append(chars[i]);
            }
        }
        if (index >= 0) {
            throw new IllegalArgumentException("The from path("
                + from
                + ") is invalid, because \"}\" is missing.");
        }
        fromPattern = Pattern.compile("^" + sb.toString() + "$");
    }

    /**
     * Sets the "to" path.
     *
     * @param to
     *            the "to" path
     */
    protected void setTo(String to) {
        if (to == null) {
            throw new NullPointerException("The to parameter is null.");
        }
        this.to = to;
        StringBuilder sb = new StringBuilder(50);
        char[] chars = to.toCharArray();
        int length = chars.length;
        int index = -1;
        for (int i = 0; i < length; i++) {
            if (chars[i] == '{') {
                if (index < 0) {
                    String name = sb.toString();
                    toFragmentList.add(new StringFragment(name));
                    sb.setLength(0);
                    index = i;
                } else {
                    throw new IllegalArgumentException("The to path("
                        + to
                        + ") is invalid, because \"}\" is missing.");
                }
            } else if (chars[i] == '}') {
                if (index >= 0) {
                    String name = to.substring(index + 1, i);
                    if (placeHolderList.indexOf(name) < 0) {
                        throw new IllegalArgumentException("The to path("
                            + to
                            + ") is invalid, because the name("
                            + name
                            + ") is not found in from path("
                            + from
                            + ").");
                    }
                    toFragmentList.add(new PlaceHolderFragment(name));
                    index = -1;
                } else {
                    throw new IllegalArgumentException("The to path("
                        + to
                        + ") is invalid, because \"{\" is missing.");
                }
            } else if (index < 0) {
                sb.append(chars[i]);
            }
        }
        if (index >= 0) {
            throw new IllegalArgumentException("The to path("
                + to
                + ") is invalid, because \"}\" is missing.");
        }
    }

    /**
     * Routes the path.
     *
     * @param request
     *            the request
     * @param path
     *            the path
     * @return a routed path
     * @throws NullPointerException
     *             if the request parameter is null or if the path parameter is
     *             null
     */
    public String route(HttpServletRequest request, String path)
            throws NullPointerException {
        if (request == null) {
            throw new NullPointerException("The request parameter is null.");
        }
        if (path == null) {
            throw new NullPointerException("The path parameter is null.");
        }
        if (placeHolderList.size() == 0) {
            if (from.equalsIgnoreCase(path)) {
                return path;
            }
            return null;
        }
        Matcher matcher = fromPattern.matcher(path);
        if (!matcher.find()) {
            return null;
        }
        Map<String, String> placeHolderValues = new HashMap<String, String>();
        int index = 1;
        for (String name : placeHolderList) {
            placeHolderValues.put(name, matcher.group(index++));
        }
        StringBuilder to = new StringBuilder(50);
        for (ToFragment f : toFragmentList) {
            f.append(request, to, placeHolderValues);
        }
        return to.toString();
    }

    /**
     * A fragment of "to" path.
     *
     */
    protected static interface ToFragment {

        /**
         * Appends a part of "to" path.
         *
         * @param request
         *            the request
         * @param to
         *            the "to" path
         * @param placeHolderValues
         *            the map of place holders
         */
        void append(HttpServletRequest request, StringBuilder to,
                Map<String, String> placeHolderValues);
    }

    /**
     * {@link ToFragment} for String.
     *
     */
    protected static class StringFragment implements ToFragment {

        /**
         * The value.
         */
        protected String value;

        /**
         * Constructor.
         *
         * @param value
         *            the value
         * @throws NullPointerException
         *             if the value parameter is null
         */
        public StringFragment(String value) throws NullPointerException {
            if (value == null) {
                throw new NullPointerException("The value parameter is null");
            }
            this.value = value;
        }

        public void append(HttpServletRequest request, StringBuilder to,
                Map<String, String> placeHolderValues) {
            to.append(value);
        }
    }

    /**
     * {@link ToFragment} for String.
     *
     */
    protected static class PlaceHolderFragment implements ToFragment {

        /**
         * The name.
         */
        protected String name;

        /**
         * Constructor.
         *
         * @param name
         *            the value
         * @throws NullPointerException
         *             if the name parameter is null
         */
        public PlaceHolderFragment(String name) throws NullPointerException {
            if (name == null) {
                throw new NullPointerException("The name parameter is null");
            }
            this.name = name;
        }

        public void append(HttpServletRequest request, StringBuilder to,
                Map<String, String> placeHolderValues) {
            to.append(encode(placeHolderValues.get(name), request
                .getCharacterEncoding()));
        }

        /**
         * Encodes the path as a part of {@link URL}.
         *
         * @param path
         *            the path
         * @param encoding
         *            the encoding
         * @return an encoded path
         * @throws WrapRuntimeException
         *             if {@link UnsupportedEncodingException} occurred
         */
        protected String encode(String path, String encoding)
                throws WrapRuntimeException {
            if (path == null) {
                return "";
            }
            if (encoding == null) {
                encoding = "UTF-8";
            }
            try {
                return URLEncoder.encode(path, encoding);
            } catch (UnsupportedEncodingException e) {
                throw new WrapRuntimeException(e);
            }
        }
    }
}
TOP

Related Classes of org.slim3.controller.router.Routing$PlaceHolderFragment

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.