Add web interface. It defaults to port 8000.
[IRC.git] / Robust / src / Analysis / TaskStateAnalysis / FlagState.java
1 package Analysis.TaskStateAnalysis;
2 import Analysis.TaskStateAnalysis.*;
3 import IR.*;
4 import IR.Tree.*;
5 import IR.Flat.*;
6 import java.util.*;
7 import java.io.*;
8 import Util.GraphNode;
9
10 /** This class is used to hold the flag states that a class in the Bristlecone 
11  *  program can exist in, during runtime.
12  */
13 public class FlagState extends GraphNode {
14     public static final int ONETAG=1;
15     public static final int NOTAGS=0;
16     public static final int MULTITAGS=-1;
17     
18     private int uid;
19     private static int nodeid=0;
20
21     private final HashSet flagstate;
22     private final ClassDescriptor cd;
23     private final Hashtable<TagDescriptor,Integer> tags;
24
25     /** Class constructor
26      *  Creates a new flagstate with all flags set to false.
27      *  @param cd ClassDescriptor
28      */
29     public FlagState(ClassDescriptor cd) {
30         this.flagstate=new HashSet();
31         this.cd=cd;
32         this.tags=new Hashtable<TagDescriptor,Integer>();
33         this.uid=FlagState.nodeid++;
34     }
35
36     /** Class constructor
37      *  Creates a new flagstate with flags set according to the HashSet.
38      *  If the flag exists in the hashset, it's set to true else set to false.
39      *  @param cd ClassDescriptor
40      *  @param flagstate a <CODE>HashSet</CODE> containing FlagDescriptors
41      */
42     private FlagState(HashSet flagstate, ClassDescriptor cd,Hashtable<TagDescriptor,Integer> tags) {
43         this.flagstate=flagstate;
44         this.cd=cd;
45         this.tags=tags;
46         this.uid=FlagState.nodeid++;
47         
48     }
49     
50     /** Accessor method
51       *  @param fd FlagDescriptor
52       *  @return true if the flagstate contains fd else false.
53       */
54     public boolean get(FlagDescriptor fd) {
55         return flagstate.contains(fd);
56     }
57
58     
59     public String toString() {
60         return cd.toString()+getTextLabel();
61     }
62
63     /** @return Iterator over the flags in the flagstate.
64      */
65      
66     public Iterator getFlags() {
67         return flagstate.iterator();
68     }
69     
70     public FlagState setTag(TagDescriptor tag){
71            
72             HashSet newset=(HashSet)flagstate.clone();
73             Hashtable<TagDescriptor,Integer> newtags=(Hashtable<TagDescriptor,Integer>)tags.clone();
74             
75             if (newtags.containsKey(tag)){
76                    switch (newtags.get(tag).intValue()){
77                            case ONETAG:
78                                         newtags.put(tag,new Integer(MULTITAGS));
79                                         break;
80                            case MULTITAGS:
81                                         newtags.put(tag,new Integer(MULTITAGS));
82                                         break;
83                         }
84                 }
85                 else{
86                         newtags.put(tag,new Integer(ONETAG));
87                 }
88                 
89                 return new FlagState(newset,cd,newtags);
90                                 
91     }
92
93     public int getTagCount(String tagtype){
94                 for (Enumeration en=getTags();en.hasMoreElements();){
95                         TagDescriptor td=(TagDescriptor)en.nextElement();
96                         if (tagtype.equals(td.getSymbol()))
97                                 return tags.get(td).intValue();   //returns either ONETAG or MULTITAG
98                 }
99                 return NOTAGS;
100                 
101     }
102     
103     public FlagState[] clearTag(TagDescriptor tag){
104             FlagState[] retstates;
105             
106             if (tags.containsKey(tag)){
107             switch(tags.get(tag).intValue()){
108                     case ONETAG:
109                         HashSet newset=(HashSet)flagstate.clone();
110                         Hashtable<TagDescriptor,Integer> newtags=(Hashtable<TagDescriptor,Integer>)tags.clone();
111                         newtags.remove(tag);
112                         retstates=new FlagState[]{new FlagState(newset,cd,newtags)};
113                         return retstates;
114                         
115                     case MULTITAGS:
116                         //when tagcount is more than 2, COUNT stays at MULTITAGS
117                         retstates=new FlagState[2];
118                         HashSet newset1=(HashSet)flagstate.clone();
119                         Hashtable<TagDescriptor,Integer> newtags1=(Hashtable<TagDescriptor,Integer>)tags.clone();
120                         retstates[1]=new FlagState(newset1,cd,newtags1);
121                         //when tagcount is 2, COUNT changes to ONETAG
122                         HashSet newset2=(HashSet)flagstate.clone();
123                         Hashtable<TagDescriptor,Integer> newtags2=(Hashtable<TagDescriptor,Integer>)tags.clone();
124                         newtags1.put(tag,new Integer(ONETAG));
125                         retstates[1]=new FlagState(newset2,cd,newtags2);
126                         return retstates;
127                 default:
128                         return null;                    
129         }
130                 }else{
131                         throw new Error("Invalid Operation: Can not clear a tag that doesn't exist.");
132                         
133                 }
134                 
135     }
136     
137     /** Creates a string description of the flagstate
138      *  e.g.  a flagstate with five flags could look like 01001
139      *  @param flags an array of flagdescriptors.
140      *  @return string representation of the flagstate.
141      */
142         public String toString(FlagDescriptor[] flags)
143         {
144                 StringBuffer sb = new StringBuffer(flagstate.size());
145                 for(int i=0;i < flags.length; i++)
146                 {
147                         if (get(flags[i]))
148                                 sb.append(1);
149                         else
150                                 sb.append(0);
151                 }
152                         
153                 return new String(sb);
154         }
155
156         /** Accessor method
157          *  @return returns the classdescriptor of the flagstate.
158          */
159          
160     public ClassDescriptor getClassDescriptor(){
161         return cd;
162     }
163
164         /** Sets the status of a specific flag in a flagstate after cloning it.
165          *  @param      fd FlagDescriptor of the flag whose status is being set.
166          *  @param  status boolean value
167          *  @return the new flagstate with <CODE>fd</CODE> set to <CODE>status</CODE>.
168          */
169          
170     public FlagState setFlag(FlagDescriptor fd, boolean status) {
171         HashSet newset=(HashSet) flagstate.clone();
172         Hashtable<TagDescriptor,Integer> newtags=(Hashtable<TagDescriptor,Integer>)tags.clone();
173         if (status)
174             newset.add(fd);
175         else if (newset.contains(fd)){
176             newset.remove(fd);
177         }
178         
179         return new FlagState(newset, cd,newtags);
180     }
181     
182     /** Tests for equality of two flagstate objects.
183     */
184     
185     public boolean equals(Object o) {
186         if (o instanceof FlagState) {
187             FlagState fs=(FlagState)o;
188             if (fs.cd!=cd)
189                 return false;
190             return (fs.flagstate.equals(flagstate) & fs.tags.equals(tags));
191         }
192         return false;
193     }
194
195     public int hashCode() {
196         return cd.hashCode()^flagstate.hashCode()^tags.hashCode();
197     }
198
199     public String getLabel() {
200         return "N"+uid;
201     }
202
203     public String getTextLabel() {
204         String label=null;
205         for(Iterator it=getFlags();it.hasNext();) {
206             FlagDescriptor fd=(FlagDescriptor) it.next();
207             if (label==null)
208                 label=fd.toString();
209             else
210                 label+=", "+fd.toString();
211         }
212         for (Enumeration en_tags=getTags();en_tags.hasMoreElements();){
213                 TagDescriptor td=(TagDescriptor)en_tags.nextElement();
214                 switch (tags.get(td).intValue()){
215                 case ONETAG:
216                     if (label==null)
217                         label=td.toString()+"(1)";
218                     else
219                         label+=", "+td.toString()+"(1)";
220                     break;
221                 case MULTITAGS:
222                     if (label==null)
223                         label=td.toString()+"(n)";
224                     else
225                         label+=", "+td.toString()+"(n)";
226                     break;
227                 default:
228                     break;
229                 }
230         }
231         if (label==null)
232             return "";
233         return label;
234     }
235     
236     public Enumeration getTags(){
237             return tags.keys();
238     }
239 }