Java tutorial
/* * 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); } }