1 16 package org.joda.time.convert; 17 18 25 class ConverterSet { 26 private final Converter[] iConverters; 27 28 private Entry[] iSelectEntries; 31 32 ConverterSet(Converter[] converters) { 33 iConverters = converters; 36 iSelectEntries = new Entry[1 << 4]; } 38 39 47 Converter select(Class type) throws IllegalStateException { 48 Entry[] entries = iSelectEntries; 50 int length = entries.length; 51 int index = type == null ? 0 : type.hashCode() & (length - 1); 52 53 Entry e; 54 while ((e = entries[index]) != null) { 56 if (e.iType == type) { 57 return e.iConverter; 58 } 59 if (++index >= length) { 60 index = 0; 61 } 62 } 63 64 66 Converter converter = selectSlow(this, type); 67 e = new Entry(type, converter); 68 69 76 entries = (Entry[])entries.clone(); 80 81 entries[index] = e; 83 84 for (int i=0; i<length; i++) { 86 if (entries[i] == null) { 87 iSelectEntries = entries; 89 return converter; 90 } 91 } 92 93 95 int newLength = length << 1; 96 Entry[] newEntries = new Entry[newLength]; 97 for (int i=0; i<length; i++) { 98 e = entries[i]; 99 type = e.iType; 100 index = type == null ? 0 : type.hashCode() & (newLength - 1); 101 while (newEntries[index] != null) { 102 if (++index >= newLength) { 103 index = 0; 104 } 105 } 106 newEntries[index] = e; 107 } 108 109 iSelectEntries = newEntries; 111 return converter; 112 } 113 114 117 int size() { 118 return iConverters.length; 119 } 120 121 124 void copyInto(Converter[] converters) { 125 System.arraycopy(iConverters, 0, converters, 0, iConverters.length); 126 } 127 128 138 ConverterSet add(Converter converter, Converter[] removed) { 139 Converter[] converters = iConverters; 140 int length = converters.length; 141 142 for (int i=0; i<length; i++) { 143 Converter existing = converters[i]; 144 if (converter.equals(existing)) { 145 if (removed != null) { 147 removed[0] = null; 148 } 149 return this; 150 } 151 152 if (converter.getSupportedType() == existing.getSupportedType()) { 153 Converter[] copy = new Converter[length]; 155 156 for (int j=0; j<length; j++) { 157 if (j != i) { 158 copy[j] = converters[j]; 159 } else { 160 copy[j] = converter; 161 } 162 } 163 164 if (removed != null) { 165 removed[0] = existing; 166 } 167 return new ConverterSet(copy); 168 } 169 } 170 171 Converter[] copy = new Converter[length + 1]; 173 System.arraycopy(converters, 0, copy, 0, length); 174 copy[length] = converter; 175 176 if (removed != null) { 177 removed[0] = null; 178 } 179 return new ConverterSet(copy); 180 } 181 182 190 ConverterSet remove(Converter converter, Converter[] removed) { 191 Converter[] converters = iConverters; 192 int length = converters.length; 193 194 for (int i=0; i<length; i++) { 195 if (converter.equals(converters[i])) { 196 return remove(i, removed); 197 } 198 } 199 200 if (removed != null) { 202 removed[0] = null; 203 } 204 return this; 205 } 206 207 215 ConverterSet remove(final int index, Converter[] removed) { 216 Converter[] converters = iConverters; 217 int length = converters.length; 218 if (index >= length) { 219 throw new IndexOutOfBoundsException (); 220 } 221 222 if (removed != null) { 223 removed[0] = converters[index]; 224 } 225 226 Converter[] copy = new Converter[length - 1]; 227 228 int j = 0; 229 for (int i=0; i<length; i++) { 230 if (i != index) { 231 copy[j++] = converters[i]; 232 } 233 } 234 235 return new ConverterSet(copy); 236 } 237 238 242 private static Converter selectSlow(ConverterSet set, Class type) { 243 Converter[] converters = set.iConverters; 244 int length = converters.length; 245 Converter converter; 246 247 for (int i=length; --i>=0; ) { 248 converter = converters[i]; 249 Class supportedType = converter.getSupportedType(); 250 251 if (supportedType == type) { 252 return converter; 254 } 255 256 if (supportedType == null || (type != null && !supportedType.isAssignableFrom(type))) { 257 set = set.remove(i, null); 259 converters = set.iConverters; 260 length = converters.length; 261 } 262 } 263 264 266 if (type == null || length == 0) { 267 return null; 268 } 269 if (length == 1) { 270 return converters[0]; 272 } 273 274 276 for (int i=length; --i>=0; ) { 278 converter = converters[i]; 279 Class supportedType = converter.getSupportedType(); 280 for (int j=length; --j>=0; ) { 281 if (j != i && converters[j].getSupportedType().isAssignableFrom(supportedType)) { 282 set = set.remove(j, null); 284 converters = set.iConverters; 285 length = converters.length; 286 i = length - 1; 287 } 288 } 289 } 290 291 293 if (length == 1) { 294 return converters[0]; 296 } 297 298 301 StringBuffer msg = new StringBuffer (); 302 msg.append("Unable to find best converter for type \""); 303 msg.append(type.getName()); 304 msg.append("\" from remaining set: "); 305 for (int i=0; i<length; i++) { 306 converter = converters[i]; 307 Class supportedType = converter.getSupportedType(); 308 309 msg.append(converter.getClass().getName()); 310 msg.append('['); 311 msg.append(supportedType == null ? null : supportedType.getName()); 312 msg.append("], "); 313 } 314 315 throw new IllegalStateException (msg.toString()); 316 } 317 318 static class Entry { 319 final Class iType; 320 final Converter iConverter; 321 322 Entry(Class type, Converter converter) { 323 iType = type; 324 iConverter = converter; 325 } 326 } 327 328 } 329 | Popular Tags |