Source code: jeops/rete/JoinReteNode.java
1 package jeops.rete;
2
3 /*
4 * JEOPS - The Java Embedded Object Production System
5 * Copyright (c) 2000 Carlos Figueira Filho
6 *
7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 2.1 of the License, or (at your option) any later version.
11 *
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
16 *
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with this library; if not, write to the Free Software
19 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20 *
21 * Contact: Carlos Figueira Filho (csff@cin.ufpe.br)
22 */
23
24 import java.util.Iterator;
25 import java.util.List;
26 import java.util.ArrayList;
27 import jeops.AbstractRuleBase;
28
29 /**
30 * A node in the Rete network that has more than one input, so that
31 * objects coming from distinct parts of the network are joined
32 * together in instances of this class.
33 *
34 * @author Carlos Figueira Filho (<a href="mailto:csff@cin.ufpe.br">csff@cin.ufpe.br</a>)
35 * @version 1.0 14 Jul 2000
36 */
37 public class JoinReteNode extends ReteNode {
38
39 /**
40 * The objects that are "waiting" at some inputs of this node for
41 * the arrival of objects in other inputs, in order to be
42 * propagated at this node. It's actually a list of lists, where
43 * for every input of this node there is a list of the objects
44 * entered by that input.
45 */
46 private List[] waitingObjects;
47
48 /**
49 * The rule base used to check the validity of the property of the
50 * incoming objects.
51 */
52 private AbstractRuleBase ruleBase;
53
54 /**
55 * The index of the rule that contains the condition to be checked
56 * by this node.
57 */
58 private int ruleIndex;
59
60 /*
61 * The index of the declaration whose property is checked by this
62 * node.
63 */
64 private int declIndex;
65
66 /**
67 * Object array, defined as an attribute for efficiency purposes
68 * only.
69 */
70 private final Object[] ARRAY;
71
72 /**
73 * Iterator array, defined as an attribute for efficiency purposes
74 * only.
75 */
76 private final Iterator[] its;
77
78 /**
79 * Class constructor.
80 *
81 * @param numberInputs the number of inputs of this node.
82 * @param ruleBase the rule base used to check if this node can be
83 * activated.
84 * @param ruleIndex the index of the rule that contains the
85 * condition to be checked by this node.
86 * @param declIndex the index of the declaration being joined by
87 * this node.
88 */
89 public JoinReteNode(int numberInputs, AbstractRuleBase ruleBase,
90 int ruleIndex, int declIndex) {
91 super(numberInputs, numberInputs);
92 if (numberInputs < 2) {
93 throw new IllegalArgumentException("Join nodes must have at least 2 inputs.");
94 }
95 waitingObjects = new List[numberInputs];
96 for (int i = 0; i < numberInputs; i++) {
97 waitingObjects[i] = new ArrayList();
98 }
99 ARRAY = new Object[ruleBase.getNumberOfDeclarations()[ruleIndex]];
100 its = new Iterator[numberInputs - 1];
101 this.ruleBase = ruleBase;
102 this.ruleIndex = ruleIndex;
103 this.declIndex = declIndex;
104 }
105 /**
106 * Remove all objects that may be stored in this node.
107 */
108 public void flush() {
109 int numberInputs = getNumberInputs();
110 for (int i = 0; i < numberInputs; i++) {
111 waitingObjects[i] = new ArrayList();
112 }
113 }
114 /**
115 * Informs this node that an object has arrived.
116 *
117 * @param obj the object that arrived at this node.
118 * @param input the input number of this node that is to receive
119 * the object.
120 */
121 public void newObject(Object obj, int input) {
122 final int numberInputs = getNumberInputs();
123 waitingObjects[input].add(obj);
124 if (input == numberInputs - 1) {
125 for (int i = 0; i < waitingObjects[0].size(); i++) {
126 for (int j = 0; j < input; j++) {
127 ARRAY[j] = waitingObjects[j].get(i);
128 }
129 ARRAY[input] = obj;
130 ruleBase.setObjects(ruleIndex, ARRAY);
131 boolean condOk;
132 try {
133 condOk = ruleBase.checkCondForDeclaration(ruleIndex, numberInputs - 1);
134 } catch (Exception e) {
135 condOk = false;
136 }
137 if (condOk) {
138 for (int j = 0; j < numberInputs; j++) {
139 propagate(ARRAY[j], j);
140 }
141 }
142 }
143 } else if (input == numberInputs - 2) {
144 int aux = numberInputs - 1;
145 int column = waitingObjects[0].size() - 1;
146 for (int j = 0; j < aux; j++) {
147 ARRAY[j] = waitingObjects[j].get(column);
148 }
149 for (Iterator i = waitingObjects[aux].iterator(); i.hasNext(); ) {
150 ARRAY[aux] = i.next();
151 ruleBase.setObjects(ruleIndex, ARRAY);
152 boolean condOk;
153 try {
154 condOk = ruleBase.checkCondForDeclaration(ruleIndex, numberInputs - 1);
155 } catch (Exception e) {
156 condOk = false;
157 }
158 if (condOk) {
159 for (int j = 0; j < numberInputs; j++) {
160 propagate(ARRAY[j], j);
161 }
162 }
163 }
164 }
165 }
166 /**
167 * Remove the given object from the memory of this node.
168 *
169 * @param obj the object to be removed.
170 */
171 public void remove(Object obj) {
172 final int numberInputs = getNumberInputs();
173 List l = waitingObjects[numberInputs - 1];
174 l.remove(obj);
175 for (int i = 0; i < numberInputs - 1; i++) {
176 its[i] = waitingObjects[i].iterator();
177 }
178 for (; its[0].hasNext(); ) {
179 boolean toBeRemoved = false;
180 for (int i = 0; i < numberInputs - 1; i++) {
181 ARRAY[i] = its[i].next();
182 if (obj.equals(ARRAY[i])) {
183 toBeRemoved = true;
184 }
185 }
186 if (toBeRemoved) {
187 for (int i = 0; i < numberInputs - 1; i++) {
188 its[i].remove();
189 }
190 }
191 }
192 }
193 /**
194 * Returns a string representation of this object. Useful for
195 * debugging.
196 *
197 * @return a string representation of this object.
198 */
199 public String toString() {
200 return ("JoinReteNode[ruleIndex="+ruleIndex+",declIndex="+declIndex+"]");
201 }
202 }