Main Page | Packages | Class Hierarchy | Class List | Directories | File List | Class Members | Related Pages

common/org/openmobileis/common/util/WildcardDictionary.java

00001 // WildcardDictionary - a dictionary with wildcard lookups
00002 //
00003 // Copyright (C) 1996 by Jef Poskanzer <jef@acme.com>.  All rights reserved.
00004 //
00005 // Redistribution and use in source and binary forms, with or without
00006 // modification, are permitted provided that the following conditions
00007 // are met:
00008 // 1. Redistributions of source code must retain the above copyright
00009 //    notice, this list of conditions and the following disclaimer.
00010 // 2. Redistributions in binary form must reproduce the above copyright
00011 //    notice, this list of conditions and the following disclaimer in the
00012 //    documentation and/or other materials provided with the distribution.
00013 //
00014 // THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
00015 // ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00016 // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
00017 // ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
00018 // FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
00019 // DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
00020 // OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
00021 // HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
00022 // LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
00023 // OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
00024 // SUCH DAMAGE.
00025 //
00026 // Visit the ACME Labs Java page for up-to-date versions of this and other
00027 // fine Java utilities: http://www.acme.com/java/
00028 //
00029 // 2005 Modification Philippe Delrieu
00030 
00031 package org.openmobileis.common.util;
00032 
00033 import java.util.*;
00034 
00036 // <P>
00037 // The keys in this dictionary are wildcard patterns.  When you do a get(),
00038 // the string you pass in is matched against all the patterns, and the
00039 // first match is returned.
00040 // <P>
00041 // The wildcard matcher is fairly simple, it implements * meaning any
00042 // string, ? meaning any single character, and | separating multiple
00043 // patterns.  All other characters must match literally.
00044 // <P>
00045 // <A HREF="/resources/classes/Acme/WildcardDictionary.java">Fetch the software.</A><BR>
00046 // <A HREF="/resources/classes/Acme.tar.gz">Fetch the entire Acme package.</A>
00047 // <P>
00048 // @see Acme.Utils#match
00049 
00050 public class WildcardDictionary extends Dictionary
00051     {
00052 
00053     private Vector keys;
00054     private Vector elements;
00055 
00057     public WildcardDictionary()
00058         {
00059         keys = new Vector();
00060         elements = new Vector();
00061         }
00062 
00064     public int size()
00065         {
00066         return elements.size();
00067         }
00068 
00070     public boolean isEmpty()
00071         {
00072         return size() == 0;
00073         }
00074 
00076     public Enumeration keys()
00077         {
00078         return keys.elements();
00079         }
00080 
00082     // on the returned object to fetch the elements sequentially.
00083     public Enumeration elements()
00084         {
00085         return elements.elements();
00086         }
00087 
00089     // The key is assumed to be a String, which is matched against
00090     // the wildcard-pattern keys in the dictionary.
00091     // @param key the string to match
00092     // @returns the FIRST element which matches with the key, or null if there's no match
00093     // @see Acme.Utils#match
00094     public synchronized Object get( Object key )
00095         {
00096         String sKey = (String) key;
00097         for ( int i = 0; i < keys.size(); ++i )
00098             {
00099             String thisKey = (String) keys.elementAt( i );
00100             if ( match( thisKey, sKey ) )
00101                 return elements.elementAt( i );
00102             }
00103         return null;
00104         }
00105 
00107     // key.  The element may be retrieved by doing a get() with the same
00108     // key.  The key and the element cannot be null.
00109     // @param key the specified wildcard-pattern key
00110     // @param value the specified element
00111     // @return the old value of the key, or null if it did not have one.
00112     // @exception NullPointerException If the value of the specified
00113     // element is null.
00114     public synchronized Object put( Object key, Object element )
00115         {
00116         int i = keys.indexOf( key );
00117         if ( i != -1 )
00118             {
00119             Object oldElement = elements.elementAt( i );
00120             elements.setElementAt( element, i );
00121             return oldElement;
00122             }
00123         else
00124             {
00125             keys.addElement( key );
00126             elements.addElement( element );
00127             return null;
00128             }
00129         }
00130 
00132     // key is not present.
00133     // @param key the key that needs to be removed
00134     // @return the value of key, or null if the key was not found.
00135     public synchronized Object remove( Object key )
00136         {
00137         int i = keys.indexOf( key );
00138         if ( i != -1 )
00139             {
00140             Object oldElement = elements.elementAt( i );
00141             keys.removeElementAt( i );
00142             elements.removeElementAt( i );
00143             return oldElement;
00144             }
00145         else
00146             return null;
00147         }
00148 
00150     // Only does ? and *, and multiple patterns separated by |.
00151 public static boolean match( String pattern, String string ){
00152         for ( int p = 0; ; ++p )
00153             {
00154             for ( int s = 0; ; ++p, ++s )
00155                 {
00156                 boolean sEnd = ( s >= string.length() );
00157                 boolean pEnd = ( p >= pattern.length() ||
00158                                  pattern.charAt( p ) == '|' );
00159                 if ( sEnd && pEnd )
00160                     return true;
00161                 if ( sEnd || pEnd )
00162                     break;
00163                 if ( pattern.charAt( p ) == '?' )
00164                     continue;
00165                 if ( pattern.charAt( p ) == '*' )
00166                     {
00167                     int i;
00168                     ++p;
00169                     for ( i = string.length(); i >= s; --i )
00170                         if ( match(
00171                                pattern.substring( p ),
00172                                string.substring( i ) ) )  /* not quite right */
00173                             return true;
00174                     break;
00175                     }
00176                 if ( pattern.charAt( p ) != string.charAt( s ) )
00177                     break;
00178                 }
00179             p = pattern.indexOf( '|', p );
00180             if ( p == -1 )
00181                 return false;
00182             }
00183         }
00184 
00185  // test program
00186   public static void main( String[] args ) {
00187    try {
00188     java.io.File logfile = new java.io.File("\\Temp\\webserver.txt");
00189     java.io.FileOutputStream fileStream = new java.io.FileOutputStream(logfile);
00190     java.io.PrintStream outStream = new java.io.PrintStream(fileStream, true);
00191     System.setOut(outStream);
00192     System.setErr(outStream);
00193           WildcardDictionary dico = new WildcardDictionary();
00194     //The order of the dictionary building is important (the fist matching is the right one)
00195     dico.put("/root/myPath?", "Path");
00196     dico.put("/root/servlet/servlet1", "Servlet1");
00197     dico.put("/root/servlet*", "Servlet");
00198     System.out.println("Path : " + dico.get("/root/myPath1"));
00199     System.out.println("Servlet2 : " + dico.get("/root/servlet/servlet2"));
00200     System.out.println("Servlet1 : " + dico.get("/root/servlet/servlet1"));
00201     fileStream.close();
00202      } catch (Exception ex) {ex.printStackTrace();}
00203    }
00204   }

Generated on Wed Dec 14 21:05:36 2005 for OpenMobileIS by  doxygen 1.4.4