📄 reteoobuilder.java
字号:
this.objectSource,
binder,
column );
} else if ( this.objectSource != null ) {
this.tupleSource = attachNode( new JoinNode( this.id++,
this.tupleSource,
this.objectSource,
binder ) );
}
}
}
public BaseNode[] getTerminalNodes(final Rule rule) {
return (BaseNode[]) this.rules.remove( rule );
}
private void attachQuery(final String queryName) {
// incrementing offset adjustment, since we are adding a new ObjectNodeType as our
// first column
this.currentOffsetAdjustment += 1;
final ObjectSource objectTypeSource = attachNode( new ObjectTypeNode( this.id++,
this.sinklistFactory.newObjectSinkList( ObjectTypeNode.class ),
new ClassObjectType( DroolsQuery.class ),
this.rete ) );
final ClassFieldExtractor extractor = new ClassFieldExtractor( DroolsQuery.class,
"name" );
final FieldValue field = FieldFactory.getFieldValue( queryName,
Evaluator.STRING_TYPE );
final Evaluator evaluator = EvaluatorFactory.getEvaluator( Evaluator.STRING_TYPE,
Evaluator.EQUAL );
final LiteralConstraint constraint = new LiteralConstraint( field,
extractor,
evaluator );
final ObjectSource alphaNodeSource = attachNode( new AlphaNode( this.id++,
this.sinklistFactory.newObjectSinkList( AlphaNode.class ),
constraint,
objectTypeSource ) );
this.tupleSource = attachNode( new LeftInputAdapterNode( this.id++,
alphaNodeSource ) );
}
private BetaNodeBinder attachColumn(final Column column,
final GroupElement parent,
final boolean removeIdentities) throws InvalidPatternException {
// Adjusting offset in case a previous Initial-Fact was added to the network
column.adjustOffset( this.currentOffsetAdjustment );
// Check if the Column is bound
if ( column.getDeclaration() != null ) {
final Declaration declaration = column.getDeclaration();
// Add the declaration the map of previously bound declarations
this.declarations.put( declaration.getIdentifier(),
declaration );
}
final List predicates = attachAlphaNodes( column,
removeIdentities );
BetaNodeBinder binder;
if ( !predicates.isEmpty() ) {
binder = new BetaNodeBinder( (FieldConstraint[]) predicates.toArray( new FieldConstraint[predicates.size()] ) );
} else {
binder = new BetaNodeBinder();
}
return binder;
}
public List attachAlphaNodes(final Column column,
final boolean removeIdentities) throws InvalidPatternException {
final List constraints = column.getConstraints();
final Class thisClass = ((ClassObjectType) column.getObjectType()).getClassType();
this.objectSource = attachNode( new ObjectTypeNode( this.id++,
this.sinklistFactory.newObjectSinkList( ObjectTypeNode.class ),
column.getObjectType(),
this.rete ) );
final List predicateConstraints = new ArrayList();
if ( removeIdentities ) {
// Check if this object type exists before
// If it does we need stop instance equals cross product
for ( final Iterator it = this.objectType.entrySet().iterator(); it.hasNext(); ) {
final Map.Entry entry = (Map.Entry) it.next();
final Class previousClass = ((ClassObjectType) entry.getKey()).getClassType();
if ( thisClass.isAssignableFrom( previousClass ) ) {
predicateConstraints.add( new InstanceNotEqualsConstraint( ((Integer) entry.getValue()).intValue() ) );
}
}
// Must be added after the checking, otherwise it matches against itself
this.objectType.put( column.getObjectType(),
new Integer( column.getFactIndex() ) );
}
for ( final Iterator it = constraints.iterator(); it.hasNext(); ) {
final Object object = it.next();
// Check if its a declaration
if ( object instanceof Declaration ) {
final Declaration declaration = (Declaration) object;
// Add the declaration the map of previously bound declarations
this.declarations.put( declaration.getIdentifier(),
declaration );
continue;
}
final FieldConstraint fieldConstraint = (FieldConstraint) object;
if ( fieldConstraint instanceof LiteralConstraint ) {
this.objectSource = attachNode( new AlphaNode( this.id++,
this.sinklistFactory.newObjectSinkList( AlphaNode.class ),
fieldConstraint,
this.objectSource ) );
} else {
checkUnboundDeclarations( fieldConstraint.getRequiredDeclarations() );
predicateConstraints.add( fieldConstraint );
}
}
return predicateConstraints;
}
private void attachNot(final TupleSource tupleSource,
final Not not,
final ObjectSource ObjectSource,
final BetaNodeBinder binder,
final Column column) {
final NotNode notNode = (NotNode) attachNode( new NotNode( this.id++,
tupleSource,
ObjectSource,
binder ) );
if ( not.getChild() instanceof Not ) {
final RightInputAdapterNode adapter = (RightInputAdapterNode) attachNode( new RightInputAdapterNode( this.id++,
column.getFactIndex(),
notNode ) );
attachNot( tupleSource,
(Not) not.getChild(),
adapter,
new BetaNodeBinder(),
column );
} else if ( not.getChild() instanceof Exists ) {
final RightInputAdapterNode adapter = (RightInputAdapterNode) attachNode( new RightInputAdapterNode( this.id++,
column.getFactIndex(),
notNode ) );
attachExists( tupleSource,
(Exists) not.getChild(),
adapter,
new BetaNodeBinder(),
column );
} else {
this.tupleSource = notNode;
}
}
private void attachExists(final TupleSource tupleSource,
final Exists exists,
final ObjectSource ObjectSource,
final BetaNodeBinder binder,
final Column column) {
NotNode notNode = (NotNode) attachNode( new NotNode( this.id++,
tupleSource,
ObjectSource,
binder ) );
RightInputAdapterNode adapter = (RightInputAdapterNode) attachNode( new RightInputAdapterNode( this.id++,
column.getFactIndex(),
notNode ) );
BetaNodeBinder identityBinder = new BetaNodeBinder( new InstanceEqualsConstraint( column.getFactIndex() ) );
notNode = (NotNode) attachNode( new NotNode( this.id++,
tupleSource,
adapter,
identityBinder ) );
if ( exists.getChild() instanceof Not ) {
adapter = (RightInputAdapterNode) attachNode( new RightInputAdapterNode( this.id++,
column.getFactIndex(),
notNode ) );
attachNot( tupleSource,
(Not) exists.getChild(),
adapter,
new BetaNodeBinder(),
column );
} else if ( exists.getChild() instanceof Exists ) {
adapter = (RightInputAdapterNode) attachNode( new RightInputAdapterNode( this.id++,
column.getFactIndex(),
notNode ) );
attachExists( tupleSource,
(Exists) exists.getChild(),
adapter,
new BetaNodeBinder(),
column );
} else {
this.tupleSource = notNode;
}
}
/**
* Attaches a node into the network. If a node already exists that could
* substitute, it is used instead.
*
* @param candidate
* The node to attach.
* @param leafNodes
* The list to which the newly added node will be added.
*/
private TupleSource attachNode(final TupleSource candidate) {
TupleSource node = (TupleSource) this.attachedNodes.get( candidate );
if ( node == null ) {
if ( this.workingMemories.length == 0 ) {
candidate.attach();
} else {
candidate.attach( this.workingMemories );
}
this.attachedNodes.put( candidate,
candidate );
node = candidate;
} else {
if( !node.isInUse() ) {
if ( this.workingMemories.length == 0 ) {
node.attach();
} else {
node.attach( this.workingMemories );
}
}
node.addShare();
this.id--;
}
return node;
}
private ObjectSource attachNode(final ObjectSource candidate) {
ObjectSource node = (ObjectSource) this.attachedNodes.get( candidate );
if ( node == null ) {
if ( this.workingMemories.length == 0 ) {
candidate.attach();
} else {
candidate.attach( this.workingMemories );
}
this.attachedNodes.put( candidate,
candidate );
node = candidate;
} else {
if( !node.isInUse() ) {
if ( this.workingMemories.length == 0 ) {
node.attach();
} else {
node.attach( this.workingMemories );
}
}
node.addShare();
this.id--;
}
return node;
}
public void removeRule(final Rule rule) {
// reset working memories for potential propagation
this.workingMemories = (ReteooWorkingMemory[]) this.ruleBase.getWorkingMemories().toArray( new ReteooWorkingMemory[this.ruleBase.getWorkingMemories().size()] );
final Object object = this.rules.get( rule );
final BaseNode[] nodes = (BaseNode[]) object;
for ( int i = 0, length = nodes.length; i < length; i++ ) {
final BaseNode node = nodes[i];
node.remove( null,
this.workingMemories );
}
}
/**
* Make sure the required declarations are previously bound
*
* @param declarations
* @throws InvalidPatternException
*/
private void checkUnboundDeclarations(final Declaration[] declarations) throws InvalidPatternException {
final List list = new ArrayList();
for ( int i = 0, length = declarations.length; i < length; i++ ) {
if ( this.declarations.get( declarations[i].getIdentifier() ) == null ) {
list.add( declarations[i].getIdentifier() );
}
}
// Make sure the required declarations
if ( list.size() != 0 ) {
final StringBuffer buffer = new StringBuffer();
buffer.append( list.get( 0 ) );
for ( int i = 1, size = list.size(); i < size; i++ ) {
buffer.append( ", " + list.get( i ) );
}
throw new InvalidPatternException( "Required Declarations not bound: '" + buffer );
}
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -