1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30 package org.logicmachine.rebl.unitTest.language.context;
31
32 import static org.junit.Assert.assertEquals;
33 import static org.junit.Assert.fail;
34 import static org.logicmachine.rebl.common.Constants.ARROW;
35 import static org.logicmachine.rebl.common.Constants.COLON;
36 import static org.logicmachine.rebl.common.Constants.DEFAULT_CHARSET;
37 import static org.logicmachine.rebl.common.Constants.NEWLINE;
38 import static org.logicmachine.rebl.common.i18n.ErrorMessages.DEFAULT_EXCEPTION_HANDLER_MESSAGE_PREFIX;
39 import static org.logicmachine.rebl.common.i18n.ExternalStrings.DEFAULT_SCOPE_NAME;
40 import static org.logicmachine.rebl.common.i18n.ExternalStrings.PARALLEL_SCOPE_ENV_VARIABLE;
41
42 import java.io.ByteArrayOutputStream;
43 import java.io.IOException;
44 import java.io.PrintStream;
45 import java.io.UnsupportedEncodingException;
46 import java.util.Calendar;
47 import java.util.Collection;
48 import java.util.GregorianCalendar;
49 import java.util.Properties;
50
51 import org.junit.AfterClass;
52 import org.junit.Ignore;
53 import org.junit.Test;
54 import org.logicmachine.rebl.common.Common;
55 import org.logicmachine.rebl.common.Many;
56 import org.logicmachine.rebl.common.i18n.ExternalStrings;
57 import org.logicmachine.rebl.domain.actions.Callable;
58 import org.logicmachine.rebl.domain.actors.Actor;
59 import org.logicmachine.rebl.domain.entities.ActiveEntity;
60 import org.logicmachine.rebl.domain.entities.Entities;
61 import org.logicmachine.rebl.domain.entities.Entity;
62 import org.logicmachine.rebl.domain.exceptions.BusinessMessage;
63 import org.logicmachine.rebl.domain.exceptions.ExceptionHandler;
64 import org.logicmachine.rebl.domain.exceptions.ExceptionHandlers;
65 import org.logicmachine.rebl.domain.resources.CloseableResource;
66 import org.logicmachine.rebl.domain.resources.Resource;
67 import org.logicmachine.rebl.domain.resources.Resources;
68 import org.logicmachine.rebl.domain.stateMachines.StateMachine;
69 import org.logicmachine.rebl.domain.stateMachines.StateMachines;
70 import org.logicmachine.rebl.domain.transactions.managers.JdbcTransactionAwareScope;
71 import org.logicmachine.rebl.language.Language;
72 import org.logicmachine.rebl.language.context.EnvironmentObject;
73 import org.logicmachine.rebl.language.context.EnvironmentObjects;
74 import org.logicmachine.rebl.language.context.Scope;
75 import org.logicmachine.rebl.monitor.Monitor;
76 import org.logicmachine.rebl.monitor.Monitors;
77 import org.logicmachine.rebl.monitor.impl.DurationMonitor;
78 import org.logicmachine.rebl.monitor.impl.ThroughputMonitor;
79 import org.logicmachine.rebl.unitTest.common.CommonTest.MyActiveEntity;
80 import org.logicmachine.rebl.unitTest.common.CommonTest.UnsuccessfulCallable;
81 import org.logicmachine.rebl.unitTest.domain.actions.MyCallableFunctions;
82 import org.logicmachine.rebl.unitTest.domain.stateMachines.States;
83
84
85 @Ignore
86 @SuppressWarnings("javadoc")
87 public abstract class GenericScopeTest<T extends Scope>
88 {
89 protected static final String ACTIVE_ENTITY_KEY_1 = "myActiveEntity1";
90 protected static final String ACTIVE_ENTITY_KEY_2 = "myActiveEntity2";
91 protected static final String ACTIVE_ENTITY_KEY_3 = "myActiveEntity3";
92 protected static final String ERROR_MESSAGE = "my error message";
93
94 protected String key = "myKey";
95 protected String newKey1 = "newKey1";
96 protected String newKey2 = "newKey2";
97
98 protected Language language;
99 protected T defaultScope;
100 protected T scope;
101
102
103 @AfterClass
104 public static void teardown()
105 {
106 Scope.setDefaultScopeType(Scope.class);
107 }
108
109 @SuppressWarnings("unchecked")
110 public void setupGenericScope()
111 {
112 language = new Language("test");
113
114 defaultScope = (T)language.withDefaultScope();
115 }
116
117 public void setupGenericScope(final String key, final String newKey1, final String newKey2, final Properties properties)
118 {
119 this.key = key;
120 this.newKey1 = newKey1;
121 this.newKey2 = newKey2;
122
123 Scope.setScopeInitialisationProperties(key, properties);
124 Scope.setScopeInitialisationProperties(newKey1, properties);
125 Scope.setScopeInitialisationProperties(newKey2, properties);
126 Scope.setScopeInitialisationProperties(DEFAULT_SCOPE_NAME, properties);
127 Scope.setScopeInitialisationProperties(JdbcTransactionAwareScope.class, properties);
128
129 setupGenericScope();
130 }
131
132 @SuppressWarnings("unchecked")
133 protected T createScope()
134 {
135 scope = (T)Scope.newInstance(key);
136
137 return scope;
138 }
139
140 public void cleanUpGenericScope()
141 {
142 Common.clearScopes();
143
144 MyCallableFunctions.reset();
145 }
146
147 public Language getLanguage()
148 {
149 return language;
150 }
151
152
153 @Test
154 public void shouldCreateScopeInstance()
155 {
156 assertEquals("expected correct key", key, createScope().key());
157 }
158
159 @Test
160 public void shouldDetermineDefaultScope()
161 {
162 assertEquals("expected default scope", true, defaultScope.isDefaultScope());
163 }
164
165 @Test
166 public void shouldDetermineNonDefaultScope()
167 {
168 final Scope newScope = Scope.newSequentialInstance(key);
169
170 assertEquals("expected default", true, defaultScope.isDefaultScope());
171 assertEquals("expected non-default", false, newScope.isDefaultScope() );
172 }
173
174 @Test
175 public void shouldCreateSequentialScope()
176 {
177 final Scope newScope = Scope.newSequentialInstance(key);
178
179 assertEquals("expected sequential scope", false, newScope.isParallel());
180 }
181
182 @Test
183 public void shouldSetSequentialScope()
184 {
185 final Scope newScope = Scope.newInstance(key).sequential();
186
187 assertEquals("expected parent scope", false, newScope.withParent().isEmpty());
188
189 assertEquals("expected sequential scope", false, newScope.isParallel());
190 }
191
192 @Test
193 public void shouldCreateParallelScope()
194 {
195 final Scope newScope = Scope.newParallelInstance(key);
196
197 assertEquals("expected parallel scope", true, newScope.isParallel());
198
199 assertEquals("expected no parent scope", true, newScope.withParent().isEmpty());
200 }
201
202 @Test
203 public void shouldSetParallelScope()
204 {
205 final Scope newScope = Scope.newInstance(key).parallel();
206
207 assertEquals("expected parallel scope", true, newScope.isParallel());
208
209 assertEquals("expected no parent scope", true, newScope.withParent().isEmpty());
210 }
211
212 @Test
213 public void shouldCreateParallelScopeIfTriggerEnvironmentVariableSet()
214 {
215
216
217
218
219 final Scope newScope = Scope.newInstance(key)
220 .withEnvironmentObject(new EnvironmentObject(PARALLEL_SCOPE_ENV_VARIABLE, "true"));
221
222 assertEquals("expected parallel scope", true, newScope.isParallel());
223
224 assertEquals("expected no parent scope", true, newScope.withParent().isEmpty());
225 }
226
227 @Test
228 public void shouldCreateSequentialScopeIfTriggerEnvironmentVariableNotSet()
229 {
230
231
232
233
234 final Scope newScope = Scope.newInstance(key)
235 .withEnvironmentObject(new EnvironmentObject(PARALLEL_SCOPE_ENV_VARIABLE, "false"));
236
237 assertEquals("expected sequential scope", false, newScope.isParallel());
238
239 assertEquals("expected parent scope", false, newScope.withParent().isEmpty());
240 }
241
242 @Test
243 public void shouldConvertParallelScopeToStandalone()
244 {
245 final Scope parallelScope = Scope.newInstance(key).parallel();
246
247 assertEquals("expected parallel scope", true, parallelScope.isParallel());
248
249 assertEquals("expected no parent scope", true, parallelScope.withParent().isEmpty());
250 }
251
252 @Test
253 public void shouldDefineScopeWithGivenKey()
254 {
255 assertEquals("expected correct key", key, Scope.newInstance(key).key());
256 }
257
258 @Test(expected = IllegalArgumentException.class)
259 public void shouldFailToCreateMultipleScopesWithSameKey()
260 {
261 Scope.newInstance(key).withScope(key);
262 }
263
264 @Test
265 @SuppressWarnings("unchecked")
266 public void shouldCreateNewScopeWithKey()
267 {
268 final T newScope = (T)Scope.newInstance(key);
269
270 assertEquals("expected new scope", false, newScope.isEmpty());
271 assertEquals("expected new scope", false, newScope.equals(newScope.withScope(newKey1)));
272 }
273
274 @Test
275 @SuppressWarnings("unchecked")
276 public void shouldCreateNewScopeWithKeyAndActiveEntity()
277 {
278 final ActiveEntity activeEntity = new ActiveEntity("myActiveEntity");
279 final T newScope = (T)Scope.newInstance(key, activeEntity);
280
281 assertEquals("expected new scope", false, newScope.isEmpty());
282 assertEquals("expected new scope", false, newScope.equals(newScope.withScope(newKey1)));
283 assertEquals("expected correct entity", activeEntity, newScope.withActiveEntity());
284 }
285
286 @Test
287 @SuppressWarnings("unchecked")
288 public void shouldDefineScope()
289 {
290 assertEquals("expected default", defaultScope, defaultScope.language().withDefaultScope());
291
292 final T newScope = (T)Scope.newInstance(key);
293
294 assertEquals("expected new scope", newScope, Common.withScope(key));
295 assertEquals("expected correct parent", defaultScope, newScope.withParent());
296 }
297
298 @Test
299 public void defaultScopeShouldHaveNoParent()
300 {
301 assertEquals("expected no parent scope", true, Common.withDefaultScope().withParent().isEmpty());
302 }
303
304 @Test
305 public void shouldHaveParent()
306 {
307 assertEquals("expected correct parent", defaultScope, defaultScope.withScope(key).withParent());
308 }
309
310 @Test
311 public void shouldCloseScope()
312 {
313 final Scope newScope = Scope.newInstance(key);
314
315 assertEquals("expected open scope", false, newScope.isClosed());
316
317 newScope.closeScope();
318
319 assertEquals("expected closed scope", true, newScope.isClosed());
320 }
321
322 @Test
323 public void shouldUnregisterScope()
324 {
325 Scope.newInstance(key);
326
327 assertEquals("expected default scope", true, language.unregisterScope(defaultScope).isEmpty());
328 }
329
330 @Test
331 @SuppressWarnings("unchecked")
332 public void shouldUnregisterSequentialScopes()
333 {
334 final T outer = (T)Scope.newInstance(key);
335 final T inner = (T)outer.withScope(newKey1);
336
337 assertEquals("expected outer scope", true, language.unregisterScope(inner).equals(outer));
338 }
339
340
341
342 @Test
343 @SuppressWarnings("unchecked")
344 public void shouldInheritConfiguredAttributesFromParentScope()
345 {
346 final T parentScope = (T)Scope.newInstance(key);
347 final T childScope1 = (T)parentScope.withScope(newKey1);
348
349 assertEquals("expected no exception handlers", true, childScope1.withExceptionHandlers().isEmpty() );
350 assertEquals("expected no environment objects", true, childScope1.getEnvironmentObjects().isEmpty() );
351 assertEquals("expected no resources", true, childScope1.getResources().isEmpty() );
352 assertEquals("expected no state machines", true, childScope1.withStateMachines().isEmpty() );
353 assertEquals("expected no component package names", true, childScope1.withComponentPackageNames().isEmpty());
354 assertEquals("expected no business entities", true, childScope1.getEntities(MyEntity.class).getCollection().isEmpty());
355 assertEquals("expected no monitors", true, childScope1.withMonitors().isEmpty() );
356
357 childScope1.withExceptionHandlers (buildExceptionHandlers() );
358 childScope1.withEnvironmentObjects (new EnvironmentObject("foo", "bar" ),
359 new EnvironmentObject("hello", "world"));
360 childScope1.withResources (buildResources() );
361 childScope1.withStateMachines (buildStateMachines() );
362 childScope1.withComponentPackageNames("foo", "bar" );
363 childScope1.withMonitors (new ThroughputMonitor(),
364 new DurationMonitor() );
365 childScope1.withEntities (buildEntities() );
366
367 final T childScope2 = (T)childScope1.withScope(newKey2);
368
369 assertEquals("expected some exception handlers", false, childScope2.withExceptionHandlers().isEmpty() );
370 assertEquals("expected some environment objects", false, childScope2.getEnvironmentObjects().isEmpty() );
371 assertEquals("expected some state machines", false, childScope2.withStateMachines().isEmpty() );
372 assertEquals("expected some component package names", false, childScope2.withComponentPackageNames().isEmpty());
373 assertEquals("expected some business entities", false, childScope2.getEntities(MyEntity.class)
374 .getCollection().isEmpty() );
375
376 assertEquals("expected no resources", true, childScope2.getResources().isEmpty() );
377 assertEquals("expected no monitors", true, childScope2.withMonitors().isEmpty() );
378 }
379
380 @Test
381 @SuppressWarnings("unchecked")
382 public void shouldInheritIsParallelAttributeFromParentScope()
383 {
384 final T parentScope = (T)Scope.newInstance(key).parallel();
385 final T childScope1 = (T)parentScope.withScope(newKey1);
386
387 assertEquals("expected sequential child scope", false, childScope1.isParallel());
388
389 parentScope.inheritParallelSetting();
390
391 final T childScope2 = (T)parentScope.withScope(newKey2);
392
393 assertEquals("expected parallel child scope", true, childScope2.isParallel());
394 }
395
396
397
398 @Test
399 public void shouldAttachExceptionHandlersToScope()
400 {
401
402 assertSize(defaultScope.withExceptionHandlers(buildExceptionHandlers())
403 .withExceptionHandlers(), 3);
404 }
405
406 @Test
407 public void shouldAttachExceptionHandlerInstancesToScope()
408 {
409
410 assertSize(defaultScope.withExceptionHandlers(new ExceptionHandler(),
411 new ExceptionHandler())
412 .withExceptionHandlers(), 3);
413 }
414
415 @Test
416 public void shouldAttachExceptionHandlerToScope()
417 {
418
419 assertSize(defaultScope.withExceptionHandler(new ExceptionHandler())
420 .withExceptionHandlers(), 2);
421 }
422
423 @Test
424 public void shouldGetExceptionHandlers()
425 {
426
427 assertSize(defaultScope.withExceptionHandlers(buildExceptionHandlers())
428 .withExceptionHandlers(), 3);
429 }
430
431
432
433 @Test
434 public void shouldAttachEnvironmentObjectsToScope()
435 {
436 final EnvironmentObjects environmentObjects = new EnvironmentObjects()
437 .add(new EnvironmentObject("foo", "bar" ))
438 .add(new EnvironmentObject("hello", "world"));
439
440 defaultScope.withEnvironmentObjects(environmentObjects);
441
442 assertSize(defaultScope.getEnvironmentObjects(), 2);
443 assertSize(defaultScope.withEnvironmentObjects(), 2);
444 }
445
446 @Test
447 public void shouldAttachEnvironmentObjectInstancesToScope()
448 {
449 assertSize(defaultScope.withEnvironmentObjects(new EnvironmentObject("foo", "bar" ),
450 new EnvironmentObject("hello", "world"))
451 .getEnvironmentObjects(), 2);
452 }
453
454 @Test
455 public void shouldAttachEnvironmentObjectToScope()
456 {
457 final Calendar now = new GregorianCalendar();
458
459 assertSize(defaultScope.withEnvironmentObject("currentDate", now).getEnvironmentObjects(), 1);
460
461 assertEquals("expected correct date", now, defaultScope.getEnvironmentObject("currentDate").value());
462 }
463
464
465
466 @Test
467 public void shouldAttachResourcesToScope()
468 {
469 assertSize(defaultScope.withResources(buildResources())
470 .getResources(), 2);
471 }
472
473 @Test
474 public void shouldAttachResourceInstancessToScope()
475 {
476 assertSize(defaultScope.withResources(new Resource("resource1"),
477 new Resource("resource2"))
478 .getResources(), 2);
479 }
480
481 @Test
482 public void shouldAttachResourceToScope()
483 {
484 assertSize(defaultScope.withResource(new Resource("resource1"))
485 .getResources(), 1);
486 }
487
488 @Test
489 public void shouldGetResources()
490 {
491 assertSize(defaultScope.withResources(buildResources())
492 .getResources(), 2);
493 }
494
495 @Test
496 public void shouldGetActiveResource()
497 {
498 final Resource resource = new Resource("test");
499 defaultScope.withActiveResource(resource);
500
501 assertEquals("expected correct resource", resource, defaultScope.withActiveResource());
502 assertEquals("expected correct resource", resource, defaultScope.getActiveResource());
503 }
504
505
506
507 @Test
508 public void shouldAttachStateMachinesToScope()
509 {
510 assertSize(defaultScope.withStateMachines(buildStateMachines())
511 .withStateMachines(), 2);
512 }
513
514 @Test
515 public void shouldAttachStateMachineInstancesToScope()
516 {
517 assertSize(defaultScope.withStateMachines(new StateMachine<States>("foo"),
518 new StateMachine<States>("bar"))
519 .withStateMachines(), 2);
520 }
521
522 @Test
523 public void shouldAttachStateMachineToScope()
524 {
525 assertSize(defaultScope.withStateMachine(new StateMachine<States>("foo"))
526 .withStateMachines(), 1);
527 }
528
529 @Test
530 public void shouldGetStateMachines()
531 {
532 defaultScope.withStateMachines(buildStateMachines());
533
534 assertEquals("expected correct state machine", true, null != defaultScope.withStateMachine("sm1" ));
535 assertEquals("expected correct state machine", true, null != defaultScope.withStateMachine("sm2" ));
536 }
537
538 @Test(expected = IllegalArgumentException.class)
539 public void shouldNotFindStateMachine()
540 {
541 defaultScope.withStateMachines(buildStateMachines()).withStateMachine("test");
542 }
543
544
545
546 @Test
547 public void shouldAttachEntitiesToScope()
548 {
549 assertSize(defaultScope.withEntities(buildEntities())
550 .getEntities(MyEntity.class).getCollection(), 2);
551 }
552
553 @Test
554 public void shouldAttachEntityInstancesToScope()
555 {
556 assertSize(defaultScope.withEntities(new MyEntity(),
557 new MyEntity())
558 .getEntities(MyEntity.class).getCollection(), 2);
559 }
560
561 @Test
562 public void shouldAttachEntityToScope()
563 {
564 assertSize(defaultScope.withEntity(new MyEntity())
565 .getEntities(MyEntity.class).getCollection(), 1);
566 }
567
568 @Test
569 public void shouldGetEntities()
570 {
571 defaultScope.withEntities(buildEntities());
572
573 assertEquals("expected correct entity", "foo",
574 defaultScope.findEntityWithinScope(MyEntity.class, "foo").key());
575
576 assertEquals("expected correct entity", "bar",
577 defaultScope.findEntityWithinScope(MyEntity.class, "bar").key());
578 }
579
580
581
582 @Test
583 public void shouldAttachComponentPackageNamesToScope()
584 {
585 assertSize(defaultScope.withComponentPackageNames("foo", "bar")
586 .withComponentPackageNames(), 2);
587 }
588
589 @Test
590 public void shouldAttachComponentPackageNameToScope()
591 {
592 assertSize(defaultScope.withComponentPackageNames("foo")
593 .withComponentPackageNames(), 1);
594 }
595
596
597
598 @Test
599 public void shouldAddIndividualMonitors()
600 {
601 defaultScope.withMonitors(new ThroughputMonitor(),
602 new DurationMonitor());
603
604 assertEquals("expected correct monitor count", 2, defaultScope.withMonitors().size());
605 }
606
607 @Test
608 public void shouldAddMonitors()
609 {
610 defaultScope.withMonitors(new Monitors().add(new ThroughputMonitor())
611 .add(new DurationMonitor()));
612
613 assertEquals("expected correct monitor count", 2, defaultScope.withMonitors().size());
614 }
615
616
617
618 @Test
619 public void shouldAddComponentPackage()
620 {
621 final String componentPackage = "org.logicmachine.rebl.unitTest.domain.actions";
622
623 defaultScope.withComponentPackageName(componentPackage);
624
625 assertEquals("expected correct component package", true, componentPackage.equals(defaultScope.withComponentPackageNames().get(0).key()));
626 }
627
628 @Test
629 public void shouldAddListOfComponentPackages()
630 {
631 final String componentPackage1 = "org.logicmachine.rebl.unitTest.domain.actions.first";
632 final String componentPackage2 = "org.logicmachine.rebl.unitTest.domain.actions.second";
633
634 defaultScope.withComponentPackageNames(componentPackage1, componentPackage2);
635
636 assertEquals("expected correct component package", true, componentPackage1.equals(defaultScope.withComponentPackageNames().get(0).key()));
637 assertEquals("expected correct component package", true, componentPackage2.equals(defaultScope.withComponentPackageNames().get(1).key()));
638 }
639
640 @Test
641 public void shouldAddListOfComponentPackagesAsColonSeparatedList()
642 {
643 final String componentPackage1 = "org.logicmachine.rebl.unitTest.domain.actions.first";
644 final String componentPackage2 = "org.logicmachine.rebl.unitTest.domain.actions.second";
645 final String componentPackages = componentPackage1 + COLON + componentPackage2;
646
647 defaultScope.withComponentPackageName(componentPackages);
648
649 assertEquals("expected correct component package", true, componentPackage1.equals(defaultScope.withComponentPackageNames().get(0).key()));
650 assertEquals("expected correct component package", true, componentPackage2.equals(defaultScope.withComponentPackageNames().get(1).key()));
651 }
652
653 @Test
654 public void shouldDirectlyInvokeCallable()
655 {
656 defaultScope.withComponentPackageName("org.logicmachine.rebl.unitTest.domain.actions")
657 .withCallable(new Callable("MyCallableFunctions::methodWithArg").withArguments(new Object()));
658
659 assertEquals("expected correct method to be invoked", true, MyCallableFunctions.methodWithArgCalled());
660 }
661
662
663
664 @Test
665 @SuppressWarnings("unchecked")
666 public void shouldAddAndFindActor()
667 {
668 final Actor actor = buildActorWithEntities();
669 final T newScope = (T)Scope.newInstance(key).withActor(actor);
670
671 actor.withKey("myActor");
672
673 assertEquals("expected correct active actor", actor, newScope.findEntityWithinScope(MyActor.class, "myActor"));
674 }
675
676 @Test
677 @SuppressWarnings("unchecked")
678 public void shouldSetActor()
679 {
680 final ActiveEntity activeEntity1 = new ActiveEntity("foo");
681 final ActiveEntity activeEntity2 = new ActiveEntity("bar");
682
683 final Actor actor = buildActorWithEntities(activeEntity1, activeEntity2);
684 final T newScope = (T)Scope.newInstance(key).withActor(actor);
685
686 assertEquals("expected correct active actor", actor, newScope.withActiveActor());
687 assertEquals("expected correct active entity", activeEntity1, newScope.withActiveEntity("foo"));
688 assertEquals("expected correct active entity", activeEntity2, newScope.withActiveEntity("bar"));
689 }
690
691 @Test
692 @SuppressWarnings("unchecked")
693 public void shouldAddAndFindActorWithActiveEntity()
694 {
695 final T newScope = (T)Scope.newInstance(key);
696 final ActiveEntity activeEntity1 = new ActiveEntity("foo").withScope(newScope);
697 final ActiveEntity activeEntity2 = new ActiveEntity("bar").withScope(newScope);
698 final Actor actor = buildActorWithEntities(activeEntity1, activeEntity2);
699
700 newScope.withActor(actor);
701
702 assertEquals("expected correct active entity", activeEntity1, actor.withActiveEntity("foo"));
703
704 assertEquals("expected correct active entity", activeEntity1, newScope.withActiveEntity(actor));
705 }
706
707 @Test
708 @SuppressWarnings("unchecked")
709 public void shouldAddAndFindActorWithSpecifiedActiveEntity()
710 {
711 final ActiveEntity activeEntity1 = new ActiveEntity("foo");
712 final ActiveEntity activeEntity2 = new ActiveEntity("bar");
713
714 final Actor actor = buildActorWithEntities(activeEntity1, activeEntity2);
715 final T newScope = (T)Scope.newInstance(key).withActor(actor);
716
717 assertEquals("expected correct active entity", activeEntity2, newScope.withActiveEntity(actor, "bar"));
718 }
719
720 @Test
721 @SuppressWarnings("unchecked")
722 public void shouldSetActiveEntity()
723 {
724 final ActiveEntity activeEntity = new ActiveEntity(ACTIVE_ENTITY_KEY_1);
725 final T newScope = (T)Scope.newInstance(key, activeEntity);
726
727 assertEquals("expected correct entity", activeEntity, newScope.withActiveEntity());
728 assertEquals("expected correct entity", activeEntity, newScope.getActiveEntity());
729 }
730
731 @Test
732 @SuppressWarnings("unchecked")
733 public void shouldGetActiveEntityViaActor()
734 {
735 final ActiveEntity activeEntity = new ActiveEntity(ACTIVE_ENTITY_KEY_1);
736 final Actor actor = new MyActor(activeEntity);
737 final T newScope = (T)Scope.newInstance(key);
738
739 assertEquals("expected correct entity", activeEntity, newScope.withActiveEntity(actor));
740 assertEquals("expected correct entity", activeEntity, newScope.withActiveEntity());
741 assertEquals("expected correct entity", activeEntity, newScope.getActiveEntity());
742 }
743
744 @Test
745 @SuppressWarnings("unchecked")
746 public void shouldGetSpecificActiveEntityViaActor()
747 {
748 final ActiveEntity activeEntity1 = new ActiveEntity("foo");
749 final ActiveEntity activeEntity2 = new ActiveEntity("bar");
750 final Actor actor = new MyActor(activeEntity1, activeEntity2);
751 final T newScope = (T)Scope.newInstance(key);
752
753 assertEquals("expected correct entity", activeEntity1, newScope.withActiveEntity(actor, "foo"));
754 assertEquals("expected correct entity", activeEntity2, newScope.withActiveEntity(actor, "bar"));
755 }
756
757 @Test
758 public void shouldReturnEmptyActiveEntityForNullActor()
759 {
760 assertEquals("expected empty entity", true, Scope.newInstance(key).withActiveEntity((Actor)null).isEmpty());
761 }
762
763 @Test
764 public void shouldReturnEmptyActiveEntityForEmptyActor()
765 {
766 assertEquals("expected empty entity", true, Scope.newInstance(key).withActiveEntity(Actor.emptyActor()).isEmpty());
767 }
768
769
770
771 @Test
772 @SuppressWarnings("unchecked")
773 public void shouldAddEntitiesToScope()
774 {
775 final ActiveEntity activeEntity1 = new ActiveEntity(ACTIVE_ENTITY_KEY_1);
776 final ActiveEntity activeEntity2 = new ActiveEntity(ACTIVE_ENTITY_KEY_2);
777 final Entities entities = new Entities().add(activeEntity1).add(activeEntity2);
778 final T newScope = (T)Scope.newInstance(key);
779
780 assertEquals("expected correct entities", entities, newScope.addToScope(ActiveEntity.class, entities));
781 }
782
783 @Test
784 @SuppressWarnings("unchecked")
785 public void shouldFindEntityWithinScope()
786 {
787 final ActiveEntity activeEntity1 = new ActiveEntity(ACTIVE_ENTITY_KEY_1);
788 final ActiveEntity activeEntity2 = new ActiveEntity(ACTIVE_ENTITY_KEY_2);
789 final Entities entities = new Entities().add(activeEntity1).add(activeEntity2);
790 final T newScope = (T)Scope.newInstance(key);
791
792 newScope.addToScope(ActiveEntity.class, entities);
793
794 assertEquals("expected correct entity", activeEntity1, newScope.findEntityWithinScope(ActiveEntity.class, ACTIVE_ENTITY_KEY_1));
795 assertEquals("expected correct entity", activeEntity2, newScope.findEntityWithinScope(ActiveEntity.class, ACTIVE_ENTITY_KEY_2));
796 assertEquals("expected no match", true, newScope.findEntityWithinScope(ActiveEntity.class, "NoMatch").isEmpty());
797 }
798
799
800
801 @Test
802 @SuppressWarnings("unchecked")
803 public void shouldWaitForAllParallelActiveEntityInstances()
804 {
805 final ActiveEntity activeEntity1 = new ActiveEntity(ACTIVE_ENTITY_KEY_1).parallel();
806 final ActiveEntity activeEntity2 = new ActiveEntity(ACTIVE_ENTITY_KEY_2).parallel();
807 final ActiveEntity activeEntity3 = new ActiveEntity(ACTIVE_ENTITY_KEY_3).sequential();
808 final T newScope = (T)Scope.newInstance(key);
809
810 newScope.withActiveEntity(activeEntity1);
811 newScope.withActiveEntity(activeEntity2);
812 newScope.withActiveEntity(activeEntity3);
813
814 activeEntity1.apply();
815 activeEntity2.apply();
816 activeEntity3.apply();
817
818 Common.waitForAllParallelActiveEntities();
819
820 assertEquals("expected no parallel instances", false, Common.hasPendingParallelActiveEntities(newScope));
821 }
822
823 @Test
824 @SuppressWarnings("unchecked")
825 public void shouldWaitForParallelActiveEntityInstancesForScope()
826 {
827 final ActiveEntity activeEntity1 = new ActiveEntity(ACTIVE_ENTITY_KEY_1).parallel();
828 final ActiveEntity activeEntity2 = new ActiveEntity(ACTIVE_ENTITY_KEY_2).parallel();
829 final ActiveEntity activeEntity3 = new ActiveEntity(ACTIVE_ENTITY_KEY_3).sequential();
830 final T newScope = (T)Scope.newInstance(key);
831
832 newScope.withActiveEntity(activeEntity1);
833 newScope.withActiveEntity(activeEntity2);
834 newScope.withActiveEntity(activeEntity3);
835
836 activeEntity1.apply();
837 activeEntity2.apply();
838 activeEntity3.apply();
839
840 Common.waitForParallelActiveEntitiesForScope(newScope);
841
842 assertEquals("expected no parallel instances", false, Common.hasPendingParallelActiveEntities(newScope));
843 }
844
845
846
847 @Test
848 public void shouldLogMessage()
849 {
850 assertLogMessageEquals("foo bar", false, false);
851 }
852
853 @Test
854 public void shouldLogMessageWithLeadingNewline()
855 {
856 assertLogMessageEquals("foo bar", true, false);
857 }
858
859 @Test
860 public void shouldLogMessageWithTrailingNewline()
861 {
862 assertLogMessageEquals("foo bar", false, true );
863 }
864
865
866
867 @Test
868 @SuppressWarnings({ "unchecked", "resource" })
869 public void shouldClearDataInScope()
870 {
871 final ActiveEntity activeEntity1 = new ActiveEntity(ACTIVE_ENTITY_KEY_1);
872 final ActiveEntity activeEntity2 = new ActiveEntity(ACTIVE_ENTITY_KEY_2);
873 final Entities entities = new Entities().add(activeEntity1).add(activeEntity2);
874 final MyCloseableResource resource = new MyCloseableResource();
875 final T newScope = (T)Scope.newInstance(key);
876
877 final EnvironmentObjects environmentObjects = new EnvironmentObjects()
878 .add(new EnvironmentObject("foo", "bar" ))
879 .add(new EnvironmentObject("hello", "world"));
880
881 newScope.withResource(resource);
882 newScope.withExceptionHandler(new MyExceptionHandler());
883 newScope.withEnvironmentObjects(environmentObjects);
884 newScope.addToScope(ActiveEntity.class, entities);
885 newScope.withStateMachine(new StateMachine<States>("foo"));
886 newScope.withComponentPackageNames("foo", "bar");
887 newScope.withActiveEntity(activeEntity1);
888
889 assertEquals("expected resource", 1, newScope.getResources().size());
890 assertEquals("expected exception handler", 1, newScope.withExceptionHandlers().size());
891 assertEquals("expected environmentObjects", 2, newScope.getEnvironmentObjects().size());
892 assertEquals("expected resource", 1, newScope.getResources().size());
893 assertEquals("expected correct stateMachine", true, null != newScope.withStateMachine("foo"));
894 assertEquals("expected correct entity", activeEntity1, newScope.findEntityWithinScope(ActiveEntity.class, ACTIVE_ENTITY_KEY_1));
895 assertEquals("expected correct entity", activeEntity2, newScope.findEntityWithinScope(ActiveEntity.class, ACTIVE_ENTITY_KEY_2));
896 assertEquals("expected componentPackageNames", 2, newScope.withComponentPackageNames().size());
897 assertEquals("expected activeEntity", activeEntity1, newScope.withActiveEntity());
898
899 assertEquals("expected parent of current scope", true, defaultScope.equals(newScope.clear()));
900
901 assertEquals("should close resource", false, resource.isOpen());
902 assertEquals("expected no resource in scope", 0, newScope.getResources().size());
903 assertEquals("expected no exception handler", 0, newScope.withExceptionHandlers().size());
904 assertEquals("expected no environmentObjects", 0, newScope.getEnvironmentObjects().size());
905 assertEquals("expected no match", true, newScope.findEntityWithinScope(ActiveEntity.class, ACTIVE_ENTITY_KEY_1).isEmpty());
906 assertEquals("expected no match", true, newScope.findEntityWithinScope(ActiveEntity.class, ACTIVE_ENTITY_KEY_2).isEmpty());
907 assertEquals("expected no componentPackageNames", 0, newScope.withComponentPackageNames().size());
908 assertEquals("expected no match", true, newScope.withActiveEntity().isEmpty());
909
910 try
911 {
912 newScope.withStateMachine("foo");
913
914 fail("expected no such state machine to be found");
915 }
916 catch(final IllegalArgumentException iae)
917 {
918
919
920
921
922
923 return;
924 }
925 finally
926 {
927 resource.close();
928 }
929
930 fail("expected IllegalArgumentException");
931 }
932
933
934
935 @Test
936 public void shouldHandleSystemExceptionWithinScope()
937 {
938
939 final Scope newScope = Scope.newInstance(key).parallel();
940
941 final MyExceptionHandler exceptionHandler = new MyExceptionHandler().withScope(newScope);
942
943 newScope.withExceptionHandler(exceptionHandler).handleException(new Exception());
944
945 assertEquals("expected system exception to be handled", true, exceptionHandler.isHandled());
946 }
947
948 @Test
949 public void shouldHandleBusinessExceptionWithinScope()
950 {
951
952 final Scope newScope = Scope.newInstance(key).parallel();
953
954 final BusinessMessage exception = new BusinessMessage("exception");
955
956 newScope.withExceptionHandler(new MyExceptionHandler().withScope(newScope)).handleException(exception);
957
958 assertEquals("expected business exception to be handled", true, exception.isHandled());
959 }
960
961 @Test
962 public void shouldNotHandleSystemException()
963 {
964
965 final Scope newScope = Scope.newInstance(key).parallel();
966
967 final MyExceptionHandler exceptionHandler = new MyExceptionHandler(false).withScope(newScope);
968
969 newScope.withExceptionHandler(exceptionHandler).handleException(new Exception());
970
971 assertEquals("expected system exception to be unhandled", false, exceptionHandler.isHandled());
972 }
973
974 @Test
975 public void shouldNotHandleBusinessException()
976 {
977
978 final Scope newScope = Scope.newInstance(key).parallel();
979
980 final BusinessMessage exception = new BusinessMessage("exception");
981
982 newScope.withExceptionHandler(new MyExceptionHandler(false).withScope(newScope)).handleException(exception);
983
984 assertEquals("expected business exception to be unhandled", false, exception.isHandled());
985 }
986
987 @Test
988 public void shouldInvokeMonitors()
989 {
990 final ActiveEntity activeEntity = new ActiveEntity(ACTIVE_ENTITY_KEY_1);
991
992 Scope.newInstance(key).withMonitors(new ThroughputMonitor(),
993 new DurationMonitor());
994
995 Common.withDefaultScope().addToScope(ActiveEntity.class, new Entities().add(activeEntity));
996
997 activeEntity.withScope(defaultScope).apply();
998
999 for (final Monitor<?> monitor : Common.withDefaultScope().withMonitors())
1000 {
1001 if (monitor instanceof ThroughputMonitor)
1002 {
1003 assertEquals("expected monitor invocation", true, ((Long)monitor.monitorGet()).longValue() > 0);
1004 }
1005 else if (monitor instanceof DurationMonitor)
1006 {
1007 assertEquals("expected quick monitor invocation", true, ((Long)monitor.monitorGet()).longValue() >= 0);
1008 }
1009 }
1010 }
1011
1012 @Test
1013 public void shouldLogMonitorResultsOnScopeClose() throws UnsupportedEncodingException, IOException
1014 {
1015 try (ByteArrayOutputStream outputStream = new ByteArrayOutputStream())
1016 {
1017 Common.withOutputStream(new PrintStream(outputStream, true, ExternalStrings.DEFAULT_CHARACTER_ENCODING));
1018
1019 final Monitor<?> monitor1 = new DurationMonitor() .withKey("myDurationMonitor" );
1020 final Monitor<?> monitor2 = new ThroughputMonitor().withKey("myThroughputMonitor");
1021
1022 final ActiveEntity activeEntity = new ActiveEntity(ACTIVE_ENTITY_KEY_1);
1023
1024 final Scope newScope = Scope.newInstance(key).withMonitors(monitor1,
1025 monitor2);
1026
1027 newScope.addToScope(ActiveEntity.class, new Entities().add(activeEntity));
1028
1029 activeEntity.withScope(defaultScope).apply();
1030
1031
1032 newScope.closeScope();
1033
1034 final String output = outputStream.toString(DEFAULT_CHARSET);
1035
1036 assertStringContains(output, "Monitor: myDurationMonitor = " );
1037 assertStringContains(output, "Monitor: myThroughputMonitor = ");
1038 }
1039 }
1040
1041
1042
1043 @Test
1044 public void shouldGetCurrentlyActiveResource()
1045 {
1046 final Scope newScope = Common.withDefaultScope();
1047 final Resource resource = new Resource("myResource");
1048
1049 newScope.withActiveResource(resource);
1050
1051 assertEquals("expected correct active resource", resource, newScope.withActiveResource());
1052 }
1053
1054 @Test
1055 public void shouldGetCurrentlyActiveActor()
1056 {
1057 final Scope newScope = Common.withDefaultScope();
1058 final Actor actor = new Actor()
1059 {
1060
1061 };
1062
1063 actor.withKey("myActor");
1064
1065 newScope.withActor(actor);
1066
1067 assertEquals("expected correct active actor", actor, newScope.withActiveActor());
1068 }
1069
1070 @Test
1071 public void shouldCreateScopeWithActorAndActiveEntity()
1072 {
1073 final ActiveEntity activeEntity = new MyActiveEntity().withKey("myActiveEntity");
1074 final MyActor actor = new MyActor(activeEntity).withKey("myActor");
1075 final Scope newScope = Scope.newInstance(key);
1076
1077 newScope.withActor(actor);
1078
1079 final ActiveEntity currentActiveEntity = newScope.withActiveEntityForActor(MyActor.class, "myActor", "myActiveEntity");
1080
1081 assertEquals("expected correct active actor", actor, newScope.withActiveActor());
1082 assertEquals("expected correct active entity", activeEntity, currentActiveEntity);
1083 }
1084
1085 @Test
1086 public void shouldCreateScopeWithActiveEntity()
1087 {
1088 final ActiveEntity activeEntity = new MyActiveEntity();
1089 final Scope newScope = Scope.newInstance(key, activeEntity);
1090
1091 assertEquals("expected correct active entity", activeEntity, newScope.withActiveEntity());
1092 }
1093
1094 @Test
1095 public void shouldGetCurrentlyActiveEntity()
1096 {
1097 final Scope newScope = Common.withDefaultScope();
1098 final ActiveEntity activeEntity = new MyActiveEntity();
1099
1100 newScope.withActiveEntity(activeEntity);
1101
1102 assertEquals("expected correct active entity", activeEntity, newScope.withActiveEntity());
1103 }
1104
1105
1106
1107 @Test
1108 public void shouldHandleExceptionWithinCallable() throws Exception
1109 {
1110
1111 Scope.process(new UnsuccessfulCallable(), scope);
1112 }
1113
1114
1115
1116 @Test
1117 public void shouldHandleException()
1118 {
1119 assertEquals("should handle exception", true, Common.withDefaultScope().handleException(new Exception(ERROR_MESSAGE)));
1120 }
1121
1122 @Test
1123 public void shouldHandleBusinessException()
1124 {
1125 assertEquals("should handle exception", true, Common.withDefaultScope().handleException(new BusinessMessage(ERROR_MESSAGE)));
1126 }
1127
1128 @Test
1129 public void shouldNotHandleNullException()
1130 {
1131 assertEquals("should not handle null exception", false, Common.withDefaultScope().handleException(null));
1132 }
1133
1134 @Test
1135 public void shouldLogException() throws IOException
1136 {
1137 try (ByteArrayOutputStream errorStream = new ByteArrayOutputStream();
1138 PrintStream printStream = buildErrorStream(errorStream))
1139 {
1140 Common.withErrorStream(printStream);
1141
1142 assertEquals("should handle exception", true, Common.withDefaultScope().handleException(new Exception(ERROR_MESSAGE)));
1143
1144 assertEquals("expected correct error log",
1145 DEFAULT_EXCEPTION_HANDLER_MESSAGE_PREFIX + ARROW + ERROR_MESSAGE + NEWLINE,
1146 errorStream.toString(ExternalStrings.DEFAULT_CHARACTER_ENCODING));
1147
1148 errorStream.close();
1149 }
1150 }
1151
1152
1153
1154 @SuppressWarnings({ "unchecked", "resource" })
1155 protected Scope buildScope()
1156 {
1157 final ActiveEntity activeEntity1 = new ActiveEntity(ACTIVE_ENTITY_KEY_1);
1158 final ActiveEntity activeEntity2 = new ActiveEntity(ACTIVE_ENTITY_KEY_2);
1159 final Entities entities = new Entities().add(activeEntity1).add(activeEntity2);
1160 final T newScope = (T)Scope.newInstance(key);
1161
1162 final MyCloseableResource myCloseableResource = new MyCloseableResource().withKey("myCloseableResource");
1163
1164 final MyExceptionHandler myExceptionHandler = new MyExceptionHandler().withKey("myExceptionHandler");
1165
1166 final EnvironmentObjects environmentObjects = new EnvironmentObjects()
1167 .add(new EnvironmentObject("foo", "bar" ))
1168 .add(new EnvironmentObject("hello", "world"));
1169
1170 newScope.withResource (myCloseableResource );
1171 newScope.withExceptionHandler (myExceptionHandler );
1172 newScope.withEnvironmentObjects (environmentObjects );
1173 newScope.addToScope (ActiveEntity.class, entities );
1174 newScope.withStateMachine (new StateMachine<States>("foo"));
1175 newScope.withComponentPackageNames("foo", "bar" );
1176 newScope.withActiveEntity (activeEntity1 );
1177
1178 return newScope;
1179 }
1180
1181
1182
1183 protected static ExceptionHandlers buildExceptionHandlers()
1184 {
1185 return new ExceptionHandlers().add(new ExceptionHandler())
1186 .add(new ExceptionHandler());
1187 }
1188
1189 protected static Resources buildResources()
1190 {
1191 return new Resources().add(new Resource("resource1"))
1192 .add(new Resource("resource2"));
1193 }
1194
1195 protected static StateMachines buildStateMachines()
1196 {
1197 return new StateMachines().add(new StateMachine<States>("sm1"))
1198 .add(new StateMachine<States>("sm2"));
1199 }
1200
1201 protected static Entities buildEntities()
1202 {
1203 final Entity entity1 = new MyEntity().withKey("foo");
1204 final Entity entity2 = new MyEntity().withKey("bar");
1205
1206 return new Entities().add(entity1)
1207 .add(entity2);
1208 }
1209
1210 protected static Actor buildActorWithEntities()
1211 {
1212 final ActiveEntity activeEntity1 = new ActiveEntity("foo");
1213 final ActiveEntity activeEntity2 = new ActiveEntity("bar");
1214
1215 return buildActorWithEntities(activeEntity1, activeEntity2);
1216 }
1217
1218 protected static Actor buildActorWithEntities(final ActiveEntity activeEntity1, final ActiveEntity activeEntity2)
1219 {
1220 return new MyActor(activeEntity1, activeEntity2);
1221 }
1222
1223 protected static void assertSize(final Collection<?> collection, final int expectedSize)
1224 {
1225 assertEquals(0 == expectedSize ? "should be empty" : "should not be empty",
1226 expectedSize,
1227 collection.size());
1228 }
1229
1230 protected static void assertStringContains(final String string, final String value)
1231 {
1232 assertEquals("expected string to contain correct value", true, string.contains(value));
1233 }
1234
1235 protected static PrintStream buildErrorStream(final ByteArrayOutputStream errorStream)
1236 {
1237 try
1238 {
1239 return new PrintStream(errorStream, true, ExternalStrings.DEFAULT_CHARACTER_ENCODING);
1240 }
1241 catch (final UnsupportedEncodingException uee)
1242 {
1243 fail(uee.getMessage());
1244
1245 return null;
1246 }
1247 }
1248
1249 protected static void assertLogMessageEquals(final String message, final boolean wantLeadingNewline, final boolean wantTrailingNewline)
1250 {
1251 try (ByteArrayOutputStream outputStream = new ByteArrayOutputStream())
1252 {
1253 String expected = message + NEWLINE;
1254
1255 Common.withOutputStream(new PrintStream(outputStream, true, ExternalStrings.DEFAULT_CHARACTER_ENCODING));
1256
1257 if (!wantLeadingNewline && !wantTrailingNewline)
1258 {
1259 Common.log(message);
1260 }
1261 else if (wantLeadingNewline)
1262 {
1263 Common.withDefaultScope().logWithLeadingNewline(message);
1264
1265 expected = NEWLINE + expected;
1266 }
1267 else if (wantTrailingNewline)
1268 {
1269 Common.withDefaultScope().logWithTrailingNewline(message);
1270
1271 expected += NEWLINE;
1272 }
1273
1274 assertEquals("expected correct log message", expected, outputStream.toString(DEFAULT_CHARSET));
1275 }
1276 catch (final UnsupportedEncodingException uee)
1277 {
1278 fail(uee.getMessage());
1279 }
1280 catch (final IOException ioe)
1281 {
1282 fail(ioe.getMessage());
1283 }
1284 }
1285
1286
1287 protected static class MyActor extends Actor
1288 {
1289 private final Many<ActiveEntity> activeEntities = new Many<>();
1290
1291
1292 public MyActor(final ActiveEntity activeEntity)
1293 {
1294 this.activeEntities.add(activeEntity);
1295 }
1296
1297 public MyActor(final ActiveEntity... activeEntities)
1298 {
1299 this.activeEntities.addAll(activeEntities);
1300 }
1301
1302 @Override
1303 public MyActor withKey(final Object key)
1304 {
1305 super.withKey(key);
1306
1307 return this;
1308 }
1309
1310 @Override
1311 public ActiveEntity getActiveEntity()
1312 {
1313 return activeEntities.iterator().next();
1314 }
1315
1316 @Override
1317 public Many<ActiveEntity> getActiveEntities()
1318 {
1319 return activeEntities;
1320 }
1321 }
1322
1323 protected static class MyEntity extends Entity
1324 {
1325 public MyEntity()
1326 {
1327
1328 }
1329 }
1330
1331 protected static class MyExceptionHandler extends ExceptionHandler
1332 {
1333 private Scope scope = null;
1334 private boolean shouldHandle = true;
1335 private boolean isHandled = false;
1336
1337
1338 public MyExceptionHandler()
1339 {
1340 this(true);
1341 }
1342
1343 public MyExceptionHandler(final boolean shouldHandle)
1344 {
1345 this.shouldHandle = shouldHandle;
1346 }
1347
1348 @Override
1349 public MyExceptionHandler withKey(final Object key)
1350 {
1351 super.withKey(key);
1352
1353 return this;
1354 }
1355
1356 public MyExceptionHandler withScope(final Scope scope)
1357 {
1358 this.scope = scope;
1359
1360 return this;
1361 }
1362
1363 @Override
1364 public boolean handleException(final Exception exception)
1365 {
1366 assertEquals("expected correct active exception handler", this, scope.withActiveExceptionHandler());
1367
1368 isHandled = shouldHandle;
1369
1370 return shouldHandle;
1371 }
1372
1373 @Override
1374 public boolean handleException(final BusinessMessage businessMessage)
1375 {
1376 assertEquals("expected correct active exception handler", this, scope.withActiveExceptionHandler());
1377
1378 if (shouldHandle)
1379 {
1380 setHandled(businessMessage);
1381 }
1382
1383 return businessMessage.isHandled();
1384 }
1385
1386 public boolean isHandled()
1387 {
1388 return isHandled;
1389 }
1390 }
1391
1392 protected static class MyCloseableResource extends CloseableResource
1393 {
1394 private boolean isOpen = true;
1395
1396
1397 @Override
1398 public void closeResource() throws IOException
1399 {
1400 isOpen = false;
1401 }
1402
1403 @Override
1404 public MyCloseableResource withKey(final Object key)
1405 {
1406 super.withKey(key);
1407
1408 return this;
1409 }
1410
1411 public boolean isOpen()
1412 {
1413 return isOpen;
1414 }
1415 }
1416 }