
org.nakedobjects.plugins.remoting.shared.ObjectEncoderSerializer Maven / Gradle / Ivy
package org.nakedobjects.plugins.remoting.shared;
import java.util.Enumeration;
import org.nakedobjects.metamodel.adapter.NakedObject;
import org.nakedobjects.metamodel.adapter.ResolveState;
import org.nakedobjects.metamodel.adapter.oid.Oid;
import org.nakedobjects.metamodel.commons.ensure.Assert;
import org.nakedobjects.metamodel.commons.exceptions.NakedObjectException;
import org.nakedobjects.metamodel.commons.exceptions.UnknownTypeException;
import org.nakedobjects.metamodel.facets.actcoll.typeof.TypeOfFacet;
import org.nakedobjects.metamodel.facets.collections.modify.CollectionFacet;
import org.nakedobjects.metamodel.facets.object.encodeable.EncodeableFacet;
import org.nakedobjects.metamodel.spec.feature.NakedObjectAssociation;
import org.nakedobjects.metamodel.util.CollectionFacetUtils;
import org.nakedobjects.plugins.remoting.shared.data.CollectionData;
import org.nakedobjects.plugins.remoting.shared.data.Data;
import org.nakedobjects.plugins.remoting.shared.data.DataFactory;
import org.nakedobjects.plugins.remoting.shared.data.EncodeableObjectData;
import org.nakedobjects.plugins.remoting.shared.data.KnownObjects;
import org.nakedobjects.plugins.remoting.shared.data.ObjectData;
import org.nakedobjects.plugins.remoting.shared.data.ReferenceData;
import org.nakedobjects.runtime.persistence.PersistorUtil;
/**
* Utility class to create Data objects representing a graph of NakedObjects.
*
* As each object is serialised its resolved state is changed to SERIALIZING; any object that is marked as
* SERIALIZING is skipped.
*/
final class ObjectEncoderSerializer {
private ObjectEncoderDataStructure dataStructure;
public CollectionData serializeCollection(
final DataFactory factory,
final NakedObject collectionAdapter,
final int graphDepth,
final KnownObjects knownObjects) {
final Oid oid = collectionAdapter.getOid();
final String collectionType = collectionAdapter.getSpecification().getFullName();
final TypeOfFacet typeOfFacet = collectionAdapter.getSpecification().getFacet(TypeOfFacet.class);
if (typeOfFacet == null) {
throw new NakedObjectException("No type of facet for collection " + collectionAdapter);
}
final String elementType = typeOfFacet.value().getName();
final boolean hasAllElements = collectionAdapter.isTransient() ||
collectionAdapter.getResolveState().isResolved();
ReferenceData[] elements;
if (hasAllElements) {
final CollectionFacet collectionFacet = CollectionFacetUtils.getCollectionFacetFromSpec(collectionAdapter);
final Enumeration e = collectionFacet.elements(collectionAdapter);
elements = new ReferenceData[collectionFacet.size(collectionAdapter)];
int i = 0;
while (e.hasMoreElements()) {
final NakedObject element = (NakedObject) e.nextElement();
elements[i++] = serializeObject(factory, element, graphDepth, knownObjects);
}
} else {
elements = new ObjectData[0];
}
return factory.createCollectionData(collectionType, elementType, oid, elements, hasAllElements, collectionAdapter.getVersion());
}
// TODO rename to serialise.,.,.
public final EncodeableObjectData serializeEncodeable(final DataFactory factory, final NakedObject object) {
final EncodeableFacet facet = object.getSpecification().getFacet(EncodeableFacet.class);
return factory.createValueData(object.getSpecification().getFullName(), facet.toEncodedString(object));
}
public final ReferenceData serializeObject(
final DataFactory factory,
final NakedObject object,
final int depth,
final KnownObjects knownObjects) {
Assert.assertNotNull(object);
return (ReferenceData) serializeObject2(factory, object, depth, knownObjects);
}
private final Data serializeObject2(
final DataFactory factory,
final NakedObject adapter,
final int graphDepth,
final KnownObjects knownObjects) {
Assert.assertNotNull(adapter);
final ResolveState resolveState = adapter.getResolveState();
boolean isTransient = adapter.isTransient();
if (!isTransient && (resolveState.isSerializing() || resolveState.isGhost() || graphDepth <= 0)) {
Assert.assertNotNull("OID needed for reference", adapter, adapter.getOid());
return factory.createIdentityData(adapter.getSpecification().getFullName(), adapter.getOid(), adapter.getVersion());
}
if (isTransient && knownObjects.containsKey(adapter)) {
return knownObjects.get(adapter);
}
boolean withCompleteData = resolveState == ResolveState.TRANSIENT || resolveState == ResolveState.RESOLVED;
final String type = adapter.getSpecification().getFullName();
final Oid oid = adapter.getOid();
final ObjectData data = factory.createObjectData(type, oid, withCompleteData, adapter.getVersion());
if (isTransient) {
knownObjects.put(adapter, data);
}
final NakedObjectAssociation[] fields = dataStructure.getFields(adapter.getSpecification());
final Data[] fieldContent = new Data[fields.length];
PersistorUtil.start(adapter, adapter.getResolveState().serializeFrom());
for (int i = 0; i < fields.length; i++) {
if (!fields[i].isPersisted()) {
continue;
}
final NakedObject field = fields[i].get(adapter);
if (fields[i].getSpecification().isEncodeable()) {
if (field == null) {
fieldContent[i] = factory.createNullData(fields[i].getSpecification().getFullName());
} else {
fieldContent[i] = serializeEncodeable(factory, field);
}
} else if (fields[i].isOneToManyAssociation()) {
fieldContent[i] = serializeCollection(factory, field, graphDepth - 1, knownObjects);
} else if (fields[i].isOneToOneAssociation()) {
if (field == null) {
fieldContent[i] = !withCompleteData ? null : factory.createNullData(fields[i].getSpecification()
.getFullName());
} else {
fieldContent[i] = serializeObject2(factory, field, graphDepth - 1, knownObjects);
}
} else {
throw new UnknownTypeException(fields[i]);
}
}
PersistorUtil.end(adapter);
data.setFieldContent(fieldContent);
return data;
}
public void setDataStructure(final ObjectEncoderDataStructure dataStructure) {
this.dataStructure = dataStructure;
}
}
// Copyright (c) Naked Objects Group Ltd.
© 2015 - 2025 Weber Informatics LLC | Privacy Policy