package ecologylab.bigsemantics.metadata;
import java.util.EmptyStackException;
import java.util.Stack;
import ecologylab.bigsemantics.collecting.SemanticsGlobalScope;
import ecologylab.bigsemantics.metadata.builtins.Document;
import ecologylab.bigsemantics.metametadata.MetaMetadata;
import ecologylab.bigsemantics.metametadata.MetaMetadataCompositeField;
import ecologylab.bigsemantics.metametadata.MetaMetadataNestedField;
import ecologylab.generic.Debug;
import ecologylab.serialization.DeserializationHookStrategy;
import ecologylab.serialization.FieldDescriptor;
public class MetadataDeserializationHookStrategy implements
DeserializationHookStrategy<Object, FieldDescriptor>
{
SemanticsGlobalScope semanticsSessionScope;
Stack<MetaMetadataNestedField> currentMMStack = new Stack<MetaMetadataNestedField>();
boolean polymorphMmd = false;
public MetadataDeserializationHookStrategy(SemanticsGlobalScope sss)
{
this.semanticsSessionScope = sss;
}
private void pushToMmStack(MetaMetadataCompositeField field) {
currentMMStack.push(field);
// Debug.debugT(this, "\tpushed " + field);
}
private void popFromMmStack() {
MetaMetadataNestedField field = currentMMStack.pop();
// Debug.debugT(this, "\tpopped " + field);
}
@Override
public void deserializationPreHook(Object e, FieldDescriptor fd)
{
if (e instanceof Metadata)
{
Metadata deserializedMetadata = (Metadata) e;
if (currentMMStack.isEmpty())
{
MetaMetadataCompositeField deserializationMM = deserializedMetadata.getMetaMetadata();
pushToMmStack(deserializationMM);
}
else if (fd instanceof MetadataFieldDescriptor)
{
MetadataFieldDescriptor mfd = (MetadataFieldDescriptor) fd;
String mmName = mfd.getMmName();
MetaMetadataNestedField currentMM = currentMMStack.peek();
MetaMetadataNestedField childMMNested =
(MetaMetadataNestedField) currentMM.lookupChild(mmName);
MetaMetadataCompositeField childMMComposite = null;
if (childMMNested.isPolymorphicInherently())
{
String tagName = deserializedMetadata.getMetadataClassDescriptor().getTagName();
childMMComposite = semanticsSessionScope.getMetaMetadataRepository().getMMByName(tagName);
polymorphMmd = true;
}
else
{
childMMComposite = childMMNested.metaMetadataCompositeField();
}
deserializedMetadata.setMetaMetadata(childMMComposite);
pushToMmStack(childMMComposite);
}
else if (fd instanceof FieldDescriptor)
{
String tagName = ((Metadata) e).getMetadataClassDescriptor().getTagName();
MetaMetadataCompositeField childMMComposite =
semanticsSessionScope.getMetaMetadataRepository().getMMByName(tagName);
deserializedMetadata.setMetaMetadata(childMMComposite);
pushToMmStack(childMMComposite);
}
if (e instanceof Document)
((Document) e).setSemanticsSessionScope(semanticsSessionScope);
}
}
@Override
public void deserializationInHook(Object e, FieldDescriptor fd)
{
if (e instanceof Metadata)
{
if (polymorphMmd) // for efficiency; if it is not polymorphic case we don't have to look up
// mmd at this point of time
{
Metadata metadata = (Metadata) e;
String mmName = metadata.getMetaMetadataName();
if (mmName != null && mmName.length() > 0)
{
MetaMetadata trueMm = semanticsSessionScope.getMetaMetadataRepository()
.getMMByName(mmName);
if (trueMm != null)
{
// Debug.println(String.format("setting [%s].metaMetadata to %s (mm_name=%s)...",
// metadata,
// trueMm,
// mmName));
metadata.setMetaMetadata(trueMm);
}
else
{
Debug.warning(this.getClass(),
"polymorphicly looking up meta-metadata failed: cannot find mmd named as "
+ mmName);
}
}
polymorphMmd = false;
}
}
}
@Override
public void deserializationPostHook(Object e, FieldDescriptor fd)
{
if (e instanceof Metadata)
{
if (fd != null && !(fd instanceof MetadataFieldDescriptor))
Debug.warning(this, "deserializationPostHook(): call with non-metadata field descriptor! " +
"probably this is a mistake!");
else
{
try
{
popFromMmStack();
}
catch (EmptyStackException exception)
{
exception.printStackTrace();
}
}
}
}
@Override
public Object changeObjectIfNecessary(Object o, FieldDescriptor fd)
{
return o;
}
}