com.laxser.blitz.web.impl.mapping.MappingFactory.java Source code

Java tutorial

Introduction

Here is the source code for com.laxser.blitz.web.impl.mapping.MappingFactory.java

Source

/*
 * Copyright 2007-2010 the original author or authors.
 *
 * 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.laxser.blitz.web.impl.mapping;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

/**
 * 
 * @author  [qieqie.wang@gmail.com]
 * 
 */
public class MappingFactory {

    // ad${da}afd
    // $xxxx$yyyy
    // {}        
    public static List<Mapping> parse(String path) {

        //
        if (path.equals("/")) {
            path = "";
        } else if (path.length() > 0 && path.charAt(0) != '/') {
            path = "/" + path;
        }
        if (path.length() > 1 && path.endsWith("/")) {
            if (path.endsWith("//")) {
                throw new IllegalArgumentException(
                        "invalid path '" + path + "' : don't end with more than one '/'");
            }
            path = path.substring(0, path.length() - 1);
        }

        if (path.length() == 0) {
            return Collections.emptyList();
        }

        List<Mapping> mappings = new ArrayList<Mapping>(8);

        //

        char[] chars = new char[path.length()];
        path.getChars(0, path.length(), chars, 0);
        int paramBegin = -1;
        int paramNameEnd = -1;
        int constantBegin = -1;
        int bracketDeep = 0; // > 0 ?{}?
        boolean startsWithBracket = true;
        for (int i = 0; i < chars.length; i++) {
            switch (chars[i]) {
            case '$':
                if (i + 1 >= chars.length) {
                    throw new IllegalArgumentException(//
                            "invalid string '" + path + "', don't end with '$'");
                }
                // constains$name"constains"
                if (constantBegin >= 0) {
                    mappings.add(createConstantMapping(path, constantBegin, i));
                    constantBegin = -1;
                }
                // $name$xyz"$name"
                if (paramBegin >= 0) {
                    mappings.add(createRegexMapping(path, paramBegin, paramNameEnd, i));
                    paramBegin = -1;
                    paramNameEnd = -1;
                }
                if (chars[i + 1] != '{') {
                    paramBegin = i + 1;
                    bracketDeep = 1;
                    startsWithBracket = false;
                }
                break;
            case '{':
                if (bracketDeep++ > 0) { //++?
                    break;
                }
                if (paramBegin < 0) {
                    paramBegin = i + 1;
                }
                // $name{xyz}"$name"
                else {
                    mappings.add(createRegexMapping(path, paramBegin, paramNameEnd, i));
                    paramBegin = -1;
                    paramNameEnd = -1;
                }
                // constains{name}"constains"
                if (constantBegin >= 0) {
                    mappings.add(createConstantMapping(path, constantBegin, i));
                    constantBegin = -1;
                }
                break;
            case ':':
                if (paramBegin < 0) {
                    throw new IllegalArgumentException(//
                            "invalid string '" + path + "', wrong ':' at position " + i);
                } else if (paramNameEnd > 0) {
                    throw new IllegalArgumentException(//
                            "invalid string '" + path + "', duplicated ':' at position " + i);
                } else {
                    paramNameEnd = i;
                }
                break;
            case '}':
                if (--bracketDeep > 0) { // --?
                    break;
                }
                if (paramBegin < 0) {
                    throw new IllegalArgumentException(//
                            "invalid string '" + path + "', wrong '}' at position " + i);
                } else {
                    mappings.add(createRegexMapping(path, paramBegin, paramNameEnd, i));
                    paramBegin = -1;
                    paramNameEnd = -1;
                }
                break;
            case '/':
                if (paramBegin < 0) {
                    if (constantBegin >= 0) {
                        mappings.add(createConstantMapping(path, constantBegin, i));
                    }
                    constantBegin = i;
                    break;
                } else if (bracketDeep == 0 || (bracketDeep == 1 && !startsWithBracket)) {
                    mappings.add(createRegexMapping(path, paramBegin, paramNameEnd, i));
                    paramBegin = -1;
                    constantBegin = i;
                    paramNameEnd = -1;
                    bracketDeep = 0;
                    break;
                }

            default:
                if (constantBegin == -1 && paramBegin == -1) {
                    constantBegin = i;
                }
                break;
            }
        }
        if (constantBegin >= 0) {
            mappings.add(createConstantMapping(path, constantBegin, chars.length));
            constantBegin = -1;
        }
        if (paramBegin >= 0) {
            mappings.add(createRegexMapping(path, paramBegin, paramNameEnd, chars.length));
            paramBegin = -1;
            paramNameEnd = -1;
        }
        return mappings;
    }

    private static Mapping createConstantMapping(//
            String userDefinedMapping, int constantBegin, int i) {
        if (constantBegin == i) {
            throw new IllegalArgumentException(userDefinedMapping + "  constantBegin=" + constantBegin);
        }
        return new ConstantMapping(userDefinedMapping.substring(constantBegin, i));
    }

    private static Mapping createRegexMapping(//
            String userDefinedMapping, int paramBegin, int paramNameEnd, int i) {
        final String rawName = userDefinedMapping.substring(paramBegin, paramNameEnd >= 0 ? paramNameEnd : i);
        if (rawName.length() == 0) {
            throw new IllegalArgumentException(//
                    "invalid string '" + userDefinedMapping + "', wrong paramName at position " + paramBegin);
        }
        String name = rawName;
        if (org.apache.commons.lang.math.NumberUtils.isDigits(rawName)) {
            name = "$" + rawName;
        }
        String regex = "";
        if (paramNameEnd >= 0) {
            regex = userDefinedMapping.substring(paramNameEnd + 1, i);
        }
        return new RegexMapping("{" + rawName + "}", name, regex);
    }

}