001/* 002 * Copyright (c) 2006-2011 Nuxeo SA (http://nuxeo.com/) and others. 003 * 004 * All rights reserved. This program and the accompanying materials 005 * are made available under the terms of the Eclipse Public License v1.0 006 * which accompanies this distribution, and is available at 007 * http://www.eclipse.org/legal/epl-v10.html 008 * 009 * Contributors: 010 * bstefanescu 011 */ 012package org.nuxeo.ecm.webengine.jaxrs.servlet.mapping; 013 014/** 015 * @author <a href="mailto:bs@nuxeo.com">Bogdan Stefanescu</a> 016 */ 017public class PathParser { 018 019 protected String[] array; 020 021 protected int count; 022 023 protected char[] buf; 024 025 protected int bufCount; 026 027 public PathParser() { 028 reset(); 029 } 030 031 public void reset() { 032 array = new String[16]; 033 buf = new char[16]; 034 count = 0; 035 bufCount = 0; 036 } 037 038 public Path parse(String path) { 039 return parse(path, -1); 040 } 041 042 public Path parse(String path, int userBits) { 043 char[] chars = path.toCharArray(); 044 if (chars.length == 0) { 045 return Path.EMPTY; 046 } 047 if (chars.length == 1 && chars[0] == '/') { 048 return Path.ROOT; 049 } 050 051 int i = 0; 052 int len = chars.length; 053 int bits = 0; 054 if (chars[chars.length - 1] == '/') { 055 bits |= Path.HAS_TRAILING_SLASH; 056 len--; 057 } 058 if (chars[0] == '/') { 059 bits |= Path.HAS_LEADING_SLASH; 060 i++; 061 } 062 063 for (; i < len; i++) { 064 char c = chars[i]; 065 if (c == '/') { 066 if (hasSegment()) { 067 addSegment(currentSegment()); 068 resetBuf(); 069 } // else -> duplicate / - it will be ignored 070 } else { 071 append(c); 072 } 073 } 074 if (hasSegment()) { 075 addSegment(currentSegment()); 076 } 077 078 return new Path(getSegments(), userBits == -1 ? bits : userBits); 079 } 080 081 public void back() { 082 if (count == 0) { 083 add(".."); 084 } else { 085 count--; 086 } 087 } 088 089 public void addSegment(String segment) { 090 if ("..".equals(segment)) { 091 back(); 092 } else if (!".".equals(segment)) { 093 add(segment); 094 } 095 } 096 097 public String[] getSegments() { 098 String[] result = new String[count]; 099 System.arraycopy(array, 0, result, 0, count); 100 return result; 101 } 102 103 private final void add(String segment) { 104 if (count + 1 == array.length) { 105 String[] result = new String[count + 16]; 106 System.arraycopy(array, 0, result, 0, count); 107 array = result; 108 } 109 array[count++] = segment; 110 } 111 112 private final void append(char c) { 113 if (bufCount + 1 == buf.length) { 114 char[] result = new char[bufCount + 16]; 115 System.arraycopy(buf, 0, result, 0, bufCount); 116 buf = result; 117 } 118 buf[bufCount++] = c; 119 } 120 121 private final String currentSegment() { 122 return new String(buf, 0, bufCount); 123 } 124 125 private final boolean hasSegment() { 126 return bufCount > 0; 127 } 128 129 private final void resetBuf() { 130 bufCount = 0; 131 } 132 133}