Docjar: A Java Source and Docuemnt Enginecom.*    java.*    javax.*    org.*    all    new    plug-in

Quick Search    Search Deep

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 }