001: /*
002: * Copyright 2006 JBoss Inc
003: *
004: * Licensed under the Apache License, Version 2.0 (the "License");
005: * you may not use this file except in compliance with the License.
006: * You may obtain a copy of the License at
007: *
008: * http://www.apache.org/licenses/LICENSE-2.0
009: *
010: * Unless required by applicable law or agreed to in writing, software
011: * distributed under the License is distributed on an "AS IS" BASIS,
012: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013: * See the License for the specific language governing permissions and
014: * limitations under the License.
015: */
016:
017: package org.drools.common;
018:
019: import org.drools.reteoo.ReteTuple;
020: import org.drools.rule.ContextEntry;
021: import org.drools.rule.Declaration;
022: import org.drools.spi.BetaNodeFieldConstraint;
023:
024: /**
025: * Checks if one tuple is the start subtuple of other tuple.
026: * For instance, if we have two tuples:
027: *
028: * T1 = [ a, b, c ]
029: * T2 = [ a, b, c, d, e]
030: *
031: * This constraint will evaluate to true as T1 is the starting subtuple
032: * of T2. On the other hand, if we have:
033: *
034: * T1 = [ a, c, b ]
035: * T2 = [ a, b, c, d, e ]
036: *
037: * This constraint will evaluate to false, as T1 is not the starting subtuple
038: * of T2. Besides having the same elements, the order is different.
039: *
040: * This constraint is used when joining subnetworks back into the main
041: * network.
042: *
043: * @author etirelli
044: *
045: */
046: public class TupleStartEqualsConstraint implements
047: BetaNodeFieldConstraint {
048:
049: private static final long serialVersionUID = 400L;
050:
051: private final Declaration[] declarations = new Declaration[0];
052:
053: private static final TupleStartEqualsConstraint INSTANCE = new TupleStartEqualsConstraint();
054:
055: // this is a stateless constraint, so we can make it a singleton
056: private TupleStartEqualsConstraint() {
057: }
058:
059: public static TupleStartEqualsConstraint getInstance() {
060: return INSTANCE;
061: }
062:
063: public Declaration[] getRequiredDeclarations() {
064: return this .declarations;
065: }
066:
067: public ContextEntry getContextEntry() {
068: return new TupleStartEqualsConstraintContextEntry();
069: }
070:
071: public boolean isAllowedCachedLeft(final ContextEntry context,
072: final Object object) {
073: // object MUST be a ReteTuple
074: final ReteTuple tuple = ((ReteTuple) object)
075: .getSubTuple(((TupleStartEqualsConstraintContextEntry) context).compareSize);
076: return ((TupleStartEqualsConstraintContextEntry) context).left
077: .equals(tuple);
078: }
079:
080: public boolean isAllowedCachedRight(final ReteTuple tuple,
081: final ContextEntry context) {
082: return tuple
083: .equals(((TupleStartEqualsConstraintContextEntry) context).right
084: .getSubTuple(tuple.size()));
085: }
086:
087: public String toString() {
088: return "[ TupleStartEqualsConstraint ]";
089: }
090:
091: public int hashCode() {
092: return 10;
093: }
094:
095: public boolean equals(final Object object) {
096: if (object instanceof TupleStartEqualsConstraint) {
097: return true;
098: }
099: return false;
100: }
101:
102: public static class TupleStartEqualsConstraintContextEntry
103: implements ContextEntry {
104:
105: private static final long serialVersionUID = 400L;
106:
107: public ReteTuple left;
108: public ReteTuple right;
109:
110: // the size of the tuple to compare
111: public int compareSize;
112:
113: private ContextEntry entry;
114:
115: public TupleStartEqualsConstraintContextEntry() {
116: }
117:
118: public ContextEntry getNext() {
119: return this .entry;
120: }
121:
122: public void setNext(final ContextEntry entry) {
123: this .entry = entry;
124: }
125:
126: public void updateFromTuple(
127: final InternalWorkingMemory workingMemory,
128: final ReteTuple tuple) {
129: this .left = tuple;
130: this .compareSize = tuple.size();
131: }
132:
133: public void updateFromFactHandle(
134: final InternalWorkingMemory workingMemory,
135: final InternalFactHandle handle) {
136: // if it is not a rete tuple, then there is a bug in the engine...
137: // it MUST be a rete tuple
138: this .right = (ReteTuple) handle.getObject();
139: }
140: }
141: }
|