1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23 package net.sf.sail.core.beans;
24
25 import java.beans.beancontext.BeanContextServicesSupport;
26 import java.net.URL;
27 import java.util.ArrayList;
28 import java.util.Collection;
29 import java.util.HashMap;
30 import java.util.HashSet;
31 import java.util.LinkedList;
32 import java.util.List;
33 import java.util.Map;
34 import java.util.Set;
35 import java.util.logging.Level;
36 import java.util.logging.Logger;
37
38 import net.sf.sail.core.beans.assembly.Assignment;
39 import net.sf.sail.core.beans.assembly.PodRegistry;
40 import net.sf.sail.core.beans.assembly.PodVarDelegate;
41 import net.sf.sail.core.beans.assembly.PropertyRef;
42 import net.sf.sail.core.curnit.PodArchiveResolver;
43 import net.sf.sail.core.util.SailBeanUtils;
44 import net.sf.sail.core.uuid.PodUuid;
45
46
47
48
49
50
51 public class Pod extends BeanContextServicesSupport {
52
53
54
55 private static final long serialVersionUID = 7881255006647471835L;
56
57
58
59
60 public static final String PROPERTY_POD_ID = "podId";
61
62
63
64
65 private static final Logger logger = Logger.getLogger(Pod.class.getName());
66
67
68 PodUuid podId;
69
70 public PodUuid getPodId() {
71 return podId;
72 }
73
74 public void setPodId(PodUuid newPodId) {
75 if (newPodId == null)
76 throw new NullPointerException("podId argument was null");
77 PodUuid oldPodId = this.podId;
78 this.podId = newPodId;
79
80
81
82
83 PodRegistry.getDefaultRegistry().reregister(this);
84
85 if (oldPodId != null)
86
87 updateLeftAssignments(assemblyCalls, oldPodId, newPodId);
88 }
89
90
91
92
93
94
95
96
97
98
99 private static void updateLeftAssignments(List<Assignment> calls,
100 PodUuid oldPodId, PodUuid newPodId) {
101 for (Assignment assignment : calls) {
102 PodVarDelegate left = assignment.getLeft();
103 if (left.getPodId().equals(oldPodId))
104 left.setPodId(newPodId);
105 }
106 }
107
108
109 Map<String, PropertyRef> vars = new HashMap<String, PropertyRef>();
110
111 public Map<String, PropertyRef> getVars() {
112 return vars;
113 }
114
115 public void setVars(Map<String, PropertyRef> vars) {
116 this.vars = vars;
117 }
118
119
120
121
122
123
124
125
126
127
128
129
130
131 public void exportProperty(PropertyRef propertyRef, String exportSocketName) {
132 bind(exportSocketName, propertyRef, false);
133 }
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148 public void importProperty(PropertyRef propertyRef, String importSocketName) {
149 bind(importSocketName, propertyRef, true);
150 }
151
152
153
154
155
156
157
158
159
160 @Deprecated
161 public void bind(String varName, PropertyRef propertyRef,
162 boolean isTransient) {
163 Object target = propertyRef.getTarget();
164 if (!this.contains(target))
165 throw new RuntimeException("pod " + this
166 + " does not contain target " + target + " of binding");
167 vars.put(varName, propertyRef);
168 if (isTransient)
169 transientRefs.add(propertyRef);
170 }
171
172
173
174
175
176
177
178 public Object resolve(String varName) {
179 Object value = null;
180 try {
181 value = (vars.get(varName)).getCurrentValue();
182 } catch (Exception e) {
183 logger.warning("exception: " + e);
184 }
185 return value;
186 }
187
188
189 Set<PropertyRef> transientRefs = new HashSet<PropertyRef>();
190
191 public Set<PropertyRef> getTransientRefs() {
192 return transientRefs;
193 }
194
195 public void setTransientRefs(Set<PropertyRef> transientRefs) {
196 this.transientRefs = transientRefs;
197 }
198
199
200 List<Assignment> assemblyCalls = new LinkedList<Assignment>();
201
202 private boolean assemblyStarted;
203
204 private boolean assembled;
205
206 public List<Assignment> getAssemblyCalls() {
207 return assemblyCalls;
208 }
209
210 public void setAssemblyCalls(List<Assignment> assemblyCalls) {
211 Object old = this.assemblyCalls;
212 this.assemblyCalls = assemblyCalls;
213 firePropertyChange("assemblyCalls", old, assemblyCalls);
214 }
215
216 protected Pod childWithId(PodUuid podId) {
217 Collection<Pod> podChildren = SailBeanUtils.childrenOfType(this,
218 Pod.class);
219 for (Pod pod : podChildren) {
220 if (pod.getPodId().equals(podId))
221 return pod;
222 }
223 return null;
224 }
225
226 public URL getPodArchive() {
227 return PodArchiveResolver.getPodArchive(podId);
228 }
229
230
231 public void assemble(PodRegistry registry) throws UnknownPodException {
232 assembleChildren(registry);
233 registry.register(this);
234 assemblyStarted = true;
235 for (Assignment assignment : assemblyCalls) {
236 try {
237 assignment.execute(registry);
238 } catch (Exception e) {
239 logger
240 .severe("Pod assemble failing due failed execution of assignment " + assignment + " by " + e);
241 throw new RuntimeException("error assembling", e);
242 }
243 }
244 assembled= true;
245 }
246
247
248 Set<PodUuid> childPodIds = new HashSet<PodUuid>();
249
250 @Override
251 public boolean add(Object targetChild) {
252 boolean success = super.add(targetChild);
253 if (logger.isLoggable(Level.FINE)) {
254 logger.fine(this + " added " + targetChild + " success:" + success);
255 }
256 if (success && targetChild instanceof Pod) {
257 Pod pod = (Pod) targetChild;
258 childPodIds.add(pod.getPodId());
259 }
260
261 return success;
262 }
263
264
265
266
267
268
269
270 @Override
271 public boolean remove(Object targetChild) {
272
273 boolean success = super.remove(targetChild);
274 if (logger.isLoggable(Level.FINE)) {
275 logger.fine(this + " removed " + targetChild + " success:"
276 + success);
277 }
278
279
280
281
282
283 if (success && targetChild instanceof Pod) {
284 Pod pod = (Pod) targetChild;
285
286
287
288
289 List<Assignment> calls = this.assemblyCalls;
290 List<Assignment> callsToRemove = new ArrayList<Assignment>();
291 for (Assignment assignment : calls) {
292 boolean remove = false;
293 if (assignment.getLeft().getPodId().equals(pod.getPodId()))
294 remove = true;
295 else if (assignment.getRight().getPodId()
296 .equals(pod.getPodId()))
297 remove = true;
298 if (remove) {
299 callsToRemove.add(assignment);
300
301 String varName = assignment.getLeft().getVarName();
302 vars.remove(varName);
303 }
304 }
305 this.assemblyCalls.removeAll(callsToRemove);
306 }
307
308 return success;
309 }
310
311
312
313
314 @Deprecated
315 private void removeFromTransientRefs(Object targetChild) {
316 for (PropertyRef ref : transientRefs) {
317 try {
318 if (targetChild == ref.getCurrentValue()) {
319 transientRefs.remove(ref);
320 }
321 } catch (Exception e) {
322
323 e.printStackTrace();
324 }
325 }
326 }
327
328 private void assembleChildren(PodRegistry registry)
329 throws UnknownPodException {
330 for (PodUuid podId : childPodIds) {
331 Pod pod = registry.getPod(podId);
332 if (pod == null)
333 throw new UnknownPodException(podId, registry);
334 add(pod);
335 pod.assemble(registry);
336 }
337 }
338
339 public Set<PodUuid> getChildPodIds() {
340 refreshChildPodsIdSet();
341 return childPodIds;
342 }
343
344
345
346
347 private void refreshChildPodsIdSet() {
348 Collection<Pod> podChildren = SailBeanUtils.childrenOfType(this,
349 Pod.class);
350 Set<PodUuid> idsOfPodChildren = new HashSet<PodUuid>();
351 for (Pod pod : podChildren) {
352 idsOfPodChildren.add(pod.getPodId());
353 }
354 childPodIds = idsOfPodChildren;
355 }
356
357
358
359
360
361
362
363
364 public void setChildPodIds(Set<PodUuid> childPodIds) {
365 this.childPodIds = childPodIds;
366 }
367
368
369
370
371
372
373
374
375
376
377 public boolean isTransient(Object value) {
378 if (value instanceof Pod)
379 return false;
380
381
382
383 if (value == null)
384 return false;
385
386
387
388
389
390 Class<? extends Object> valueClass = value.getClass();
391 if (valueClass.isArray()) {
392 Object[] values = ((Object[]) value);
393 for (int i = 0; i < values.length; i++) {
394 Object elementValue = values[i];
395 if (valueMatchesReference(elementValue, transientRefs)) {
396 return true;
397 }
398 }
399 }
400
401 if (valueMatchesReference(value, transientRefs)) {
402
403 return true;
404 }
405
406 return false;
407 }
408
409
410
411
412
413
414
415 private static boolean valueMatchesReference(Object value,
416 Set<PropertyRef> propertyReferences) {
417 for (PropertyRef ref : propertyReferences) {
418 try {
419 if (value == ref.getCurrentValue()) {
420 return true;
421 }
422 } catch (Exception e) {
423 logger.warning("exception: " + e);
424 }
425 }
426 return false;
427 }
428
429 @Override
430 public String toString() {
431 return "Pod@" + podId;
432 }
433
434
435
436 @Override
437 public int hashCode() {
438 return super.hashCode();
439
440
441
442
443 }
444
445
446
447
448
449 public void touch() {
450
451
452
453 }
454
455
456
457
458 public boolean isAssembled() {
459 return assembled;
460 }
461
462 }