1 8 9 package com.sleepycat.persist.impl; 10 11 import java.util.ArrayList ; 12 import java.util.Arrays ; 13 import java.util.HashMap ; 14 import java.util.IdentityHashMap ; 15 import java.util.List ; 16 import java.util.Map ; 17 18 import com.sleepycat.persist.model.ClassMetadata; 19 import com.sleepycat.persist.model.FieldMetadata; 20 import com.sleepycat.persist.raw.RawField; 21 import com.sleepycat.persist.raw.RawObject; 22 23 58 public class CompositeKeyFormat extends Format { 59 60 private static final long serialVersionUID = 306843428409314630L; 61 62 private ClassMetadata metadata; 63 private List <FieldInfo> fields; 64 private transient Accessor objAccessor; 65 private transient Accessor rawAccessor; 66 private transient volatile Map <String ,RawField> rawFields; 67 private transient volatile FieldInfo[] rawInputFields; 68 69 static String [] getFieldNameArray(List <FieldMetadata> list) { 70 int index = 0; 71 String [] a = new String [list.size()]; 72 for (FieldMetadata f : list) { 73 a[index] = f.getName(); 74 index += 1; 75 } 76 return a; 77 } 78 79 CompositeKeyFormat(Class cls, 80 ClassMetadata metadata, 81 List <FieldMetadata> fieldNames) { 82 this(cls, metadata, getFieldNameArray(fieldNames)); 83 } 84 85 CompositeKeyFormat(Class cls, 86 ClassMetadata metadata, 87 String [] fieldNames) { 88 super(cls); 89 this.metadata = metadata; 90 91 92 Class superCls = cls.getSuperclass(); 93 if (superCls != Object .class) { 94 throw new IllegalArgumentException 95 ("Composite key class must be derived from Object: " + 96 cls.getName()); 97 } 98 99 100 List <FieldInfo> instanceFields = FieldInfo.getInstanceFields(cls); 101 fields = new ArrayList <FieldInfo>(instanceFields.size()); 102 for (String fieldName : fieldNames) { 103 FieldInfo field = null; 104 for (FieldInfo tryField : instanceFields) { 105 if (fieldName.equals(tryField.getName())) { 106 field = tryField; 107 break; 108 } 109 } 110 if (field == null) { 111 throw new IllegalArgumentException 112 ("Composite key field is not an instance field:" + 113 getClassName() + '.' + fieldName); 114 } 115 fields.add(field); 116 instanceFields.remove(field); 117 if (!SimpleCatalog.isSimpleType(field.getFieldClass())) { 118 throw new IllegalArgumentException 119 ("Composite key field is not a simple type: " + 120 getClassName() + '.' + fieldName); 121 } 122 } 123 if (instanceFields.size() > 0) { 124 throw new IllegalArgumentException 125 ("All composite key instance fields must be key fields: " + 126 getClassName() + '.' + instanceFields.get(0).getName()); 127 } 128 } 129 130 @Override 131 void migrateFromBeta(Map <String ,Format> formatMap) { 132 super.migrateFromBeta(formatMap); 133 for (FieldInfo field : fields) { 134 field.migrateFromBeta(formatMap); 135 } 136 } 137 138 @Override 139 boolean isModelClass() { 140 return true; 141 } 142 143 @Override 144 ClassMetadata getClassMetadata() { 145 if (metadata == null) { 146 throw new IllegalStateException (getClassName()); 147 } 148 return metadata; 149 } 150 151 @Override 152 public Map <String ,RawField> getFields() { 153 154 161 if (rawFields == null) { 162 Map <String ,RawField> map = new HashMap <String ,RawField>(); 163 for (RawField field : fields) { 164 map.put(field.getName(), field); 165 } 166 rawFields = map; 167 } 168 return rawFields; 169 } 170 171 @Override 172 void collectRelatedFormats(Catalog catalog, 173 Map <String ,Format> newFormats) { 174 175 for (FieldInfo field : fields) { 176 field.collectRelatedFormats(catalog, newFormats); 177 } 178 } 179 180 @Override 181 void initialize(Catalog catalog) { 182 183 for (FieldInfo field : fields) { 184 field.initialize(catalog); 185 } 186 187 Class type = getType(); 188 if (type != null) { 189 if (EnhancedAccessor.isEnhanced(type)) { 190 objAccessor = new EnhancedAccessor(type); 191 } else { 192 objAccessor = new ReflectionAccessor(catalog, type, fields); 193 } 194 } 195 rawAccessor = new RawAccessor(this, fields); 196 } 197 198 @Override 199 Object newArray(int len) { 200 return objAccessor.newArray(len); 201 } 202 203 @Override 204 public Object newInstance(EntityInput input, boolean rawAccess) { 205 Accessor accessor = rawAccess ? rawAccessor : objAccessor; 206 return accessor.newInstance(); 207 } 208 209 @Override 210 public Object readObject(Object o, EntityInput input, boolean rawAccess) { 211 Accessor accessor = rawAccess ? rawAccessor : objAccessor; 212 accessor.readNonKeyFields(o, input, 0, Accessor.MAX_FIELD_NUM, -1); 213 return o; 214 } 215 216 @Override 217 void writeObject(Object o, EntityOutput output, boolean rawAccess) { 218 Accessor accessor = rawAccess ? rawAccessor : objAccessor; 219 accessor.writeNonKeyFields(o, output); 220 } 221 222 @Override 223 Object convertRawObject(Catalog catalog, 224 boolean rawAccess, 225 RawObject rawObject, 226 IdentityHashMap converted) { 227 228 234 FieldInfo[] myFields = rawInputFields; 235 if (myFields == null) { 236 myFields = new FieldInfo[fields.size()]; 237 fields.toArray(myFields); 238 rawInputFields = myFields; 239 } 240 if (rawObject.getSuper() != null) { 241 throw new IllegalArgumentException 242 ("RawObject has too many superclasses: " + 243 rawObject.getType().getClassName()); 244 } 245 RawObject[] objects = new RawObject[myFields.length]; 246 Arrays.fill(objects, rawObject); 247 EntityInput in = new RawComplexInput 248 (catalog, rawAccess, converted, myFields, objects); 249 Object o = newInstance(in, rawAccess); 250 converted.put(rawObject, o); 251 return readObject(o, in, rawAccess); 252 } 253 254 @Override 255 void skipContents(RecordInput input) { 256 int maxNum = fields.size(); 257 for (int i = 0; i < maxNum; i += 1) { 258 fields.get(i).getType().skipContents(input); 259 } 260 } 261 262 @Override 263 void copySecKey(RecordInput input, RecordOutput output) { 264 int maxNum = fields.size(); 265 for (int i = 0; i < maxNum; i += 1) { 266 fields.get(i).getType().copySecKey(input, output); 267 } 268 } 269 270 @Override 271 boolean evolve(Format newFormatParam, Evolver evolver) { 272 273 274 if (!(newFormatParam instanceof CompositeKeyFormat)) { 275 evolver.addEvolveError 276 (this, newFormatParam, null, 277 "A composite key class may not be changed to a different " + 278 "type"); 279 return false; 280 } 281 CompositeKeyFormat newFormat = (CompositeKeyFormat) newFormatParam; 282 283 284 if (fields.size() != newFormat.fields.size()) { 285 evolver.addEvolveError 286 (this, newFormat, 287 "Composite key class fields were added or removed ", 288 "Old fields: " + fields + 289 " new fields: " + newFormat.fields); 290 return false; 291 } 292 293 294 boolean newVersion = false; 295 for (int i = 0; i < fields.size(); i += 1) { 296 int result = evolver.evolveRequiredKeyField 297 (this, newFormat, fields.get(i), 298 newFormat.fields.get(i)); 299 if (result == Evolver.EVOLVE_FAILURE) { 300 return false; 301 } 302 if (result == Evolver.EVOLVE_NEEDED) { 303 newVersion = true; 304 } 305 } 306 307 313 if (newVersion) { 314 evolver.useEvolvedFormat(this, newFormat, newFormat); 315 } else { 316 evolver.useOldFormat(this, newFormat); 317 } 318 return true; 319 } 320 } 321 | Popular Tags |