1 package Analysis.TaskStateAnalysis;
8 import java.io.FileWriter;
9 import java.io.FileOutputStream;
12 public class SafetyAnalysis {
14 private Hashtable executiongraph;
15 private Hashtable<ClassDescriptor, Hashtable<FlagState, HashSet>> safeexecution; //to use to build code
16 private static final int OR = 0;
17 private static final int AND = 1;
18 private Hashtable reducedgraph;
19 private String classname;
21 private TaskAnalysis taskanalysis;
22 private Hashtable<ClassDescriptor, HashSet> myoptionals;
24 private ClassDescriptor processedclass;
27 public Hashtable<ClassDescriptor, Hashtable<FlagState, HashSet>> getResult(){
31 public Hashtable<ClassDescriptor, HashSet> getMyOptionals(){
35 /*Structure that stores a possible optional
36 task which would be safe to execute and
37 the possible flagstates the object could
38 be in before executing the task during an
39 execution without failure*/
42 public SafetyAnalysis(Hashtable executiongraph, State state, TaskAnalysis taskanalysis){
43 this.executiongraph = executiongraph;
44 this.safeexecution = new Hashtable();
45 this.reducedgraph = new Hashtable();
47 this.taskanalysis = taskanalysis;
48 this.myoptionals = new Hashtable();
51 /*finds the the source node in the execution graph*/
52 private EGTaskNode findSourceNode(Vector nodes){
53 for(Iterator it = nodes.iterator(); it.hasNext();){
54 EGTaskNode tn = (EGTaskNode)it.next();
62 /*returns the nodes corresponding to the tasks
63 that can fire with the object in flagstate
65 private Vector findEGTaskNode(String previousflagstate, Vector nodes){
66 Vector tns = new Vector();
67 for(Iterator it = nodes.iterator(); it.hasNext();){
68 EGTaskNode tn = (EGTaskNode)it.next();
69 if(tn.getFSName().compareTo(previousflagstate)==0)
74 else if (tns.size() > 1){
75 for(Iterator it = tns.iterator(); it.hasNext();){
76 EGTaskNode tn = (EGTaskNode)it.next();
83 /*returns the executiongraph corresponding to the classname*/
84 private Vector getConcernedClass( String classname ){
85 Enumeration e = executiongraph.keys();
86 while( e.hasMoreElements() ){
87 ClassDescriptor cd = (ClassDescriptor)e.nextElement();
88 if (classname.compareTo(cd.getSymbol())==0)
89 return (Vector)executiongraph.get(cd);
94 /*Actual method used by the compiler.
95 It computes the analysis for every
96 possible flagstates of every classes*/
97 public void buildPath() throws java.io.IOException {
98 /*Explore the taskanalysis structure*/
99 System.out.println("------- ANALYSING OPTIONAL TASKS -------");
100 Enumeration e=taskanalysis.flagstates.keys();
102 while (e.hasMoreElements()) {
103 System.out.println("\nAnalysing class :");
104 processedclass=(ClassDescriptor)e.nextElement();
105 classname = processedclass.getSymbol();
106 HashSet newhashset = new HashSet();
107 myoptionals.put(processedclass, newhashset);
108 Hashtable cdhashtable = new Hashtable();
110 System.out.println("\t"+classname+ "\n");
111 //get the graph result of executiongraph class
112 Vector nodes = new Vector();
113 nodes = getConcernedClass( classname );
115 System.out.println("Impossible to find "+classname+". Unexpected.");
118 else if(nodes.size()==0){
119 System.out.println("Nothing to do");
124 EGTaskNode sourcenode = findSourceNode(nodes);
125 doGraphMarking(sourcenode);
126 createDOTFile( classname );
127 reducedgraph.clear();
129 Collection fses = ((Hashtable)taskanalysis.flagstates.get(processedclass)).values();
130 Iterator itfses = fses.iterator();
131 while (itfses.hasNext()) {
132 FlagState fs = (FlagState)itfses.next();
133 Hashtable fsresult = new Hashtable();
134 //get the tasknodes possible to execute with the flagstate before failure
135 HashSet tempnodes = new HashSet();
136 Vector tns = new Vector();
137 System.out.println("Analysing "+fs.getTextLabel());
138 tns = findEGTaskNode(fs.getTextLabel(), nodes);
140 System.out.println("\tNo task corresponding, terminal FS");
143 System.out.println("\tProcessing...");
145 //compute the result for all the nodes contained in tns.
146 //return the intersection of tns that are the same task and union for others.
148 HashSet availabletasks = new HashSet();
149 availabletasks = computeTns(tns);
151 //removeDoubles(availabletasks);
153 for(Iterator it = availabletasks.iterator(); it.hasNext();){
154 MyOptional mo = (MyOptional)it.next();
155 resultingFS(mo, classname);
158 cdhashtable.put(fs, availabletasks);
161 safeexecution.put(processedclass, cdhashtable);
170 private void printTEST(){
172 Enumeration e = safeexecution.keys();
173 while (e.hasMoreElements()) {
174 ClassDescriptor cdtemp=(ClassDescriptor)e.nextElement();
175 System.out.println("\nTesting class : "+cdtemp.getSymbol()+"\n");
176 Hashtable hashtbtemp = safeexecution.get(cdtemp);
177 Enumeration fses = hashtbtemp.keys();
178 while(fses.hasMoreElements()){
179 FlagState fs = (FlagState)fses.nextElement();
180 System.out.println("\t"+fs.getTextLabel()+"\n\tSafe tasks to execute :\n");
181 HashSet availabletasks = (HashSet)hashtbtemp.get(fs);
182 for(Iterator mos = availabletasks.iterator(); mos.hasNext();){
183 MyOptional mm = (MyOptional)mos.next();
184 System.out.println("\t\tTASK "+mm.td.getSymbol()+"\n");
185 System.out.println("\t\tDepth : "+mm.depth);
186 System.out.println("\t\twith flags :");
187 for(Iterator myfses = mm.flagstates.iterator(); myfses.hasNext();){
188 System.out.println("\t\t\t"+((FlagState)myfses.next()).getTextLabel());
190 System.out.println("\t\tand exitflags :");
191 for(Iterator fseshash = mm.exitfses.iterator(); fseshash.hasNext();){
192 HashSet temphs = (HashSet)fseshash.next();
193 System.out.println("");
194 for(Iterator exfses = temphs.iterator(); exfses.hasNext();){
195 System.out.println("\t\t\t"+((FlagState)exfses.next()).getTextLabel());
198 Predicate predicate = mm.predicate;
199 System.out.println("\t\tPredicate constains :");
200 for(Iterator varit = predicate.vardescriptors.iterator(); varit.hasNext();){
201 VarDescriptor vard = (VarDescriptor)varit.next();
202 System.out.println("\t\t\tClass "+vard.getType().getClassDesc().getSymbol());
204 System.out.println("\t\t------------");
208 System.out.println("\n\n\n\tMyoptionals contains : ");
209 for(Iterator myoit = myoptionals.get(cdtemp).iterator(); myoit.hasNext();){
210 MyOptional mm = (MyOptional)myoit.next();
211 System.out.println("\t\tTASK "+mm.td.getSymbol()+"\n");
212 System.out.println("\t\tDepth : "+mm.depth);
213 System.out.println("\t\twith flags :");
214 for(Iterator myfses = mm.flagstates.iterator(); myfses.hasNext();){
215 System.out.println("\t\t\t"+((FlagState)myfses.next()).getTextLabel());
217 System.out.println("\t\tand exitflags :");
218 for(Iterator fseshash = mm.exitfses.iterator(); fseshash.hasNext();){
219 HashSet temphs = (HashSet)fseshash.next();
220 System.out.println("");
221 for(Iterator exfses = temphs.iterator(); exfses.hasNext();){
222 System.out.println("\t\t\t"+((FlagState)exfses.next()).getTextLabel());
225 Predicate predicate = mm.predicate;
226 System.out.println("\t\tPredicate constains :");
227 for(Iterator varit = predicate.vardescriptors.iterator(); varit.hasNext();){
228 VarDescriptor vard = (VarDescriptor)varit.next();
229 System.out.println("\t\t\tClass "+vard.getType().getClassDesc().getSymbol());
231 System.out.println("\t\t------------");
238 /*Marks the executiongraph :
243 private void doGraphMarking(EGTaskNode extremity) throws java.io.IOException{
244 //detects if there is a loop or no more nodes to explore
245 if (extremity.isMarked() || !((Iterator)extremity.edges()).hasNext()){
246 if (!((Iterator)extremity.edges()).hasNext()) extremity.mark();
247 reducedgraph.put(extremity.getuid(), extremity);
252 reducedgraph.put(extremity.getuid(), extremity);
254 //calls doGraphMarking recursively with the next nodes as params
255 for( Iterator it = extremity.edges(); it.hasNext(); ){
256 EGEdge edge = (EGEdge)it.next();
257 doGraphMarking((EGTaskNode)edge.getTarget());
262 private void process(EGTaskNode tn){
265 testIfNextIsSelfLoop(tn);
270 private void testIfOptional(EGTaskNode tn){
271 for(Iterator edges = tn.edges(); edges.hasNext();){
272 EGEdge edge = (EGEdge)edges.next();
273 EGTaskNode nexttn = (EGTaskNode)edge.getTarget();
274 if (nexttn.getTD()!=null)
275 if(nexttn.getTD().isOptional(classname))
276 nexttn.setOptional();
280 private void testIfMultiple(EGTaskNode tn){
281 for(Iterator edges = tn.edges(); edges.hasNext();){
282 EGEdge edge = (EGEdge)edges.next();
283 EGTaskNode nexttn = (EGTaskNode)edge.getTarget();
284 if (nexttn.getTD() == null ) return;//to be fixed
285 if( nexttn.getTD().numParameters() > 1 ){
286 nexttn.setMultipleParams();
291 //maybe a little bug to fix
292 private void testIfRuntime(EGTaskNode tn){
293 for(Iterator edges = tn.edges(); edges.hasNext();){
294 EGEdge edge = (EGEdge)edges.next();
295 EGTaskNode nexttn = (EGTaskNode)edge.getTarget();
296 if( ((String)nexttn.getName()).compareTo("Runtime") == 0 )
301 /*That correspond to the case where it is
302 not possible for us to choose a path of
303 execution. The optional task has to be
304 present in all the possible executions
305 at this point. So we mark the node as an
307 private void testIfAND(EGTaskNode tn){
308 Vector vtemp = new Vector();
309 Vector tomark = new Vector();
310 for(Iterator edges = tn.edges(); edges.hasNext();){
311 EGEdge edge = (EGEdge)edges.next();
312 EGTaskNode nexttn = (EGTaskNode)edge.getTarget();
314 for (Iterator it = vtemp.iterator(); it.hasNext();){
315 EGTaskNode nexttn2 = (EGTaskNode)it.next();
316 if (nexttn.getName()==nexttn2.getName()){
322 if (contains == 0) vtemp.add(nexttn);
325 for(Iterator it2 = tomark.iterator(); it2.hasNext();)
326 ((EGTaskNode)it2.next()).setAND();
329 //maybe little bug to fix
330 private void testIfNextIsSelfLoop(EGTaskNode tn){
331 for(Iterator edges = tn.edges(); edges.hasNext();){
332 EGEdge edge = (EGEdge)edges.next();
333 EGTaskNode nexttn = (EGTaskNode)edge.getTarget();
334 if(nexttn.isSelfLoop()) nexttn.setAND();
339 /*recursive method that returns a set of MyOptionals
340 The computation basically consist in returning the
341 intersection or union of sets depending on the nature
342 of the node : OR -> UNION
344 The method also looks for tag changes.
346 private HashSet determineIfIsSafe(EGTaskNode tn, int depth, HashSet visited, Predicate predicate){
347 Predicate temppredicate = new Predicate();
348 if(tn == null) return null;
351 HashSet temp = new HashSet();
352 if( tn.isMultipleParams() ){
353 if( goodMultiple(tn) ){
354 temppredicate = combinePredicates(predicate, returnPredicate(tn));
355 System.out.println("Good multiple, Optional "+tn.getName());
359 else temppredicate = combinePredicates(temppredicate, predicate);
360 //if the tn is optional and there is no more nodes/presence of a loop
361 //create the MyOptional and return it as a singleton.
362 if( !((Iterator)tn.edges()).hasNext() || tn.isSelfLoop()){
363 HashSet fstemp = new HashSet();
364 fstemp.add(tn.getFS());
365 MyOptional mo = new MyOptional(tn.getTD(), fstemp, depth, temppredicate);
366 myoptionals.get(processedclass).add(mo);
370 else if(visited.contains(tn)){
373 //else compute the edges, create the MyOptional and add it to the set.
375 int newdepth = depth + 1;
377 HashSet newhashset = new HashSet(visited);
378 HashSet fstemp = new HashSet();
379 fstemp.add(tn.getFS());
380 MyOptional mo = new MyOptional(tn.getTD(), fstemp, depth, temppredicate);
381 myoptionals.get(processedclass).add(mo);
382 temp = computeEdges(tn, newdepth, newhashset, temppredicate);
388 HashSet temp = new HashSet();
389 if( tn.isMultipleParams() ){
390 if( goodMultiple(tn) ){
391 temppredicate = combinePredicates(predicate, returnPredicate(tn));
392 System.out.println("Good multiple, not Optional "+tn.getName());
395 System.out.println("Bad multiple, not Optional "+tn.getName());
399 else temppredicate = combinePredicates(temppredicate, predicate);
400 //if not optional but terminal just return an empty set.
401 if( !((Iterator)tn.edges()).hasNext() || visited.contains(tn) || tn.isSelfLoop()){
404 //if not terminal return the computation of the edges.
406 int newdepth = depth + 1;
408 HashSet newhashset = new HashSet(visited);
409 return computeEdges(tn, newdepth, newhashset, temppredicate);
413 //if there has been a tag change return an empty set.
415 HashSet temp = new HashSet();
420 private boolean goodMultiple(EGTaskNode tn){
421 TaskDescriptor td = tn.getTD();
422 HashSet classes = new HashSet();
423 for(int i = 0 ; i<td.numParameters(); i++){
424 ClassDescriptor cd = td.getParamType(i).getClassDesc();
425 if(cd.getSymbol().compareTo(classname)!=0)
430 Stack stack = new Stack();
431 FlatMethod fm = state.getMethodFlat(td);
432 FlatNode fn = (FlatNode)fm;
434 Stack nodestack=new Stack();
435 HashSet discovered=new HashSet();
439 //Iterating through the nodes
440 while(!nodestack.isEmpty()) {
441 FlatNode fn1 = (FlatNode) nodestack.pop();
442 if (fn1.kind()==FKind.FlatFlagActionNode) {
443 FlatFlagActionNode ffan=(FlatFlagActionNode)fn1;
444 if (ffan.getTaskType() == FlatFlagActionNode.TASKEXIT) {
445 for(Iterator it_tfp=ffan.getTempFlagPairs();it_tfp.hasNext();) {
446 TempFlagPair tfp=(TempFlagPair)it_tfp.next();
447 TempDescriptor tempd = tfp.getTemp();
448 if (classes.contains((ClassDescriptor)((TypeDescriptor)tempd.getType()).getClassDesc()))
451 continue; // avoid queueing the return node if reachable
454 /* Queue other nodes past this one */
455 for(int i=0;i<fn1.numNext();i++) {
456 FlatNode fnext=fn1.getNext(i);
457 if (!discovered.contains(fnext)) {
458 discovered.add(fnext);
459 nodestack.push(fnext);
467 private Predicate returnPredicate(EGTaskNode tn){
468 Predicate result = new Predicate();
469 TaskDescriptor td = tn.getTD();
470 for(int i=0; i<td.numParameters(); i++){
471 TypeDescriptor typed = td.getParamType(i);
472 if(((ClassDescriptor)typed.getClassDesc()).getSymbol().compareTo(classname)!=0){
473 VarDescriptor vd = td.getParameter(i);
474 result.vardescriptors.add(vd);
475 HashSet flaglist = new HashSet();
476 flaglist.add((FlagExpressionNode)td.getFlag(vd));
477 result.flags.put( vd, flaglist);
478 if((TagExpressionList)td.getTag(vd) != null)
479 result.tags.put( vd, (TagExpressionList)td.getTag(vd));
485 /*check if there has been a tag Change*/
486 private boolean tagChange(EGTaskNode tn){
487 if(tn.getTD() == null) return false;//to be fixed
488 FlatMethod fm = state.getMethodFlat(tn.getTD());
489 FlatNode fn = (FlatNode)fm;
491 Stack nodestack=new Stack();
492 HashSet discovered=new HashSet();
496 //Iterating through the nodes
497 while(!nodestack.isEmpty()) {
498 FlatNode fn1 = (FlatNode) nodestack.pop();
499 if (fn1.kind()==FKind.FlatFlagActionNode) {
500 FlatFlagActionNode ffan=(FlatFlagActionNode)fn1;
501 if (ffan.getTaskType() == FlatFlagActionNode.TASKEXIT) {
502 Iterator it_ttp=ffan.getTempTagPairs();
503 if(it_ttp.hasNext()){
504 System.out.println("Tag change detected in Task "+tn.getName());
507 else continue; // avoid queueing the return node if reachable
511 /* Queue other nodes past this one */
512 for(int i=0;i<fn1.numNext();i++) {
513 FlatNode fnext=fn1.getNext(i);
514 if (!discovered.contains(fnext)) {
515 discovered.add(fnext);
516 nodestack.push(fnext);
524 private HashSet computeEdges(EGTaskNode tn, int depth, HashSet visited, Predicate predicate){
525 Hashtable andlist = new Hashtable();
526 Vector orlist = new Vector();
527 for(Iterator edges = tn.edges(); edges.hasNext();){
528 EGTaskNode tntemp = (EGTaskNode)((EGEdge)edges.next()).getTarget();
529 if(tntemp.type() == OR) orlist.add(tntemp);
530 else if(tntemp.type() == AND){
531 if(andlist.containsKey(tntemp.getName())){
532 ((Vector)andlist.get(tntemp.getName())).add(tntemp);}
534 Vector vector = new Vector();
536 andlist.put(tntemp.getName(), vector);
541 return (createUnion(computeOrVector(orlist, depth, visited, predicate), computeAndList(andlist, depth, visited, predicate)));
544 private HashSet computeTns(Vector tns){
545 Hashtable andlist = new Hashtable();
546 Vector orlist = new Vector();
547 for(Iterator nodes = tns.iterator(); nodes.hasNext();){
548 EGTaskNode tntemp = (EGTaskNode)nodes.next();
549 if(tntemp.type() == OR) orlist.add(tntemp);
550 else if(tntemp.type() == AND){
551 if(andlist.containsKey(tntemp.getName())){
552 ((Vector)andlist.get(tntemp.getName())).add(tntemp);}
554 Vector vector = new Vector();
556 andlist.put(tntemp.getName(), vector);
561 return (createUnion(computeOrVector(orlist, 0), computeAndList(andlist, 0)));
565 private HashSet computeOrVector( Vector orlist, int depth, HashSet visited, Predicate predicate){
566 if(orlist.isEmpty()){
567 HashSet temp = new HashSet();
571 HashSet temp = new HashSet();
572 for(Iterator tns = orlist.iterator(); tns.hasNext();){
573 EGTaskNode tn = (EGTaskNode)tns.next();
574 temp = createUnion(determineIfIsSafe(tn, depth, visited, predicate), temp);
581 private HashSet computeOrVector( Vector orlist, int depth){
582 if(orlist.isEmpty()){
583 HashSet temp = new HashSet();
587 HashSet temp = new HashSet();
588 for(Iterator tns = orlist.iterator(); tns.hasNext();){
589 EGTaskNode tn = (EGTaskNode)tns.next();
590 HashSet visited = new HashSet();
591 Predicate predicate = new Predicate();
592 temp = createUnion(determineIfIsSafe(tn, depth, visited, predicate), temp);
599 private HashSet computeAndList(Hashtable andlist, int depth, HashSet visited, Predicate predicate){
600 if( andlist.isEmpty()){
601 HashSet temp = new HashSet();
605 HashSet temp = new HashSet();
606 Collection c = andlist.values();
607 for(Iterator vectors = c.iterator(); vectors.hasNext();){
608 Vector vector = (Vector)vectors.next();
609 temp = createUnion(computeAndVector(vector, depth, visited, predicate), temp);
616 private HashSet computeAndList(Hashtable andlist, int depth){
617 if( andlist.isEmpty()){
618 HashSet temp = new HashSet();
622 HashSet temp = new HashSet();
623 Collection c = andlist.values();
624 for(Iterator vectors = c.iterator(); vectors.hasNext();){
625 Vector vector = (Vector)vectors.next();
626 temp = createUnion(computeAndVector(vector, depth), temp);
633 private HashSet computeAndVector(Vector vector, int depth, HashSet visited, Predicate predicate){
634 HashSet temp = new HashSet();
636 for(Iterator tns = vector.iterator(); tns.hasNext();){
637 EGTaskNode tn = (EGTaskNode)tns.next();
640 temp = determineIfIsSafe(tn, depth, visited, predicate);
643 temp = createIntersection(determineIfIsSafe(tn, depth, visited, predicate), temp);
649 private HashSet computeAndVector(Vector vector, int depth){
650 HashSet temp = new HashSet();
652 for(Iterator tns = vector.iterator(); tns.hasNext();){
653 EGTaskNode tn = (EGTaskNode)tns.next();
656 HashSet visited = new HashSet();
657 Predicate predicate = new Predicate();
658 temp = determineIfIsSafe(tn, depth, visited, predicate);
661 HashSet visited = new HashSet();
662 Predicate predicate = new Predicate();
663 temp = createIntersection(determineIfIsSafe(tn, depth, visited, predicate), temp);
669 private HashSet createUnion( HashSet A, HashSet B){
675 /*private void removeDoubles( HashSet A ){
676 //remove duplicated MyOptionals (might happend in few cases)
677 Vector toremove = new Vector();
679 for(Iterator itA = A.iterator(); itA.hasNext();){
680 MyOptional myA = (MyOptional)itA.next();
682 Iterator itA2 = A.iterator();
683 for(int j = 0; j<i; j++){
686 for(Iterator itA3 = itA2; itA3.hasNext();){
687 MyOptional myA2 = (MyOptional)itA3.next();
689 //myA.depth = (myA.depth < myA2.depth) ? myA.depth : myA2.depth;
691 System.out.println("removed!");
695 for( Iterator it = toremove.iterator(); it.hasNext();)
699 private HashSet createIntersection( HashSet A, HashSet B){
700 HashSet result = new HashSet();
701 for(Iterator itB = B.iterator(); itB.hasNext();){
702 MyOptional myB = (MyOptional)itB.next();
703 for(Iterator itA = A.iterator(); itA.hasNext();){
704 MyOptional myA = (MyOptional)itA.next();
705 if(((String)myA.td.getSymbol()).compareTo((String)myB.td.getSymbol())==0){
706 HashSet newfs = new HashSet();
707 newfs.addAll(myA.flagstates);
708 newfs.addAll(myB.flagstates);
709 int newdepth = (myA.depth < myB.depth) ? myA.depth : myB.depth;
710 MyOptional newmy = new MyOptional(myB.td, newfs, newdepth, combinePredicates(myA.predicate, myB.predicate));
718 private Predicate combinePredicates(Predicate A, Predicate B){
719 Predicate result = new Predicate();
720 result.vardescriptors.addAll(A.vardescriptors);
721 for(Iterator varit = B.vardescriptors.iterator(); varit.hasNext();){
722 VarDescriptor vd = (VarDescriptor)varit.next();
723 if(result.vardescriptors.contains(vd))System.out.println("Already in ");
725 System.out.println("Not already in...");
726 result.vardescriptors.add(vd);
729 for(Iterator varit = result.vardescriptors.iterator(); varit.hasNext();){
730 VarDescriptor vd = (VarDescriptor)varit.next();
731 HashSet bflags = B.flags.get(vd);
732 if( bflags == null ){
733 System.out.println("not in B");
737 if (result.flags.containsKey(vd)) ((HashSet)result.flags.get(vd)).addAll(bflags);
738 else result.flags.put(vd, bflags);
740 TagExpressionList btags = B.tags.get(vd);
742 if (result.tags.containsKey(vd)) System.out.println("There should be nothing to do because same tag");
743 else result.tags.put(vd, btags);
750 /*Thoose two tasks create the dot file named markedgraph.dot */
752 private void createDOTFile(String classname) throws java.io.IOException {
753 Collection v = reducedgraph.values();
754 java.io.PrintWriter output;
755 File dotfile_flagstates= new File("markedgraph_"+classname+".dot");
756 FileOutputStream dotstream=new FileOutputStream(dotfile_flagstates,true);
757 output = new java.io.PrintWriter(dotstream, true);
758 output.println("digraph dotvisitor {");
759 output.println("\tnode [fontsize=10,height=\"0.1\", width=\"0.1\"];");
760 output.println("\tedge [fontsize=6];");
762 output.println("}\n");
765 private void traverse(java.io.PrintWriter output, Collection v) {
768 for(Iterator it1 = v.iterator(); it1.hasNext();){
769 tn = (EGTaskNode)it1.next();
770 output.println("\t"+tn.getLabel()+" [label=\""+tn.getTextLabel()+"\"");
771 if (tn.isOptional()){
772 if (tn.isMultipleParams()) output.println(", shape = tripleoctagon");
773 else output.println(", shape=doubleoctagon");
775 else if (tn.isMultipleParams()) output.println(", shape=octagon");
776 if (tn.type()==AND) output.println(", color=blue");
777 output.println("];");
779 for(Iterator it2 = tn.edges();it2.hasNext();){
780 EGTaskNode tn2 = (EGTaskNode)((Edge)it2.next()).getTarget();
781 output.println("\t"+tn.getLabel()+" -> "+tn2.getLabel()+";");
787 /* returns a set of the possible sets of flagstates
788 resulting from the execution of the optional task.
789 To do it with have to look for TaskExit FlatNodes
792 private void resultingFS(MyOptional mo, String classname){
793 Stack stack = new Stack();
794 HashSet result = new HashSet();
795 FlatMethod fm = state.getMethodFlat((TaskDescriptor)mo.td);
796 FlatNode fn = (FlatNode)fm;
798 Stack nodestack=new Stack();
799 HashSet discovered=new HashSet();
803 //Iterating through the nodes
804 while(!nodestack.isEmpty()) {
805 FlatNode fn1 = (FlatNode) nodestack.pop();
806 if (fn1.kind()==FKind.FlatFlagActionNode) {
807 FlatFlagActionNode ffan=(FlatFlagActionNode)fn1;
808 if (ffan.getTaskType() == FlatFlagActionNode.TASKEXIT) {
810 //System.out.println("TASKEXIT");
812 HashSet tempset = new HashSet();
813 for(Iterator it_fs = mo.flagstates.iterator(); it_fs.hasNext();){
814 FlagState fstemp = (FlagState)it_fs.next();
815 for(Iterator it_tfp=ffan.getTempFlagPairs();it_tfp.hasNext();) {
816 TempFlagPair tfp=(TempFlagPair)it_tfp.next();
817 TempDescriptor td = tfp.getTemp();
818 if (((String)((ClassDescriptor)((TypeDescriptor)td.getType()).getClassDesc()).getSymbol()).compareTo(classname)==0){
819 fstemp=fstemp.setFlag(tfp.getFlag(),ffan.getFlagChange(tfp));
822 //System.out.println("new flag : "+fstemp.getTextLabel());
826 continue; // avoid queueing the return node if reachable
828 }else if (fn1.kind()==FKind.FlatReturnNode) {
830 //System.out.println("RETURN NODE REACHABLE WITHOUT TASKEXITS");
832 result.add(mo.flagstates);
835 /* Queue other nodes past this one */
836 for(int i=0;i<fn1.numNext();i++) {
837 FlatNode fnext=fn1.getNext(i);
838 if (!discovered.contains(fnext)) {
839 discovered.add(fnext);
840 nodestack.push(fnext);