1 8 9 package com.sleepycat.persist.impl; 10 11 import java.lang.reflect.Array ; 12 import java.util.Arrays ; 13 import java.util.HashSet ; 14 import java.util.IdentityHashMap ; 15 import java.util.List ; 16 import java.util.Map ; 17 import java.util.Set ; 18 19 import com.sleepycat.persist.raw.RawObject; 20 21 30 public class EnumFormat extends Format { 31 32 private static final long serialVersionUID = 1069833955604373538L; 33 34 private String [] names; 35 private transient Object [] values; 36 37 EnumFormat(Class type) { 38 super(type); 39 values = type.getEnumConstants(); 40 names = new String [values.length]; 41 for (int i = 0; i < names.length; i += 1) { 42 names[i] = ((Enum ) values[i]).name(); 43 } 44 } 45 46 @Override 47 public boolean isEnum() { 48 return true; 49 } 50 51 @Override 52 public List <String > getEnumConstants() { 53 return Arrays.asList(names); 54 } 55 56 @Override 57 void collectRelatedFormats(Catalog catalog, 58 Map <String ,Format> newFormats) { 59 } 60 61 @Override 62 void initialize(Catalog catalog) { 63 if (values == null) { 64 Class cls = getType(); 65 if (cls != null) { 66 values = new Object [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 75 Object newArray(int len) { 76 return Array.newInstance(getType(), len); 77 } 78 79 @Override 80 public Object 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 90 public Object readObject(Object o, EntityInput input, boolean rawAccess) { 91 92 return o; 93 } 94 95 @Override 96 void writeObject(Object o, EntityOutput output, boolean rawAccess) { 97 if (rawAccess) { 98 String 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 ("Bad enum: " + o); 114 } 115 116 @Override 117 Object convertRawObject(Catalog catalog, 118 boolean rawAccess, 119 RawObject rawObject, 120 IdentityHashMap converted) { 121 String name = rawObject.getEnum(); 122 for (int i = 0; i < names.length; i += 1) { 123 if (names[i].equals(name)) { 124 Object o = values[i]; 125 converted.put(rawObject, o); 126 return o; 127 } 128 } 129 throw new IllegalArgumentException 130 ("Enum constant is not defined: " + name); 131 } 132 133 @Override 134 void skipContents(RecordInput input) { 135 input.skipFast(input.getPackedIntByteLength()); 136 } 137 138 @Override 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 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 <String > oldNames = new HashSet <String >(Arrays.asList(names)); 159 List <String > 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 175 return false; 176 } 177 } 178 } 179 } 180 | Popular Tags |