00001 package edu.ksu.cis.bandera.annotation;
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035 import edu.ksu.cis.bandera.jext.*;
00036 import ca.mcgill.sable.soot.*;
00037 import ca.mcgill.sable.soot.jimple.*;
00038 import java.util.*;
00039 import edu.ksu.cis.bandera.jjjc.decompiler.*;
00040 public class AnnotationManager {
00041 private Hashtable annotations = new Hashtable();
00042 private Hashtable inlineTable = new Hashtable();
00043 private Hashtable methodStmtTable = new Hashtable();
00044 private Hashtable inlinedLocalTable = new Hashtable();
00045 private Hashtable localTable = new Hashtable();
00046 private Hashtable newOldLocalTable = new Hashtable();
00047 private Hashtable oldNewLocalTable = new Hashtable();
00048 private Hashtable oldNewStmtTable = new Hashtable();
00049 private Hashtable newOldStmtTable = new Hashtable();
00050 private Hashtable stmtLocalTable = new Hashtable();
00051 private Hashtable localPackingTable = new Hashtable();
00052 private Hashtable replacedStmt = new Hashtable();
00053 private Hashtable filenameLinePairAnnotationTable = new Hashtable();
00054 private Hashtable stmtAnnotationTable = new Hashtable();
00055
00056
00057
00058 public AnnotationManager() {
00059 }
00060
00061
00062
00063
00064
00065
00066 public void addAnnotation(SootClass sc, Object o, Annotation annotation) {
00067 Hashtable table = (Hashtable) annotations.get(sc);
00068
00069 if (table == null) {
00070 table = new Hashtable();
00071 annotations.put(sc, table);
00072 }
00073
00074 table.put(o, annotation);
00075 }
00076
00077
00078
00079
00080 public void addAnnotation(ClassDeclarationAnnotation cda) {
00081 SootClass sc = cda.getSootClass();
00082 Hashtable table = (Hashtable) annotations.get(sc);
00083
00084 if (table == null) {
00085 table = new Hashtable();
00086 annotations.put(sc, table);
00087 }
00088 table.put(sc, cda);
00089 }
00090
00091
00092
00093
00094
00095 public Annotation getAnnotation(SootClass sc) {
00096 Hashtable table = (Hashtable) annotations.get(sc);
00097 if (table == null) return null;
00098 return (Annotation) table.get(sc);
00099 }
00100
00101
00102
00103
00104
00105
00106 public Annotation getAnnotation(SootClass sc, Object o) {
00107 Hashtable table = (Hashtable) annotations.get(sc);
00108 if (table == null) return null;
00109 return (Annotation) table.get(o);
00110 }
00111
00112
00113
00114
00115
00116 public Annotation getAnnotation(FilenameLinePair flp) {
00117 return (Annotation) filenameLinePairAnnotationTable.get(flp);
00118 }
00119
00120
00121
00122
00123 public Hashtable getAnnotationTable() {
00124 return annotations;
00125 }
00126
00127
00128
00129
00130 public Enumeration getCompiledClasses() {
00131 return annotations.keys();
00132 }
00133
00134
00135
00136
00137
00138 public Annotation getContainingAnnotation(Stmt stmt) throws AnnotationException {
00139 if (inlineTable.get(stmt) != null) {
00140 return (Annotation) inlineTable.get(stmt);
00141 }
00142 if (stmtAnnotationTable.get(stmt) != null) {
00143 return (Annotation) stmtAnnotationTable.get(stmt);
00144 }
00145 Vector result = new Vector();
00146 for (Enumeration e = annotations.keys(); e.hasMoreElements();) {
00147 SootClass sc = (SootClass) e.nextElement();
00148 Annotation a = getContainingAnnotation(sc, stmt);
00149 if (a != null) if (!result.contains(a)) result.addElement(a);
00150 }
00151 if (result.size() > 1)
00152 throw new AnnotationException("Statement " + stmt + " is contained in two or more annotations");
00153 else if (result.size() < 1) return null;
00154 else {
00155 Annotation a = (Annotation) result.firstElement();
00156 stmtAnnotationTable.put(stmt, a);
00157 return a;
00158 }
00159 }
00160
00161
00162
00163
00164
00165
00166 public Annotation getContainingAnnotation(SootClass sootClass, Stmt stmt) throws AnnotationException {
00167 if (inlineTable.get(stmt) != null) {
00168 return (Annotation) inlineTable.get(stmt);
00169 }
00170 if (stmtAnnotationTable.get(stmt) != null) {
00171 return (Annotation) stmtAnnotationTable.get(stmt);
00172 }
00173 Vector result = new Vector();
00174
00175 Hashtable table = (Hashtable) annotations.get(sootClass);
00176 if (table == null) return null;
00177
00178 Annotation a = null;
00179 for (Enumeration e = table.elements(); e.hasMoreElements();) {
00180 try {
00181 Annotation ann = (Annotation) e.nextElement();
00182 if (!(ann instanceof FieldDeclarationAnnotation))
00183 a = ann.getContainingAnnotation(stmt);
00184 } catch (Exception exception) {
00185 a = null;
00186 }
00187 if (a != null) if (!result.contains(a)) result.addElement(a);
00188 }
00189
00190 if (result.size() > 1)
00191 throw new AnnotationException("Statement " + stmt + " is contained in two or more annotations");
00192 else if (result.size() < 1) return null;
00193 else {
00194 a = (Annotation) result.firstElement();
00195 stmtAnnotationTable.put(stmt, a);
00196 return a;
00197 }
00198 }
00199
00200
00201
00202
00203
00204
00205
00206 public Annotation getContainingAnnotation(SootClass sootClass, Object object, Stmt stmt) throws AnnotationException {
00207 if (inlineTable.get(stmt) != null) {
00208 return (Annotation) inlineTable.get(stmt);
00209 }
00210 if (stmtAnnotationTable.get(stmt) != null) {
00211 return (Annotation) stmtAnnotationTable.get(stmt);
00212 }
00213 else {
00214 Annotation a = getAnnotation(sootClass, object).getContainingAnnotation(stmt);
00215 stmtAnnotationTable.put(stmt, a);
00216 return a;
00217 }
00218 }
00219
00220
00221
00222
00223
00224 public SootMethod getContainingSootMethod(Stmt stmt) {
00225 return (SootMethod) methodStmtTable.get(stmt);
00226 }
00227
00228
00229
00230
00231 public java.util.Hashtable getFilenameLinePairAnnotationTable() {
00232 return filenameLinePairAnnotationTable;
00233 }
00234
00235
00236
00237
00238
00239 public HashSet getInlinedLocal(LocalExpr e) {
00240 return (HashSet) oldNewLocalTable.get(e);
00241 }
00242
00243
00244
00245
00246
00247 public Vector getInlinedStmt(Stmt oldStmt) {
00248
00249
00250
00251
00252
00253
00254
00255
00256
00257
00258
00259
00260
00261
00262
00263
00264 return (Vector) oldNewStmtTable.get(oldStmt);
00265 }
00266
00267
00268
00269
00270 public java.util.Hashtable getLocalPackingTable() {
00271 return localPackingTable;
00272 }
00273
00274
00275
00276
00277
00278 public Annotation getMethodAnnotationContainingAnnotation(Annotation annotation) {
00279 for (Enumeration e = annotations.elements(); e.hasMoreElements();) {
00280 for (Enumeration e2 = ((Hashtable) e.nextElement()).elements(); e2.hasMoreElements();) {
00281 Annotation a = (Annotation) e2.nextElement();
00282 if (a.contains(annotation) && ((a instanceof MethodDeclarationAnnotation)
00283 || (a instanceof ConstructorDeclarationAnnotation))) return a;
00284 }
00285 }
00286 return null;
00287 }
00288
00289
00290
00291
00292
00293 public Stmt getReplacedStmt(Stmt s) {
00294 return (Stmt) replacedStmt.get(s);
00295 }
00296
00297
00298
00299
00300 public java.util.Hashtable getStmtLocalTable() {
00301 return stmtLocalTable;
00302 }
00303
00304
00305
00306
00307
00308 public void putFilenameLinePairAnnotation(FilenameLinePair flp, Annotation a) {
00309 Annotation oldAnn = getAnnotation(flp);
00310 if (oldAnn == null) {
00311 filenameLinePairAnnotationTable.put(flp, a);
00312
00313 } else {
00314 String cname = oldAnn.getClass().getName();
00315 if ("edu.ksu.cis.bandera.annotation.SequentialAnnotation".equals(cname)
00316 || "edu.ksu.cis.bandera.annotation.BlockStmtAnnotation".equals(cname)) {
00317 filenameLinePairAnnotationTable.put(flp, a);
00318
00319 }
00320 }
00321 }
00322
00323
00324
00325
00326
00327
00328
00329 public boolean putInlineLocal(LocalExpr newLocal, LocalExpr oldLocal) {
00330 if (newOldLocalTable.get(oldLocal) != null) {
00331 oldLocal = (LocalExpr) newOldLocalTable.get(oldLocal);
00332 }
00333 if (oldNewLocalTable.get(oldLocal) == null) {
00334 oldNewLocalTable.put(oldLocal, new HashSet());
00335 }
00336 ((HashSet) oldNewLocalTable.get(oldLocal)).add(newLocal);
00337 if (newOldLocalTable.get(newLocal) != null) {
00338 if (newOldLocalTable.get(newLocal) != oldLocal) {
00339
00340 return false;
00341 }
00342 }
00343 newOldLocalTable.put(newLocal, oldLocal);
00344 return true;
00345 }
00346
00347
00348
00349
00350
00351
00352
00353 public boolean putInlineStmt(Stmt newStmt, Stmt oldStmt, SootMethod method) {
00354 try {
00355 if (newOldStmtTable.get(oldStmt) != null) {
00356 Stmt s = (Stmt) newOldStmtTable.get(oldStmt);
00357 if (s != null) {
00358 if (getContainingAnnotation(s) != null) {
00359 oldStmt = s;
00360 }
00361 }
00362 }
00363
00364
00365 if (newOldStmtTable.get(newStmt) != null) {
00366 if (newOldStmtTable.get(newStmt) != oldStmt) {
00367
00368 return false;
00369 }
00370 }
00371 Annotation a = getContainingAnnotation(oldStmt);
00372 if (a == null) {
00373
00374
00375 return false;
00376 }
00377 inlineTable.put(newStmt, a);
00378 methodStmtTable.put(newStmt, method);
00379 if (oldNewStmtTable.get(oldStmt) == null) {
00380 oldNewStmtTable.put(oldStmt, new Vector());
00381 }
00382 ((Vector) oldNewStmtTable.get(oldStmt)).addElement(newStmt);
00383
00384
00385
00386
00387
00388
00389
00390
00391
00392
00393 newOldStmtTable.put(newStmt, oldStmt);
00394 return true;
00395 } catch (Exception e) {
00396
00397 return false;
00398 }
00399 }
00400
00401
00402
00403
00404
00405 public void putReplacedStmt(Stmt newStmt, Stmt oldStmt) {
00406 replacedStmt.put(oldStmt, newStmt);
00407 }
00408
00409
00410
00411
00412 public void setFilenameLinePairAnnotationTable(java.util.Hashtable newFilenameLinePairAnnotationTable) {
00413 filenameLinePairAnnotationTable = newFilenameLinePairAnnotationTable;
00414 }
00415
00416
00417
00418
00419 public void setLocalPackingTable(java.util.Hashtable newLocalPackingTable) {
00420 localPackingTable = newLocalPackingTable;
00421 }
00422
00423
00424
00425
00426 public void setStmtLocalTable(java.util.Hashtable newStmtLocalTable) {
00427 stmtLocalTable = newStmtLocalTable;
00428 }
00429 }