001/* 002 * (C) Copyright 2006-2011 Nuxeo SA (http://nuxeo.com/) and others. 003 * 004 * Licensed under the Apache License, Version 2.0 (the "License"); 005 * you may not use this file except in compliance with the License. 006 * You may obtain a copy of the License at 007 * 008 * http://www.apache.org/licenses/LICENSE-2.0 009 * 010 * Unless required by applicable law or agreed to in writing, software 011 * distributed under the License is distributed on an "AS IS" BASIS, 012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 013 * See the License for the specific language governing permissions and 014 * limitations under the License. 015 * 016 * Contributors: 017 * bstefanescu 018 */ 019package org.nuxeo.ecm.webengine.jaxrs.servlet.mapping; 020 021/** 022 * @author <a href="mailto:bs@nuxeo.com">Bogdan Stefanescu</a> 023 */ 024public class PathParser { 025 026 protected String[] array; 027 028 protected int count; 029 030 protected char[] buf; 031 032 protected int bufCount; 033 034 public PathParser() { 035 reset(); 036 } 037 038 public void reset() { 039 array = new String[16]; 040 buf = new char[16]; 041 count = 0; 042 bufCount = 0; 043 } 044 045 public Path parse(String path) { 046 return parse(path, -1); 047 } 048 049 public Path parse(String path, int userBits) { 050 char[] chars = path.toCharArray(); 051 if (chars.length == 0) { 052 return Path.EMPTY; 053 } 054 if (chars.length == 1 && chars[0] == '/') { 055 return Path.ROOT; 056 } 057 058 int i = 0; 059 int len = chars.length; 060 int bits = 0; 061 if (chars[chars.length - 1] == '/') { 062 bits |= Path.HAS_TRAILING_SLASH; 063 len--; 064 } 065 if (chars[0] == '/') { 066 bits |= Path.HAS_LEADING_SLASH; 067 i++; 068 } 069 070 for (; i < len; i++) { 071 char c = chars[i]; 072 if (c == '/') { 073 if (hasSegment()) { 074 addSegment(currentSegment()); 075 resetBuf(); 076 } // else -> duplicate / - it will be ignored 077 } else { 078 append(c); 079 } 080 } 081 if (hasSegment()) { 082 addSegment(currentSegment()); 083 } 084 085 return new Path(getSegments(), userBits == -1 ? bits : userBits); 086 } 087 088 public void back() { 089 if (count == 0) { 090 add(".."); 091 } else { 092 count--; 093 } 094 } 095 096 public void addSegment(String segment) { 097 if ("..".equals(segment)) { 098 back(); 099 } else if (!".".equals(segment)) { 100 add(segment); 101 } 102 } 103 104 public String[] getSegments() { 105 String[] result = new String[count]; 106 System.arraycopy(array, 0, result, 0, count); 107 return result; 108 } 109 110 private final void add(String segment) { 111 if (count + 1 == array.length) { 112 String[] result = new String[count + 16]; 113 System.arraycopy(array, 0, result, 0, count); 114 array = result; 115 } 116 array[count++] = segment; 117 } 118 119 private final void append(char c) { 120 if (bufCount + 1 == buf.length) { 121 char[] result = new char[bufCount + 16]; 122 System.arraycopy(buf, 0, result, 0, bufCount); 123 buf = result; 124 } 125 buf[bufCount++] = c; 126 } 127 128 private final String currentSegment() { 129 return new String(buf, 0, bufCount); 130 } 131 132 private final boolean hasSegment() { 133 return bufCount > 0; 134 } 135 136 private final void resetBuf() { 137 bufCount = 0; 138 } 139 140}