View Javadoc

1   /*
2    * EL4J, the Extension Library for the J2EE, adds incremental enhancements to
3    * the spring framework, http://el4j.sf.net
4    * Copyright (C) 2005 by ELCA Informatique SA, Av. de la Harpe 22-24,
5    * 1000 Lausanne, Switzerland, http://www.elca.ch
6    *
7    * EL4J is published under the GNU Lesser General Public License (LGPL)
8    * Version 2.1. See http://www.gnu.org/licenses/
9    *
10   * This program is distributed in the hope that it will be useful,
11   * but WITHOUT ANY WARRANTY; without even the implied warranty of
12   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13   * GNU Lesser General Public License for more details.
14   *
15   * For alternative licensing, please contact info@elca.ch
16   */
17  package ch.elca.el4j.util.codingsupport;
18  
19  import java.io.ObjectStreamException;
20  import java.io.Serializable;
21  import java.util.Hashtable;
22  
23  
24  /**
25   * The parent class for enums using the typesafe enum pattern (these enums are
26   * not comparable). Use the AbstractComparableEnum class as a parent if you need
27   * comparable enums. The pattern ensures that enums are correctly serialized and
28   * that there are some common accessor methods.
29   * <p>
30   *
31   * <h2>Concepts</h2>
32   * <ul>
33   * <li><b>Enumerations</b> are programming language types. Elements of an
34   * enumeration are one of a fixed (small) number of enumerable elements. For
35   * example, a simple enumeration for a program for playing cards could be
36   * {Spade, Heart, Diamonds, Club}. An element of this enumeration would then be
37   * any one of the four types of cards.
38   * </ul>
39   *
40   *  <h2>How to Use</h2>
41   *
42   *  <H3> Usage example</H3>
43   *
44   *  The following code shows how to write an enumeration with the three possible
45   *  values <BR>
46   *  <code>{ASSERT, REQUIRE, ENSURE}</code>:
47   * <code> <pre>
48   * package ch.elca.el4j.codingsupport;
49   *
50   * import java.io.ObjectStreamException;
51   * // only needed due to a IBM JDK 1.2.2 bug
52   *
53   * /**
54   *  * Represents the type of an assertion.
55   *  * It uses the typesafe enum pattern for <BR>
56   *  * <code> enum AssertType { ASSERT, REQUIRE, ENSURE }; </code>
57   *  * <p>
58   *  *
59   *  * The code for class is potentially generated.
60   *  *
61   *  * /
62   *  public class AssertType extends AbstractDefaultEnum {
63   *
64   *      //  define a private constructor with the two arguments
65   *      //  and delegate construction
66   *      //  to the parent class's constructor:
67   *      private AssertType(String name, int code) {
68   *        super(name, code);
69   *      }
70   *
71   *      // now define the elements:
72   *
73   *      public static final AssertType ASSERT =
74   *        new AssertType(&quot;ASSERT&quot;,1);
75   *
76   *      public static final AssertType REQUIRE =
77   *        new AssertType(&quot;REQUIRE&quot;,2);
78   *
79   *      public static final AssertType ENSURE =
80   *        new AssertType(&quot;ENSURE&quot;,3);
81   *      }
82   *
83   *      // Customize the get(String) method
84   *      public static AssertType get(String name) {
85   *        return (AssertType) AbstractDefaultEnum.get(AssertType.class, name);
86   *      }
87   *  }
88   * </pre> </code>
89   *
90   * <H2>Deployment Environment</H2>
91   * The duplication of <code>readResolve</code> method in each enumeration is
92   * not needed because JDK 1.2.2 is no longer supported by EL4J.
93   *
94   * See also AbstractComparableEnum for a variant of this class that allow
95   * comparisons (i.e. it implements Comparable). <br/>
96   * The pattern for the implementation of this class was inspired by the book
97   * "Effective Java" by Joshua Bloch.
98   *
99   * @svnLink $Revision: 3873 $;$Date: 2009-08-04 13:59:45 +0200 (Di, 04. Aug 2009) $;$Author: swismer $;$URL: https://el4j.svn.sourceforge.net/svnroot/el4j/branches/el4j_3_1/el4j/framework/modules/core/src/main/java/ch/elca/el4j/util/codingsupport/AbstractDefaultEnum.java $
100  *
101  * @see <a href="http://www.javaworld.com/javaworld/javatips/jw-javatip122.html">
102  *          Typesafe Enum Pattern Pitfalls</a>
103  *
104  * @author Raphael Boog (RBO)
105  */
106 public abstract class AbstractDefaultEnum implements Serializable {
107 	/**
108 	 * A hastable containing all instances of this class.
109 	 */
110 	protected static final Hashtable<String,Object> s_singletons =
111 		new Hashtable<String,Object>();
112 
113 	/**
114 	 * The name of this enum element.
115 	 */
116 	protected String m_name;
117 
118 	/**
119 	* The integer code for this enum element.
120 	*/
121 	protected int m_code;
122 
123 	/**
124 	 * Constructor that initializes the name and and adds this instance into
125 	 * the signletons list along with its key. The key is comprised of the class
126 	 * name and the name of this enum
127 	 *
128 	 * @param name Is the name of this instance.
129 	 * @param code Is the code.
130 	 */
131 	protected AbstractDefaultEnum(String name, int code) {
132 		m_name = name;
133 		m_code = code;
134 		// First parameter is a unique key.
135 		// Second parameter is a unique value.
136 		s_singletons.put((this.getClass()).getName() + "." + m_name, this);
137 	}
138 
139 	/**
140 	 * Return the named enum (names are case sensitive!).
141 	 *
142 	 * @param myClass Is the type to get.
143 	 * @param name Is the name of the instantiated class.
144 	 * @return the named enum or null in case it is not found.
145 	 */
146 	protected static Object get(Class<?> myClass, String name) {
147 		return s_singletons.get(myClass.getName() + "." + name);
148 	}
149 
150 	/**
151 	 * Return the enum's name.
152 	 * @return the enum's name.
153 	 */
154 	public String toString() {
155 		return m_name;
156 	}
157 
158 	/**
159 	 * @return Return the enum's code.
160 	 */
161 	public int toInt() {
162 		return m_code;
163 	}
164 
165 	/**
166 	 * Return true if and only if that object is equivalent to the object this
167 	 * operation is invoked upon. Remark: due to the fact that there is only one
168 	 * Object for each element of an enumeration, the == operator has the same
169 	 * semantics (but more efficient).
170 	 *
171 	 * {@inheritDoc}
172 	 */
173 	public final boolean equals(Object that) {
174 		return super.equals(that);
175 	}
176 
177 	/**
178 	 * Retruns the hash code of this instance.
179 	 *
180 	 * {@inheritDoc}
181 	 */
182 	public final int hashCode() {
183 		return super.hashCode();
184 	}
185 
186 	/**
187 	 * Performs an unique return of this instance after deserialzation.<br>
188 	 *
189 	 * This method has no effect with the JDK 1.2.2 of IBM. If you use the JDK
190 	 * version, this <code>readResolve</code> method must be duplicated in each
191 	 * enum subclass. EL4J does not support it any longer.
192 	 *
193 	 * @return readResolve
194 	 * @throws ObjectStreamException On reading error.
195 	 */
196 	public Object readResolve() throws ObjectStreamException {
197 		return s_singletons.get((this.getClass()).getName() + "." + m_name);
198 	}
199 }