1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package org.eclipse.jetty.http.pathmap;
20
21 import java.util.regex.Matcher;
22 import java.util.regex.Pattern;
23
24 public class RegexPathSpec extends PathSpec
25 {
26 protected Pattern pattern;
27
28 protected RegexPathSpec()
29 {
30 super();
31 }
32
33 public RegexPathSpec(String regex)
34 {
35 super.pathSpec = regex;
36 boolean inGrouping = false;
37 this.pathDepth = 0;
38 this.specLength = pathSpec.length();
39
40 StringBuilder signature = new StringBuilder();
41 for (char c : pathSpec.toCharArray())
42 {
43 switch (c)
44 {
45 case '[':
46 inGrouping = true;
47 break;
48 case ']':
49 inGrouping = false;
50 signature.append('g');
51 break;
52 case '*':
53 signature.append('g');
54 break;
55 case '/':
56 if (!inGrouping)
57 {
58 this.pathDepth++;
59 }
60 break;
61 default:
62 if (!inGrouping)
63 {
64 if (Character.isLetterOrDigit(c))
65 {
66 signature.append('l');
67 }
68 }
69 break;
70 }
71 }
72 this.pattern = Pattern.compile(pathSpec);
73
74
75 String sig = signature.toString();
76
77 if (Pattern.matches("^l*$",sig))
78 {
79 this.group = PathSpecGroup.EXACT;
80 }
81 else if (Pattern.matches("^l*g+",sig))
82 {
83 this.group = PathSpecGroup.PREFIX_GLOB;
84 }
85 else if (Pattern.matches("^g+l+$",sig))
86 {
87 this.group = PathSpecGroup.SUFFIX_GLOB;
88 }
89 else
90 {
91 this.group = PathSpecGroup.MIDDLE_GLOB;
92 }
93 }
94
95 public Matcher getMatcher(String path)
96 {
97 return this.pattern.matcher(path);
98 }
99
100 @Override
101 public String getPathInfo(String path)
102 {
103
104 if (group == PathSpecGroup.PREFIX_GLOB)
105 {
106 Matcher matcher = getMatcher(path);
107 if (matcher.matches())
108 {
109 if (matcher.groupCount() >= 1)
110 {
111 String pathInfo = matcher.group(1);
112 if ("".equals(pathInfo))
113 {
114 return "/";
115 }
116 else
117 {
118 return pathInfo;
119 }
120 }
121 }
122 }
123 return null;
124 }
125
126 @Override
127 public String getPathMatch(String path)
128 {
129 Matcher matcher = getMatcher(path);
130 if (matcher.matches())
131 {
132 if (matcher.groupCount() >= 1)
133 {
134 int idx = matcher.start(1);
135 if (idx > 0)
136 {
137 if (path.charAt(idx - 1) == '/')
138 {
139 idx--;
140 }
141 return path.substring(0,idx);
142 }
143 }
144 return path;
145 }
146 return null;
147 }
148
149 public Pattern getPattern()
150 {
151 return this.pattern;
152 }
153
154 @Override
155 public String getRelativePath(String base, String path)
156 {
157
158 return null;
159 }
160
161 @Override
162 public boolean matches(final String path)
163 {
164 int idx = path.indexOf('?');
165 if (idx >= 0)
166 {
167
168 return getMatcher(path.substring(0,idx)).matches();
169 }
170 else
171 {
172
173 return getMatcher(path).matches();
174 }
175 }
176 }