KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > geronimo > security > util > URLPattern


1 /**
2  * Licensed to the Apache Software Foundation (ASF) under one or more
3  * contributor license agreements. See the NOTICE file distributed with
4  * this work for additional information regarding copyright ownership.
5  * The ASF licenses this file to You under the Apache License, Version 2.0
6  * (the "License"); you may not use this file except in compliance with
7  * the License. You may obtain a copy of the License at
8  *
9  * http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  */

17
18 package org.apache.geronimo.security.util;
19
20 import java.util.Collection JavaDoc;
21 import java.util.HashSet JavaDoc;
22 import java.util.Iterator JavaDoc;
23 import java.util.Set JavaDoc;
24
25
26 /**
27  * Utility class for <code>ModuleConfiguration</code>. This class is used to generate qualified patterns, HTTP
28  * method sets, complements of HTTP method sets, and HTTP method sets w/ transport restrictions for URL patterns that
29  * are found in the web deployment descriptor.
30  * @version $Rev: 476049 $ $Date: 2006-11-16 23:35:17 -0500 (Thu, 16 Nov 2006) $
31  */

32 public class URLPattern {
33     private final static String JavaDoc[] HTTP_METHODS = {"GET", "POST", "PUT", "DELETE", "HEAD", "OPTIONS", "TRACE"};
34     private final static int[] HTTP_MASKS = {0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40};
35     private final static int NA = 0x00;
36     private final static int INTEGRAL = 0x01;
37     private final static int CONFIDENTIAL = 0x02;
38
39     private final URLPatternCheck type;
40     private final String JavaDoc pattern;
41     private int httpMethodsMask;
42     private int transport;
43     private final HashSet JavaDoc roles = new HashSet JavaDoc();
44
45     /**
46      * Construct an instance of the utility class for <code>WebModuleConfiguration</code>.
47      * @param pat the URL pattern that this instance is to collect information on
48      * @see "JSR 115, section 3.1.3" Translating Servlet Deployment Descriptors
49      */

50     public URLPattern(String JavaDoc pat) {
51         if (pat == null) throw new java.lang.IllegalArgumentException JavaDoc("URL pattern cannot be null");
52         if (pat.length() == 0) throw new java.lang.IllegalArgumentException JavaDoc("URL pattern cannot be empty");
53
54         if (pat.equals("/") || pat.equals("/*")) {
55             type = DEFAULT;
56         } else if (pat.charAt(0) == '/' && pat.endsWith("/*")) {
57             type = PATH_PREFIX;
58         } else if (pat.charAt(0) == '*') {
59             type = EXTENSION;
60         } else {
61             type = EXACT;
62         }
63         pattern = pat;
64     }
65
66     /**
67      * Get a qualifed URL pattern relative to a particular set of URL patterns. This algorithm is described in
68      * JSR 115, section 3.1.3.1 "Qualified URL Pattern Names".
69      * @param patterns the set of possible URL patterns that could be used to qualify this pattern
70      * @return a qualifed URL pattern
71      */

72     public String JavaDoc getQualifiedPattern(Set JavaDoc patterns) {
73         if (type == EXACT) {
74             return pattern;
75         } else {
76             HashSet JavaDoc bucket = new HashSet JavaDoc();
77             StringBuffer JavaDoc result = new StringBuffer JavaDoc(pattern);
78             Iterator JavaDoc iter = patterns.iterator();
79
80             // Collect a set of qualifying patterns, depending on the type of this pattern.
81
while (iter.hasNext()) {
82                 URLPattern p = (URLPattern) iter.next();
83                 if (type.check(this, p)) {
84                     bucket.add(p.pattern);
85                 }
86             }
87
88             // append the set of qualifying patterns
89
iter = bucket.iterator();
90             while (iter.hasNext()) {
91                 result.append(':');
92                 result.append((String JavaDoc) iter.next());
93             }
94             return result.toString();
95         }
96     }
97
98     /**
99      * Add a method to the union of HTTP methods associated with this URL pattern. An empty string is short hand for
100      * the set of all HTTP methods.
101      * @param method the HTTP method to be added to the set.
102      */

103     public void addMethod(String JavaDoc method) {
104         if (method.length() == 0) {
105             httpMethodsMask = 0xFF;
106             return;
107         }
108
109         boolean found = false;
110         for (int j = 0; j < HTTP_METHODS.length; j++) {
111             if (method.equals(HTTP_METHODS[j])) {
112                 httpMethodsMask |= HTTP_MASKS[j];
113                 found = true;
114
115                 break;
116             }
117         }
118         if (!found) throw new IllegalArgumentException JavaDoc("Invalid HTTP method");
119     }
120
121     /**
122      * Return the set of HTTP methods that have been associated with this URL pattern.
123      * @return a set of HTTP methods
124      */

125     public String JavaDoc getMethods() {
126         StringBuffer JavaDoc buffer = null;
127
128         for (int i = 0; i < HTTP_MASKS.length; i++) {
129             if ((httpMethodsMask & HTTP_MASKS[i]) > 0) {
130                 if (buffer == null) {
131                     buffer = new StringBuffer JavaDoc();
132                 } else {
133                     buffer.append(",");
134                 }
135                 buffer.append(HTTP_METHODS[i]);
136             }
137         }
138
139         return (buffer == null ? "" : buffer.toString());
140     }
141
142     public String JavaDoc getComplementedMethods() {
143         StringBuffer JavaDoc buffer = null;
144
145         for (int i = 0; i < HTTP_MASKS.length; i++) {
146             if ((httpMethodsMask & HTTP_MASKS[i]) == 0) {
147                 if (buffer == null) {
148                     buffer = new StringBuffer JavaDoc();
149                 } else {
150                     buffer.append(",");
151                 }
152                 buffer.append(HTTP_METHODS[i]);
153             }
154         }
155
156         return (buffer == null ? "" : buffer.toString());
157     }
158
159     public String JavaDoc getMethodsWithTransport() {
160         StringBuffer JavaDoc buffer = new StringBuffer JavaDoc(getMethods());
161
162
163         if (transport != NA) {
164             buffer.append(":");
165
166             if (transport != 0x03) {
167                 if (transport == INTEGRAL) {
168                     buffer.append("INTEGRAL");
169                 } else {
170                     buffer.append("CONFIDENTIAL");
171                 }
172             }
173         }
174
175         return buffer.toString();
176     }
177
178     public void setTransport(String JavaDoc trans) {
179         switch (transport) {
180             case NA:
181                 {
182                     if ("INTEGRAL".equals(trans)) {
183                         transport = INTEGRAL;
184                     } else if ("CONFIDENTIAL".equals(trans)) {
185                         transport = CONFIDENTIAL;
186                     }
187                     break;
188                 }
189
190             case INTEGRAL:
191                 {
192                     if ("CONFIDENTIAL".equals(trans)) {
193                         transport = CONFIDENTIAL;
194                     }
195                     break;
196                 }
197         }
198     }
199
200     public void addRole(String JavaDoc role) {
201         roles.add(role);
202     }
203
204     public void addAllRoles(Collection JavaDoc collection) {
205         roles.addAll(collection);
206     }
207
208     public HashSet JavaDoc getRoles() {
209         return roles;
210     }
211
212     public boolean equals(Object JavaDoc obj) {
213         if (!(obj instanceof URLPattern)) return false;
214
215         URLPattern test = (URLPattern) obj;
216
217         return pattern.equals(test.pattern);
218     }
219
220     public int hashCode() {
221         return pattern.hashCode();
222     }
223
224     boolean matches(URLPattern p) {
225         String JavaDoc test = p.pattern;
226
227         // their pattern values are String equivalent
228
if (pattern.equals(test)) return true;
229
230         return type.matches(pattern, test);
231     }
232
233     private final static URLPatternCheck EXACT = new URLPatternCheck() {
234         public boolean check(URLPattern base, URLPattern test) {
235             return matches(base.pattern, test.pattern);
236         }
237
238         public boolean matches(String JavaDoc base, String JavaDoc test) {
239             return base.equals(test);
240         }
241     };
242
243     private final static URLPatternCheck PATH_PREFIX = new URLPatternCheck() {
244         public boolean check(URLPattern base, URLPattern test) {
245             return ((test.type == PATH_PREFIX || test.type == EXACT)
246                     && base.matches(test)
247                     && !base.equals(test));
248         }
249
250         /**
251          * This pattern is a path-prefix pattern (that is, it starts with "/" and ends with "/*") and the argument
252          * pattern starts with the substring of this pattern, minus its last 2 characters, and the next character of
253          * the argument pattern, if there is one, is "/"
254          * @param base the base pattern
255          * @param test the pattern to be tested
256          * @return <code>true</code> if <code>test</code> is matched by <code>base</code>
257          */

258         public boolean matches(String JavaDoc base, String JavaDoc test) {
259             int length = base.length() - 2;
260             if (length > test.length()) return false;
261
262             for (int i = 0; i < length; i++) {
263                 if (base.charAt(i) != test.charAt(i)) return false;
264             }
265
266             if (test.length() == length)
267                 return true;
268             else if (test.charAt(length) != '/') return false;
269
270             return true;
271         }
272     };
273
274     private final static URLPatternCheck EXTENSION = new URLPatternCheck() {
275         public boolean check(URLPattern base, URLPattern test) {
276             if (test.type == PATH_PREFIX) return true;
277
278             if (test.type == EXACT) return matches(base.pattern, test.pattern);
279
280             return false;
281         }
282
283         /**
284          * This pattern is an extension pattern (that is, it startswith "*.") and the argument pattern ends with
285          * this pattern.
286          * @param base the base pattern
287          * @param test the pattern to be tested
288          * @return <code>true</code> if <code>test</code> is matched by <code>base</code>
289          */

290         public boolean matches(String JavaDoc base, String JavaDoc test) {
291             return test.endsWith(base.substring(1));
292         }
293     };
294
295     private final static URLPatternCheck DEFAULT = new URLPatternCheck() {
296         public boolean check(URLPattern base, URLPattern test) {
297             return base.matches(test) && !base.equals(test);
298         }
299
300         /**
301          * This pattern is the path-prefix pattern "/*" or the reference pattern is the special default pattern,
302          * "/", which matches all argument patterns.
303          * @param base the base pattern
304          * @param test the pattern to be tested
305          * @return <code>true</code> if <code>test</code> is matched by <code>base</code>
306          * @see "JSR 115"
307          */

308         public boolean matches(String JavaDoc base, String JavaDoc test) {
309             return true;
310         }
311     };
312 }
313
Popular Tags