/** * Utility method for getting or creating a format as appropriate for bindings and key creators. */ static Format getOrCreateFormat(Catalog useCatalog, String clsName, boolean rawAccess) throws RefreshException { if (rawAccess) { Format format = useCatalog.getFormat(clsName); if (format == null) { throw new IllegalArgumentException("Not a persistent class: " + clsName); } return format; } else { Class cls = useCatalog.resolveKeyClass(clsName); return useCatalog.getFormat(cls, true /*checkEntitySubclassIndexes*/); } }
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; }
public Format getFormat(final String className) { if (formatMap != null) { final Format f = formatMap.get(className); if (f != null) { return f; } } return simpleCatalog.getFormat(className); }
@Override void initialize(Catalog catalog, EntityModel model, int initVersion) { /* Set the component format for a new (never initialized) format. */ if (componentFormat == null) { Class cls = getType().getComponentType(); componentFormat = catalog.getFormat(cls.getName()); } useComponentFormat = componentFormat.getLatestVersion(); }
@Override void initialize(Catalog catalog, EntityModel model, int initVersion) { /* Set the proxy format for a new (never initialized) format. */ if (proxyFormat == null) { assert proxyClassName != null; proxyFormat = catalog.getFormat(proxyClassName); } /* Make the linkage from proxy format to proxied format. */ proxyFormat.setProxiedFormat(this); }
/** @see EntityInput#skipField */ public void skipField(Format declaredFormat) { if (declaredFormat != null && declaredFormat.isPrimitive()) { declaredFormat.skipContents(this); } else { int formatId = readPackedInt(); if (formatId > 0) { Format format = catalog.getFormat(formatId, true /*expectStored*/); format.skipContents(this); } } }
void initialize(Catalog catalog, int initVersion) { /* * Reset the format if it was never initialized, which can occur when a * new format instance created during class evolution and discarded * because nothing changed. [#16233] * * Note that the format field may be null when used in a composite key * format used as a key comparator (via PersistComparator). In that * case (null format), we must not attempt to reset the format. */ if (format != null && format.isNew()) { format = catalog.getFormat(className); } }
/** * Creates the instance, reads the entity key first to track visited entities correctly, then * reads the data and returns the entity. * * <p>This is a special case of EntityInput.readObject for a top level entity. Special treatments * are: - The formatId must be >= 0; since this is the top level instance, it cannot refer to a * visited object nor be a null reference. - The entity is not checked for existence in the * visited object set; entities cannot be referenced by another entity. - Reader.readPriKey must * be called prior to calling Reader.readObject. */ static Object readEntity( Catalog useCatalog, DatabaseEntry key, Object priKey, DatabaseEntry data, boolean rawAccess) throws RefreshException { RecordInput dataInput = new RecordInput( useCatalog, rawAccess, null, 0, data.getData(), data.getOffset(), data.getSize()); int initialOffset = dataInput.getBufferOffset(); int formatId = dataInput.readPackedInt(); Format format = useCatalog.getFormat(formatId, true /*expectStored*/); dataInput.registerEntityFormat(format); Reader reader = format.getReader(); Object entity = reader.newInstance(dataInput, rawAccess); if (priKey == null) { /* If priKey is null, need to deserialize the primary key. */ RecordInput keyInput = new RecordInput( useCatalog, rawAccess, null, 0, key.getData(), key.getOffset(), key.getSize()); reader.readPriKey(entity, keyInput, rawAccess); } else { /* * If priKey is not null, directly assign it to the primary key * field. [#19248] */ Accessor accessor = reader.getAccessor(entity instanceof RawObject ? true : rawAccess); if (accessor == null) { accessor = format .getLatestVersion() .getReader() .getAccessor(entity instanceof RawObject ? true : rawAccess); } accessor.setPriField(entity, priKey); } dataInput.registerEntity(entity, initialOffset); entity = reader.readObject(entity, dataInput, rawAccess); return entity; }
/** * Called when copying secondary keys, for an input that is positioned on the secondary key field. * Handles references to previously occurring objects, returning a different RecordInput than this * one if appropriate. */ KeyLocation getKeyLocation(Format fieldFormat) { RecordInput input = this; if (!fieldFormat.isPrimitive()) { int formatId = input.readPackedInt(); if (formatId == Format.ID_NULL) { /* Key field is null. */ return null; } if (formatId < 0) { int offset = (-(formatId + 1)); if (offset == RecordInput.PRI_KEY_VISITED_OFFSET) { assert priKeyEntry != null && priKeyFormatId > 0; input = new RecordInput(this, priKeyEntry); formatId = priKeyFormatId; } else { input = new RecordInput(this, offset); formatId = input.readPackedInt(); } } fieldFormat = catalog.getFormat(formatId, true /*expectStored*/); } /* Key field is non-null. */ return new KeyLocation(input, fieldFormat); }
public Format getFormat(final Class cls, final boolean checkEntitySubclassIndexes) { return simpleCatalog.getFormat(cls, checkEntitySubclassIndexes); }
public Format getFormat(final int formatId, final boolean expectStored) { return simpleCatalog.getFormat(formatId, expectStored); }
/** See Store.refresh. */ void refresh(final PersistCatalog newCatalog) { catalog = newCatalog; entityFormat = catalog.getFormat(entityFormat.getClassName()); keyFieldFormat = catalog.getFormat(keyFieldFormat.getClassName()); }
/** @see EntityInput#readObject */ public Object readObject() { /* Save the current offset before reading the format ID. */ Integer visitedOffset = off; RecordInput useInput = this; int formatId = readPackedInt(); Object o = null; /* For a zero format ID, return a null instance. */ if (formatId == Format.ID_NULL) { return null; } /* For a negative format ID, lookup an already visited instance. */ if (formatId < 0) { int offset = (-(formatId + 1)); if (visited != null) { o = visited.get(offset); } if (o == RecordInput.PROHIBIT_REF_OBJECT) { throw new IllegalArgumentException(RecordInput.PROHIBIT_NESTED_REF_MSG); } if (o != null) { /* Return a previously visited object. */ return o; } else { /* * When reading starts from a non-zero offset, we may have to * go back in the stream and read the referenced object. This * happens when reading secondary key fields. */ visitedOffset = offset; if (offset == RecordInput.PRI_KEY_VISITED_OFFSET) { assert priKeyEntry != null && priKeyFormatId > 0; useInput = new RecordInput(this, priKeyEntry); formatId = priKeyFormatId; } else { useInput = new RecordInput(this, offset); formatId = useInput.readPackedInt(); } } } /* * Add a visted object slot that prohibits nested references to this * object during the call to Reader.newInstance below. The newInstance * method is allowed to read nested fields (in which case * Reader.readObject further below does nothing) under certain * conditions, but under these conditions we do not support nested * references to the parent object. [#15815] */ if (visited == null) { visited = new HashMap<Integer, Object>(VISITED_INIT_SIZE); } visited.put(visitedOffset, RecordInput.PROHIBIT_REF_OBJECT); /* Create the object using the format indicated. */ Format format = catalog.getFormat(formatId, true /*expectStored*/); Reader reader = format.getReader(); o = reader.newInstance(useInput, rawAccess); /* * Set the newly created object in the map of visited objects. This * must be done before calling Reader.readObject, which allows the * object to contain a reference to itself. */ visited.put(visitedOffset, o); /* * Finish reading the object. Then replace it in the visited map in * case a converted object is returned by readObject. */ Object o2 = reader.readObject(o, useInput, rawAccess); if (o != o2) { visited.put(visitedOffset, o2); } return o2; }