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.io.Serializable;
020:
021: import org.drools.common.BaseNode;
022: import org.drools.common.DefaultFactHandle;
023: import org.drools.common.InternalWorkingMemory;
024: import org.drools.spi.PropagationContext;
025:
026: /**
027: * A source of <code>FactHandle</code>s for an <code>ObjectSink</code>.
028: *
029: * <p>
030: * Nodes that propagate <code>FactHandleImpl</code> extend this class.
031: * </p>
032: *
033: * @see ObjectSource
034: * @see DefaultFactHandle
035: *
036: * @author <a href="mailto:mark.proctor@jboss.com">Mark Proctor</a>
037: * @author <a href="mailto:bob@werken.com">Bob McWhirter</a>
038: */
039: public abstract class ObjectSource extends BaseNode implements
040: Serializable {
041: // ------------------------------------------------------------
042: // Instance members
043: // ------------------------------------------------------------
044:
045: /** The destination for <code>FactHandleImpl</code>. */
046: protected ObjectSinkPropagator sink;
047:
048: protected ObjectSource objectSource;
049:
050: private int alphaNodeHashingThreshold;
051:
052: // ------------------------------------------------------------
053: // Constructors
054: // ------------------------------------------------------------
055:
056: /**
057: * Single parameter constructor that specifies the unique id of the node.
058: *
059: * @param id
060: */
061: ObjectSource(final int id) {
062: this (id, null, 3);
063: }
064:
065: /**
066: * Single parameter constructor that specifies the unique id of the node.
067: *
068: * @param id
069: */
070: ObjectSource(final int id, final ObjectSource objectSource,
071: final int alphaNodeHashingThreshold) {
072: super (id);
073: this .objectSource = objectSource;
074: this .alphaNodeHashingThreshold = alphaNodeHashingThreshold;
075: this .sink = EmptyObjectSinkAdapter.getInstance();
076: }
077:
078: // ------------------------------------------------------------
079: // Instance methods
080: // ------------------------------------------------------------
081:
082: /**
083: * Adds the <code>ObjectSink</code> so that it may receive
084: * <code>FactHandleImpl</code> propagated from this
085: * <code>ObjectSource</code>.
086: *
087: * @param objectSink
088: * The <code>ObjectSink</code> to receive propagated
089: * <code>FactHandleImpl</code>.
090: */
091: protected void addObjectSink(final ObjectSink objectSink) {
092: if (this .sink == EmptyObjectSinkAdapter.getInstance()) {
093: this .sink = new SingleObjectSinkAdapter(objectSink);
094: } else if (this .sink instanceof SingleObjectSinkAdapter) {
095: final CompositeObjectSinkAdapter sinkAdapter = new CompositeObjectSinkAdapter(
096: this .alphaNodeHashingThreshold);
097: sinkAdapter.addObjectSink(this .sink.getSinks()[0]);
098: sinkAdapter.addObjectSink(objectSink);
099: this .sink = sinkAdapter;
100: } else {
101: ((CompositeObjectSinkAdapter) this .sink)
102: .addObjectSink(objectSink);
103: }
104: }
105:
106: /**
107: * Removes the <code>ObjectSink</code>
108: *
109: * @param objectSink
110: * The <code>ObjectSink</code> to remove
111: */
112: protected void removeObjectSink(final ObjectSink objectSink) {
113: if (this .sink == EmptyObjectSinkAdapter.getInstance()) {
114: throw new IllegalArgumentException(
115: "Cannot remove a sink, when the list of sinks is null");
116: }
117:
118: if (this .sink instanceof SingleObjectSinkAdapter) {
119: this .sink = EmptyObjectSinkAdapter.getInstance();
120: } else {
121: final CompositeObjectSinkAdapter sinkAdapter = (CompositeObjectSinkAdapter) this .sink;
122: sinkAdapter.removeObjectSink(objectSink);
123: if (sinkAdapter.size() == 1) {
124: this .sink = new SingleObjectSinkAdapter(sinkAdapter
125: .getSinks()[0]);
126: }
127: }
128: }
129:
130: public abstract void updateSink(ObjectSink sink,
131: PropagationContext context,
132: InternalWorkingMemory workingMemory);
133:
134: public ObjectSinkPropagator getSinkPropagator() {
135: return this.sink;
136: }
137:
138: }
|