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, Hashtable> optionaltaskdescriptors;
24 private ClassDescriptor processedclass;
27 public Hashtable<ClassDescriptor, Hashtable<FlagState, HashSet>> getResult(){
31 public Hashtable<ClassDescriptor, Hashtable> getOptionalTaskDescriptors(){
32 return optionaltaskdescriptors;
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.optionaltaskdescriptors = 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 Hashtable newhashtable = new Hashtable();
107 optionaltaskdescriptors.put(processedclass, newhashtable);
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.");
117 } else if (nodes.size()==0) {
118 System.out.println("Nothing to do");
123 EGTaskNode sourcenode = findSourceNode(nodes);
124 doGraphMarking(sourcenode);
125 createDOTFile( classname );
126 reducedgraph.clear();
128 Collection fses = ((Hashtable)taskanalysis.flagstates.get(processedclass)).values();
129 Iterator itfses = fses.iterator();
130 while (itfses.hasNext()) {
131 FlagState fs = (FlagState)itfses.next();
132 Hashtable fsresult = new Hashtable();
133 //get the tasknodes possible to execute with the flagstate before failure
134 HashSet tempnodes = new HashSet();
135 Vector tns = new Vector();
136 System.out.println("Analysing "+fs.getTextLabel());
137 tns = findEGTaskNode(fs.getTextLabel(), nodes);
139 System.out.println("\tNo task corresponding, terminal FS");
142 System.out.println("\tProcessing...");
144 //compute the result for all the nodes contained in tns.
145 //return the intersection of tns that are the same task and union for others.
147 HashSet availabletasks = new HashSet();
148 availabletasks = computeTns(tns);
150 //removeDoubles(availabletasks);
152 for(Iterator it = availabletasks.iterator(); it.hasNext();){
153 OptionalTaskDescriptor otd = (OptionalTaskDescriptor)it.next();
154 resultingFS(otd, classname);
157 cdhashtable.put(fs, availabletasks);
160 safeexecution.put(processedclass, cdhashtable);
163 putinoptionaltaskdescriptors();
169 private void putinoptionaltaskdescriptors(){
170 Enumeration e = safeexecution.keys();
171 while (e.hasMoreElements()) {
172 ClassDescriptor cdtemp=(ClassDescriptor)e.nextElement();
173 optionaltaskdescriptors.get(cdtemp).clear();
174 Hashtable hashtbtemp = safeexecution.get(cdtemp);
175 Enumeration fses = hashtbtemp.keys();
176 while(fses.hasMoreElements()){
177 FlagState fs = (FlagState)fses.nextElement();
178 HashSet availabletasks = (HashSet)hashtbtemp.get(fs);
179 for(Iterator otd_it = availabletasks.iterator(); otd_it.hasNext();){
180 OptionalTaskDescriptor otd = (OptionalTaskDescriptor)otd_it.next();
181 optionaltaskdescriptors.get(cdtemp).put(otd, otd);
187 private void printTEST(){
188 Enumeration e = safeexecution.keys();
189 while (e.hasMoreElements()) {
190 ClassDescriptor cdtemp=(ClassDescriptor)e.nextElement();
191 System.out.println("\nTesting class : "+cdtemp.getSymbol()+"\n");
192 Hashtable hashtbtemp = safeexecution.get(cdtemp);
193 Enumeration fses = hashtbtemp.keys();
194 while(fses.hasMoreElements()){
195 FlagState fs = (FlagState)fses.nextElement();
196 System.out.println("\t"+fs.getTextLabel()+"\n\tSafe tasks to execute :\n");
197 HashSet availabletasks = (HashSet)hashtbtemp.get(fs);
198 for(Iterator otd_it = availabletasks.iterator(); otd_it.hasNext();){
199 OptionalTaskDescriptor otd = (OptionalTaskDescriptor)otd_it.next();
200 System.out.println("\t\tTASK "+otd.td.getSymbol()+" UID : "+otd.getuid()+"\n");
201 System.out.println("\t\tDepth : "+otd.depth);
202 System.out.println("\t\twith flags :");
203 for(Iterator myfses = otd.flagstates.iterator(); myfses.hasNext();){
204 System.out.println("\t\t\t"+((FlagState)myfses.next()).getTextLabel());
206 System.out.println("\t\tand exitflags :");
207 for(Iterator fseshash = otd.exitfses.iterator(); fseshash.hasNext();){
208 HashSet temphs = (HashSet)fseshash.next();
209 System.out.println("");
210 for(Iterator exfses = temphs.iterator(); exfses.hasNext();){
211 System.out.println("\t\t\t"+((FlagState)exfses.next()).getTextLabel());
214 Predicate predicate = otd.predicate;
215 System.out.println("\t\tPredicate constains :");
216 Collection c = predicate.vardescriptors.values();
217 for(Iterator varit = c.iterator(); varit.hasNext();){
218 VarDescriptor vard = (VarDescriptor)varit.next();
219 System.out.println("\t\t\tClass "+vard.getType().getClassDesc().getSymbol());
221 System.out.println("\t\t------------");
225 System.out.println("\n\n\n\tOptionaltaskdescriptors contains : ");
226 Collection c_otd = optionaltaskdescriptors.get(cdtemp).values();
227 for(Iterator otd_it = c_otd.iterator(); otd_it.hasNext();){
228 OptionalTaskDescriptor otd = (OptionalTaskDescriptor)otd_it.next();
229 System.out.println("\t\tTASK "+otd.td.getSymbol()+" UID : "+otd.getuid()+"\n");
230 System.out.println("\t\tDepth : "+otd.depth);
231 System.out.println("\t\twith flags :");
232 for(Iterator myfses = otd.flagstates.iterator(); myfses.hasNext();){
233 System.out.println("\t\t\t"+((FlagState)myfses.next()).getTextLabel());
235 System.out.println("\t\tand exitflags :");
236 for(Iterator fseshash = otd.exitfses.iterator(); fseshash.hasNext();){
237 HashSet temphs = (HashSet)fseshash.next();
238 System.out.println("");
239 for(Iterator exfses = temphs.iterator(); exfses.hasNext();){
240 System.out.println("\t\t\t"+((FlagState)exfses.next()).getTextLabel());
243 Predicate predicate = otd.predicate;
244 System.out.println("\t\tPredicate contains :");
245 Collection c = predicate.vardescriptors.values();
246 for(Iterator varit = c.iterator(); varit.hasNext();){
247 VarDescriptor vard = (VarDescriptor)varit.next();
248 System.out.println("\t\t\tClass "+vard.getType().getClassDesc().getSymbol());
249 HashSet temphash = predicate.flags.get(vard.getName());
250 if(temphash == null) System.out.println("null hashset");
251 else System.out.println("\t\t\t"+temphash.size()+" flag(s)");
254 System.out.println("\t\t------------");
261 /*Marks the executiongraph :
266 private void doGraphMarking(EGTaskNode extremity) throws java.io.IOException{
267 //detects if there is a loop or no more nodes to explore
268 if (extremity.isMarked() || !((Iterator)extremity.edges()).hasNext()){
269 if (!((Iterator)extremity.edges()).hasNext()) extremity.mark();
270 reducedgraph.put(extremity.getuid(), extremity);
274 reducedgraph.put(extremity.getuid(), extremity);
276 //calls doGraphMarking recursively with the next nodes as
278 for( Iterator it = extremity.edges(); it.hasNext(); ){
279 EGEdge edge = (EGEdge)it.next();
280 doGraphMarking((EGTaskNode)edge.getTarget());
285 private void process(EGTaskNode tn){
288 testIfNextIsSelfLoop(tn);
293 private void testIfOptional(EGTaskNode tn){
294 for(Iterator edges = tn.edges(); edges.hasNext();){
295 EGEdge edge = (EGEdge)edges.next();
296 EGTaskNode nexttn = (EGTaskNode)edge.getTarget();
297 if (nexttn.getTD()!=null)
298 if(nexttn.getTD().isOptional(classname))
299 nexttn.setOptional();
303 private void testIfMultiple(EGTaskNode tn){
304 for(Iterator edges = tn.edges(); edges.hasNext();){
305 EGEdge edge = (EGEdge)edges.next();
306 EGTaskNode nexttn = (EGTaskNode)edge.getTarget();
307 if (nexttn.getTD() == null ) return;//to be fixed
308 if( nexttn.getTD().numParameters() > 1 ){
309 nexttn.setMultipleParams();
314 //maybe a little bug to fix
315 private void testIfRuntime(EGTaskNode tn){
316 for(Iterator edges = tn.edges(); edges.hasNext();){
317 EGEdge edge = (EGEdge)edges.next();
318 EGTaskNode nexttn = (EGTaskNode)edge.getTarget();
319 if( ((String)nexttn.getName()).compareTo("Runtime") == 0 )
324 /*That correspond to the case where it is
325 not possible for us to choose a path of
326 execution. The optional task has to be
327 present in all the possible executions
328 at this point. So we mark the node as an
330 private void testIfAND(EGTaskNode tn){
331 Vector vtemp = new Vector();
332 Vector tomark = new Vector();
333 for(Iterator edges = tn.edges(); edges.hasNext();){
334 EGEdge edge = (EGEdge)edges.next();
335 EGTaskNode nexttn = (EGTaskNode)edge.getTarget();
337 for (Iterator it = vtemp.iterator(); it.hasNext();){
338 EGTaskNode nexttn2 = (EGTaskNode)it.next();
339 if (nexttn.getName()==nexttn2.getName()){
345 if (contains == 0) vtemp.add(nexttn);
348 for(Iterator it2 = tomark.iterator(); it2.hasNext();)
349 ((EGTaskNode)it2.next()).setAND();
352 //maybe little bug to fix
353 private void testIfNextIsSelfLoop(EGTaskNode tn){
354 for(Iterator edges = tn.edges(); edges.hasNext();){
355 EGEdge edge = (EGEdge)edges.next();
356 EGTaskNode nexttn = (EGTaskNode)edge.getTarget();
357 if(nexttn.isSelfLoop()) nexttn.setAND();
362 /*recursive method that returns a set of OptionalTaskDescriptors
363 The computation basically consist in returning the
364 intersection or union of sets depending on the nature
365 of the node : OR -> UNION
367 The method also looks for tag changes.
369 private HashSet determineIfIsSafe(EGTaskNode tn, int depth, HashSet visited, Predicate predicate){
370 Predicate temppredicate = new Predicate();
371 if(tn == null) return null;
374 HashSet temp = new HashSet();
375 if( tn.isMultipleParams() ){
376 if( goodMultiple(tn) ){
377 temppredicate = combinePredicates(predicate, returnPredicate(tn));
378 System.out.println("Good multiple, Optional "+tn.getName());
382 else temppredicate = combinePredicates(temppredicate, predicate);
383 //if the tn is optional and there is no more nodes/presence of a loop
384 //create the OptionalTaskDescriptor and return it as a singleton.
385 if( !((Iterator)tn.edges()).hasNext() || tn.isSelfLoop()){
386 HashSet fstemp = new HashSet();
387 fstemp.add(tn.getFS());
388 OptionalTaskDescriptor otd = new OptionalTaskDescriptor(tn.getTD(), fstemp, depth, temppredicate);
389 if(optionaltaskdescriptors.get(processedclass).get(otd)!=null){
390 otd = (OptionalTaskDescriptor)((Hashtable)optionaltaskdescriptors.get(processedclass)).get(otd);
392 else optionaltaskdescriptors.get(processedclass).put(otd, otd);
396 else if(visited.contains(tn)){
399 //else compute the edges, create the OptionalTaskDescriptor and add it to the set.
401 int newdepth = depth + 1;
403 HashSet newhashset = new HashSet(visited);
404 HashSet fstemp = new HashSet();
405 fstemp.add(tn.getFS());
406 OptionalTaskDescriptor otd = new OptionalTaskDescriptor(tn.getTD(), fstemp, depth, temppredicate);
407 if(optionaltaskdescriptors.get(processedclass).get(otd)!=null){
408 otd = (OptionalTaskDescriptor)((Hashtable)optionaltaskdescriptors.get(processedclass)).get(otd);
410 else optionaltaskdescriptors.get(processedclass).put(otd, otd);
411 temp = computeEdges(tn, newdepth, newhashset, temppredicate);
417 HashSet temp = new HashSet();
418 if( tn.isMultipleParams() ){
419 if( goodMultiple(tn) ){
420 temppredicate = combinePredicates(predicate, returnPredicate(tn));
421 System.out.println("Good multiple, not Optional "+tn.getName());
424 System.out.println("Bad multiple, not Optional "+tn.getName());
428 else temppredicate = combinePredicates(temppredicate, predicate);
429 //if not optional but terminal just return an empty set.
430 if( !((Iterator)tn.edges()).hasNext() || visited.contains(tn) || tn.isSelfLoop()){
433 //if not terminal return the computation of the edges.
435 int newdepth = depth + 1;
437 HashSet newhashset = new HashSet(visited);
438 return computeEdges(tn, newdepth, newhashset, temppredicate);
442 //if there has been a tag change return an empty set.
444 HashSet temp = new HashSet();
449 private boolean goodMultiple(EGTaskNode tn){
450 TaskDescriptor td = tn.getTD();
451 HashSet classes = new HashSet();
452 for(int i = 0 ; i<td.numParameters(); i++){
453 ClassDescriptor cd = td.getParamType(i).getClassDesc();
454 if(cd.getSymbol().compareTo(classname)!=0)
459 Stack stack = new Stack();
460 FlatMethod fm = state.getMethodFlat(td);
461 FlatNode fn = (FlatNode)fm;
463 Stack nodestack=new Stack();
464 HashSet discovered=new HashSet();
468 //Iterating through the nodes
469 while(!nodestack.isEmpty()) {
470 FlatNode fn1 = (FlatNode) nodestack.pop();
471 if (fn1.kind()==FKind.FlatFlagActionNode) {
472 FlatFlagActionNode ffan=(FlatFlagActionNode)fn1;
473 if (ffan.getTaskType() == FlatFlagActionNode.TASKEXIT) {
474 for(Iterator it_tfp=ffan.getTempFlagPairs();it_tfp.hasNext();) {
475 TempFlagPair tfp=(TempFlagPair)it_tfp.next();
476 TempDescriptor tempd = tfp.getTemp();
477 if (classes.contains((ClassDescriptor)((TypeDescriptor)tempd.getType()).getClassDesc()))
478 return false;//return false if a taskexit modifies one of the other parameters
480 continue; // avoid queueing the return node if reachable
483 /* Queue other nodes past this one */
484 for(int i=0;i<fn1.numNext();i++) {
485 FlatNode fnext=fn1.getNext(i);
486 if (!discovered.contains(fnext)) {
487 discovered.add(fnext);
488 nodestack.push(fnext);
496 private Predicate returnPredicate(EGTaskNode tn){
497 Predicate result = new Predicate();
498 TaskDescriptor td = tn.getTD();
499 for(int i=0; i<td.numParameters(); i++){
500 TypeDescriptor typed = td.getParamType(i);
501 if(((ClassDescriptor)typed.getClassDesc()).getSymbol().compareTo(classname)!=0){
502 VarDescriptor vd = td.getParameter(i);
503 result.vardescriptors.put(vd.getName(), vd);
504 HashSet flaglist = new HashSet();
505 flaglist.add((FlagExpressionNode)td.getFlag(vd));
506 result.flags.put( vd.getName(), flaglist);
507 if((TagExpressionList)td.getTag(vd) != null)
508 result.tags.put( vd.getName(), (TagExpressionList)td.getTag(vd));
514 /*check if there has been a tag Change*/
515 private boolean tagChange(EGTaskNode tn){
516 if(tn.getTD() == null) return false;//to be fixed
517 FlatMethod fm = state.getMethodFlat(tn.getTD());
518 FlatNode fn = (FlatNode)fm;
520 Stack nodestack=new Stack();
521 HashSet discovered=new HashSet();
525 //Iterating through the nodes
526 while(!nodestack.isEmpty()) {
527 FlatNode fn1 = (FlatNode) nodestack.pop();
528 if (fn1.kind()==FKind.FlatFlagActionNode) {
529 FlatFlagActionNode ffan=(FlatFlagActionNode)fn1;
530 if (ffan.getTaskType() == FlatFlagActionNode.TASKEXIT) {
531 Iterator it_ttp=ffan.getTempTagPairs();
532 if(it_ttp.hasNext()){
533 System.out.println("Tag change detected in Task "+tn.getName());
536 else continue; // avoid queueing the return node if reachable
540 /* Queue other nodes past this one */
541 for(int i=0;i<fn1.numNext();i++) {
542 FlatNode fnext=fn1.getNext(i);
543 if (!discovered.contains(fnext)) {
544 discovered.add(fnext);
545 nodestack.push(fnext);
553 private HashSet computeEdges(EGTaskNode tn, int depth, HashSet visited, Predicate predicate){
554 Hashtable andlist = new Hashtable();
555 Vector orlist = new Vector();
556 for(Iterator edges = tn.edges(); edges.hasNext();){
557 EGTaskNode tntemp = (EGTaskNode)((EGEdge)edges.next()).getTarget();
558 if(tntemp.type() == OR) orlist.add(tntemp);
559 else if(tntemp.type() == AND){
560 if(andlist.containsKey(tntemp.getName())){
561 ((Vector)andlist.get(tntemp.getName())).add(tntemp);}
563 Vector vector = new Vector();
565 andlist.put(tntemp.getName(), vector);
570 return (createUnion(computeOrVector(orlist, depth, visited, predicate), computeAndList(andlist, depth, visited, predicate)));
573 private HashSet computeTns(Vector tns){
574 Hashtable andlist = new Hashtable();
575 Vector orlist = new Vector();
576 for(Iterator nodes = tns.iterator(); nodes.hasNext();){
577 EGTaskNode tntemp = (EGTaskNode)nodes.next();
578 if(tntemp.type() == OR) orlist.add(tntemp);
579 else if(tntemp.type() == AND){
580 if(andlist.containsKey(tntemp.getName())){
581 ((Vector)andlist.get(tntemp.getName())).add(tntemp);}
583 Vector vector = new Vector();
585 andlist.put(tntemp.getName(), vector);
590 return (createUnion(computeOrVector(orlist, 0), computeAndList(andlist, 0)));
594 private HashSet computeOrVector( Vector orlist, int depth, HashSet visited, Predicate predicate){
595 if(orlist.isEmpty()){
596 HashSet temp = new HashSet();
600 HashSet temp = new HashSet();
601 for(Iterator tns = orlist.iterator(); tns.hasNext();){
602 EGTaskNode tn = (EGTaskNode)tns.next();
603 temp = createUnion(determineIfIsSafe(tn, depth, visited, predicate), temp);
610 private HashSet computeOrVector( Vector orlist, int depth){
611 if(orlist.isEmpty()){
612 HashSet temp = new HashSet();
616 HashSet temp = new HashSet();
617 for(Iterator tns = orlist.iterator(); tns.hasNext();){
618 EGTaskNode tn = (EGTaskNode)tns.next();
619 HashSet visited = new HashSet();
620 Predicate predicate = new Predicate();
621 temp = createUnion(determineIfIsSafe(tn, depth, visited, predicate), temp);
628 private HashSet computeAndList(Hashtable andlist, int depth, HashSet visited, Predicate predicate){
629 if( andlist.isEmpty()){
630 HashSet temp = new HashSet();
634 HashSet temp = new HashSet();
635 Collection c = andlist.values();
636 for(Iterator vectors = c.iterator(); vectors.hasNext();){
637 Vector vector = (Vector)vectors.next();
638 temp = createUnion(computeAndVector(vector, depth, visited, predicate), temp);
645 private HashSet computeAndList(Hashtable andlist, int depth){
646 if( andlist.isEmpty()){
647 HashSet temp = new HashSet();
651 HashSet temp = new HashSet();
652 Collection c = andlist.values();
653 for(Iterator vectors = c.iterator(); vectors.hasNext();){
654 Vector vector = (Vector)vectors.next();
655 temp = createUnion(computeAndVector(vector, depth), temp);
662 private HashSet computeAndVector(Vector vector, int depth, HashSet visited, Predicate predicate){
663 HashSet temp = new HashSet();
665 for(Iterator tns = vector.iterator(); tns.hasNext();){
666 EGTaskNode tn = (EGTaskNode)tns.next();
669 temp = determineIfIsSafe(tn, depth, visited, predicate);
672 temp = createIntersection(determineIfIsSafe(tn, depth, visited, predicate), temp);
678 private HashSet computeAndVector(Vector vector, int depth){
679 HashSet temp = new HashSet();
681 for(Iterator tns = vector.iterator(); tns.hasNext();){
682 EGTaskNode tn = (EGTaskNode)tns.next();
685 HashSet visited = new HashSet();
686 Predicate predicate = new Predicate();
687 temp = determineIfIsSafe(tn, depth, visited, predicate);
690 HashSet visited = new HashSet();
691 Predicate predicate = new Predicate();
692 temp = createIntersection(determineIfIsSafe(tn, depth, visited, predicate), temp);
698 private HashSet createUnion( HashSet A, HashSet B){
705 private HashSet createIntersection( HashSet A, HashSet B){
706 HashSet result = new HashSet();
707 for(Iterator b_it = B.iterator(); b_it.hasNext();){
708 OptionalTaskDescriptor otd_b = (OptionalTaskDescriptor)b_it.next();
709 for(Iterator a_it = A.iterator(); a_it.hasNext();){
710 OptionalTaskDescriptor otd_a = (OptionalTaskDescriptor)a_it.next();
711 if(((String)otd_a.td.getSymbol()).compareTo((String)otd_b.td.getSymbol())==0){
712 HashSet newfs = new HashSet();
713 newfs.addAll(otd_a.flagstates);
714 newfs.addAll(otd_b.flagstates);
715 int newdepth = (otd_a.depth < otd_b.depth) ? otd_a.depth : otd_b.depth;
716 OptionalTaskDescriptor newotd = new OptionalTaskDescriptor(otd_b.td, newfs, newdepth, combinePredicates(otd_a.predicate, otd_b.predicate));
717 if(optionaltaskdescriptors.get(processedclass).get(newotd)!=null){
718 newotd = (OptionalTaskDescriptor)((Hashtable)optionaltaskdescriptors.get(processedclass)).get(newotd);
720 else optionaltaskdescriptors.get(processedclass).put(newotd, newotd);
729 private Predicate combinePredicates(Predicate A, Predicate B){
730 Predicate result = new Predicate();
731 result.vardescriptors.putAll(A.vardescriptors);
732 result.flags.putAll(A.flags);
733 result.tags.putAll(A.tags);
734 Collection c = B.vardescriptors.values();
735 for(Iterator varit = c.iterator(); varit.hasNext();){//maybe change that
736 VarDescriptor vd = (VarDescriptor)varit.next();
737 if(result.vardescriptors.containsKey(vd.getName())) System.out.println("Already in ");
739 result.vardescriptors.put(vd.getName(), vd);
742 Collection vardesc = result.vardescriptors.values();
743 for(Iterator varit = vardesc.iterator(); varit.hasNext();){
744 VarDescriptor vd = (VarDescriptor)varit.next();
745 HashSet bflags = B.flags.get(vd.getName());
746 if( bflags == null ){
750 if (result.flags.containsKey(vd.getName())) ((HashSet)result.flags.get(vd.getName())).addAll(bflags);
751 else result.flags.put(vd.getName(), bflags);
753 TagExpressionList btags = B.tags.get(vd.getName());
755 if (result.tags.containsKey(vd.getName())) System.out.println("Tag found but there should be nothing to do because same tag");
756 else result.tags.put(vd.getName(), btags);
763 /*Thoose two tasks create the dot file named markedgraph.dot */
765 private void createDOTFile(String classname) throws java.io.IOException {
766 Collection v = reducedgraph.values();
767 java.io.PrintWriter output;
768 File dotfile_flagstates= new File("markedgraph_"+classname+".dot");
769 FileOutputStream dotstream=new FileOutputStream(dotfile_flagstates,true);
770 output = new java.io.PrintWriter(dotstream, true);
771 output.println("digraph dotvisitor {");
772 output.println("\tnode [fontsize=10,height=\"0.1\", width=\"0.1\"];");
773 output.println("\tedge [fontsize=6];");
775 output.println("}\n");
778 private void traverse(java.io.PrintWriter output, Collection v) {
781 for(Iterator it1 = v.iterator(); it1.hasNext();){
782 tn = (EGTaskNode)it1.next();
783 output.println("\t"+tn.getLabel()+" [label=\""+tn.getTextLabel()+"\"");
784 if (tn.isOptional()){
785 if (tn.isMultipleParams()) output.println(", shape = tripleoctagon");
786 else output.println(", shape=doubleoctagon");
788 else if (tn.isMultipleParams()) output.println(", shape=octagon");
789 if (tn.type()==AND) output.println(", color=blue");
790 output.println("];");
792 for(Iterator it2 = tn.edges();it2.hasNext();){
793 EGTaskNode tn2 = (EGTaskNode)((Edge)it2.next()).getTarget();
794 output.println("\t"+tn.getLabel()+" -> "+tn2.getLabel()+";");
800 /* returns a set of the possible sets of flagstates
801 resulting from the execution of the optional task.
802 To do it with have to look for TaskExit FlatNodes
805 private void resultingFS(OptionalTaskDescriptor otd, String classname){
806 Stack stack = new Stack();
807 HashSet result = new HashSet();
808 FlatMethod fm = state.getMethodFlat((TaskDescriptor)otd.td);
809 FlatNode fn = (FlatNode)fm;
811 Stack nodestack=new Stack();
812 HashSet discovered=new HashSet();
816 //Iterating through the nodes
817 while(!nodestack.isEmpty()) {
818 FlatNode fn1 = (FlatNode) nodestack.pop();
819 if (fn1.kind()==FKind.FlatFlagActionNode) {
820 FlatFlagActionNode ffan=(FlatFlagActionNode)fn1;
821 if (ffan.getTaskType() == FlatFlagActionNode.TASKEXIT) {
822 HashSet tempset = new HashSet();
823 for(Iterator it_fs = otd.flagstates.iterator(); it_fs.hasNext();){
824 FlagState fstemp = (FlagState)it_fs.next();
825 for(Iterator it_tfp=ffan.getTempFlagPairs();it_tfp.hasNext();) {
826 TempFlagPair tfp=(TempFlagPair)it_tfp.next();
827 TempDescriptor td = tfp.getTemp();
828 if (((String)((ClassDescriptor)((TypeDescriptor)td.getType()).getClassDesc()).getSymbol()).compareTo(classname)==0){
829 fstemp=fstemp.setFlag(tfp.getFlag(),ffan.getFlagChange(tfp));
835 continue; // avoid queueing the return node if reachable
837 }else if (fn1.kind()==FKind.FlatReturnNode) {
838 result.add(otd.flagstates);
841 /* Queue other nodes past this one */
842 for(int i=0;i<fn1.numNext();i++) {
843 FlatNode fnext=fn1.getNext(i);
844 if (!discovered.contains(fnext)) {
845 discovered.add(fnext);
846 nodestack.push(fnext);