@Override boolean evolve(Format newFormatParam, Evolver evolver) { if (!(newFormatParam instanceof ProxiedFormat)) { evolver.addEvolveError( this, newFormatParam, null, "A proxied class may not be changed to a different type"); return false; } ProxiedFormat newFormat = (ProxiedFormat) newFormatParam; if (!evolver.evolveFormat(proxyFormat)) { return false; } Format newProxyFormat = proxyFormat.getLatestVersion(); if (!newProxyFormat.getClassName().equals(newFormat.getProxyClassName())) { evolver.addEvolveError( this, newFormat, null, "The proxy class for this type has been changed from: " + newProxyFormat.getClassName() + " to: " + newFormat.getProxyClassName()); return false; } if (newProxyFormat != proxyFormat) { evolver.useEvolvedFormat(this, this, newFormat); } else { evolver.useOldFormat(this, newFormat); } return true; }
static Format checkRawType(Catalog catalog, Object o, Format declaredFormat) { assert declaredFormat != null; Format format; if (o instanceof RawObject) { format = (Format) ((RawObject) o).getType(); } else { format = catalog.getFormat(o.getClass()); if (!format.isSimple() || format.isEnum()) { throw new IllegalArgumentException( "Not a RawObject or a non-enum simple type: " + format.getClassName()); } } if (!format.isAssignableTo(declaredFormat)) { throw new IllegalArgumentException( "Not a subtype of the field's declared class " + declaredFormat.getClassName() + ": " + format.getClassName()); } if (!format.isCurrentVersion()) { throw new IllegalArgumentException( "Raw type version is not current. Class: " + format.getClassName() + " Version: " + format.getVersion()); } Format proxiedFormat = format.getProxiedFormat(); if (proxiedFormat != null) { format = proxiedFormat; } return format; }
/** * Returns the format for the given entity and validates it, throwing an exception if it is * invalid for this binding. */ private Format getValidFormat(Object entity) throws RefreshException { /* A null entity is not allowed. */ if (entity == null) { throw new IllegalArgumentException("An entity may not be null"); } /* * Get the format. getFormat throws IllegalArgumentException if the * class is not persistent. */ Format format; if (rawAccess) { if (!(entity instanceof RawObject)) { throw new IllegalArgumentException("Entity must be a RawObject"); } format = (Format) ((RawObject) entity).getType(); } else { format = catalog.getFormat(entity.getClass(), true /*checkEntitySubclassIndexes*/); } /* Check that the entity class/subclass is valid for this binding. */ if (format.getEntityFormat() != entityFormat) { throw new IllegalArgumentException( "The entity class (" + format.getClassName() + ") must be this entity class or a subclass of it: " + entityFormat.getClassName()); } return format; }
/** See Store.refresh. */ void refresh(final PersistCatalog newCatalog) { catalog = newCatalog; entityFormat = newCatalog.getFormat(entityFormat.getClassName()); if (keyAssigner != null) { keyAssigner.refresh(newCatalog); } }
/** * Returns the proxy class name. The proxyClassName field is non-null for a constructed object and * null for a de-serialized object. Whenever the proxyClassName field is null (for a de-serialized * object), the proxyFormat will be non-null. */ private String getProxyClassName() { if (proxyClassName != null) { return proxyClassName; } else { assert proxyFormat != null; return proxyFormat.getClassName(); } }
@Override boolean evolve(Format newFormat, Evolver evolver) { /* * When the class name of the component changes, we need a new format * that references it. Otherwise, don't propogate changes from * components upward to their arrays. */ Format latest = componentFormat.getLatestVersion(); if (latest != componentFormat && !latest.getClassName().equals(componentFormat.getClassName())) { evolver.useEvolvedFormat(this, newFormat, newFormat); } else { evolver.useOldFormat(this, newFormat); } return true; }
@Override void copySecMultiKey(RecordInput input, Format keyFormat, Set results) throws RefreshException { int len = input.readPackedInt(); for (int i = 0; i < len; i += 1) { KeyLocation loc = input.getKeyLocation(useComponentFormat); if (loc == null) { throw new IllegalArgumentException("Secondary key values in array may not be null"); } if (loc.format != useComponentFormat) { throw DbCompat.unexpectedState(useComponentFormat.getClassName()); } int off1 = loc.input.getBufferOffset(); useComponentFormat.skipContents(loc.input); int off2 = loc.input.getBufferOffset(); DatabaseEntry entry = new DatabaseEntry(loc.input.getBufferBytes(), off1, off2 - off1); results.add(entry); } }
/** See Store.refresh. */ void refresh(final PersistCatalog newCatalog) { catalog = newCatalog; entityFormat = catalog.getFormat(entityFormat.getClassName()); keyFieldFormat = catalog.getFormat(keyFieldFormat.getClassName()); }
Object checkAndConvert(Object o, Format declaredFormat) { if (o == null) { if (declaredFormat.isPrimitive()) { throw new IllegalArgumentException( "A primitive type may not be null or missing: " + declaredFormat.getClassName()); } } else if (declaredFormat.isSimple()) { if (declaredFormat.isPrimitive()) { if (o.getClass() != declaredFormat.getWrapperFormat().getType()) { throw new IllegalArgumentException( "Raw value class: " + o.getClass().getName() + " must be the wrapper class for a primitive type: " + declaredFormat.getClassName()); } } else { if (o.getClass() != declaredFormat.getType()) { throw new IllegalArgumentException( "Raw value class: " + o.getClass().getName() + " must be the declared class for a simple type: " + declaredFormat.getClassName()); } } } else { if (o instanceof RawObject) { Object o2 = null; if (!rawAccess) { if (converted != null) { o2 = converted.get(o); } else { converted = new IdentityHashMap(); } } if (o2 != null) { o = o2; } else { if (!rawAccess) { o = catalog.convertRawObject((RawObject) o, converted); } } } else { if (!SimpleCatalog.isSimpleType(o.getClass())) { throw new IllegalArgumentException( "Raw value class: " + o.getClass().getName() + " must be RawObject a simple type"); } } if (rawAccess) { checkRawType(catalog, o, declaredFormat); } else { if (!declaredFormat.getType().isAssignableFrom(o.getClass())) { throw new IllegalArgumentException( "Raw value class: " + o.getClass().getName() + " is not assignable to type: " + declaredFormat.getClassName()); } } } return o; }
private void evolveIndex(Format format, EvolveEvent event, EvolveListener listener) throws DatabaseException { Class entityClass = format.getType(); String entityClassName = format.getClassName(); EntityMetadata meta = model.getEntityMetadata(entityClassName); String keyClassName = meta.getPrimaryKey().getClassName(); keyClassName = SimpleCatalog.keyClassName(keyClassName); DatabaseConfig dbConfig = getPrimaryConfig(meta); PrimaryIndex<Object, Object> index = getPrimaryIndex(Object.class, keyClassName, entityClass, entityClassName); Database db = index.getDatabase(); EntityBinding binding = index.getEntityBinding(); DatabaseEntry key = new DatabaseEntry(); DatabaseEntry data = new DatabaseEntry(); Cursor readCursor = db.openCursor(null, CursorConfig.READ_UNCOMMITTED); try { while (readCursor.getNext(key, data, null) == OperationStatus.SUCCESS) { if (evolveNeeded(key, data, binding)) { Transaction txn = null; if (dbConfig.getTransactional()) { boolean success = false; txn = env.beginTransaction(null, null); } boolean doCommit = false; Cursor writeCursor = null; try { writeCursor = db.openCursor(txn, null); if (writeCursor.getSearchKey(key, data, LockMode.RMW) == OperationStatus.SUCCESS) { boolean written = false; if (evolveNeeded(key, data, binding)) { writeCursor.putCurrent(data); written = true; } if (listener != null) { EvolveInternal.updateEvent(event, entityClassName, 1, written ? 1 : 0); if (!listener.evolveProgress(event)) { break; } } } } finally { if (writeCursor != null) { writeCursor.close(); } if (txn != null) { if (doCommit) { txn.commit(); } else { txn.abort(); } } } } } } finally { readCursor.close(); } }