* @return the actual attached node that may be the one given as parameter
* or eventually one that was already in the cache if sharing is enabled
*/
public BaseNode attachNode(final BuildContext context,
final BaseNode candidate) {
BaseNode node = null;
RuleBasePartitionId partition = null;
if ( candidate.getType() == NodeTypeEnums.EntryPointNode ) {
// entry point nodes are always shared
node = context.getKnowledgeBase().getRete().getEntryPointNode( ((EntryPointNode) candidate).getEntryPoint() );
// all EntryPointNodes belong to the main partition
partition = RuleBasePartitionId.MAIN_PARTITION;
} else if ( candidate.getType() == NodeTypeEnums.ObjectTypeNode ) {
// object type nodes are always shared
Map<ObjectType, ObjectTypeNode> map = context.getKnowledgeBase().getRete().getObjectTypeNodes( context.getCurrentEntryPoint() );
if ( map != null ) {
ObjectTypeNode otn = map.get( ((ObjectTypeNode) candidate).getObjectType() );
if ( otn != null ) {
// adjusting expiration offset
otn.setExpirationOffset( Math.max( otn.getExpirationOffset(),
((ObjectTypeNode) candidate).getExpirationOffset() ) );
node = otn;
}
}
// all ObjectTypeNodes belong to the main partition
partition = RuleBasePartitionId.MAIN_PARTITION;
} else if ( isSharingEnabledForNode( context,
candidate ) ) {
if ( (context.getTupleSource() != null) && NodeTypeEnums.isLeftTupleSink( candidate ) ) {
node = context.getTupleSource().getSinkPropagator().getMatchingNode( candidate );
} else if ( (context.getObjectSource() != null) && NodeTypeEnums.isObjectSink( candidate ) ) {
node = context.getObjectSource().getSinkPropagator().getMatchingNode( candidate );
} else {
throw new RuntimeException( "This is a bug on node sharing verification. Please report to development team." );
}
}
if ( node == null || node.isStreamMode() ) {
// SteamMode in Phreak does not allow sharing
// only attach() if it is a new node
node = candidate;
// new node, so it must be labeled
if ( partition == null ) {
// if it does not has a predefined label
if ( context.getPartitionId() == null ) {
// if no label in current context, create one
context.setPartitionId( context.getKnowledgeBase().createNewPartitionId() );
}
partition = context.getPartitionId();
}
// set node whit the actual partition label
node.setPartitionId( partition );
node.attach(context);
// adds the node to the context list to track all added nodes
context.getNodes().add( node );
} else {
// shared node found
mergeNodes(node, candidate);
// undo previous id assignment
context.releaseId( candidate.getId() );
}
node.addAssociation( context.getRule(), context.peekRuleComponent() );
return node;
}