/** * Copyright 2010 JBoss Inc * * 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.common; import java.io.IOException; import java.io.ObjectInput; import java.io.ObjectOutput; import org.drools.reteoo.LeftTuple; import org.drools.rule.ContextEntry; import org.drools.rule.Declaration; import org.drools.spi.BetaNodeFieldConstraint; /** * Checks if one tuple is the start subtuple of other tuple. * For instance, if we have two tuples: * * T1 = [ a, b, c ] * T2 = [ a, b, c, d, e] * * This constraint will evaluate to true as T1 is the starting subtuple * of T2. On the other hand, if we have: * * T1 = [ a, c, b ] * T2 = [ a, b, c, d, e ] * * This constraint will evaluate to false, as T1 is not the starting subtuple * of T2. Besides having the same elements, the order is different. * * This constraint is used when joining subnetworks back into the main * network. * * @author etirelli * */ public class TupleStartEqualsConstraint implements BetaNodeFieldConstraint { private static final long serialVersionUID = 510l; private Declaration[] declarations = new Declaration[0]; private static final TupleStartEqualsConstraint INSTANCE = new TupleStartEqualsConstraint(); // this is a stateless constraint, so we can make it a singleton public TupleStartEqualsConstraint() { } public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException { declarations = (Declaration[])in.readObject(); } public void writeExternal(ObjectOutput out) throws IOException { out.writeObject(declarations); } public static TupleStartEqualsConstraint getInstance() { return INSTANCE; } public Declaration[] getRequiredDeclarations() { return this.declarations; } public void replaceDeclaration(Declaration oldDecl, Declaration newDecl) { } public boolean isTemporal() { return false; } public ContextEntry createContextEntry() { return new TupleStartEqualsConstraintContextEntry(); } public boolean isAllowedCachedLeft(final ContextEntry context, final InternalFactHandle handle) { // object MUST be a ReteTuple final LeftTuple tuple = ((LeftTuple) handle.getObject()).getSubTuple( ((TupleStartEqualsConstraintContextEntry) context).compareSize ); return ((TupleStartEqualsConstraintContextEntry) context).left.equals( tuple ); } public boolean isAllowedCachedRight(final LeftTuple tuple, final ContextEntry context) { return tuple.equals( ((TupleStartEqualsConstraintContextEntry) context).right.getSubTuple( tuple.size() ) ); } public String toString() { return "[ TupleStartEqualsConstraint ]"; } public int hashCode() { return 10; } public boolean equals(final Object object) { if ( object instanceof TupleStartEqualsConstraint ) { return true; } return false; } public Object clone() { return INSTANCE; } public static class TupleStartEqualsConstraintContextEntry implements ContextEntry { private static final long serialVersionUID = 510l; public LeftTuple left; public LeftTuple right; // the size of the tuple to compare public int compareSize; private ContextEntry entry; public TupleStartEqualsConstraintContextEntry() { } public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException { left = (LeftTuple)in.readObject(); right = (LeftTuple)in.readObject(); compareSize = in.readInt(); entry = (ContextEntry)in.readObject(); } public void writeExternal(ObjectOutput out) throws IOException { out.writeObject(left); out.writeObject(right); out.writeInt(compareSize); out.writeObject(entry); } public ContextEntry getNext() { return this.entry; } public void setNext(final ContextEntry entry) { this.entry = entry; } public void updateFromTuple(final InternalWorkingMemory workingMemory, final LeftTuple tuple) { this.left = tuple; this.compareSize = tuple.size(); } public void updateFromFactHandle(final InternalWorkingMemory workingMemory, final InternalFactHandle handle) { // if it is not a rete tuple, then there is a bug in the engine... // it MUST be a rete tuple this.right = (LeftTuple) handle.getObject(); } public void resetTuple() { this.left = null; } public void resetFactHandle() { this.right = null; } } public ConstraintType getType() { return ConstraintType.BETA; } }