1 16 package org.apache.commons.lang.enums; 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 235 public abstract class Enum implements Comparable , Serializable { 236 237 238 private static final long serialVersionUID = -487045951170455942L; 239 240 245 private static final Map EMPTY_MAP = Collections.unmodifiableMap(new HashMap (0)); 246 247 250 private static final Map cEnumClasses = new HashMap (); 251 252 255 private final String iName; 256 257 260 private transient final int iHashCode; 261 262 266 protected transient String iToString = null; 267 268 271 private static class Entry { 272 275 final Map map = new HashMap (); 276 279 final Map unmodifiableMap = Collections.unmodifiableMap(map); 280 283 final List list = new ArrayList (25); 284 287 final List unmodifiableList = Collections.unmodifiableList(list); 288 289 292 private Entry() { 293 } 294 } 295 296 306 protected Enum(String name) { 307 super(); 308 init(name); 309 iName = name; 310 iHashCode = 7 + getEnumClass().hashCode() + 3 * name.hashCode(); 311 } 313 314 321 private void init(String name) { 322 if (StringUtils.isEmpty(name)) { 323 throw new IllegalArgumentException ("The Enum name must not be empty or null"); 324 } 325 326 Class enumClass = getEnumClass(); 327 if (enumClass == null) { 328 throw new IllegalArgumentException ("getEnumClass() must not be null"); 329 } 330 Class cls = getClass(); 331 boolean ok = false; 332 while (cls != null && cls != Enum .class && cls != ValuedEnum.class) { 333 if (cls == enumClass) { 334 ok = true; 335 break; 336 } 337 cls = cls.getSuperclass(); 338 } 339 if (ok == false) { 340 throw new IllegalArgumentException ("getEnumClass() must return a superclass of this class"); 341 } 342 343 Entry entry = (Entry) cEnumClasses.get(enumClass); 345 if (entry == null) { 346 entry = createEntry(enumClass); 347 cEnumClasses.put(enumClass, entry); 348 } 349 if (entry.map.containsKey(name)) { 350 throw new IllegalArgumentException ("The Enum name must be unique, '" + name + "' has already been added"); 351 } 352 entry.map.put(name, this); 353 entry.list.add(this); 354 } 355 356 362 protected Object readResolve() { 363 Entry entry = (Entry) cEnumClasses.get(getEnumClass()); 364 if (entry == null) { 365 return null; 366 } 367 return (Enum ) entry.map.get(getName()); 368 } 369 370 372 383 protected static Enum getEnum(Class enumClass, String name) { 384 Entry entry = getEntry(enumClass); 385 if (entry == null) { 386 return null; 387 } 388 return (Enum ) entry.map.get(name); 389 } 390 391 404 protected static Map getEnumMap(Class enumClass) { 405 Entry entry = getEntry(enumClass); 406 if (entry == null) { 407 return EMPTY_MAP; 408 } 409 return entry.unmodifiableMap; 410 } 411 412 426 protected static List getEnumList(Class enumClass) { 427 Entry entry = getEntry(enumClass); 428 if (entry == null) { 429 return Collections.EMPTY_LIST; 430 } 431 return entry.unmodifiableList; 432 } 433 434 448 protected static Iterator iterator(Class enumClass) { 449 return Enum.getEnumList(enumClass).iterator(); 450 } 451 452 459 private static Entry getEntry(Class enumClass) { 460 if (enumClass == null) { 461 throw new IllegalArgumentException ("The Enum Class must not be null"); 462 } 463 if (Enum .class.isAssignableFrom(enumClass) == false) { 464 throw new IllegalArgumentException ("The Class must be a subclass of Enum"); 465 } 466 Entry entry = (Entry) cEnumClasses.get(enumClass); 467 return entry; 468 } 469 470 478 private static Entry createEntry(Class enumClass) { 479 Entry entry = new Entry(); 480 Class cls = enumClass.getSuperclass(); 481 while (cls != null && cls != Enum .class && cls != ValuedEnum.class) { 482 Entry loopEntry = (Entry) cEnumClasses.get(cls); 483 if (loopEntry != null) { 484 entry.list.addAll(loopEntry.list); 485 entry.map.putAll(loopEntry.map); 486 break; } 488 cls = cls.getSuperclass(); 489 } 490 return entry; 491 } 492 493 499 public final String getName() { 500 return iName; 501 } 502 503 513 public Class getEnumClass() { 514 return getClass(); 515 } 516 517 530 public final boolean equals(Object other) { 531 if (other == this) { 532 return true; 533 } else if (other == null) { 534 return false; 535 } else if (other.getClass() == this.getClass()) { 536 return iName.equals(((Enum ) other).iName); 540 } else { 541 if (other.getClass().getName().equals(this.getClass().getName()) == false) { 543 return false; 544 } 545 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 |