001: /**
002: * JOnAS: Java(TM) Open Application Server
003: * Copyright (C) 2004 Bull S.A.
004: * Contact: jonas-team@objectweb.org
005: *
006: * This library is free software; you can redistribute it and/or
007: * modify it under the terms of the GNU Lesser General Public
008: * License as published by the Free Software Foundation; either
009: * version 2.1 of the License, or any later version.
010: *
011: * This library is distributed in the hope that it will be useful,
012: * but WITHOUT ANY WARRANTY; without even the implied warranty of
013: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
014: * Lesser General Public License for more details.
015: *
016: * You should have received a copy of the GNU Lesser General Public
017: * License along with this library; if not, write to the Free Software
018: * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
019: * USA
020: *
021: * Initial developer: Florent BENOIT
022: * --------------------------------------------------------------------------
023: * $Id: Pattern.java 4854 2004-06-01 11:24:01Z benoitf $
024: * --------------------------------------------------------------------------
025: */package org.objectweb.jonas_web.deployment.api;
026:
027: /**
028: * Defines a Pattern object for JACC
029: * Allow to check if this pattern is a path prefix pattern, and can return the
030: * type of the pattern
031: * Implements Comparable interface to sort items
032: * @see JACC 3.1.3.1 and 3.1.3.3 for more details
033: * @author Florent Benoit
034: */
035: public class Pattern implements Comparable {
036:
037: /**
038: * Exact pattern
039: * @see JACC 3.1.3.3 table 3.2
040: */
041: private static final int EXACT = 0;
042:
043: /**
044: * Path prefix pattern
045: * @see JACC 3.1.3.3 table 3.2
046: */
047: private static final int PATH_PREFIX = 1;
048:
049: /**
050: * Extension pattern
051: * @see JACC 3.1.3.3 table 3.2
052: */
053: private static final int EXTENSION = 2;
054:
055: /**
056: * Default pattern
057: * @see JACC 3.1.3.3 table 3.2
058: */
059: private static final int DEFAULT = 3;
060:
061: /**
062: * String representation of the pattern
063: */
064: private String pattern = null;
065:
066: /**
067: * Type of the pattern
068: */
069: private int type;
070:
071: /**
072: * Constructor
073: * @param pattern string representation of the pattern
074: */
075: public Pattern(String pattern) {
076: this .pattern = pattern;
077: defineTypePattern();
078: }
079:
080: /**
081: * Defines the type of the pattern
082: * Avoid to compute the type every time it is asked
083: */
084: private void defineTypePattern() {
085: if (pattern.startsWith("/") && pattern.endsWith("/*")) {
086: // Path prefix
087: type = PATH_PREFIX;
088: } else if (pattern.startsWith("*.")) {
089: // Extension
090: type = EXTENSION;
091: } else if (pattern.equals("/")) {
092: // Default
093: type = DEFAULT;
094: } else {
095: // else it is EXACT
096: type = EXACT;
097: }
098: }
099:
100: /**
101: * Test if this pattern is a path-prefix pattern or not
102: * (Starts with "/" and ends with "/*"
103: * @return true if this pattern is a path-prefix
104: */
105: public boolean isPathPrefix() {
106: return (type == PATH_PREFIX);
107: }
108:
109: /**
110: * Test if this pattern is an extension pattern
111: * (Starts with ".*")
112: * @return true if this pattern is an extension pattern
113: */
114: public boolean isExtensionPattern() {
115: return (type == EXTENSION);
116: }
117:
118: /**
119: * Test if this pattern is the default pattern
120: * (equals to "/")
121: * @return true if this pattern is the default pattern
122: */
123: public boolean isDefaultPattern() {
124: return (type == DEFAULT);
125: }
126:
127: /**
128: * Test if this pattern is an exact pattern
129: * (not in the other case)
130: * @return true if this pattern is an exact pattern
131: */
132: public boolean isExactPattern() {
133: return (type == EXACT);
134: }
135:
136: /**
137: * Test if the pattern starts with the given pattern
138: * It's the inverse of this definition :
139: * The other pattern starts with the substring of this pattern,
140: * minus its last 2 characters, and the next character
141: * of the other pattern, if there is one, is "/"
142: * @param substring string to test
143: * @return true if the pattern starts with the given pattern
144: */
145: public boolean isSubstringPattern(String substring) {
146: int size = substring.length();
147: if (size == 0) {
148: return true;
149: } else {
150: // true if next character = '/' if any or true if equals (no last char)
151: return (pattern.startsWith(substring) && (pattern.length() == size || pattern
152: .substring(size).charAt(0) == '/'));
153: }
154: }
155:
156: /**
157: * Test if this pattern matches another pattern
158: * This URL pattern matches another pattern if they
159: * are related, by case sensitive comparison, as follows:
160: * - their pattern values are String equivalent, or
161: * - this pattern is the path-prefix pattern "/*", or
162: * - this pattern is a path-prefix pattern (that is, it
163: * starts with "/" and ends with "/*") and the other
164: * pattern starts with the substring of this pattern,
165: * minus its last 2 characters, and the next character
166: * of the other pattern, if there is one, is "/", or
167: * - this pattern is an extension pattern (that is, it
168: * starts with "*.") and the other pattern ends with this
169: * pattern, or this pattern is the special default pattern,
170: * "/", which matches all other patterns.
171: * @param otherPattern pattern to check for matching
172: * @see JACC 3.1.3.3 for the definition of these rules
173: * @return true if the patterns match
174: */
175: public boolean isMatching(Pattern otherPattern) {
176: if (pattern.equals(otherPattern)) {
177: // case 1
178: return true;
179: } else if ((pattern.length() == 2) && isPathPrefix()) {
180: // case 2
181: return true;
182: } else if (isPathPrefix()
183: && otherPattern.isSubstringPattern(pattern.substring(0,
184: pattern.length() - 2))) {
185: // case 3
186: return true;
187: } else if (isExtensionPattern()
188: && otherPattern.getValue().endsWith(
189: pattern.substring(1))) {
190: // case 4
191: return true;
192: } else {
193: // case 5 or no match
194: return isDefaultPattern();
195: }
196: }
197:
198: /**
199: * Gets the string representation of this object
200: * @return the string representation of this pattern
201: */
202: public String getValue() {
203: return pattern;
204: }
205:
206: /**
207: * String representation
208: * @return the string representation of this pattern
209: */
210: public String toString() {
211: return getValue();
212: }
213:
214: /**
215: * Tests if this object is equal to another object
216: * @param o given object to test
217: * @return true if the other object is a pattern object with the same value
218: */
219: public boolean equals(Object o) {
220: if (!(o instanceof Pattern)) {
221: return false;
222: }
223: return pattern.equals(((Pattern) o).getValue());
224: }
225:
226: /**
227: * Gets the hashcode of this object
228: * @return hashcode of this object
229: */
230: public int hashCode() {
231: return pattern.hashCode();
232: }
233:
234: /**
235: * Compares this object with the specified object for order.
236: * @param o object to compare
237: * @return a negative integer, zero, or a positive integer
238: * as this object is less than, equal to, or greater than
239: * the specified object.
240: */
241: public int compareTo(Object o) {
242: if (!(o instanceof Pattern)) {
243: return -1;
244: }
245: return pattern.compareTo(((Pattern) o).getValue());
246: }
247:
248: }
|