package com.sleepycat.persist.impl;
import com.sleepycat.bind.tuple.TupleOutput;
import com.sleepycat.persist.raw.RawObject;
class RecordOutput extends TupleOutput implements EntityOutput {
private Catalog catalog;
private boolean rawAccess;
private VisitedObjects visited;
RecordOutput(Catalog catalog, boolean rawAccess) {
super();
this.catalog = catalog;
this.rawAccess = rawAccess;
}
public void writeObject(Object o, Format fieldFormat) {
if (o == null) {
writePackedInt(Format.ID_NULL);
return;
}
if (visited != null) {
int offset = visited.getOffset(o);
if (offset == VisitedObjects.PROHIBIT_REF_OFFSET) {
throw new IllegalArgumentException
(VisitedObjects.PROHIBIT_NESTED_REF_MSG);
}
if (offset > 0) {
writePackedInt(-(offset + 1));
return;
}
}
Format format;
if (rawAccess) {
format = RawAbstractInput.checkRawType(catalog, o, fieldFormat);
} else {
format = catalog.getFormat(o.getClass());
}
if (format.getProxiedFormat() != null) {
throw new IllegalArgumentException
("May not store proxy classes directly: " +
format.getClassName());
}
if (format.isEntity()) {
throw new IllegalArgumentException
("References to entities are not allowed: " +
o.getClass().getName());
}
if (visited == null) {
visited = new VisitedObjects();
}
boolean prohibitNestedRefs = format.areNestedRefsProhibited();
int visitedOffset = size();
int visitedIndex = visited.add(o, prohibitNestedRefs ?
VisitedObjects.PROHIBIT_REF_OFFSET :
visitedOffset);
writePackedInt(format.getId());
format.writeObject(o, this, rawAccess);
if (prohibitNestedRefs) {
visited.setOffset(visitedIndex, visitedOffset);
}
}
public void writeKeyObject(Object o, Format fieldFormat) {
if (o == null) {
throw new IllegalArgumentException
("Key field object may not be null");
}
Format format;
if (rawAccess) {
if (o instanceof RawObject) {
format = (Format) ((RawObject) o).getType();
} else {
format = catalog.getFormat(o.getClass());
if (fieldFormat.isPrimitive()) {
fieldFormat = fieldFormat.getWrapperFormat();
}
}
} else {
format = catalog.getFormat(o.getClass());
}
if (fieldFormat != format) {
throw new IllegalArgumentException
("The key field object class (" + o.getClass().getName() +
") must be the field's declared class: " +
fieldFormat.getClassName());
}
fieldFormat.writeObject(o, this, rawAccess);
}
public void registerPriKeyObject(Object o) {
if (visited == null) {
visited = new VisitedObjects();
}
visited.add(o, VisitedObjects.PRI_KEY_VISITED_OFFSET);
}
public void writeArrayLength(int length) {
writePackedInt(length);
}
public void writeEnumConstant(String[] names, int index) {
writePackedInt(index);
}
}