001: package org.drools.reteoo;
002:
003: /*
004: * Copyright 2005 JBoss Inc
005: *
006: * Licensed under the Apache License, Version 2.0 (the "License");
007: * you may not use this file except in compliance with the License.
008: * You may obtain a copy of the License at
009: *
010: * http://www.apache.org/licenses/LICENSE-2.0
011: *
012: * Unless required by applicable law or agreed to in writing, software
013: * distributed under the License is distributed on an "AS IS" BASIS,
014: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
015: * See the License for the specific language governing permissions and
016: * limitations under the License.
017: */
018:
019: import java.util.LinkedList;
020:
021: import org.drools.RuleBaseConfiguration;
022: import org.drools.common.BaseNode;
023: import org.drools.common.InternalWorkingMemory;
024: import org.drools.common.NodeMemory;
025: import org.drools.common.PropagationContextImpl;
026: import org.drools.rule.GroupElement;
027: import org.drools.rule.Rule;
028: import org.drools.spi.PropagationContext;
029:
030: /**
031: * Leaf Rete-OO node responsible for enacting <code>Action</code> s on a
032: * matched <code>Rule</code>.
033: *
034: * @see org.drools.rule.Rule
035: *
036: * @author <a href="mailto:bob@eng.werken.com">bob mcwhirter </a>
037: */
038: public final class QueryTerminalNode extends BaseNode implements
039: TupleSinkNode, NodeMemory, TerminalNode {
040: // ------------------------------------------------------------
041: // Instance members
042: // ------------------------------------------------------------
043:
044: /**
045: *
046: */
047: private static final long serialVersionUID = 400L;
048: /** The rule to invoke upon match. */
049: private final Rule rule;
050: private final GroupElement subrule;
051: private final TupleSource tupleSource;
052:
053: private TupleSinkNode previousTupleSinkNode;
054: private TupleSinkNode nextTupleSinkNode;
055:
056: // ------------------------------------------------------------
057: // Constructors
058: // ------------------------------------------------------------
059:
060: /**
061: * Construct.
062: *
063: * @param inputSource
064: * The parent tuple source.
065: * @param rule
066: * The rule.
067: */
068: public QueryTerminalNode(final int id, final TupleSource source,
069: final Rule rule, final GroupElement subrule) {
070: super (id);
071: this .rule = rule;
072: this .subrule = subrule;
073: this .tupleSource = source;
074: }
075:
076: // ------------------------------------------------------------
077: // Instance methods
078: // ------------------------------------------------------------
079:
080: /**
081: * Retrieve the <code>Action</code> associated with this node.
082: *
083: * @return The <code>Action</code> associated with this node.
084: */
085: public Rule getRule() {
086: return this .rule;
087: }
088:
089: // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
090: // org.drools.impl.TupleSink
091: // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
092:
093: /**
094: * Assert a new <code>Tuple</code>.
095: *
096: * @param tuple
097: * The <code>Tuple</code> being asserted.
098: * @param workingMemory
099: * The working memory seesion.
100: * @throws AssertionException
101: * If an error occurs while asserting.
102: */
103: public void assertTuple(final ReteTuple tuple,
104: final PropagationContext context,
105: final InternalWorkingMemory workingMemory) {
106: final LinkedList list = (LinkedList) workingMemory
107: .getNodeMemory(this );
108: if (list.isEmpty()) {
109: ((ReteooWorkingMemory) workingMemory).setQueryResults(
110: this .rule.getName(), this );
111: }
112: list.add(tuple);
113: }
114:
115: public void retractTuple(final ReteTuple tuple,
116: final PropagationContext context,
117: final InternalWorkingMemory workingMemory) {
118: }
119:
120: public String toString() {
121: return "[QueryTerminalNode: rule=" + this .rule.getName() + "]";
122: }
123:
124: public void ruleAttached() {
125:
126: }
127:
128: public void attach() {
129: this .tupleSource.addTupleSink(this );
130: }
131:
132: public void attach(final InternalWorkingMemory[] workingMemories) {
133: attach();
134:
135: for (int i = 0, length = workingMemories.length; i < length; i++) {
136: final InternalWorkingMemory workingMemory = workingMemories[i];
137: final PropagationContext propagationContext = new PropagationContextImpl(
138: workingMemory.getNextPropagationIdCounter(),
139: PropagationContext.RULE_ADDITION, null, null);
140: this .tupleSource.updateSink(this , propagationContext,
141: workingMemory);
142: }
143: }
144:
145: public void remove(final BaseNode node,
146: final InternalWorkingMemory[] workingMemories) {
147: for (int i = 0, length = workingMemories.length; i < length; i++) {
148: workingMemories[i].clearNodeMemory(this );
149: }
150:
151: removeShare();
152:
153: this .tupleSource.remove(this , workingMemories);
154: }
155:
156: public void updateNewNode(
157: final InternalWorkingMemory workingMemory,
158: final PropagationContext context) {
159: // There are no child nodes to update, do nothing.
160: }
161:
162: public Object createMemory(final RuleBaseConfiguration config) {
163: //return new QueryTerminalNodeMemory();
164: return new LinkedList();
165: }
166:
167: /**
168: * @return the subrule
169: */
170: public GroupElement getSubrule() {
171: return this .subrule;
172: }
173:
174: /**
175: * Returns the previous node
176: * @return
177: * The previous TupleSinkNode
178: */
179: public TupleSinkNode getPreviousTupleSinkNode() {
180: return this .previousTupleSinkNode;
181: }
182:
183: /**
184: * Sets the previous node
185: * @param previous
186: * The previous TupleSinkNode
187: */
188: public void setPreviousTupleSinkNode(final TupleSinkNode previous) {
189: this .previousTupleSinkNode = previous;
190: }
191:
192: /**
193: * Returns the next node
194: * @return
195: * The next TupleSinkNode
196: */
197: public TupleSinkNode getNextTupleSinkNode() {
198: return this .nextTupleSinkNode;
199: }
200:
201: /**
202: * Sets the next node
203: * @param next
204: * The next TupleSinkNode
205: */
206: public void setNextTupleSinkNode(final TupleSinkNode next) {
207: this.nextTupleSinkNode = next;
208: }
209:
210: }
|