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 }