KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > sleepycat > persist > impl > EnumFormat


1 /*-
2  * See the file LICENSE for redistribution information.
3  *
4  * Copyright (c) 2002,2006 Oracle. All rights reserved.
5  *
6  * $Id: EnumFormat.java,v 1.18 2006/10/30 21:14:32 bostic Exp $
7  */

8
9 package com.sleepycat.persist.impl;
10
11 import java.lang.reflect.Array JavaDoc;
12 import java.util.Arrays JavaDoc;
13 import java.util.HashSet JavaDoc;
14 import java.util.IdentityHashMap JavaDoc;
15 import java.util.List JavaDoc;
16 import java.util.Map JavaDoc;
17 import java.util.Set JavaDoc;
18
19 import com.sleepycat.persist.raw.RawObject;
20
21 /**
22  * Format for all enum types.
23  *
24  * In this class we resort to using reflection to allocate arrays of enums.
25  * If there is a need for it, reflection could be avoided in the future by
26  * generating code as new array formats are encountered.
27  *
28  * @author Mark Hayes
29  */

30 public class EnumFormat extends Format {
31
32     private static final long serialVersionUID = 1069833955604373538L;
33
34     private String JavaDoc[] names;
35     private transient Object JavaDoc[] values;
36
37     EnumFormat(Class JavaDoc type) {
38         super(type);
39         values = type.getEnumConstants();
40         names = new String JavaDoc[values.length];
41         for (int i = 0; i < names.length; i += 1) {
42             names[i] = ((Enum JavaDoc) values[i]).name();
43         }
44     }
45
46     @Override JavaDoc
47     public boolean isEnum() {
48         return true;
49     }
50
51     @Override JavaDoc
52     public List JavaDoc<String JavaDoc> getEnumConstants() {
53         return Arrays.asList(names);
54     }
55
56     @Override JavaDoc
57     void collectRelatedFormats(Catalog catalog,
58                                Map JavaDoc<String JavaDoc,Format> newFormats) {
59     }
60
61     @Override JavaDoc
62     void initialize(Catalog catalog) {
63         if (values == null) {
64             Class JavaDoc cls = getType();
65             if (cls != null) {
66                 values = new Object JavaDoc[names.length];
67                 for (int i = 0; i < names.length; i += 1) {
68                     values[i] = Enum.valueOf(cls, names[i]);
69                 }
70             }
71         }
72     }
73     
74     @Override JavaDoc
75     Object JavaDoc newArray(int len) {
76         return Array.newInstance(getType(), len);
77     }
78
79     @Override JavaDoc
80     public Object JavaDoc newInstance(EntityInput input, boolean rawAccess) {
81         int index = input.readEnumConstant(names);
82         if (rawAccess) {
83             return new RawObject(this, names[index]);
84         } else {
85             return values[index];
86         }
87     }
88
89     @Override JavaDoc
90     public Object JavaDoc readObject(Object JavaDoc o, EntityInput input, boolean rawAccess) {
91         /* newInstance reads the value -- do nothing here. */
92         return o;
93     }
94
95     @Override JavaDoc
96     void writeObject(Object JavaDoc o, EntityOutput output, boolean rawAccess) {
97         if (rawAccess) {
98             String JavaDoc name = ((RawObject) o).getEnum();
99             for (int i = 0; i < names.length; i += 1) {
100                 if (names[i].equals(name)) {
101                     output.writeEnumConstant(names, i);
102                     return;
103                 }
104             }
105         } else {
106             for (int i = 0; i < values.length; i += 1) {
107                 if (o == values[i]) {
108                     output.writeEnumConstant(names, i);
109                     return;
110                 }
111             }
112         }
113         throw new IllegalStateException JavaDoc("Bad enum: " + o);
114     }
115
116     @Override JavaDoc
117     Object JavaDoc convertRawObject(Catalog catalog,
118                             boolean rawAccess,
119                             RawObject rawObject,
120                             IdentityHashMap JavaDoc converted) {
121         String JavaDoc name = rawObject.getEnum();
122         for (int i = 0; i < names.length; i += 1) {
123             if (names[i].equals(name)) {
124                 Object JavaDoc o = values[i];
125                 converted.put(rawObject, o);
126                 return o;
127             }
128         }
129         throw new IllegalArgumentException JavaDoc
130             ("Enum constant is not defined: " + name);
131     }
132
133     @Override JavaDoc
134     void skipContents(RecordInput input) {
135         input.skipFast(input.getPackedIntByteLength());
136     }
137
138     @Override JavaDoc
139     boolean evolve(Format newFormatParam, Evolver evolver) {
140         if (!(newFormatParam instanceof EnumFormat)) {
141             evolver.addEvolveError
142                 (this, newFormatParam,
143                  "Incompatible enum type changed detected",
144                  "An enum class may not be changed to a non-enum type");
145             /* For future:
146             evolver.addMissingMutation
147                 (this, newFormatParam,
148                  "Converter is required when an enum class is changed to " +
149                  "a non-enum type");
150             */

151             return false;
152         }
153         EnumFormat newFormat = (EnumFormat) newFormatParam;
154         if (Arrays.equals(names, newFormat.names)) {
155             evolver.useOldFormat(this, newFormat);
156             return true;
157         } else {
158             Set JavaDoc<String JavaDoc> oldNames = new HashSet JavaDoc<String JavaDoc>(Arrays.asList(names));
159             List JavaDoc<String JavaDoc> newNames = Arrays.asList(newFormat.names);
160             if (newNames.containsAll(oldNames)) {
161                 evolver.useEvolvedFormat(this, newFormat, newFormat);
162                 return true;
163             } else {
164                 oldNames.removeAll(newNames);
165                 evolver.addEvolveError
166                     (this, newFormat,
167                      "Incompatible enum type changed detected",
168                      "Enum values may not be removed: " + oldNames);
169                 /* For future:
170                 evolver.addMissingMutation
171                     (this, newFormatParam,
172                      "Converter is required when a value is removed from an " +
173                      "enum: " + oldNames);
174                 */

175                 return false;
176             }
177         }
178     }
179 }
180
Popular Tags