1 package org.xvsm.internal;
2
3 import java.net.URI;
4 import java.util.ArrayList;
5 import java.util.List;
6 import java.util.Properties;
7
8 import org.apache.log4j.Logger;
9 import org.xvsm.core.ContainerRef;
10 import org.xvsm.core.Entry;
11 import org.xvsm.core.aspect.AspectContext;
12 import org.xvsm.core.aspect.IAspect;
13 import org.xvsm.core.aspect.IPoint;
14 import org.xvsm.core.aspect.LocalIPoint;
15 import org.xvsm.interfaces.ICapi;
16 import org.xvsm.interfaces.ICoordinator;
17 import org.xvsm.interfaces.container.IContainerEngine;
18 import org.xvsm.interfaces.container.ITransactionLayer;
19 import org.xvsm.internal.exceptions.AspectNotOkException;
20 import org.xvsm.internal.exceptions.AspectRescheduleException;
21 import org.xvsm.internal.exceptions.AspectSkipException;
22 import org.xvsm.internal.exceptions.ContainerFullException;
23 import org.xvsm.internal.exceptions.CountNotMetException;
24 import org.xvsm.internal.exceptions.FatalException;
25 import org.xvsm.internal.exceptions.InvalidContainerException;
26 import org.xvsm.internal.exceptions.InvalidTransactionException;
27 import org.xvsm.internal.exceptions.NoSuchCoordinationTypeException;
28 import org.xvsm.internal.exceptions.TransactionLockException;
29 import org.xvsm.internal.exceptions.XCoreException;
30 import org.xvsm.internal.tasks.TransactionTask;
31 import org.xvsm.internal.tasks.TransactionTaskType;
32 import org.xvsm.selectors.Selector;
33 import org.xvsm.transactions.Transaction;
34 import org.xvsm.transactions.TransactionManager;
35
36 /***
37 * Static class used to manage {@link Transaction}s.
38 *
39 * @author Christian Schreiber, Michael Proestler
40 *
41 */
42 public class TransactionLayer implements ITransactionLayer {
43
44 /***
45 * The logger for this class.
46 */
47 private static Logger logger = Logger.getLogger(ITransactionLayer.class);
48
49 /***
50 * The container for this transaction manager.
51 */
52 private IContainerEngine c;
53
54 /***
55 * The aspect manager for this container.
56 */
57 private AspectManager aspectManager = new AspectManager();
58
59 /***
60 * Default constructor.
61 */
62 public TransactionLayer() {
63 c = new ContainerEngine();
64 }
65
66 /***
67 * Default constructor.
68 *
69 * @param size
70 * the size of the container.
71 */
72 public TransactionLayer(int size) {
73 c = new ContainerEngine(size);
74 }
75
76 /***
77 * Commits a sub transaction and updates the locks (sets the lock to
78 * tx.getFather()). The commit method of the container is called too.
79 *
80 * @param tx
81 * the transaction to commit.
82 * @throws TransactionLockException
83 * thrown if a lock cannot be aquired.
84 */
85 private void commitSubtransaction(Transaction tx)
86 throws TransactionLockException {
87 if (logger.isDebugEnabled()) {
88 logger.debug("commitSubtransaction(" + tx + ") -- "
89 + this.getCref());
90 }
91
92 Transaction father = tx.getFather();
93
94
95
96
97
98 c.commitSubTransaction(tx);
99
100
101 for (ContainerRef cref : tx.getModifiedContainers()) {
102 father.addContainerRef(cref);
103 }
104 for (ICoordinator coord : tx.getModifiedCoordinators()) {
105 father.addCoordinator(coord);
106 }
107 TransactionManager.getInstance().removeTransaction(tx);
108
109 if (logger.isDebugEnabled()) {
110 logger.debug("commitSubtransaction() transaction commited -- "
111 + this.getCref());
112 }
113 }
114
115 /***
116 * Rolls back a sub transaction.
117 *
118 * @param tx
119 * The transaction to roll back.
120 * @throws TransactionLockException
121 * thrown if a lock cannot be aquired.
122 */
123 private void rollbackSubtransaction(Transaction tx)
124 throws TransactionLockException {
125 if (logger.isDebugEnabled()) {
126 logger.debug("rollbackSubtransaction(" + tx + ") -- "
127 + this.getCref());
128 }
129
130
131
132
133
134
135 c.rollback(tx);
136 TransactionManager.getInstance().removeTransaction(tx);
137 if (logger.isDebugEnabled()) {
138 logger.debug("rollbackSubtransaction() transaction rolled back -- "
139 + this.getCref());
140 }
141 }
142
143 /***
144 * {@inheritDoc}.
145 */
146 public void commit(Transaction tx) throws TransactionLockException,
147 InvalidTransactionException, AspectRescheduleException,
148 AspectNotOkException {
149 if (logger.isDebugEnabled()) {
150 logger.debug("commit(" + tx + ") -- " + this.getCref());
151 }
152
153 if (tx == null) {
154 throw new IllegalArgumentException("Can not commit transaction "
155 + tx);
156 }
157 if (tx.getFather() != null) {
158 throw new IllegalArgumentException(
159 "Can not commit a child transaction.");
160 }
161 tx = this.initTransaction(tx);
162
163
164 this.c.commit(tx);
165
166
167 tx.removeContainerRef(this.getCref());
168
169
170 if (logger.isDebugEnabled()) {
171 logger.debug("commit() transaction commited -- " + this.getCref());
172 }
173 }
174
175 /***
176 * {@inheritDoc}.
177 */
178 public void rollback(Transaction tx) throws InvalidTransactionException,
179 TransactionLockException, AspectRescheduleException,
180 AspectNotOkException {
181 if (logger.isDebugEnabled()) {
182 logger.debug("rollback(" + tx + ") -- " + this.getCref());
183 }
184 if (tx == null) {
185 throw new IllegalArgumentException("Can not rollback transaction "
186 + tx);
187 }
188 if (tx.getFather() != null) {
189 throw new IllegalArgumentException(
190 "Can not commit a child transaction.");
191 }
192 tx = this.initTransaction(tx);
193
194
195 c.rollback(tx);
196
197
198 tx.removeContainerRef(this.getCref());
199
200 if (logger.isDebugEnabled()) {
201 logger.debug("rollback() transaction rolled back -- "
202 + this.getCref());
203 }
204 }
205
206 /***
207 * {@inheritDoc}.
208 */
209 public ICoordinator getCoordTypefromSelector(Class<? extends Selector> s)
210 throws NoSuchCoordinationTypeException {
211 return c.getCoordTypefromSelector(s);
212 }
213
214 /***
215 * {@inheritDoc}.
216 */
217 public int getSize() {
218 return c.getSize();
219 }
220
221 /***
222 * {@inheritDoc}.
223 */
224 public List<Entry> read(Transaction tx, List<Selector> selectors,
225 int retrycount, Properties aspectContext)
226 throws NoSuchCoordinationTypeException, CountNotMetException,
227 InvalidTransactionException, TransactionLockException,
228 AspectRescheduleException, AspectNotOkException {
229
230 if (logger.isDebugEnabled()) {
231 logger.debug("read(" + tx + ", " + selectors + "," + retrycount
232 + ", " + aspectContext + ") -- " + this.getCref());
233 }
234 Transaction stx = null;
235 try {
236
237 tx = this.initTransaction(tx);
238
239 boolean skip = false;
240 AspectContext acontext = new AspectContext(LocalIPoint.PreRead,
241 this.getCref(), tx, selectors, null, null, retrycount,
242 aspectContext);
243 try {
244 this.executeAspect(acontext);
245 } catch (AspectRescheduleException e) {
246 this.rollbackSubtransaction(acontext.getTx());
247 throw e;
248 } catch (AspectNotOkException e) {
249 try {
250 TransactionManager.getInstance().rollbackTransaction(
251 acontext.getTx());
252 } catch (XCoreException e1) {
253 throw new FatalException(e1);
254 }
255 throw e;
256 } catch (AspectSkipException e) {
257 skip = true;
258 }
259
260 tx = acontext.getTx();
261
262 stx = TransactionManager.getInstance().createSubTransaction(tx);
263
264 selectors = acontext.getSelectors();
265 retrycount = acontext.getRetrycount();
266
267 List<Entry> result = new ArrayList<Entry>();
268 if (!skip) {
269 result = c.read(stx, selectors);
270
271
272 for (Entry e : result) {
273 for (Selector s : e.getSelectors()) {
274 tx.addCoordinator(c.getCoordTypefromSelector(s
275 .getClass()));
276 }
277 }
278
279 }
280 try {
281 acontext.setLocalIPoint(LocalIPoint.PostRead);
282 acontext.setEntries(result);
283 this.executeAspect(acontext);
284 } catch (AspectRescheduleException e) {
285 this.rollbackSubtransaction(stx);
286 throw e;
287 } catch (AspectNotOkException e) {
288 try {
289 TransactionManager.getInstance().rollbackTransaction(
290 acontext.getTx());
291 } catch (XCoreException e1) {
292 throw new FatalException(e1);
293 }
294 throw e;
295 } catch (AspectSkipException e) {
296 try {
297 TransactionManager.getInstance().rollbackTransaction(
298 acontext.getTx());
299 } catch (XCoreException e1) {
300 throw new FatalException(e1);
301 }
302 throw new FatalException(
303 "SKIP not allowed as answer of a post aspect.");
304 }
305 this.commitSubtransaction(stx);
306 tx = acontext.getTx();
307
308 if (tx.isImplicit()) {
309 try {
310 TransactionManager.getInstance().commitTransaction(tx);
311 } catch (XCoreException e) {
312 throw new FatalException(e);
313 }
314 }
315
316 if (logger.isDebugEnabled()) {
317 logger.debug("read() entries read: " + acontext.getEntries()
318 + " -- " + this.getCref());
319 }
320
321 return acontext.getEntries();
322 } catch (CountNotMetException e) {
323 if (logger.isDebugEnabled()) {
324 logger.debug("read() CountNotMetException was thrown " + e
325 + " -- " + this.getCref());
326 }
327 this.rollbackSubtransaction(stx);
328 throw e;
329 } catch (TransactionLockException e) {
330 if (logger.isDebugEnabled()) {
331 logger.debug("read() TransactionLockException " + e + " -- "
332 + this.getCref());
333 }
334 this.rollbackSubtransaction(stx);
335 throw e;
336 }
337 }
338
339 /***
340 * {@inheritDoc}.
341 */
342 public List<Entry> shift(List<Entry> entries, Transaction tx,
343 Properties aspectContext) throws NoSuchCoordinationTypeException,
344 InvalidTransactionException, TransactionLockException,
345 AspectRescheduleException, AspectNotOkException {
346 if (logger.isDebugEnabled()) {
347 logger.debug("shift(" + entries + ", " + tx + ", " + aspectContext
348 + ") -- " + this.getCref());
349 }
350 Transaction stx = null;
351 try {
352
353 tx = this.initTransaction(tx);
354
355 AspectContext acontext = new AspectContext(LocalIPoint.PreShift,
356 this.getCref(), tx, null, entries, null, 0, aspectContext);
357 boolean skip = false;
358 try {
359 this.executeAspect(acontext);
360 } catch (AspectRescheduleException e) {
361 this.rollbackSubtransaction(acontext.getTx());
362 throw e;
363 } catch (AspectNotOkException e) {
364 try {
365 TransactionManager.getInstance().rollbackTransaction(
366 acontext.getTx());
367 } catch (XCoreException e1) {
368 throw new FatalException(e1);
369 }
370 throw e;
371 } catch (AspectSkipException e) {
372 skip = true;
373 }
374 entries = acontext.getEntries();
375 tx = acontext.getTx();
376
377 stx = TransactionManager.getInstance().createSubTransaction(tx);
378
379 List<Entry> shifted = null;
380 if (!skip) {
381 shifted = new ArrayList<Entry>();
382 for (Entry e : entries) {
383
384 shifted.addAll(this.c.shift(e, stx));
385
386 for (Selector s : e.getSelectors()) {
387 stx.addCoordinator(c.getCoordTypefromSelector(s
388 .getClass()));
389 }
390 }
391
392
393 for (Entry en : shifted) {
394 for (Selector s : en.getSelectors()) {
395 stx.addCoordinator(c.getCoordTypefromSelector(s
396 .getClass()));
397 }
398 }
399 }
400 acontext.setDeleted(shifted);
401
402 try {
403 acontext.setLocalIPoint(LocalIPoint.PostShift);
404 this.executeAspect(acontext);
405 } catch (AspectRescheduleException e) {
406 this.rollbackSubtransaction(stx);
407 throw e;
408 } catch (AspectNotOkException e) {
409 try {
410 TransactionManager.getInstance().rollbackTransaction(
411 acontext.getTx());
412 } catch (XCoreException e1) {
413 throw new FatalException(e1);
414 }
415 throw e;
416 } catch (AspectSkipException e) {
417 try {
418 TransactionManager.getInstance().rollbackTransaction(
419 acontext.getTx());
420 } catch (XCoreException e1) {
421 throw new FatalException(e1);
422 }
423 throw new FatalException(
424 "SKIP not allowed as answer of a post aspect.");
425 }
426 this.commitSubtransaction(stx);
427 tx = acontext.getTx();
428
429 if (tx.isImplicit()) {
430 try {
431 TransactionManager.getInstance().commitTransaction(tx);
432 } catch (XCoreException e) {
433 throw new FatalException(e);
434 }
435 }
436
437 if (logger.isDebugEnabled()) {
438 logger.debug("shift() entries shifted: "
439 + acontext.getDeleted());
440 }
441 return acontext.getDeleted();
442 } catch (TransactionLockException e) {
443 if (logger.isDebugEnabled()) {
444 logger.debug("shift() TransactionLockException " + e + " -- "
445 + this.getCref());
446 }
447 this.rollbackSubtransaction(stx);
448 throw e;
449 }
450
451 }
452
453 /***
454 * {@inheritDoc}.
455 */
456 public List<Entry> take(boolean isDelete, Transaction tx,
457 List<Selector> selectors, int retrycount, Properties aspectContext)
458 throws NoSuchCoordinationTypeException, CountNotMetException,
459 InvalidTransactionException, TransactionLockException,
460 AspectRescheduleException, AspectNotOkException {
461 if (logger.isDebugEnabled()) {
462 logger.debug("take(" + isDelete + ", " + tx + ", " + selectors
463 + ", " + retrycount + ", " + aspectContext + ") -- "
464 + this.getCref());
465 }
466
467 Transaction stx = null;
468 try {
469 tx = this.initTransaction(tx);
470
471 AspectContext acontext = new AspectContext(
472 isDelete ? LocalIPoint.PreDestroy : LocalIPoint.PreTake,
473 this.getCref(), tx, selectors, null, null, retrycount,
474 aspectContext);
475 boolean skip = false;
476 try {
477 this.executeAspect(acontext);
478 } catch (AspectRescheduleException e) {
479 this.rollbackSubtransaction(acontext.getTx());
480 throw e;
481 } catch (AspectNotOkException e) {
482 try {
483 TransactionManager.getInstance().rollbackTransaction(
484 acontext.getTx());
485 } catch (XCoreException e1) {
486 throw new FatalException(e1);
487 }
488 throw e;
489 } catch (AspectSkipException e) {
490 skip = true;
491 }
492 tx = acontext.getTx();
493 stx = TransactionManager.getInstance().createSubTransaction(tx);
494 selectors = acontext.getSelectors();
495 retrycount = acontext.getRetrycount();
496
497 List<Entry> entries = null;
498 if (!skip) {
499
500 entries = c.take(stx, selectors);
501
502 for (Entry e : entries) {
503 for (Selector s : e.getSelectors()) {
504 stx.addCoordinator(c.getCoordTypefromSelector(s
505 .getClass()));
506 }
507 }
508 }
509 acontext.setDeleted(entries);
510 try {
511 acontext.setLocalIPoint(isDelete ? LocalIPoint.PostDestroy
512 : LocalIPoint.PostTake);
513 this.executeAspect(acontext);
514 } catch (AspectRescheduleException e) {
515 this.rollbackSubtransaction(stx);
516 throw e;
517 } catch (AspectNotOkException e) {
518 try {
519 TransactionManager.getInstance().rollbackTransaction(
520 acontext.getTx());
521 } catch (XCoreException e1) {
522 throw new FatalException(e1);
523 }
524 throw e;
525 } catch (AspectSkipException e) {
526 try {
527 TransactionManager.getInstance().rollbackTransaction(
528 acontext.getTx());
529 } catch (XCoreException e1) {
530 throw new FatalException(e1);
531 }
532 throw new FatalException(
533 "SKIP not allowed as answer of a post aspect.");
534 }
535 this.commitSubtransaction(stx);
536 tx = acontext.getTx();
537
538 if (tx.isImplicit()) {
539 try {
540 TransactionManager.getInstance().commitTransaction(tx);
541 } catch (XCoreException e) {
542 throw new FatalException(e);
543 }
544 }
545
546 if (logger.isDebugEnabled()) {
547 logger.debug("take() entries taken: " + acontext.getDeleted()
548 + " -- " + this.getCref());
549 }
550
551 return acontext.getDeleted();
552 } catch (CountNotMetException e) {
553 if (logger.isDebugEnabled()) {
554 logger.debug("take() CountNotMetException was thrown: " + e
555 + " -- " + this.getCref());
556 }
557 this.rollbackSubtransaction(stx);
558 throw e;
559 } catch (TransactionLockException e) {
560 if (logger.isDebugEnabled()) {
561 logger.debug("take() TransactionLockException " + e + " -- "
562 + this.getCref());
563 }
564 this.rollbackSubtransaction(stx);
565 throw e;
566 }
567 }
568
569 /***
570 * Writes one Entry. The method uses a sub transaction for writing the entry
571 * to ensure the all coordinators a rolled back if one coordinator can not
572 * write the entry.
573 *
574 * @param e
575 * the entry to write.
576 * @param tx
577 * the transaction for the operation.
578 * @throws ContainerFullException
579 * thrown when the entry can not be written because there is no
580 * free place for it (e.g. full bounded container, vector
581 * position already used, key already present).
582 * @throws NoSuchCoordinationTypeException
583 * thrown when there is a selector which needs a coordination
584 * type which has not been activated on the container
585 * @throws TransactionLockException
586 * if an entry or container is locked by another transaction.
587 */
588 private void write(Entry e, Transaction tx) throws ContainerFullException,
589 TransactionLockException, NoSuchCoordinationTypeException {
590 if (logger.isDebugEnabled()) {
591 logger.debug("write(" + e + ", " + tx + ") -- " + this.getCref());
592 }
593
594
595
596
597 Transaction stx = TransactionManager.getInstance()
598 .createSubTransaction(tx);
599
600 try {
601 c.write(e, stx);
602 } catch (ContainerFullException e1) {
603 this.rollbackSubtransaction(stx);
604 throw e1;
605 } catch (TransactionLockException e1) {
606 this.rollbackSubtransaction(stx);
607 throw e1;
608 } catch (NoSuchCoordinationTypeException e1) {
609 this.rollbackSubtransaction(stx);
610 throw e1;
611 }
612
613 for (Selector s : e.getSelectors()) {
614 stx.addCoordinator(c.getCoordTypefromSelector(s.getClass()));
615 }
616
617 this.commitSubtransaction(stx);
618
619 if (logger.isDebugEnabled()) {
620 logger.debug("write() entry written -- " + this.getCref());
621 }
622
623 }
624
625 /***
626 * {@inheritDoc}.
627 */
628 public void write(List<Entry> entries, Transaction tx, int retrycount,
629 Properties aspectContext) throws ContainerFullException,
630 TransactionLockException, NoSuchCoordinationTypeException,
631 InvalidTransactionException, AspectRescheduleException,
632 AspectNotOkException {
633 if (logger.isDebugEnabled()) {
634 logger.debug("write(" + entries + ", " + tx + ", " + retrycount
635 + ", " + aspectContext + ") -- " + this.getCref());
636 }
637
638
639 tx = this.initTransaction(tx);
640 Transaction stx = null;
641 try {
642 AspectContext acontext = new AspectContext(LocalIPoint.PreWrite,
643 this.getCref(), tx, null, entries, null, retrycount,
644 aspectContext);
645 boolean skip = false;
646 try {
647 this.executeAspect(acontext);
648 } catch (AspectRescheduleException e) {
649 this.rollbackSubtransaction(acontext.getTx());
650 throw e;
651 } catch (AspectNotOkException e) {
652 try {
653 TransactionManager.getInstance().rollbackTransaction(
654 acontext.getTx());
655 } catch (XCoreException e1) {
656 throw new FatalException(e1);
657 }
658 throw e;
659 } catch (AspectSkipException e) {
660 skip = true;
661 }
662 tx = acontext.getTx();
663 entries = acontext.getEntries();
664 retrycount = acontext.getRetrycount();
665
666
667 stx = TransactionManager.getInstance().createSubTransaction(tx);
668
669 if (!skip) {
670 for (Entry e : entries) {
671 this.write(e, stx);
672 }
673 }
674 try {
675 acontext.setLocalIPoint(LocalIPoint.PostWrite);
676 this.executeAspect(acontext);
677 } catch (AspectRescheduleException e) {
678 this.rollbackSubtransaction(stx);
679 throw e;
680 } catch (AspectNotOkException e) {
681 try {
682 TransactionManager.getInstance().rollbackTransaction(
683 acontext.getTx());
684 } catch (XCoreException e1) {
685 throw new FatalException(e1);
686 }
687 throw e;
688 } catch (AspectSkipException e) {
689
690 try {
691 TransactionManager.getInstance().rollbackTransaction(
692 acontext.getTx());
693 } catch (XCoreException e1) {
694 throw new FatalException(e1);
695 }
696 throw new FatalException(
697 "SKIP not allowed as answer of a post aspect.");
698 }
699 tx = acontext.getTx();
700
701 this.commitSubtransaction(stx);
702
703 if (tx.isImplicit()) {
704 try {
705 TransactionManager.getInstance().commitTransaction(tx);
706 } catch (XCoreException e) {
707 throw new FatalException(e);
708 }
709 }
710 } catch (ContainerFullException e1) {
711 if (logger.isDebugEnabled()) {
712 logger.debug("write() NoPlaceLeftException was thrown: " + e1
713 + " -- " + this.getCref());
714 }
715 this.rollbackSubtransaction(stx);
716 if (tx.isImplicit()) {
717 try {
718 TransactionManager.getInstance().rollbackTransaction(tx);
719 } catch (XCoreException e) {
720 throw new FatalException(e);
721 }
722 }
723 throw e1;
724 } catch (TransactionLockException e) {
725 if (logger.isDebugEnabled()) {
726 logger.debug("write() TransactionLockException " + e + " -- "
727 + this.getCref() + " Reason: " + e.getReason());
728 }
729 this.rollbackSubtransaction(stx);
730 throw e;
731 }
732
733 if (logger.isDebugEnabled()) {
734 logger.debug("write() entries written -- " + this.getCref());
735 }
736
737 }
738
739 /***
740 * Checks if the transaction is valid. If tx is <code>null</code> a new
741 * implicit transaction will be created and returned.<br>
742 * The returned transaction has to be used for the work.
743 *
744 * @param tx
745 * the transaction to check.
746 * @return the transaction which has to be used.
747 * @throws InvalidTransactionException
748 * if tx is invalid
749 */
750 private Transaction initTransaction(Transaction tx)
751 throws InvalidTransactionException {
752
753 if (tx == null) {
754 tx = TransactionManager.getInstance().createImplicitTransaction(
755 ICapi.INFINITE_TIMEOUT);
756 }
757
758
759 if (!TransactionManager.getInstance().isValid(tx)) {
760 throw new InvalidTransactionException("Unknown Transaction: " + tx);
761
762 }
763
764 tx.addContainerRef(this.getCref());
765
766 return tx;
767 }
768
769 /***
770 * {@inheritDoc}.
771 */
772 public ContainerRef getCref() {
773 return c.getCref();
774 }
775
776 /***
777 * {@inheritDoc}.
778 */
779 public void setCref(ContainerRef cref) {
780 c.setCref(cref);
781 }
782
783 /***
784 * Creates an AspectContext and executes the aspects.
785 *
786 * @param context
787 * the aspect context.
788 * @throws AspectNotOkException
789 * thrown if the operation has to be rescheduled.
790 * @throws AspectRescheduleException
791 * thrown if the operation has to be undone and the transaction
792 * has to be rolled back.
793 * @throws AspectSkipException
794 * thrown if the operation shall be skiped.
795 */
796 private void executeAspect(AspectContext context)
797 throws AspectNotOkException, AspectRescheduleException,
798 AspectSkipException {
799
800 Transaction tx = context.getTx();
801
802
803
804
805 Transaction ntx = context.getTx();
806 while (ntx.getFather() != null) {
807 ntx = ntx.getFather();
808 }
809 boolean implicit = tx.isImplicit();
810 ntx.setImplicit(false);
811 context.setTx(ntx);
812
813
814 Properties aspectContext = context.getAspectContext();
815
816 if (aspectContext == null) {
817 aspectContext = new Properties();
818 context.setAspectContext(aspectContext);
819 }
820
821 aspectContext.put("Transaction", tx);
822 aspectContext.put("TxnIsImplicit", new Boolean(implicit));
823
824
825 try {
826 this.aspectManager.execute(context);
827 } finally {
828
829
830
831 context.setTx(tx);
832
833
834
835 tx.setImplicit(implicit);
836
837
838 context.getAspectContext().remove("Transaction");
839 context.getAspectContext().remove("TxnIsImplicit");
840 }
841 }
842
843 /***
844 *
845 * {@inheritDoc}.
846 */
847
848 public String addAspects(List<IPoint> points, IAspect aspect,
849 Properties aspectContext) {
850 AspectContext acontext = new AspectContext(LocalIPoint.PreAddAspect,
851 points, aspect, aspectContext);
852 boolean skip = false;
853 String id = null;
854 try {
855 this.aspectManager.execute(acontext);
856 } catch (AspectNotOkException e) {
857
858 throw new FatalException(
859 "Aspect is not allowed to answer NotOk here.");
860 } catch (AspectRescheduleException e) {
861 throw new FatalException(
862 "Aspect is not allowed to answer Delay here.");
863 } catch (AspectSkipException e) {
864 skip = true;
865 }
866 if (!skip) {
867 for (IPoint p : acontext.getIpoints()) {
868 id = this.aspectManager.addAspect(p, acontext.getAspect());
869 }
870 }
871 acontext.setLocalIPoint(LocalIPoint.PostAddAspect);
872 try {
873 this.aspectManager.execute(acontext);
874 } catch (Exception e) {
875 throw new FatalException(
876 "Aspect is not allowed to answer with something else then OK!");
877 }
878 return id;
879 }
880
881 /***
882 *
883 * {@inheritDoc}.
884 */
885
886 public void removeAspect(IPoint p, URI uri, Properties aspectContext) {
887 AspectContext acontext = new AspectContext(LocalIPoint.PreRemoveAspect,
888 java.util.Arrays.asList(new IPoint[] { p }), uri, aspectContext);
889 boolean skip = false;
890 try {
891 this.aspectManager.execute(acontext);
892 } catch (AspectNotOkException e) {
893
894 throw new FatalException(
895 "Aspect is not allowed to answer NotOk here.");
896 } catch (AspectRescheduleException e) {
897 throw new FatalException(
898 "Aspect is not allowed to answer Delay here.");
899 } catch (AspectSkipException e) {
900 skip = true;
901 }
902 if (!skip) {
903 for (IPoint pp : acontext.getIpoints()) {
904 this.aspectManager.removeAspect(pp, acontext.getAspectURI());
905 }
906 }
907 try {
908 acontext.setLocalIPoint(LocalIPoint.PostRemoveAspect);
909 this.aspectManager.execute(acontext);
910 } catch (Exception e) {
911
912
913 throw new FatalException(
914 "Aspect is not allowed to answer with something else then OK!");
915 }
916 }
917
918 /***
919 * {@inheritDoc}
920 */
921
922 public void addCoordinator(Class<? extends Selector> s, ICoordinator coord) {
923 this.c.addCoordinator(s, coord);
924 }
925
926 /***
927 * {@inheritDoc}
928 */
929
930 public List<ICoordinator> getCoordinators() {
931
932 return null;
933 }
934
935 /***
936 * {@inheritDoc}
937 */
938 public int currentSize() {
939 return c.currentSize();
940 }
941 }