KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > objectweb > jass > as > ActivityImpl


1 /**
2  - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
3  -
4  - JASS: Java Advanced tranSaction Support
5  -
6  - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
7  -
8  - This module was originally developed by
9  -
10  - LSD (Distributed Systems Lab, http://lsd.ls.fi.upm.es/lsd/lsd.htm)
11  - at Universidad Politecnica de Madrid (UPM) as an ObjectWeb Consortium
12  - (http://www.objectweb.org) project.
13  -
14  - This project has been partially funded by the European Commission under
15  - the IST programme of V FP grant IST-2001-37126 and by the Spanish
16  - Ministry of Science & Technology (MCyT) grants TIC2002-10376-E and
17  - TIC2001-1586-C03-02
18  -
19  - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
20  - The original code and portions created by LSD are
21  - Copyright (c) 2004 LSD (UPM)
22  - All rights reserved.
23  -
24  - Redistribution and use in source and binary forms, with or without
25  - modification, are permitted provided that the following conditions are met:
26  -
27  - -Redistributions of source code must retain the above copyright notice, this
28  - list of conditions and the following disclaimer.
29  -
30  - -Redistributions in binary form must reproduce the above copyright notice,
31  - this list of conditions and the following disclaimer in the documentation
32  - and/or other materials provided with the distribution.
33  -
34  - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
35  - AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
36  - IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
37  - ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
38  - LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
39  - CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
40  - SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
41  - INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
42  - CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
43  - ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
44  - POSSIBILITY OF SUCH DAMAGE.
45  - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
46  -
47  - Author: Francisco Perez Sorrosal (frperezs)
48  -
49  - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
50 */

51
52 package org.objectweb.jass.as;
53
54 import java.io.Serializable JavaDoc;
55 import java.util.HashMap JavaDoc;
56 import java.util.HashSet JavaDoc;
57 import java.util.Iterator JavaDoc;
58 import java.util.LinkedList JavaDoc;
59 import java.util.Set JavaDoc;
60
61 import javax.activity.ActionErrorException JavaDoc;
62 import javax.activity.ActionNotFoundException JavaDoc;
63 import javax.activity.ActivityCoordinator JavaDoc;
64 import javax.activity.ActivityNotProcessedException JavaDoc;
65 import javax.activity.ActivityPendingException JavaDoc;
66 import javax.activity.CompletionStatus JavaDoc;
67 import javax.activity.ContextPendingException JavaDoc;
68 import javax.activity.CoordinationInformation JavaDoc;
69 import javax.activity.GlobalId JavaDoc;
70 import javax.activity.InvalidActivityException JavaDoc;
71 import javax.activity.InvalidStateException JavaDoc;
72 import javax.activity.NotOriginatorException JavaDoc;
73 import javax.activity.Outcome JavaDoc;
74 import javax.activity.Signal JavaDoc;
75 import javax.activity.SignalSetInactiveException JavaDoc;
76 import javax.activity.SignalSetUnknownException JavaDoc;
77 import javax.activity.Status JavaDoc;
78 import javax.activity.SystemException JavaDoc;
79 import javax.activity.coordination.Action;
80 import javax.activity.coordination.SignalSet;
81 import javax.transaction.Transaction JavaDoc;
82
83 import org.apache.log4j.Logger;
84
85 import org.jboss.util.timeout.Timeout;
86 import org.jboss.util.timeout.TimeoutFactory;
87 import org.jboss.util.timeout.TimeoutTarget;
88
89 import org.objectweb.jass.as.exceptions.SignalSetNotRegisteredException;
90 import org.objectweb.jass.as.util.SignalSetInfo;
91
92 /**
93  * Each object of this class represents an activity and its coordinator.
94  * Implements the AS ActivityCoordinator interface in order to be able to
95  * broadcast signals to registered actions. TimeoutTarget is implemented in
96  * order to be warned of timeout.
97  * @author fran
98  * Date: Feb 16, 2004
99  * org.objectweb.jass.asActivityImpl.java
100  */

101 public class ActivityImpl
102     implements ActivityCoordinator JavaDoc, TimeoutTarget, Serializable JavaDoc {
103
104     // Constants -----------------------------------------------------
105

106     // Attributes ----------------------------------------------------
107

108     private static Logger log = Logger.getLogger(ActivityImpl.class);
109     // Unique activity identifier
110
private ActivityIdImpl activityId;
111     // Indicates the superior ActivityCoordinator of the activity
112
private ActivityImpl superior = null;
113     // Contains the childs of the activity
114
private LinkedList JavaDoc childs = new LinkedList JavaDoc();
115     // Activity current status
116
private int status = Status.StatusNoActivity;
117     // Activity completion status
118
private int completionStatus = CompletionStatus.CompletionStatusFail;
119     // The time the activity was started
120
private long start;
121     // Activity timeout
122
private Timeout timeout = null;
123     private boolean timedOut = false;
124     // Contains objects representing information about the registered
125
// signalSets. The keys are the signalSetNames
126
private HashMap JavaDoc signalSets = new HashMap JavaDoc();
127     // The name of the completion SignalSet
128
private String JavaDoc completionSSName = null;
129     // A reference to UserActivity implementation
130
private ActivityService manager = null;
131     // Mutex for thread-safety. This should only be changed in the lock()
132
// and unlock() methods
133
private boolean locked = false;
134     // Flags that the activity has finished
135
private boolean done = false;
136     private HashSet JavaDoc threads = new HashSet JavaDoc();
137
138     // Constructors ---------------------------------------------------------------
139

140     public ActivityImpl(
141         ActivityService activityService,
142         ActivityIdImpl activityId,
143         ActivityImpl superior,
144         int timeout) {
145
146         log.info(getThreadName() + " STARTING ACTIVITY " + activityId.print());
147         this.manager = activityService;
148         this.activityId = activityId;
149         this.superior = superior;
150         // Set the starting time of the currentActivity and
151
// the timeout in milliseconds (timeout parameter in secs * 1000)
152
start = System.currentTimeMillis();
153         // We only set the timeout when its distinct from zero
154
if (timeout != 0) {
155             this.timeout =
156                 TimeoutFactory.createTimeout(start + (timeout * 1000), this);
157             log.info("\tTimeout = " + timeout);
158         } else
159             log.info("\tTimeout NOT set to this activity");
160         // Change to the right status
161
status = Status.StatusActive;
162         log.info(getThreadName() + activityId.print() + " STARTED!!!");
163     }
164
165     // Public -----------------------------------------------------------------
166

167     // ActivityCoordinator implementation -------------------------------------
168

169     /**
170      * Establishes an interest relationship between the specified Action and
171      * SignalSet for the Activity represented by the target ActivityCoordinator.
172      * When a Signal which is a member of the SignalSet is sent, the
173      * processSignal method of the Action will be invoked with that Signal. If
174      * multiple Actions are registered, then priority may be used to place an
175      * order on how they will be invoked when Signals are sent: higher priority
176      * Actions will occur first in the Action list, and hence be invoked before
177      * other, lower priority, Actions. The priority value must be a positive
178      * value; a value of zero means that the Activity Service implementation is
179      * free to place the Action at any point in the Action list. If the
180      * specified Action is registered multiple times for the same SignalSet
181      * then it will be invoked multiple times with the Signals from that
182      * SignalSet.
183      */

184     public void addAction(Action action, String JavaDoc signalSetName, int priority)
185         throws SignalSetUnknownException JavaDoc, SystemException JavaDoc, IllegalStateException JavaDoc {
186
187         SignalSetInfo ssInfo = null;
188         SignalSet signalSet = null;
189
190         log.info(activityId.print());
191         // If the SignalSet is not registered in the activity (signalSets HashMap)...
192
if (!signalSets.containsKey(signalSetName)) {
193
194             log.info("\tSignalSet " + signalSetName + " not yet registered.");
195             log.info("\tRegistering SignalSet and adding action...");
196
197             try {
198                 // ... first, we obtain an instance and associate with its name...
199
signalSet = manager.getService().getSignalSet(signalSetName);
200                 signalSet.setActivityCoordinator(this);
201                 ssInfo = new SignalSetInfo(signalSet);
202                 ssInfo.addAction(action, priority, false);
203                 signalSets.put(signalSetName, ssInfo);
204                 log.info("\tSignalSet " + signalSetName + " registered");
205             } catch (SignalSetUnknownException JavaDoc e) {
206                 log.warn("Null SignalSet");
207                 e.printStackTrace();
208             } catch (Exception JavaDoc e) {
209                 e.printStackTrace();
210             }
211         } else { // The signalSet already exists in the HashMap
212
log.info("\tSignalSet "+ signalSetName + " already registered. Adding action...");
213             ssInfo = (SignalSetInfo) signalSets.get(signalSetName);
214             ssInfo.addAction(action, priority, false);
215             signalSets.put(signalSetName, ssInfo);
216         }
217         log.info("\tAction added!!!");
218         log.info("\tActions registered = " + ssInfo.getNumberRegisteredActions());
219     }
220
221     /**
222      * Establishes an interest relationship between the specified
223      * Action and all SignalSets used by the Activity represented
224      * by the target ActivityCoordinator. When a Signal which is
225      * a member of any of the SignalSets is sent, the processSignal
226      * method of the Action will be invoked with that Signal.
227      * If multiple Actions are registered, then priority may be used
228      * to place an order on how they will be invoked when Signals are
229      * sent: higher priority Actions will occur first in the Action
230      * list, and hence be invoked before other, lower priority, Actions.
231      * The priority value must be a positive value; a value of zero
232      * means that the Activity Service implementation is free to place
233      * the Action at any point in the Action list.
234      * If the specified Action is registered multiple times with the
235      * target ActivityCoordinator then it will be invoked multiple times
236      * with each Signal.
237      */

238     public void addGlobalAction(Action action, int priority)
239         throws SystemException JavaDoc, java.lang.IllegalStateException JavaDoc {
240
241         // First, we get all registered signal sets...
242
Set JavaDoc keys = signalSets.keySet();
243         Iterator JavaDoc it = keys.iterator();
244         // ...and then we iterate on them adding the action.
245
while (it.hasNext()) {
246             SignalSetInfo ssInfo = (SignalSetInfo) it.next();
247             ssInfo.addAction(action, priority, true);
248         }
249     }
250
251     /**
252      * Removes the interest relationship between the specified Action
253      * and SignalSet for the Activity represented by the target
254      * ActivityCoordinator. If signalSetName is an empty String then
255      * the interest relationship is removed between the specified Action
256      * and all SignalSets in the target Activity. This operation has no
257      * effect on any global actions.
258      * If the specified Action was registered multiple times with the
259      * target ActivityCoordinator then only a single instance of this Action
260      * is removed by each call to this method.
261      */

262     public void removeAction(Action action, String JavaDoc signalSetName)
263         throws ActionNotFoundException JavaDoc, SystemException JavaDoc, IllegalStateException JavaDoc {
264
265         boolean result = false;
266
267         if ((status == Status.StatusCompleting)
268             || (status == Status.StatusCompleted)
269             || (status == Status.StatusCompletingHeuristic))
270             throw new IllegalStateException JavaDoc();
271
272         if (!signalSets.containsKey(signalSetName))
273             throw new SystemException JavaDoc(
274                 "SignalSet " + signalSetName + " not registered");
275         result =
276             ((SignalSetInfo) signalSets.get(signalSetName)).removeAction(
277                 action,
278                 false);
279
280         if (!result)
281             throw new ActionNotFoundException JavaDoc();
282     }
283
284     /**
285      * Removes the interest relationship between the specified Action and all
286      * SignalSets for the Activity represented by the target ActivityCoordinator.
287      * This operation has no effect on any non-global actions. If the specified
288      * Action was registered multiple times with the target ActivityCoordinator
289      * then only a single instance of this Action is removed by each call to
290      * this method.
291      */

292     public void removeGlobalAction(Action action)
293         throws ActionNotFoundException JavaDoc, SystemException JavaDoc, IllegalStateException JavaDoc {
294
295         if ((status == Status.StatusCompleting)
296             || (status == Status.StatusCompleted)
297             || (status == Status.StatusCompletingHeuristic))
298             throw new IllegalStateException JavaDoc();
299
300         // First, we get all registered signal sets...
301
Set JavaDoc keys = signalSets.keySet();
302         Iterator JavaDoc it = keys.iterator();
303         // ...and then we iterate on them removing the action.
304
while (it.hasNext()) {
305             SignalSetInfo ssInfo = (SignalSetInfo) it.next();
306             ssInfo.removeAction(action, true);
307         }
308     }
309     
310     /**
311      * Returns all the Actions that have been registered with
312      * an interest in the specified signalSetName. This method may
313      * be used by a HLS that has determined that an Activity needs
314      * to be persisted and needs to log the Actions registered in the Activity.
315      */

316     public Action[] getActions(java.lang.String JavaDoc signalSetName)
317         throws SignalSetUnknownException JavaDoc, SystemException JavaDoc {
318
319         if (!signalSets.containsKey(signalSetName))
320             throw new SignalSetUnknownException JavaDoc();
321
322         return ((SignalSetInfo) signalSets.get(signalSetName)).getActions();
323     }
324     
325     /**
326      * Returns the number of Actions, including global Actions,
327      * registered with the target ActivityCoordinator with an
328      * interest in the specified SignalSet.
329      */

330     public int getNumberRegisteredActions(String JavaDoc signalSetName)
331         throws SignalSetUnknownException JavaDoc, SystemException JavaDoc {
332
333         if (!signalSets.containsKey(signalSetName))
334             throw new SignalSetUnknownException JavaDoc();
335
336         return ((SignalSetInfo) signalSets.get(signalSetName))
337             .getNumberRegisteredActions();
338     }
339
340     /**
341      * Sets the name of the SignalSet that should be used for the distribution
342      * of completion signals when the current Activity completes.
343      * This method can be called multiple times during the lifetime of an
344      * Activity, before the Activity starts completion processing.
345      * The last value specified before completion processing starts is used
346      * during completion processing.
347      */

348     public void setCompletionSignalSetName(String JavaDoc signalSetName)
349         throws SignalSetUnknownException JavaDoc, SystemException JavaDoc, IllegalStateException JavaDoc {
350
351         completionSSName = signalSetName;
352     }
353     
354     /**
355      * Returns the name of the SignalSet, if any, that will be used for the
356      * distribution of completion signals when the current Activity completes.
357      */

358     public String JavaDoc getCompletionSignalSetName() throws SystemException JavaDoc {
359
360         return completionSSName;
361     }
362     
363     /**
364      * Returns the parent ActivityCoordinator or null if the target
365      * ActivityCoordinator represents a top-level Activity.
366      */

367     public ActivityCoordinator JavaDoc getParent() throws SystemException JavaDoc {
368
369         return superior;
370     }
371
372     /**
373      * Returns the GlobalId of the Activity represented by the target ActivityCoordinator.
374      */

375     public GlobalId JavaDoc getGlobalId() throws SystemException JavaDoc {
376         
377         return activityId;
378     }
379     
380     /**
381      * Returns the Status of the Activity represented by the target ActivityCoordinator.
382      */

383     public int getStatus() throws SystemException JavaDoc {
384         
385         return status;
386     }
387     
388     /**
389      * Returns the Status of the Activity represented by the target ActivityCoordinator's
390      * parent. If the target ActivityCoordinator represents a top-level
391      * Activity, then the Status of this top-level Activity is returned.
392      */

393     public int getParentStatus() throws SystemException JavaDoc {
394
395         if (superior != null)
396             return superior.getStatus();
397         else
398             return status;
399     }
400
401     /**
402      * Returns a printable string describing the Activity represented by the target
403      * ActivityCoordinator.
404      */

405     public String JavaDoc getName() throws SystemException JavaDoc {
406         return activityId.print();
407     }
408
409     /**
410      * Returns true if the specified coord represents the same Activity as the
411      * target ActivityCoordinator.
412      */

413     public boolean isSameActivity(ActivityCoordinator JavaDoc coord)
414         throws SystemException JavaDoc {
415
416         if (coord != null && coord instanceof ActivityImpl)
417             return this.activityId.equals(coord.getGlobalId());
418
419         return false;
420     }
421     
422     /**
423      * Causes the Activity associated with the target ActivityCoordinator to
424      * complete with the specified CompletionStatus. The Activity service sets
425      * the Status to StatusCompleting before asking any completion SignalSet
426      * to start producing Signals.
427      * If there are any child active or suspended Activities or transactions
428      * and the CompletionStatus is CompletionStatusFail or
429      * CompletionStatusFailOnly then those child Activites will have their
430      * CompletionStatuses set to CompletionStatusFailOnly and any child
431      * transaction will be called to setRollbackOnly.
432      * The UserActivity interface should be used in preference to the
433      * ActivityCoordinator for completing Activities in most circumstances.
434      * This method is provided primarily for use after recovery when the
435      * Activity to be completed is not associated with the calling thread.
436      */

437     public Outcome JavaDoc completeActivity(int completionStatus)
438         throws
439             ActivityPendingException JavaDoc,
440             ContextPendingException JavaDoc,
441             NotOriginatorException JavaDoc,
442             InvalidStateException JavaDoc,
443             ActivityNotProcessedException JavaDoc,
444             SystemException JavaDoc {
445         // Set the completion status of this instance and...
446
this.completionStatus = completionStatus;
447         // ...delegate on the implementation dependant method.
448
return completeActivity();
449     }
450
451     /**
452      * TODO NOT YET IMPLEMENTED
453      */

454     public Outcome JavaDoc heuristicComplete(int completionStatus)
455         throws
456             ActivityPendingException JavaDoc,
457             ContextPendingException JavaDoc,
458             InvalidStateException JavaDoc,
459             ActivityNotProcessedException JavaDoc,
460             SystemException JavaDoc {
461         return null;
462     }
463     
464     /**
465      * Causes the SignalSet specified by signalSetName to start producing
466      * signals for all registered Actions at times other than during completion.
467      * Pre-defined SignalSets, such as Synchronization, cannot be requested to
468      * produce signals via this method.
469      */

470     public Outcome JavaDoc processSignalSet(String JavaDoc signalSetName, int completionStatus)
471         throws
472             SignalSetUnknownException JavaDoc,
473             ActivityNotProcessedException JavaDoc,
474             InvalidActivityException JavaDoc,
475             SystemException JavaDoc {
476
477         SignalSet processingSS = null;
478         Signal JavaDoc signal = null;
479         Outcome JavaDoc out = null;
480         Action[] actions = null;
481
482         // If the activity is finished, throw an exception
483
if (done)
484             throw new InvalidActivityException JavaDoc();
485         // If the SignalSet is not registered, throw an exception
486
if (!signalSets.containsKey(signalSetName))
487             throw new SignalSetUnknownException JavaDoc();
488
489         // First, get the SignalSet to process...
490
try {
491             processingSS = getSignalSet(signalSetName);
492             processingSS.setCompletionStatus(completionStatus, status);
493         } catch (SignalSetNotRegisteredException e) {
494             status = Status.StatusError;
495             throw new ActivityNotProcessedException JavaDoc();
496         }
497
498         log.info("Processing " + signalSetName);
499
500         if ((actions = getActions(signalSetName)) == null)
501             log.info("\tNO actions registered with " + signalSetName);
502         else { // If there are actions to process...
503
try {
504                 // ...then deliver the signals...
505
deliverSignals(processingSS, actions);
506                 // ...and finally, get the SignalSet outcome.
507
out = processingSS.getOutcome();
508             } catch (Exception JavaDoc e) {
509                 e.printStackTrace();
510             }
511         }
512
513         return out;
514     }
515
516     // Implements TimeoutTarget -----------------------------------------------
517

518     /**
519      * Called when our timeout expires.
520      */

521     public void timedOut(Timeout timeout) {
522         try {
523             lock();
524             log.warn("Activity " + activityId.print() + " TIMED OUT !!!!!");
525             log.warn(" Status = " + getStringStatus(status));
526             if (this.timeout == null)
527                 return; // Don't race with timeout cancellation.
528
this.timeout = null;
529             timedOut = true;
530             switch (status) {
531                 case Status.StatusCompleting :
532                 case Status.StatusCompleted :
533                     // Give a chance to finish
534
return;
535                 case Status.StatusActive :
536                 case Status.StatusError :
537                     // We mark the status of the child activities as
538
// CompletionStatusFail
539
markChildActivitiesWithFail();
540                     return;
541                 default :
542                     log.warn("Unknown status at timeout, Activity = " + toString());
543                     status = Status.StatusUnknown;
544                     return;
545             }
546         } finally {
547             unlock();
548         }
549     }
550
551     // My Public Methods ------------------------------------------------------
552

553     /**
554      * Associates the calling thread with this activity.
555      */

556     public void associateCurrentThread() {
557
558         log.info(
559             "Associating thread "
560                 + getThreadName()
561                 + " with activity "
562                 + activityId.print());
563         threads.add(Thread.currentThread());
564         log.warn("Associated threads = " + threads.size());
565     }
566
567     /**
568      * Disassociates the calling thread from this activity.
569      */

570     public void disassociateCurrentThread() {
571
572         log.warn(
573             "Disassociating thread "
574                 + getThreadName()
575                 + " from activity "
576                 + activityId.print());
577         threads.remove(Thread.currentThread());
578         log.warn("Associated threads = " + threads.size());
579         Thread.interrupted();
580     }
581
582     /**
583      * Return the string representation of the activity status.
584      *
585      * @param status the integer status to convert.
586      * @return the string representation of the status.
587      */

588     public String JavaDoc getStringStatus(int status) {
589
590         switch (status) {
591             case Status.StatusActive :
592                 return "STATUS_ACTIVE";
593             case Status.StatusCompleted :
594                 return "STATUS_COMPLETED";
595             case Status.StatusCompleting :
596                 return "STATUS_COMPLETING";
597             case Status.StatusCompletingHeuristic :
598                 return "STATUS_COMPLETING_HEURISTIC";
599             case Status.StatusError :
600                 return "STATUS_ERROR";
601             case Status.StatusNoActivity :
602                 return "STATUS_NO_ACTIVITY";
603             case Status.StatusUnknown :
604                 return "STATUS_UNKNOWN";
605
606             default :
607                 return "STATUS_UNKNOWN(" + status + ")";
608         }
609     }
610     /**
611      * Return the string representation of the activity completion status.
612      *
613      * @param completionStatus the integer completion status to convert.
614      * @return the string representation of the completion status.
615      */

616     public String JavaDoc getStringCompletionStatus(int completionStatus) {
617
618         switch (completionStatus) {
619             case CompletionStatus.CompletionStatusFail :
620                 return "COMPLETION_STATUS_FAIL";
621             case CompletionStatus.CompletionStatusFailOnly :
622                 return "COMPLETION_STATUS_FAIL_ONLY";
623             case CompletionStatus.CompletionStatusSuccess :
624                 return "COMPLETION_STATUS_SUCCESS";
625
626             default :
627                 return "COMPLETION_STATUS_UNKNOWN(" + completionStatus + ")";
628         }
629     }
630
631     // My Protected ---------------------------------------------------------------
632

633     /**
634      * Protected method to complete the activity.
635      */

636     protected Outcome JavaDoc completeActivity()
637         throws
638             ActivityPendingException JavaDoc,
639             ContextPendingException JavaDoc,
640             NotOriginatorException JavaDoc,
641             InvalidStateException JavaDoc,
642             ActivityNotProcessedException JavaDoc,
643             SystemException JavaDoc {
644
645         SignalSet processingSS = null;
646         Outcome JavaDoc out = null;
647         Action[] actions = null;
648
649         log.info(getThreadName() + " COMPLETING ACTIVITY " + activityId.print());
650
651         if ((completionStatus == CompletionStatus.CompletionStatusSuccess)
652             && (childs.size() > 0))
653             throw new ContextPendingException JavaDoc();
654         if (threads.size() > 1)
655             throw new ActivityPendingException JavaDoc();
656
657         status = Status.StatusCompleting;
658
659         if (timedOut) // If timeout has expired, complete with FAIL.
660
completionStatus = CompletionStatus.CompletionStatusFail;
661         if (timeout != null)
662             timeout.cancel();
663
664         log.info("\tWITH " + getStringCompletionStatus(completionStatus));
665
666         if (completionSSName == null) {
667             // It may be not have been set yet by the HLS.
668
completionSSName = manager.getService().getCompletionSignalSetName();
669             // If still it is null, then return a null outcome.
670
if (completionSSName == null) {
671                 log.info("\tThere is no completion SignalSet to process.");
672                 // We finish the instance
673
log.info(
674                     getThreadName() + " " + activityId.print() + " COMPLETED!!!");
675                 instanceDone();
676                 return out;
677             }
678         }
679
680         // The completion SignalSet may or not have been registered previously
681
try {
682             if (signalSets.containsKey(completionSSName)) {
683                 log.debug("SignalSet " + completionSSName + " already registered");
684                 processingSS = getSignalSet(completionSSName);
685                 actions = getActions(completionSSName);
686             } else {
687                 log.debug("SignalSet " + completionSSName + " not registered");
688                 processingSS = manager.getService().getSignalSet(completionSSName);
689                 processingSS.setActivityCoordinator(this);
690             }
691         } catch (Exception JavaDoc e) {
692             // SignalSetUnknownException, SignalSetNotRegisteredException
693
// NoImplementException, SignalSetActiveException
694
status = Status.StatusError;
695             throw new ActivityNotProcessedException JavaDoc();
696         }
697
698         log.info("\tProcessing Completion SignalSet -> " + completionSSName);
699         processingSS.setCompletionStatus(completionStatus, status);
700
701         try {
702             if (actions == null)
703                 log.info("\tNO actions registered");
704             else {
705                 deliverSignals(processingSS, actions);
706                 // WARNING!!! We can't modify a CompletionStatusFailOnly completionStatus
707
int signalSetCompStat = processingSS.getCompletionStatus();
708                 if ((signalSetCompStat
709                     != CompletionStatus.CompletionStatusFailOnly)
710                     && (completionStatus == CompletionStatus.CompletionStatusFailOnly))
711                     throw new InvalidStateException JavaDoc();
712                 completionStatus = signalSetCompStat;
713                 // Finally, we obtain the SignalSet outcome and CompletionStatus
714
out = processingSS.getOutcome();
715             }
716             processingSS.destroy();
717             log.info("\tCompletion SignalSet processing completed.");
718             log.info(
719                 "\tFinal CompletionStatus = "
720                     + getStringCompletionStatus(completionStatus));
721             status = Status.StatusCompleted;
722         } catch (Exception JavaDoc e) {
723             e.printStackTrace();
724         } finally {
725             // We finish the instance
726
log.info(getThreadName() + " " + activityId.print() + " COMPLETED!!!");
727             instanceDone();
728         }
729         return out;
730     }
731
732     /**
733      * Delivers the SignalSet signals to registered actions.
734      * @param signalSet the triggered SignalSet.
735      * @param actions the actions registered with the SignalSet.
736      * @throws ActionErrorException
737      */

738     private void deliverSignals(SignalSet signalSet, Action[] actions)
739         throws ActionErrorException JavaDoc {
740
741         Signal JavaDoc signal = null;
742         CoordinationInformation JavaDoc info = null;
743         Outcome JavaDoc out = null;
744
745         while ((signal = signalSet.getSignal()) != null) {
746             int i = 0;
747             boolean nextSignal = false;
748             log.info("\tSending " + signal.getName() + " signal...");
749             log.info("\t# of registered actions = " + actions.length);
750             while ((i < actions.length) && (nextSignal == false)) {
751                 if (actions[i] != null) {
752                     log.debug("\tSending number: " + i);
753                     out = actions[i].processSignal(signal);
754                     // Get and check the coordination information
755
try {
756                         info = signalSet.setResponse(out);
757                     } catch (SignalSetInactiveException JavaDoc e) {
758                         e.printStackTrace();
759                     }
760                     if ((info != null) && (info.isActionInterested() == false)) {
761                         // We must remove the action in order to not process
762
// it in other processings while this activity still is alive...
763
SignalSetInfo ssi =
764                             ((SignalSetInfo) signalSets
765                                 .get(signalSet.getSignalSetName()));
766                         ssi.removeAction(actions[i], false);
767                         // ...and remove action from array for the current processing...
768
actions[i] = null;
769                     }
770                     if ((info != null) && (info.useNextSignal() == true)) {
771                         nextSignal = true;
772                         break; // We take other signal
773
}
774                 }
775                 i = i + 1;
776             }
777         }
778     }
779
780     /**
781      * Sets the completionStatus for this activity.
782      */

783     protected void setCompletionStatus(int completionStatus)
784         throws InvalidStateException JavaDoc {
785
786         if (this.completionStatus == CompletionStatus.CompletionStatusFailOnly)
787             throw new InvalidStateException JavaDoc();
788         this.completionStatus = completionStatus;
789     }
790
791     /**
792      * Gets the completionStatus of this activity.
793      */

794     protected int getCompletionStatus() {
795         return completionStatus;
796     }
797
798     /**
799      * Adds a child to the children list.
800      * @param child - The new child.
801      */

802     protected void addChild(ActivityImpl child) {
803         childs.add(child);
804     }
805
806     /**
807      * Removes a child from the list of children.
808      * @param child - The child to remove.
809      */

810     protected void removeChild(ActivityImpl child) {
811         childs.remove(child);
812     }
813
814     /**
815      * Returns an array of activity children.
816      * @return - The array with all the children of this activity.
817      */

818     protected ActivityImpl[] getChilds() {
819         ActivityImpl[] array = null;
820         
821         if (childs.size() > 0)
822             array = (ActivityImpl[]) childs.toArray(new ActivityImpl[childs.size()]);
823         return array;
824     }
825
826     // My Private -------------------------------------------------------------
827

828     /**
829      * Returns a SignalSet from the registered signal sets.
830      * @param signalSetName the name of the SignalSet to return.
831      * @return the registered SignalSet.
832      * @throws SignalSetNotRegisteredException thrown if the requested SignalSet
833      * has not been registered.
834      */

835     private SignalSet getSignalSet(String JavaDoc signalSetName)
836         throws SignalSetNotRegisteredException {
837
838         SignalSetInfo signalSet = (SignalSetInfo) signalSets.get(signalSetName);
839         if (signalSet == null)
840             throw new SignalSetNotRegisteredException();
841         return signalSet.getSignalSet();
842     }
843
844     /**
845      * Mark the child activities with fail. This is done when the
846      * timeout expires.
847      */

848     private void markChildActivitiesWithFail() {
849         ActivityImpl child = null;
850         if (childs != null) {
851             try {
852                 log.debug("Marking with FAIL childs... of " + getName());
853                 Iterator JavaDoc it = childs.iterator();
854                 while (it.hasNext()) {
855                     child = (ActivityImpl) it.next();
856                     child.setCompletionStatus(CompletionStatus.CompletionStatusFail);
857                     log.debug("Child " + child.getName() + " marked!!!");
858                     child.markChildActivitiesWithFail();
859                 }
860             } catch (SystemException JavaDoc e) {
861                 e.printStackTrace();
862             } catch (InvalidStateException JavaDoc e) {
863                 log.debug("Child " + child + "is already marked as FAIL ONLY");
864             }
865         }
866     }
867
868     /**
869      * Lock this instance.
870      */

871     private synchronized void lock() {
872         if (done)
873             throw new IllegalStateException JavaDoc("Activity has terminated");
874         if (locked) {
875             log.warn("Lock contention, activity=" + toString());
876             //DEBUG Thread.currentThread().dumpStack();
877
while (locked) {
878                 try {
879                     // Wakeup happens when:
880
// - notify() is called from unlock()
881
// - notifyAll is called from instanceDone()
882
wait();
883                 } catch (InterruptedException JavaDoc ex) {
884                     // ignore
885
}
886                 if (done)
887                     throw new IllegalStateException JavaDoc("Activity has now terminated");
888             }
889         }
890         locked = true;
891     }
892
893     /**
894      * Unlock this instance.
895      */

896     private synchronized void unlock() {
897         if (!locked) {
898             log.warn(
899                 "Unlocking, but not locked, activity=" + toString(),
900                 new Throwable JavaDoc("[Stack trace]"));
901         }
902         locked = false;
903         notify();
904     }
905
906     /**
907      * Mark this activity as non-existing.
908      */

909     private synchronized void instanceDone() {
910         // If activity is nested, remove the parent association
911
if (superior != null)
912             superior.removeChild(this);
913         // Release this activity from the table for GC
914
manager.releaseActivityImpl(this);
915         // Set the status to StatusNoActivity
916
status = Status.StatusNoActivity;
917         // Notify all threads waiting for the lock
918
notifyAll();
919         // This instance is finished
920
done = true;
921     }
922
923     /**
924      * Returns the name of current thread.
925      * @return the current thread name.
926      */

927     private String JavaDoc getThreadName() {
928         return Thread.currentThread().getName();
929     }
930
931     // Inner classes ----------------------------------------------------------
932

933     // Debug -----------------------------------------------------------------
934

935     private Transaction JavaDoc associatedTransaction = null;
936     
937     public void setTransaction(Transaction JavaDoc tx) {
938         associatedTransaction = tx;
939     }
940     
941     public Transaction JavaDoc getTransaction() {
942             return associatedTransaction;
943     }
944     
945     // End Debug --------------------------------------------------------------
946
}
Popular Tags