1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package fulmine.context;
17
18 import static fulmine.util.Utils.logException;
19 import static fulmine.util.Utils.safeToString;
20
21 import java.util.Collection;
22 import java.util.Map;
23 import java.util.Set;
24
25 import fulmine.AbstractLifeCycle;
26 import fulmine.IDomain;
27 import fulmine.IType;
28 import fulmine.Type;
29 import fulmine.model.IModelManager;
30 import fulmine.model.container.ContainerFactory;
31 import fulmine.model.container.IContainer;
32 import fulmine.model.container.IContainerFactory;
33 import fulmine.util.collection.CollectionFactory;
34 import fulmine.util.log.AsyncLog;
35 import fulmine.util.reference.AutoCreatingStore;
36 import fulmine.util.reference.IAutoCreatingStore;
37 import fulmine.util.reference.IObjectBuilder;
38
39
40
41
42
43
44
45
46
47 final class ModelManager extends AbstractLifeCycle implements IModelManager
48 {
49 private final static AsyncLog LOG = new AsyncLog(DistributionManager.class);
50
51
52
53
54
55 final IAutoCreatingStore<String, IAutoCreatingStore<IType, IAutoCreatingStore<IDomain, Map<String, IContainer>>>> remoteContainers;
56
57
58
59
60
61 final IAutoCreatingStore<IType, IAutoCreatingStore<IDomain, Map<String, IContainer>>> localContainers;
62
63
64
65
66
67
68 private static final class BuilderKeyedByDomain
69 implements
70 IObjectBuilder<IType, IAutoCreatingStore<IDomain, Map<String, IContainer>>>
71 {
72 public IAutoCreatingStore<IDomain, Map<String, IContainer>> create(
73 IType key)
74 {
75 return new AutoCreatingStore<IDomain, Map<String, IContainer>>(
76 new BuilderKeyedOnString());
77 }
78 }
79
80
81
82
83
84
85 private static final class BuilderKeyedByType
86 implements
87 IObjectBuilder<String, IAutoCreatingStore<IType, IAutoCreatingStore<IDomain, Map<String, IContainer>>>>
88 {
89
90 public IAutoCreatingStore<IType, IAutoCreatingStore<IDomain, Map<String, IContainer>>> create(
91 String key)
92 {
93 return new AutoCreatingStore<IType, IAutoCreatingStore<IDomain, Map<String, IContainer>>>(
94 new BuilderKeyedByDomain());
95 }
96 }
97
98
99
100
101
102
103 private static final class BuilderKeyedOnString implements
104 IObjectBuilder<IDomain, Map<String, IContainer>>
105 {
106 public Map<String, IContainer> create(IDomain key)
107 {
108 return CollectionFactory.newMap();
109 }
110 }
111
112
113 private final IFrameworkContext context;
114
115
116 private final IContainerFactory containerFactory;
117
118
119
120
121
122
123
124 ModelManager(IFrameworkContext context)
125 {
126 super();
127 this.context = context;
128 this.containerFactory = new ContainerFactory();
129 this.localContainers =
130 new AutoCreatingStore<IType, IAutoCreatingStore<IDomain, Map<String, IContainer>>>(
131 new BuilderKeyedByDomain());
132 this.remoteContainers =
133 new AutoCreatingStore<String, IAutoCreatingStore<IType, IAutoCreatingStore<IDomain, Map<String, IContainer>>>>(
134 new BuilderKeyedByType());
135 }
136
137 @Override
138 protected AsyncLog getLog()
139 {
140 return LOG;
141 }
142
143 @Override
144 protected final void doStart()
145 {
146 if (getLog().isInfoEnabled())
147 {
148 getLog().info("Started");
149 }
150 }
151
152 @Override
153 protected final void doDestroy()
154 {
155 clearLocalContainers();
156 clearRemoteContainers();
157 this.containerFactory.destroy();
158 }
159
160 public IContainer getLocalContainer(String identity, IType type,
161 IDomain domain)
162 {
163 return doGet(this.context.getIdentity(), identity, type, domain,
164 this.localContainers, true);
165 }
166
167 public boolean containsLocalContainer(String containerIdentity, IType type,
168 IDomain domain)
169 {
170 return doContainerExists(containerIdentity, type, domain,
171 this.localContainers);
172 }
173
174 public IContainer getRemoteContainer(String remoteContextIdentity,
175 final String identity, final IType type, IDomain domain)
176 {
177 return doGet(remoteContextIdentity, identity, type, domain,
178 this.remoteContainers.get(remoteContextIdentity), false);
179 }
180
181 public boolean containsRemoteContainer(String remoteContextIdentity,
182 String containerIdentity, IType type, IDomain domain)
183 {
184 return doContainerExists(containerIdentity, type, domain,
185 this.remoteContainers.get(remoteContextIdentity));
186 }
187
188 public void addContainer(IContainer container)
189 {
190 if (container.isLocal())
191 {
192 doAdd(container.getIdentity(), container, this.localContainers);
193 }
194 else
195 {
196 doAdd(container.getIdentity(), container,
197 this.remoteContainers.get(container.getNativeContextIdentity()));
198 }
199 }
200
201 public boolean removeContainer(IContainer container)
202 {
203 if (container == null || container.getContext() == null)
204 {
205 return false;
206 }
207 if (container.isLocal())
208 {
209 return doRemove(container.getIdentity(), container.getType(),
210 container.getDomain(), this.localContainers);
211 }
212 final boolean doRemove =
213 doRemove(container.getIdentity(), container.getType(),
214 container.getDomain(),
215 this.remoteContainers.get(container.getNativeContextIdentity()));
216 return doRemove;
217 }
218
219 public Collection<IContainer> getLocalContainers()
220 {
221 return doGetAll(this.localContainers);
222 }
223
224 public Collection<IContainer> getRemoteContainers(
225 String remoteContextIdentity)
226 {
227 return doGetAll(this.remoteContainers.get(remoteContextIdentity));
228 }
229
230 public IContainerFactory getContainerFactory()
231 {
232 return this.containerFactory;
233 }
234
235
236
237
238 void clearRemoteContainers()
239 {
240 if (getLog().isInfoEnabled())
241 {
242 getLog().info("Removing all remote containers");
243 }
244 synchronized (this.remoteContainers)
245 {
246 final Set<String> remoteContextIdentities =
247 CollectionFactory.newSet(this.remoteContainers.keySet());
248 for (String remoteContextIdentity : remoteContextIdentities)
249 {
250 doClear(this.remoteContainers.get(remoteContextIdentity));
251 }
252 }
253 }
254
255
256
257
258 void clearLocalContainers()
259 {
260 if (getLog().isInfoEnabled())
261 {
262 getLog().info("Removing all local containers");
263 }
264 doClear(this.localContainers);
265 }
266
267
268
269
270
271
272
273
274
275 private Collection<IContainer> doGetAll(
276 IAutoCreatingStore<IType, IAutoCreatingStore<IDomain, Map<String, IContainer>>> containers)
277 {
278 synchronized (containers)
279 {
280 Collection<IContainer> all = CollectionFactory.newSet();
281 final Set<IType> keySet = containers.keySet();
282 for (IType type : keySet)
283 {
284 try
285 {
286 final Set<IDomain> domains = containers.get(type).keySet();
287 for (IDomain domain : domains)
288 {
289 all.addAll(containers.get(type).get(domain).values());
290 }
291 }
292 catch (Exception e)
293 {
294 logException(getLog(), type, e);
295 }
296 }
297 return all;
298 }
299 }
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319 private IContainer doGet(
320 String nativeContextIdentity,
321 String identity,
322 IType type,
323 IDomain domain,
324 IAutoCreatingStore<IType, IAutoCreatingStore<IDomain, Map<String, IContainer>>> containers,
325 boolean local)
326 {
327 IContainer container = null;
328 synchronized (containers)
329 {
330 container = containers.get(type).get(domain).get(identity);
331 }
332 if (container == null)
333 {
334 container =
335 getContainerFactory().createContainer(nativeContextIdentity,
336 identity, type, domain, this.context, local);
337
338 }
339 return container;
340 }
341
342
343
344
345
346
347
348
349 private void doClear(
350 IAutoCreatingStore<IType, IAutoCreatingStore<IDomain, Map<String, IContainer>>> containers)
351 {
352 final Collection<IContainer> all = doGetAll(containers);
353 for (IContainer container : all)
354 {
355 try
356 {
357 container.destroy();
358 }
359 catch (Exception e)
360 {
361 logException(getLog(), container, e);
362 }
363 }
364 synchronized (containers)
365 {
366 containers.clear();
367 }
368 }
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384 private boolean doContainerExists(
385 String containerIdentity,
386 IType type,
387 IDomain domain,
388 IAutoCreatingStore<IType, IAutoCreatingStore<IDomain, Map<String, IContainer>>> containers)
389 {
390 synchronized (containers)
391 {
392 if (!containers.containsKey(type))
393 {
394 return false;
395 }
396 if (!containers.get(type).containsKey(domain))
397 {
398 return false;
399 }
400 return containers.get(type).get(domain).containsKey(
401 containerIdentity);
402 }
403 }
404
405
406
407
408
409
410
411
412
413
414
415 private void doAdd(
416 String identity,
417 IContainer container,
418 IAutoCreatingStore<IType, IAutoCreatingStore<IDomain, Map<String, IContainer>>> containers)
419 {
420 IContainer previous = null;
421 synchronized (containers)
422 {
423 previous =
424 containers.get(container.getType()).get(container.getDomain()).put(
425 identity, container);
426 }
427 if (previous != null)
428 {
429 if (getLog().isInfoEnabled())
430 {
431 getLog().info(
432 "Previous container has been overwritten: " + previous
433 + " with: " + safeToString(container), new Exception());
434 }
435 }
436 }
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452 private boolean doRemove(
453 String identity,
454 IType type,
455 IDomain domain,
456 IAutoCreatingStore<IType, IAutoCreatingStore<IDomain, Map<String, IContainer>>> containers)
457 {
458 synchronized (containers)
459 {
460 if (containers.containsKey(type))
461 {
462 final IAutoCreatingStore<IDomain, Map<String, IContainer>> types =
463 containers.get(type);
464 if (types.containsKey(domain))
465 {
466 final IContainer removed =
467 types.get(domain).remove(identity);
468 return removed != null;
469 }
470 }
471 }
472 return false;
473 }
474
475 }