KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > ws > jaxme > js > pattern > TypesafeEnumerationGenerator


1 /*
2  * Copyright 2003, 2004 The Apache Software Foundation
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15
16  */

17 package org.apache.ws.jaxme.js.pattern;
18
19 import java.io.Serializable JavaDoc;
20 import java.util.ArrayList JavaDoc;
21 import java.util.HashSet JavaDoc;
22 import java.util.List JavaDoc;
23 import java.util.Set JavaDoc;
24
25 import org.apache.ws.jaxme.js.JavaComment;
26 import org.apache.ws.jaxme.js.JavaConstructor;
27 import org.apache.ws.jaxme.js.JavaField;
28 import org.apache.ws.jaxme.js.JavaInnerClass;
29 import org.apache.ws.jaxme.js.JavaMethod;
30 import org.apache.ws.jaxme.js.JavaQName;
31 import org.apache.ws.jaxme.js.JavaQNameImpl;
32 import org.apache.ws.jaxme.js.JavaSource;
33 import org.apache.ws.jaxme.js.JavaSourceFactory;
34 import org.apache.ws.jaxme.js.Util;
35
36 /** <p>This class is a generator for the typesafe enumeration
37  * pattern. It creates a class that contains only a few,
38  * specified instances. Other instances cannot be created.</p>
39  * <p>Any instance has a name and a value. The name
40  *
41  * @author <a HREF="mailto:joe@ispsoft.de">Jochen Wiedmann</a>
42  * @version $Id: TypesafeEnumerationGenerator.java,v 1.2 2004/02/16 23:39:54 jochen Exp $
43  */

44 public class TypesafeEnumerationGenerator {
45   public static class Item {
46     private String JavaDoc name;
47      private String JavaDoc value;
48
49      /** <p>Sets the enumeration items name. This must be a valid
50       * Java identifier.</p>
51       */

52      public void setName(String JavaDoc pName) {
53         if (pName != null) {
54           Util.checkJavaIdentifier(pName);
55         }
56         name = pName;
57      }
58
59      /** <p>Returns the enumeration items name.</p>
60       */

61      public String JavaDoc getName() {
62         return name;
63      }
64
65      /** <p>Sets the enumeration items value.</p>
66       */

67      public void setValue(String JavaDoc pValue) {
68         value = pValue;
69      }
70
71      /** <p>Returns the enumeration items value.</p>
72       */

73      public String JavaDoc getValue() {
74         return value;
75      }
76
77      /** <p>Verifies the enumeration item.</p>
78       * @throws IllegalStateException The enumeration items value is not set.
79       */

80      public void finish() {
81         if (getValue() == null) {
82           throw new IllegalStateException JavaDoc("The enumeration items 'value' attribute is not set.");
83         }
84         if (getName() == null) {
85           try {
86              Util.asJavaIdentifier(getValue().toUpperCase());
87           } catch (Exception JavaDoc e) {
88              throw new IllegalStateException JavaDoc("The enumeration items 'name' attribute is not set " +
89                                                 " and the value " + getValue() +
90                                                 " cannot be converted into a valid Java identifier.");
91           }
92         }
93      }
94   }
95
96   private boolean isAddingEquals = true;
97
98   /** <p>Sets whether the generator should add implementations for the methods
99     * {@link Object#equals(java.lang.Object)} and {@link Object#hashCode()}
100     * or not. Defaults to true.</p>
101     */

102   public void setAddingEquals(boolean pAddingEquals) {
103      isAddingEquals = pAddingEquals;
104   }
105
106   /** <p>Returns whether the generator should add implementations for the methods
107     * {@link Object#equals(java.lang.Object)} and {@link Object#hashCode()}
108     * or not. Defaults to true.</p>
109     */

110   public boolean isAddingEquals() {
111      return isAddingEquals;
112   }
113
114   /** <p>Generates a new typesafe enumeration.</p>
115     * @param pFactory The factory to use for generating the items.
116     * @param pTargetClass Fully qualified name of the class being generated.
117     * @param pItems The enumeration items; a public, static, final instance
118     * will be generated for any element in the array
119     */

120   public JavaSource generate(JavaSourceFactory pFactory, JavaQName pTargetClass,
121                                Item[] pItems) {
122      JavaSource result = pFactory.newJavaSource(pTargetClass, JavaSource.PUBLIC);
123     doGenerate(result, pItems);
124      return result;
125   }
126
127   /** <p>Generates a new typesafe enumeration, which is an inner class of
128     * the class <code>pSource</code>.</p>
129     * @param pSource The class, which shall have an inner class
130     * @param pName Name of the inner class
131     * @param pItems The enumeration items; a public, static, final instance
132     * will be generated for any element in the array
133     */

134   public JavaInnerClass generate(JavaSource pSource, String JavaDoc pName, Item[] pItems) {
135      JavaInnerClass result = pSource.newJavaInnerClass(pName, JavaSource.PUBLIC);
136      result.setStatic(true);
137      doGenerate(result, pItems);
138      return result;
139   }
140
141   /** <p>Does the actual generation, invoked by the <code>generate()</code>
142     * frontends.</p>
143     */

144   private void doGenerate(JavaSource pSource, Item[] pItems) {
145      Set JavaDoc names = new HashSet JavaDoc();
146      Set JavaDoc values = new HashSet JavaDoc();
147      for (int i = 0; i < pItems.length; i++) {
148         String JavaDoc itemName = pItems[i].getName();
149         String JavaDoc itemValue = pItems[i].getValue();
150         if (itemName == null) {
151           itemName = Util.asJavaIdentifier(itemValue.toUpperCase());
152           pItems[i].setName(itemName);
153         }
154         if (names.contains(itemName)) {
155           throw new IllegalStateException JavaDoc("The item name " + itemName + " is not unique.");
156         }
157         if (values.contains(itemValue)) {
158           throw new IllegalStateException JavaDoc("The item value " + itemValue + " is not unique.");
159         }
160         names.add(itemName);
161         names.add(itemValue);
162      }
163
164      pSource.addImplements(Serializable JavaDoc.class);
165      JavaField name = pSource.newJavaField("name", String JavaDoc.class, JavaSource.PRIVATE);
166      name.setFinal(true);
167      JavaField value = pSource.newJavaField("value", String JavaDoc.class, JavaSource.PRIVATE);
168      name.setFinal(true);
169      JavaConstructor jcon = pSource.newJavaConstructor(JavaSource.PRIVATE);
170      jcon.addParam(String JavaDoc.class, "pName");
171      jcon.addParam(String JavaDoc.class, "pValue");
172      jcon.addLine("name = pName;");
173      jcon.addLine("value = pValue;");
174     List JavaDoc instanceList = new ArrayList JavaDoc();
175      for (int i = 0; i < pItems.length; i++) {
176       Item item = pItems[i];
177         String JavaDoc itemName = item.getName();
178         String JavaDoc itemValue = item.getValue();
179         JavaField instance = pSource.newJavaField(itemName, pSource.getQName(),
180                                                    JavaSource.PUBLIC);
181         instance.newComment().addLine("The enumeration item with name " + itemName +
182                                        " and value " + itemValue + ".");
183         instance.setStatic(true);
184         instance.setFinal(true);
185         instance.addLine("new ", pSource.getQName(), "(", JavaSource.getQuoted(itemName),
186                          ", ", JavaSource.getQuoted(itemValue), ")");
187
188         if (i > 0) instanceList.add(", ");
189        instanceList.add(instance);
190     }
191
192      JavaQName arrayType = JavaQNameImpl.getArray(pSource.getQName());
193      JavaField allInstances = pSource.newJavaField("allInstances", arrayType,
194                                                       JavaSource.PRIVATE);
195      allInstances.setStatic(true);
196      allInstances.setFinal(true);
197      allInstances.addLine("new ", arrayType, "{", instanceList, "}");
198
199      JavaMethod getName = pSource.newJavaMethod("getName", String JavaDoc.class,
200                                                    JavaSource.PUBLIC);
201      getName.newComment().addLine("The enumeration items name.");
202      getName.addLine("return ", name, ";");
203
204      JavaMethod getValue = pSource.newJavaMethod("getValue", String JavaDoc.class,
205                                                 JavaSource.PUBLIC);
206      getValue.newComment().addLine("The enumeration items value.");
207      getValue.addLine("return ", value, ";");
208
209      JavaMethod getInstances = pSource.newJavaMethod("getInstances", arrayType,
210                                                       JavaSource.PUBLIC);
211      getInstances.setStatic(true);
212      getInstances.addLine("return ", allInstances, ";");
213
214      JavaMethod getInstanceByName = pSource.newJavaMethod("getInstanceByName",
215                                                            pSource.getQName(),
216                                                            JavaSource.PUBLIC);
217     getInstanceByName.setStatic(true);
218      getInstanceByName.addParam(String JavaDoc.class, "pName");
219      JavaComment jc = getInstanceByName.newComment();
220      jc.addLine("Returns the item with the given name.</p>");
221      jc.addThrows(IllegalArgumentException JavaDoc.class.getName() +
222                    " The name <code>pName</code> is invalid and no such item exists.");
223      getInstanceByName.addLine(String JavaDoc.class, " s = pName.intern();");
224      boolean first = true;
225      for (int i = 0; i < pItems.length; i++) {
226         Item item = pItems[i];
227         Object JavaDoc[] args = new Object JavaDoc[]{JavaSource.getQuoted(item.getName()), " == s"};
228         getInstanceByName.addIf(first, args);
229         getInstanceByName.addLine("return ", item.getName(), ";");
230         first = false;
231      }
232      getInstanceByName.addElse();
233      getInstanceByName.addLine("throw new ", IllegalArgumentException JavaDoc.class, "(",
234                                JavaSource.getQuoted("Invalid name: "),
235                               " + pName);");
236      getInstanceByName.addEndIf();
237
238      JavaMethod getInstanceByValue = pSource.newJavaMethod("getInstanceByValue",
239                                                                              pSource.getQName(),
240                                                                              JavaSource.PUBLIC);
241      getInstanceByValue.setStatic(true);
242      getInstanceByValue.addParam(String JavaDoc.class, "pValue");
243      jc = getInstanceByValue.newComment();
244      jc.addLine("Returns the item with the given value.</p>");
245      jc.addThrows(IllegalArgumentException JavaDoc.class.getName() +
246                       " The name <code>pValue</code> is invalid and no such item exists.");
247      getInstanceByValue.addLine(String JavaDoc.class, " s = pValue.intern();");
248      first = true;
249      for (int i = 0; i < pItems.length; i++) {
250         Item item = pItems[i];
251         Object JavaDoc[] args = new Object JavaDoc[]{JavaSource.getQuoted(item.getValue()), " == s"};
252         getInstanceByValue.addIf(first, args);
253         getInstanceByValue.addLine("return ", item.getName(), ";");
254         first = false;
255      }
256      getInstanceByValue.addElse();
257      getInstanceByValue.addLine("throw new ", IllegalArgumentException JavaDoc.class, "(",
258                                         JavaSource.getQuoted("Invalid name: "),
259                                         " + pValue);");
260      getInstanceByValue.addEndIf();
261
262      if (isAddingEquals()) {
263         JavaMethod equals = pSource.newJavaMethod("equals", JavaQNameImpl.BOOLEAN,
264                                                   JavaSource.PUBLIC);
265         equals.addParam(Object JavaDoc.class, "o");
266         equals.addIf("o == null || !(o instanceof ", pSource.getQName(), ")");
267         equals.addLine("return false;");
268         equals.addEndIf();
269         equals.addLine("return name.equals(((", pSource.getQName(), ") o).name);");
270
271       JavaMethod hashCode = pSource.newJavaMethod("hashCode", JavaQNameImpl.INT,
272                                                   JavaSource.PUBLIC);
273       hashCode.addLine("return name.hashCode();");
274      }
275   }
276 }
277
Popular Tags