View Javadoc

1   //
2   //  ========================================================================
3   //  Copyright (c) 1995-2013 Mort Bay Consulting Pty. Ltd.
4   //  ------------------------------------------------------------------------
5   //  All rights reserved. This program and the accompanying materials
6   //  are made available under the terms of the Eclipse Public License v1.0
7   //  and Apache License v2.0 which accompanies this distribution.
8   //
9   //      The Eclipse Public License is available at
10  //      http://www.eclipse.org/legal/epl-v10.html
11  //
12  //      The Apache License v2.0 is available at
13  //      http://www.opensource.org/licenses/apache2.0.php
14  //
15  //  You may elect to redistribute this code under either of these licenses.
16  //  ========================================================================
17  //
18  
19  package org.eclipse.jetty.util;
20  
21  import java.nio.ByteBuffer;
22  import java.util.AbstractMap;
23  import java.util.Collections;
24  import java.util.Comparator;
25  import java.util.Map;
26  import java.util.Set;
27  import java.util.TreeMap;
28  
29  /* ------------------------------------------------------------ */
30  /** Map implementation Optimized for Strings keys..
31   * This String Map has been optimized for mapping small sets of
32   * Strings where the most frequently accessed Strings have been put to
33   * the map first.
34   *
35   * It also has the benefit that it can look up entries by substring or
36   * sections of char and byte arrays.  This can prevent many String
37   * objects from being created just to look up in the map.
38   *
39   * This map is NOT synchronized.
40   * @deprecated Use {@link Trie}
41   */
42  public class StringMap<O> extends AbstractMap<String,O>
43  {
44      private final TreeMap<Object, O> _map;
45      
46      
47      public static final boolean CASE_INSENSTIVE=true;
48      
49      /* ------------------------------------------------------------ */
50  
51      private final boolean _caseInsensitive;
52      
53      
54      /* ------------------------------------------------------------ */
55      /** Constructor. 
56       */
57      public StringMap()
58      {
59          this(false);
60      }
61      
62      /* ------------------------------------------------------------ */
63      /** Constructor. 
64       * @param ignoreCase 
65       */
66      public StringMap(final boolean ignoreCase)
67      {
68          _caseInsensitive=ignoreCase;
69          _map = new TreeMap<Object,O>(new Comparator<Object>()
70          {
71              @Override
72              public int compare(Object o1, Object o2)
73              {
74                  String s1=(o1 instanceof String)?(String)o1:null;
75                  ByteBuffer b1=(o1 instanceof ByteBuffer)?(ByteBuffer)o1:null;
76                  if (s1==null && b1==null)
77                      s1=o1.toString();
78                  String s2=(String)o2;
79                  
80                  int n1 = s1==null?b1.remaining():s1.length();
81                  int n2 = s2.length();
82                  int min = Math.min(n1, n2);
83                  for (int i = 0; i < min; i++) {
84                      char c1 = s1==null?(char)b1.get(b1.position()+i):s1.charAt(i);
85                      char c2 = s2.charAt(i);
86                      if (c1 != c2) {
87                          if (ignoreCase)
88                          {
89                              c1 = Character.toUpperCase(c1);
90                              c2 = Character.toUpperCase(c2);
91                              if (c1 != c2) {
92                                  c1 = Character.toLowerCase(c1);
93                                  c2 = Character.toLowerCase(c2);
94                                  if (c1 != c2) {
95                                      // No overflow because of numeric promotion
96                                      return c1 - c2;
97                                  }
98                              }
99                          }
100                         else
101                             return c1 - c2;
102                     }
103                 }
104                 return n1 - n2;
105             }
106         });
107     }
108 
109     /* ------------------------------------------------------------ */
110     public boolean isIgnoreCase()
111     {
112         return _caseInsensitive;
113     }
114 
115     /* ------------------------------------------------------------ */
116     @Override
117     public O put(String key, O value)
118     {
119         return _map.put(key,value);
120     }
121 
122     /* ------------------------------------------------------------ */
123     @Override
124     public O get(Object key)
125     {
126         return _map.get(key);
127     }
128     
129     /* ------------------------------------------------------------ */
130     public O get(String key)
131     {
132         return _map.get(key);
133     }
134     
135     /* ------------------------------------------------------------ */
136     public O get(String key,int offset,int length)
137     {
138         return _map.get(key.substring(offset,offset+length));
139     }
140     
141     /* ------------------------------------------------------------ */
142     public O get(ByteBuffer buffer)
143     {
144         return _map.get(buffer);
145     }
146     
147     /* ------------------------------------------------------------ */
148     @Override
149     public O remove(Object key)
150     {
151         return _map.remove(key);
152     }
153     
154     /* ------------------------------------------------------------ */
155     public O remove(String key)
156     {
157         return _map.remove(key);
158     }
159 
160     /* ------------------------------------------------------------ */
161     @Override
162     public Set<Map.Entry<String,O>> entrySet()
163     {
164         Object o=_map.entrySet();
165         return Collections.unmodifiableSet((Set<Map.Entry<String,O>>)o);
166     }
167     
168     /* ------------------------------------------------------------ */
169     @Override
170     public int size()
171     {
172         return _map.size();
173     }
174 
175     /* ------------------------------------------------------------ */
176     @Override
177     public boolean isEmpty()
178     {
179         return _map.isEmpty();
180     }
181 
182     /* ------------------------------------------------------------ */
183     @Override
184     public boolean containsKey(Object key)
185     {
186         return _map.containsKey(key);
187     }
188     
189     /* ------------------------------------------------------------ */
190     @Override
191     public void clear()
192     {
193         _map.clear();
194     }
195 
196 }