@Override public Object newInstance(EntityInput input, boolean rawAccess) { Reader reader = proxyFormat.getReader(); if (rawAccess) { return reader.newInstance(null, true); } else { PersistentProxy proxy = (PersistentProxy) reader.newInstance(null, false); proxy = (PersistentProxy) reader.readObject(proxy, input, false); return proxy.convertProxy(); } }
/** @see EntityInput#readKeyObject */ public Object readKeyObject(Format format) { /* Create and read the object using the given key format. */ Reader reader = format.getReader(); Object o = reader.newInstance(this, rawAccess); return reader.readObject(o, this, rawAccess); }
/** * 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; }
/** @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; }