1 16 package org.apache.commons.lang.enum; 17 18 import java.io.Serializable; 19 import java.lang.reflect.InvocationTargetException; 20 import java.lang.reflect.Method; 21 import java.util.ArrayList; 22 import java.util.Collections; 23 import java.util.HashMap; 24 import java.util.Iterator; 25 import java.util.List; 26 import java.util.Map; 27 28 import org.apache.commons.lang.ClassUtils; 29 import org.apache.commons.lang.StringUtils; 30 31 238 public abstract class Enum implements Comparable, Serializable { 239 240 241 private static final long serialVersionUID = -487045951170455942L; 242 243 248 private static final Map EMPTY_MAP = Collections.unmodifiableMap(new HashMap(0)); 249 250 253 private static final Map cEnumClasses = new HashMap(); 254 255 258 private final String iName; 259 260 263 private transient final int iHashCode; 264 265 269 protected transient String iToString = null; 270 271 274 private static class Entry { 275 278 final Map map = new HashMap(); 279 282 final Map unmodifiableMap = Collections.unmodifiableMap(map); 283 286 final List list = new ArrayList(25); 287 290 final List unmodifiableList = Collections.unmodifiableList(list); 291 292 295 private Entry() { 296 } 297 } 298 299 309 protected Enum(String name) { 310 super(); 311 init(name); 312 iName = name; 313 iHashCode = 7 + getEnumClass().hashCode() + 3 * name.hashCode(); 314 } 316 317 324 private void init(String name) { 325 if (StringUtils.isEmpty(name)) { 326 throw new IllegalArgumentException("The Enum name must not be empty or null"); 327 } 328 329 Class enumClass = getEnumClass(); 330 if (enumClass == null) { 331 throw new IllegalArgumentException("getEnumClass() must not be null"); 332 } 333 Class cls = getClass(); 334 boolean ok = false; 335 while (cls != null && cls != Enum.class && cls != ValuedEnum.class) { 336 if (cls == enumClass) { 337 ok = true; 338 break; 339 } 340 cls = cls.getSuperclass(); 341 } 342 if (ok == false) { 343 throw new IllegalArgumentException("getEnumClass() must return a superclass of this class"); 344 } 345 346 Entry entry = (Entry) cEnumClasses.get(enumClass); 348 if (entry == null) { 349 entry = createEntry(enumClass); 350 cEnumClasses.put(enumClass, entry); 351 } 352 if (entry.map.containsKey(name)) { 353 throw new IllegalArgumentException("The Enum name must be unique, '" + name + "' has already been added"); 354 } 355 entry.map.put(name, this); 356 entry.list.add(this); 357 } 358 359 365 protected Object readResolve() { 366 Entry entry = (Entry) cEnumClasses.get(getEnumClass()); 367 if (entry == null) { 368 return null; 369 } 370 return (Enum) entry.map.get(getName()); 371 } 372 373 375 386 protected static Enum getEnum(Class enumClass, String name) { 387 Entry entry = getEntry(enumClass); 388 if (entry == null) { 389 return null; 390 } 391 return (Enum) entry.map.get(name); 392 } 393 394 407 protected static Map getEnumMap(Class enumClass) { 408 Entry entry = getEntry(enumClass); 409 if (entry == null) { 410 return EMPTY_MAP; 411 } 412 return entry.unmodifiableMap; 413 } 414 415 429 protected static List getEnumList(Class enumClass) { 430 Entry entry = getEntry(enumClass); 431 if (entry == null) { 432 return Collections.EMPTY_LIST; 433 } 434 return entry.unmodifiableList; 435 } 436 437 451 protected static Iterator iterator(Class enumClass) { 452 return Enum.getEnumList(enumClass).iterator(); 453 } 454 455 462 private static Entry getEntry(Class enumClass) { 463 if (enumClass == null) { 464 throw new IllegalArgumentException("The Enum Class must not be null"); 465 } 466 if (Enum.class.isAssignableFrom(enumClass) == false) { 467 throw new IllegalArgumentException("The Class must be a subclass of Enum"); 468 } 469 Entry entry = (Entry) cEnumClasses.get(enumClass); 470 return entry; 471 } 472 473 481 private static Entry createEntry(Class enumClass) { 482 Entry entry = new Entry(); 483 Class cls = enumClass.getSuperclass(); 484 while (cls != null && cls != Enum.class && cls != ValuedEnum.class) { 485 Entry loopEntry = (Entry) cEnumClasses.get(cls); 486 if (loopEntry != null) { 487 entry.list.addAll(loopEntry.list); 488 entry.map.putAll(loopEntry.map); 489 break; } 491 cls = cls.getSuperclass(); 492 } 493 return entry; 494 } 495 496 502 public final String getName() { 503 return iName; 504 } 505 506 516 public Class getEnumClass() { 517 return getClass(); 518 } 519 520 533 public final boolean equals(Object other) { 534 if (other == this) { 535 return true; 536 } else if (other == null) { 537 return false; 538 } else if (other.getClass() == this.getClass()) { 539 return iName.equals(((Enum) other).iName); 543 } else { 544 try { 546 Method mth = other.getClass().getMethod("getName", null); 547 String name = (String) mth.invoke(other, null); 548 return iName.equals(name); 549 } catch (NoSuchMethodException e) { 550 } catch (IllegalAccessException e) { 552 } catch (InvocationTargetException e) { 554 } 556 return false; 557 } 558 } 559 560 565 public final int hashCode() { 566 return iHashCode; 567 } 568 569 582 public int compareTo(Object other) { 583 if (other == this) { 584 return 0; 585 } 586 return iName.compareTo(((Enum) other).iName); 587 } 588 589 596 public String toString() { 597 if (iToString == null) { 598 String shortName = ClassUtils.getShortClassName(getEnumClass()); 599 iToString = shortName + "[" + getName() + "]"; 600 } 601 return iToString; 602 } 603 604 } 605 | Popular Tags |