start of new file
[IRC.git] / Robust / src / Benchmarks / Jhttpp2 / BR / WildcardDictionary.java
1 // WildcardDictionary - a dictionary with wildcard lookups
2 //
3 // Copyright (C) 1996 by Jef Poskanzer <jef@acme.com>.  All rights reserved.
4 //
5 // Redistribution and use in source and binary forms, with or without
6 // modification, are permitted provided that the following conditions
7 // are met:
8 // 1. Redistributions of source code must retain the above copyright
9 //    notice, this list of conditions and the following disclaimer.
10 // 2. Redistributions in binary form must reproduce the above copyright
11 //    notice, this list of conditions and the following disclaimer in the
12 //    documentation and/or other materials provided with the distribution.
13 //
14 // THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
15 // ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16 // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17 // ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
18 // FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19 // DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20 // OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21 // HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22 // LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23 // OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
24 // SUCH DAMAGE.
25 //
26 // Visit the ACME Labs Java page for up-to-date versions of this and other
27 // fine Java utilities: http://www.acme.com/java/
28
29 // package Acme;
30
31 import java.util.*;
32
33 /// A dictionary with wildcard lookups.
34 // <P>
35 // The keys in this dictionary are wildcard patterns.  When you do a get(),
36 // the string you pass in is matched against all the patterns, and the
37 // first match is returned.
38 // <P>
39 // The wildcard matcher is fairly simple, it implements * meaning any
40 // string, ? meaning any single character, and | separating multiple
41 // patterns.  All other characters must match literally.
42 // <P>
43 // <A HREF="/resources/classes/Acme/WildcardDictionary.java">Fetch the software.</A><BR>
44 // <A HREF="/resources/classes/Acme.tar.gz">Fetch the entire Acme package.</A>
45 // <P>
46 // @see Acme.Utils#match
47
48 public class WildcardDictionary extends Dictionary {
49
50     private Vector keys;
51     private Vector elements;
52
53     /// Constructor.
54     public WildcardDictionary() {
55         keys = new Vector();
56         elements = new Vector();
57     }
58
59     /// Returns the number of elements contained within the dictionary.
60     public int size() {
61         return elements.size();
62     }
63
64     /// Returns true if the dictionary contains no elements.
65     public boolean isEmpty() {
66         return size() == 0;
67     }
68
69     /// Returns an enumeration of the dictionary's keys.
70     public Enumeration keys() {
71         return keys.elements();
72     }
73
74     /// Returns an enumeration of the elements. Use the Enumeration methods
75     // on the returned object to fetch the elements sequentially.
76     public Enumeration elements() {
77         return elements.elements();
78     }
79
80     /// Gets the object associated with the specified key in the dictionary.
81     // The key is assumed to be a String, which is matched against
82     // the wildcard-pattern keys in the dictionary.
83     // @param key the string to match
84     // @returns the element for the key, or null if there's no match
85     // @see Acme.Utils#match
86     public synchronized Object get( Object key )
87         {
88         String sKey = (String) key;
89         for ( int i = 0; i < keys.size(); ++i )
90             {
91             String thisKey = (String) keys.elementAt( i );
92             if ( match( thisKey, sKey ) )
93                 return elements.elementAt( i );
94             }
95         return null;
96         }
97
98     /// Puts the specified element into the Dictionary, using the specified
99     // key.  The element may be retrieved by doing a get() with the same
100     // key.  The key and the element cannot be null.
101     // @param key the specified wildcard-pattern key
102     // @param value the specified element
103     // @return the old value of the key, or null if it did not have one.
104     // @exception NullPointerException If the value of the specified
105     // element is null.
106     public synchronized Object put( Object key, Object element )
107         {
108         int i = keys.indexOf( key );
109         if ( i != -1 )
110             {
111             Object oldElement = elements.elementAt( i );
112             elements.setElementAt( element, i );
113             return oldElement;
114             }
115         else
116             {
117             keys.addElement( key );
118             elements.addElement( element );
119             return null;
120             }
121         }
122
123     /// Removes the element corresponding to the key. Does nothing if the
124     // key is not present.
125     // @param key the key that needs to be removed
126     // @return the value of key, or null if the key was not found.
127     public synchronized Object remove( Object key )
128         {
129         int i = keys.indexOf( key );
130         if ( i != -1 )
131             {
132             Object oldElement = elements.elementAt( i );
133             keys.removeElementAt( i );
134             elements.removeElementAt( i );
135             return oldElement;
136             }
137         else
138             return null;
139         }
140
141        /** Checks whether a string matches a given wildcard pattern.
142         * Only does ? and *, and multiple patterns separated by |.
143         */
144     public static boolean match( String pattern, String string ) {
145         for ( int p = 0; true; ++p ) {
146             boolean cnt=true;
147             for ( int s = 0; cnt; ++p, ++s ) {
148                 boolean sEnd = ( s >= string.length() );
149                 boolean pEnd = ( p >= pattern.length() ||
150                                  pattern.charAt( p ) == '|' );
151                 if ( sEnd && pEnd )
152                     return true;
153                 if ( sEnd || pEnd )
154                     cnt=false;
155                 else if ( pattern.charAt( p ) != '?' ) {
156                     if ( pattern.charAt( p ) == '*' ) {
157                         int i;
158                         ++p;
159                         for ( i = string.length(); i >= s; --i )
160                             if ( match(
161                                        pattern.substring( p ),
162                                        string.substring( i ) ) )  /* not quite right */
163                                 return true;
164                         cnt=false;
165                     }
166                     if ( pattern.charAt( p ) != string.charAt( s ) )
167                         cnt=false;
168                 }
169             }
170             p = pattern.indexOf( '|', p );
171             if ( p == -1 )
172                 return false;
173         }
174     }
175     /**
176      * Deletes all elements and keys.
177      */
178     public void removeAllElements() {
179         elements.clear();
180         keys.clear();
181     }
182 }