MarshallerReaderContext context ) throws IOException,
ClassNotFoundException {
ObjectInputStream stream = context.stream;
Map<Integer, BaseNode> sinks = context.sinks;
LeftTupleSink sink = parentLeftTuple.getLeftTupleSink();
switch (sink.getType()) {
case NodeTypeEnums.JoinNode: {
BetaMemory memory = (BetaMemory) context.wm.getNodeMemory( (BetaNode) sink );
addToLeftMemory( parentLeftTuple,
memory );
while (stream.readShort() == PersisterEnums.RIGHT_TUPLE) {
int childSinkId = stream.readInt();
LeftTupleSink childSink = (LeftTupleSink) sinks.get( childSinkId );
int factHandleId = stream.readInt();
RightTupleKey key = new RightTupleKey( factHandleId,
sink );
RightTuple rightTuple = context.rightTuples.get( key );
LeftTuple childLeftTuple = childSink.createLeftTuple( parentLeftTuple,
rightTuple,
null,
null,
childSink,
true );
readLeftTuple( childLeftTuple,
context );
}
break;
}
case NodeTypeEnums.EvalConditionNode: {
while (stream.readShort() == PersisterEnums.LEFT_TUPLE) {
LeftTupleSink childSink = (LeftTupleSink) sinks.get( stream.readInt() );
LeftTuple childLeftTuple = childSink.createLeftTuple( parentLeftTuple,
childSink,
true );
readLeftTuple( childLeftTuple,
context );
}
break;
}
case NodeTypeEnums.NotNode:
case NodeTypeEnums.ForallNotNode: {
BetaMemory memory = (BetaMemory) context.wm.getNodeMemory( (BetaNode) sink );
int type = stream.readShort();
if (type == PersisterEnums.LEFT_TUPLE_NOT_BLOCKED) {
addToLeftMemory( parentLeftTuple,
memory );
while (stream.readShort() == PersisterEnums.LEFT_TUPLE) {
LeftTupleSink childSink = (LeftTupleSink) sinks.get( stream.readInt() );
LeftTuple childLeftTuple = childSink.createLeftTuple( parentLeftTuple,
childSink,
true );
readLeftTuple( childLeftTuple,
context );
}
} else {
int factHandleId = stream.readInt();
RightTupleKey key = new RightTupleKey( factHandleId,
sink );
RightTuple rightTuple = context.rightTuples.get( key );
parentLeftTuple.setBlocker( rightTuple );
rightTuple.addBlocked( parentLeftTuple );
}
break;
}
case NodeTypeEnums.ExistsNode: {
BetaMemory memory = (BetaMemory) context.wm.getNodeMemory( (BetaNode) sink );
int type = stream.readShort();
if (type == PersisterEnums.LEFT_TUPLE_NOT_BLOCKED) {
addToLeftMemory( parentLeftTuple,
memory );
} else {
int factHandleId = stream.readInt();
RightTupleKey key = new RightTupleKey( factHandleId,
sink );
RightTuple rightTuple = context.rightTuples.get( key );
parentLeftTuple.setBlocker( rightTuple );
rightTuple.addBlocked( parentLeftTuple );
while (stream.readShort() == PersisterEnums.LEFT_TUPLE) {
LeftTupleSink childSink = (LeftTupleSink) sinks.get( stream.readInt() );
LeftTuple childLeftTuple = childSink.createLeftTuple( parentLeftTuple,
childSink,
true );
readLeftTuple( childLeftTuple,
context );
}
}
break;
}
case NodeTypeEnums.AccumulateNode: {
// accumulate nodes generate new facts on-demand and need special procedures when de-serializing from persistent storage
AccumulateMemory memory = (AccumulateMemory) context.wm.getNodeMemory( (BetaNode) sink );
memory.betaMemory.getLeftTupleMemory().add( parentLeftTuple );
AccumulateContext accctx = new AccumulateContext();
parentLeftTuple.setObject( accctx );
// first we de-serialize the generated fact handle
InternalFactHandle handle = readFactHandle( context );
accctx.result = new RightTuple( handle,
(RightTupleSink) sink );
// then we de-serialize the associated accumulation context
accctx.context = (Serializable[]) stream.readObject();
// then we de-serialize the boolean propagated flag
accctx.propagated = stream.readBoolean();
// then we de-serialize all the propagated tuples
short head = -1;
while (( head = stream.readShort() ) != PersisterEnums.END) {
switch (head) {
case PersisterEnums.RIGHT_TUPLE: {
int factHandleId = stream.readInt();
RightTupleKey key = new RightTupleKey( factHandleId,
sink );
RightTuple rightTuple = context.rightTuples.get( key );
// just wiring up the match record
sink.createLeftTuple( parentLeftTuple,
rightTuple,
null,
null,
sink,
true );
break;
}
case PersisterEnums.LEFT_TUPLE: {
int sinkId = stream.readInt();
LeftTupleSink childSink = (LeftTupleSink) sinks.get( sinkId );
LeftTuple childLeftTuple = new LeftTupleImpl( parentLeftTuple,
accctx.result,
childSink,
true );
readLeftTuple( childLeftTuple,
context );
break;
}
default: {
throw new RuntimeDroolsException(
"Marshalling error. This is a bug. Please contact the development team." );
}
}
}
break;
}
case NodeTypeEnums.RightInputAdaterNode: {
// RIANs generate new fact handles on-demand to wrap tuples and need special procedures when de-serializing from persistent storage
ObjectHashMap memory = (ObjectHashMap) context.wm.getNodeMemory( (MemoryFactory) sink );
// create fact handle
int id = stream.readInt();
long recency = stream.readLong();
InternalFactHandle handle = new DefaultFactHandle(
id,
parentLeftTuple,
recency,
context.wm.getEntryPoints().get( EntryPoint.DEFAULT.getEntryPointId() ) );
memory.put( parentLeftTuple,
handle );
readRightTuples( handle,
context );
stream.readShort(); // Persistence.END
break;
}
case NodeTypeEnums.FromNode: {
// context.out.println( "FromNode" );
// FNs generate new fact handles on-demand to wrap objects and need special procedures when serializing to persistent storage
FromMemory memory = (FromMemory) context.wm.getNodeMemory( (MemoryFactory) sink );
memory.betaMemory.getLeftTupleMemory().add( parentLeftTuple );
Map<Object, RightTuple> matches = new LinkedHashMap<Object, RightTuple>();
parentLeftTuple.setObject( matches );
while (stream.readShort() == PersisterEnums.FACT_HANDLE) {
// we de-serialize the generated fact handle ID
InternalFactHandle handle = readFactHandle( context );
context.handles.put( handle.getId(),
handle );
readRightTuples( handle,
context );
matches.put( handle.getObject(),
handle.getFirstRightTuple() );
}
while (stream.readShort() == PersisterEnums.RIGHT_TUPLE) {
LeftTupleSink childSink = (LeftTupleSink) sinks.get( stream.readInt() );
int factHandleId = stream.readInt();
RightTupleKey key = new RightTupleKey( factHandleId,
null ); // created tuples in from node always use null sink
RightTuple rightTuple = context.rightTuples.get( key );
LeftTuple childLeftTuple = new LeftTupleImpl( parentLeftTuple,
rightTuple,
childSink,
true );
readLeftTuple( childLeftTuple,
context );
}
// context.out.println( "FromNode --- END" );
break;
}
case NodeTypeEnums.UnificationNode: {
boolean isOpen = context.readBoolean();
if (isOpen) {
QueryElementNode node = (QueryElementNode) sink;
InternalFactHandle handle = readFactHandle( context );
context.handles.put( handle.getId(),
handle );
node.createDroolsQuery( parentLeftTuple,
handle,
context.wm );
readLeftTuples( context );
} else {
while (stream.readShort() == PersisterEnums.LEFT_TUPLE) {
LeftTupleSink childSink = (LeftTupleSink) sinks.get( stream.readInt() );
// we de-serialize the generated fact handle ID
InternalFactHandle handle = readFactHandle( context );
context.handles.put( handle.getId(),
handle );
RightTuple rightTuple = new RightTuple( handle );
// @TODO check if open query
LeftTuple childLeftTuple = new LeftTupleImpl( parentLeftTuple,
rightTuple,
childSink,
true );
readLeftTuple( childLeftTuple,
context );
}
}
break;
}
case NodeTypeEnums.RuleTerminalNode: {
int pos = context.terminalTupleMap.size();
context.terminalTupleMap.put( pos,
parentLeftTuple );
break;
}
case NodeTypeEnums.QueryTerminalNode: {
boolean unificationNode = context.readBoolean();
if (unificationNode) {
// we de-serialize the generated fact handle ID
InternalFactHandle handle = readFactHandle( context );
context.handles.put( handle.getId(),
handle );
RightTuple rightTuple = new RightTuple( handle );
parentLeftTuple.setObject( rightTuple );
LeftTuple entry = parentLeftTuple;
// find the DroolsQuery object
while (entry.getParent() != null) {
entry = entry.getParent();
}
DroolsQuery query = (DroolsQuery) entry.getLastHandle().getObject();
LeftTuple leftTuple = ( (UnificationNodeViewChangedEventListener) query.getQueryResultCollector() ).getLeftTuple();
while (stream.readShort() == PersisterEnums.LEFT_TUPLE) {
LeftTupleSink childSink = (LeftTupleSink) sinks.get( stream.readInt() );
// @TODO check if open query!!!
LeftTuple childLeftTuple = childSink.createLeftTuple( leftTuple,
rightTuple,
childSink );
readLeftTuple( childLeftTuple,
context );
}