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 org.drools.RuleBaseConfiguration;
020: import org.drools.common.BaseNode;
021: import org.drools.common.InternalFactHandle;
022: import org.drools.common.InternalWorkingMemory;
023: import org.drools.common.NodeMemory;
024: import org.drools.common.PropagationContextImpl;
025: import org.drools.spi.PropagationContext;
026: import org.drools.util.Iterator;
027: import org.drools.util.ObjectHashMap;
028: import org.drools.util.ObjectHashMap.ObjectEntry;
029:
030: /**
031: * When joining a subnetwork into the main network again, RightInputAdapterNode adapts the
032: * subnetwork's tuple into a fact in order right join it with the tuple being propagated in
033: * the main network.
034: *
035: * @author <a href="mailto:mark.proctor@jboss.com">Mark Proctor</a>
036: * @author <a href="mailto:bob@werken.com">Bob McWhirter</a>
037: * @author <a href="mailto:etirelli@redhat.com">Edson Tirelli</a>
038: *
039: */
040: public class RightInputAdapterNode extends ObjectSource implements
041: TupleSink, NodeMemory {
042:
043: private static final long serialVersionUID = 400L;
044:
045: private final TupleSource tupleSource;
046:
047: /**
048: * Constructor specifying the unique id of the node in the Rete network, the position of the propagating <code>FactHandleImpl</code> in
049: * <code>ReteTuple</code> and the source that propagates the receive <code>ReteTuple<code>s.
050: *
051: * @param id
052: * Unique id
053: * @param source
054: * The <code>TupleSource</code> which propagates the received <code>ReteTuple</code>
055: */
056: public RightInputAdapterNode(final int id, final TupleSource source) {
057: super (id);
058: this .tupleSource = source;
059: this .setHasMemory(true);
060: }
061:
062: /**
063: * Creates and return the node memory
064: */
065: public Object createMemory(final RuleBaseConfiguration config) {
066: return new ObjectHashMap();
067: }
068:
069: /**
070: * Takes the asserted <code>ReteTuple</code> received from the <code>TupleSource</code> and
071: * adapts it into a FactHandleImpl
072: *
073: * @param tuple
074: * The asserted <code>ReteTuple</code>.
075: * @param context
076: * The <code>PropagationContext</code> of the <code>WorkingMemory<code> action.
077: * @param workingMemory
078: * the <code>WorkingMemory</code> session.
079: */
080: public void assertTuple(final ReteTuple tuple,
081: final PropagationContext context,
082: final InternalWorkingMemory workingMemory) {
083:
084: // creating a dummy fact handle to wrap the tuple
085: final InternalFactHandle handle = workingMemory
086: .getFactHandleFactory().newFactHandle(tuple);
087:
088: if (!workingMemory.isSequential()) {
089: final ObjectHashMap memory = (ObjectHashMap) workingMemory
090: .getNodeMemory(this );
091: // add it to a memory mapping
092: memory.put(tuple, handle);
093: }
094:
095: // propagate it
096: this .sink.propagateAssertObject(handle, context, workingMemory);
097: }
098:
099: /**
100: * Retracts the corresponding tuple by retrieving and retracting
101: * the fact created for it
102: */
103: public void retractTuple(final ReteTuple tuple,
104: final PropagationContext context,
105: final InternalWorkingMemory workingMemory) {
106:
107: final ObjectHashMap memory = (ObjectHashMap) workingMemory
108: .getNodeMemory(this );
109:
110: // retrieve handle from memory
111: final InternalFactHandle handle = (InternalFactHandle) memory
112: .remove(tuple);
113:
114: // propagate a retract for it
115: this .sink.propagateRetractObject(handle, context,
116: workingMemory, true);
117:
118: // destroy dummy handle
119: workingMemory.getFactHandleFactory().destroyFactHandle(handle);
120: }
121:
122: public void attach() {
123: this .tupleSource.addTupleSink(this );
124: }
125:
126: public void attach(final InternalWorkingMemory[] workingMemories) {
127: attach();
128:
129: for (int i = 0, length = workingMemories.length; i < length; i++) {
130: final InternalWorkingMemory workingMemory = workingMemories[i];
131: final PropagationContext propagationContext = new PropagationContextImpl(
132: workingMemory.getNextPropagationIdCounter(),
133: PropagationContext.RULE_ADDITION, null, null);
134: this .tupleSource.updateSink(this , propagationContext,
135: workingMemory);
136: }
137: }
138:
139: public void updateSink(final ObjectSink sink,
140: final PropagationContext context,
141: final InternalWorkingMemory workingMemory) {
142:
143: final ObjectHashMap memory = (ObjectHashMap) workingMemory
144: .getNodeMemory(this );
145:
146: final Iterator it = memory.iterator();
147:
148: // iterates over all propagated handles and assert them to the new sink
149: for (ObjectEntry entry = (ObjectEntry) it.next(); entry != null; entry = (ObjectEntry) it
150: .next()) {
151: sink.assertObject((InternalFactHandle) entry.getValue(),
152: context, workingMemory);
153: }
154: }
155:
156: public void remove(final BaseNode node,
157: final InternalWorkingMemory[] workingMemories) {
158: if (!node.isInUse()) {
159: removeObjectSink((ObjectSink) node);
160: }
161: removeShare();
162: this.tupleSource.remove(this, workingMemories);
163: }
164:
165: }
|