Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance. Project price only 1 $
You can buy this project and download/modify it how often you want.
/*
* Copyright 2005 Red Hat, Inc. and/or its affiliates.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.drools.core.reteoo;
import java.io.IOException;
import java.io.ObjectInput;
import java.io.ObjectOutput;
import java.util.List;
import org.drools.core.base.evaluators.IsAEvaluatorDefinition;
import org.drools.core.common.InternalFactHandle;
import org.drools.core.common.InternalWorkingMemory;
import org.drools.core.common.RuleBasePartitionId;
import org.drools.core.reteoo.builder.BuildContext;
import org.drools.core.rule.constraint.EvaluatorConstraint;
import org.drools.core.rule.constraint.MvelConstraint;
import org.drools.core.spi.AlphaNodeFieldConstraint;
import org.drools.core.spi.PropagationContext;
import org.drools.core.util.bitmask.BitMask;
import org.kie.api.definition.rule.Rule;
import org.kie.api.runtime.rule.Operator;
/**
* AlphaNodes are nodes in the Rete network used
* to apply FieldConstraint<.code>s on asserted fact
* objects where the FieldConstraints have no dependencies on any other of the facts in the current Rule.
*
* @see AlphaNodeFieldConstraint
*/
public class AlphaNode extends ObjectSource
implements
ObjectSinkNode {
private static final long serialVersionUID = 510l;
/**
* The FieldConstraint
*/
private AlphaNodeFieldConstraint constraint;
private ObjectSinkNode previousRightTupleSinkNode;
private ObjectSinkNode nextRightTupleSinkNode;
public AlphaNode() {
}
/**
* Construct an AlphaNode with a unique id using the provided
* FieldConstraint and the given ObjectSource.
* Set the boolean flag to true if the node is supposed to have local
* memory, or false otherwise. Memory is optional for AlphaNodes
* and is only of benefic when adding additional Rules at runtime.
*
* @param id Node's ID
* @param constraint Node's constraints
* @param objectSource Node's object source
*/
public AlphaNode(final int id,
final AlphaNodeFieldConstraint constraint,
final ObjectSource objectSource,
final BuildContext context) {
super(id,
context.getPartitionId(),
context.getKnowledgeBase().getConfiguration().isMultithreadEvaluation(),
objectSource,
context.getKnowledgeBase().getConfiguration().getAlphaNodeHashingThreshold());
this.constraint = constraint.cloneIfInUse();
if (this.constraint instanceof MvelConstraint) {
((MvelConstraint) this.constraint).registerEvaluationContext(context);
}
initDeclaredMask(context);
hashcode = calculateHashCode();
}
public void readExternal(ObjectInput in) throws IOException,
ClassNotFoundException {
super.readExternal(in);
constraint = (AlphaNodeFieldConstraint) in.readObject();
declaredMask = (BitMask) in.readObject();
inferredMask = (BitMask) in.readObject();
}
public void writeExternal(ObjectOutput out) throws IOException {
super.writeExternal(out);
out.writeObject(constraint);
out.writeObject(declaredMask);
out.writeObject(inferredMask);
}
/**
* Retruns the FieldConstraint
*
* @return FieldConstraint
*/
public AlphaNodeFieldConstraint getConstraint() {
return this.constraint;
}
public short getType() {
return NodeTypeEnums.AlphaNode;
}
public void attach(BuildContext context) {
this.source.addObjectSink(this);
}
@Override
public void setPartitionId(BuildContext context, RuleBasePartitionId partitionId) {
if (this.partitionId != null && this.partitionId != partitionId) {
if (source instanceof AlphaNode) {
source.setPartitionId( context, partitionId );
}
source.sink.changeSinkPartition( (ObjectSink)this, this.partitionId, partitionId, source.alphaNodeHashingThreshold );
}
this.partitionId = partitionId;
}
public void assertObject(final InternalFactHandle factHandle,
final PropagationContext context,
final InternalWorkingMemory workingMemory) {
if (this.constraint.isAllowed(factHandle,
workingMemory)) {
this.sink.propagateAssertObject(factHandle,
context,
workingMemory);
}
}
public void modifyObject(final InternalFactHandle factHandle,
final ModifyPreviousTuples modifyPreviousTuples,
final PropagationContext context,
final InternalWorkingMemory workingMemory) {
if (context.getModificationMask().intersects(inferredMask)) {
if (this.constraint.isAllowed(factHandle, workingMemory)) {
this.sink.propagateModifyObject(factHandle,
modifyPreviousTuples,
context,
workingMemory);
}
} else {
byPassModifyToBetaNode(factHandle, modifyPreviousTuples, context, workingMemory);
}
}
public void byPassModifyToBetaNode(final InternalFactHandle factHandle,
final ModifyPreviousTuples modifyPreviousTuples,
final PropagationContext context,
final InternalWorkingMemory workingMemory) {
sink.byPassModifyToBetaNode(factHandle, modifyPreviousTuples, context, workingMemory);
}
public void updateSink(final ObjectSink sink,
final PropagationContext context,
final InternalWorkingMemory workingMemory) {
// get the objects from the parent
ObjectSinkUpdateAdapter adapter = new ObjectSinkUpdateAdapter(sink,
this.constraint);
this.source.updateSink(adapter,
context,
workingMemory);
}
public String toString() {
return "[AlphaNode(" + this.id + ") constraint=" + this.constraint + "]";
}
private int calculateHashCode() {
return (this.source != null ? this.source.hashCode() : 0) * 37 + (this.constraint != null ? this.constraint.hashCode() : 0) * 31;
}
@Override
public boolean equals(Object object) {
return this == object ||
(internalEquals((AlphaNode)object) &&
(this.source != null ?
this.source.thisNodeEquals(((AlphaNode) object).source) :
((AlphaNode) object).source == null) );
}
@Override
protected boolean internalEquals( Object object ) {
if ( object == null || !(object instanceof AlphaNode) || this.hashCode() != object.hashCode() ) {
return false;
}
return (constraint instanceof MvelConstraint ?
((MvelConstraint) constraint).equals(((AlphaNode)object).constraint, getKnowledgeBase()) :
constraint.equals(((AlphaNode)object).constraint));
}
/**
* Returns the next node
*
* @return The next ObjectSinkNode
*/
public ObjectSinkNode getNextObjectSinkNode() {
return this.nextRightTupleSinkNode;
}
/**
* Sets the next node
*
* @param next The next ObjectSinkNode
*/
public void setNextObjectSinkNode(final ObjectSinkNode next) {
this.nextRightTupleSinkNode = next;
}
/**
* Returns the previous node
*
* @return The previous ObjectSinkNode
*/
public ObjectSinkNode getPreviousObjectSinkNode() {
return this.previousRightTupleSinkNode;
}
/**
* Sets the previous node
*
* @param previous The previous ObjectSinkNode
*/
public void setPreviousObjectSinkNode(final ObjectSinkNode previous) {
this.previousRightTupleSinkNode = previous;
}
/**
* Used with the updateSink method, so that the parent ObjectSource
* can update the TupleSink
*/
private static class ObjectSinkUpdateAdapter
implements
ObjectSink {
private final ObjectSink sink;
private final AlphaNodeFieldConstraint constraint;
public ObjectSinkUpdateAdapter(final ObjectSink sink,
final AlphaNodeFieldConstraint constraint) {
this.sink = sink;
this.constraint = constraint;
}
public void assertObject(final InternalFactHandle handle,
final PropagationContext propagationContext,
final InternalWorkingMemory workingMemory) {
if (this.constraint.isAllowed(handle,
workingMemory)) {
this.sink.assertObject(handle,
propagationContext,
workingMemory);
}
}
public int getId() {
return 0;
}
public RuleBasePartitionId getPartitionId() {
return this.sink.getPartitionId();
}
public void writeExternal(ObjectOutput out) throws IOException {
// this is a short living adapter class, so no need for serialization
}
public void readExternal(ObjectInput in) throws IOException,
ClassNotFoundException {
// this is a short living adapter class, so no need for serialization
}
public void modifyObject(final InternalFactHandle factHandle,
final ModifyPreviousTuples modifyPreviousTuples,
final PropagationContext context,
final InternalWorkingMemory workingMemory) {
throw new UnsupportedOperationException("This method should NEVER EVER be called");
}
public void byPassModifyToBetaNode(InternalFactHandle factHandle,
ModifyPreviousTuples modifyPreviousTuples,
PropagationContext context,
InternalWorkingMemory workingMemory) {
}
public short getType() {
return NodeTypeEnums.AlphaNode;
}
public int getAssociationsSize() {
return sink.getAssociationsSize();
}
public int getAssociatedRuleSize() {
return sink.getAssociatedRuleSize();
}
public int getAssociationsSize(Rule rule) {
return sink.getAssociationsSize(rule);
}
public boolean isAssociatedWith(Rule rule) {
return sink.isAssociatedWith(rule);
}
public boolean thisNodeEquals(final Object object) {
return false;
}
public int nodeHashCode() {
return this.hashCode();
}
}
public BitMask calculateDeclaredMask(List settableProperties) {
boolean typeBit = false;
if (constraint instanceof EvaluatorConstraint && ((EvaluatorConstraint) constraint).isSelf()) {
Operator op = ((EvaluatorConstraint) constraint).getEvaluator().getOperator();
if (op == IsAEvaluatorDefinition.ISA || op == IsAEvaluatorDefinition.NOT_ISA) {
typeBit = true;
}
}
BitMask mask = constraint.getListenedPropertyMask(settableProperties);
return typeBit ? mask.set(PropertySpecificUtil.TRAITABLE_BIT) : mask;
}
@Override
public BitMask getDeclaredMask() {
return declaredMask;
}
public BitMask getInferredMask() {
return inferredMask;
}
}