1
2
3
4
5
6
7
8
9
10
11 package org.mule.context.notification;
12
13 import org.mule.api.context.notification.ServerNotification;
14 import org.mule.api.context.notification.BlockingServerEvent;
15
16 import java.util.Set;
17 import java.util.HashSet;
18 import java.util.LinkedList;
19 import java.util.Iterator;
20
21 import org.apache.commons.logging.Log;
22 import org.apache.commons.logging.LogFactory;
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37 class Node implements RestrictedNode
38 {
39
40
41 public static final int SUCCESS = 0;
42 public static final int FAILURE = 1;
43 public static final int EMPTY = 2;
44
45
46 private Class clazz = null;
47 private int action;
48 private String id;
49 private boolean isIdDefined = false;
50 private boolean nodeOk = false;
51
52 protected final transient Log logger = LogFactory.getLog(this.getClass());
53
54
55 private Set parallel = new HashSet();
56
57 private LinkedList serial = new LinkedList();
58
59 public Node(Class clazz, int action, String id)
60 {
61 this(clazz, action);
62 this.id = id;
63 isIdDefined = true;
64 }
65
66 public Node(Class clazz, int action)
67 {
68 this.clazz = clazz;
69 this.action = action;
70 }
71
72 public Node()
73 {
74 nodeOk = true;
75 }
76
77 public Node parallel(RestrictedNode node)
78 {
79 if (null != node.getNotificationClass() &&
80 BlockingServerEvent.class.isAssignableFrom(node.getNotificationClass()))
81 {
82 logger.warn("Registered blocking event as parallel: " + node);
83 }
84 parallel.add(node);
85 return this;
86 }
87
88
89
90
91
92 public Node parallelSynch(RestrictedNode node)
93 {
94 if (null != node.getNotificationClass() &&
95 !BlockingServerEvent.class.isAssignableFrom(node.getNotificationClass()))
96 {
97 throw new IllegalStateException("Node " + node + " is not a synch event");
98 }
99 parallel.add(node);
100 return this;
101 }
102
103 public RestrictedNode serial(RestrictedNode node)
104 {
105 if (null != node.getNotificationClass() &&
106 !BlockingServerEvent.class.isAssignableFrom(node.getNotificationClass()))
107 {
108 logger.warn("Registered non-blocking event as serial: " + node);
109 }
110 serial.addLast(node);
111 return this;
112 }
113
114
115
116
117
118 public int match(ServerNotification notification)
119 {
120
121 if (!nodeOk)
122 {
123 if (testLocal(notification))
124 {
125 nodeOk = true;
126 return SUCCESS;
127 }
128 else
129 {
130 return FAILURE;
131 }
132 }
133
134
135 if (parallel.size() > 0)
136 {
137 for (Iterator children = parallel.iterator(); children.hasNext();)
138 {
139 Node child = (Node) children.next();
140 switch (child.match(notification))
141 {
142 case SUCCESS:
143 return SUCCESS;
144 case EMPTY:
145 children.remove();
146 break;
147 case FAILURE:
148 break;
149 default:
150 throw new IllegalStateException("Bad return from child");
151 }
152 }
153 }
154
155
156 if (parallel.size() > 0)
157 {
158 return FAILURE;
159 }
160
161
162 if (serial.size() > 0)
163 {
164 for (Iterator children = serial.iterator(); children.hasNext();)
165 {
166 Node child = (Node) children.next();
167 switch (child.match(notification))
168 {
169 case SUCCESS:
170 return SUCCESS;
171 case EMPTY:
172 children.remove();
173 break;
174 case FAILURE:
175 return FAILURE;
176 default:
177 throw new IllegalStateException("Bad return from child");
178 }
179 }
180
181 }
182
183 if (serial.size() > 0)
184 {
185 return FAILURE;
186 }
187 else
188 {
189 return EMPTY;
190 }
191 }
192
193 private boolean testLocal(ServerNotification notification)
194 {
195 return clazz.equals(notification.getClass())
196 && action == notification.getAction()
197 && (!isIdDefined ||
198 (null == id && null == notification.getResourceIdentifier()) ||
199 (null != id && id.equals(notification.getResourceIdentifier())));
200 }
201
202 public boolean contains(Class clazz, int action)
203 {
204 if (null != this.clazz && this.clazz.equals(clazz) && this.action == action)
205 {
206 return true;
207 }
208 for (Iterator children = parallel.iterator(); children.hasNext();)
209 {
210 if (((RestrictedNode) children.next()).contains(clazz, action))
211 {
212 return true;
213 }
214 }
215 for (Iterator children = serial.iterator(); children.hasNext();)
216 {
217 if (((RestrictedNode) children.next()).contains(clazz, action))
218 {
219 return true;
220 }
221 }
222 return false;
223 }
224
225 public RestrictedNode getAnyRemaining()
226 {
227 if (! nodeOk)
228 {
229 return this;
230 }
231 for (Iterator children = parallel.iterator(); children.hasNext();)
232 {
233 RestrictedNode any = ((RestrictedNode) children.next()).getAnyRemaining();
234 if (null != any)
235 {
236 return any;
237 }
238 }
239 for (Iterator children = serial.iterator(); children.hasNext();)
240 {
241 RestrictedNode any = ((RestrictedNode) children.next()).getAnyRemaining();
242 if (null != any)
243 {
244 return any;
245 }
246 }
247 return null;
248 }
249
250 public boolean isExhausted()
251 {
252 return null == getAnyRemaining();
253 }
254
255 public Class getNotificationClass()
256 {
257 return clazz;
258 }
259
260 public String toString()
261 {
262 return clazz + ": " + action + (isIdDefined ? ": " + id : "");
263 }
264
265 }