00001 package edu.ksu.cis.bandera.abstraction.util;
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 Bandera;
00036 import java.io.*;
00037 import java.util.*;
00038 import java.lang.reflect.*;
00039 import ca.mcgill.sable.soot.*;
00040 import edu.ksu.cis.bandera.abstraction.*;
00041 import edu.ksu.cis.bandera.abstraction.gui.*;
00042 public class AbstractionClassLoader extends ClassLoader {
00043 private static AbstractionClassLoader acl = new AbstractionClassLoader(AbstractionLibraryManager.abstractionPath);
00044 private static String abstractionPackage = AbstractionLibraryManager.abstractionPackage;
00045 private Hashtable abstractionClasses = new Hashtable();
00046 private String abstractionPath;
00047
00048
00049
00050
00051 private AbstractionClassLoader(AbstractionClassLoader other) {
00052 if (!new File(other.abstractionPath).exists()) {
00053 System.out.println("Invalid abstraction path");
00054 other.abstractionPath = System.getProperty("user.dir");
00055 }
00056 abstractionPath = other.abstractionPath;
00057 for (Enumeration e = other.abstractionClasses.elements(); e.hasMoreElements();) {
00058 Object o = e.nextElement();
00059 if (o instanceof Class) {
00060 Class abstractionClass = (Class) o;
00061 String qName = abstractionClass.getName();
00062 String filename = getFilename(qName);
00063 if (filename == null) continue;
00064 long lastModified = ((Long) other.abstractionClasses.get(abstractionClass)).longValue();
00065 if (lastModified == new File(filename).lastModified()) {
00066 abstractionClasses.put(qName, abstractionClass);
00067 abstractionClasses.put(abstractionClass, new Long(lastModified));
00068 }
00069 }
00070 }
00071 }
00072
00073
00074
00075
00076 private AbstractionClassLoader(String abstractionPath) {
00077 if (!new File(abstractionPath).exists()) {
00078 System.err.println("Invalid abstraction path");
00079 abstractionPath = System.getProperty("user.dir");
00080 }
00081 this.abstractionPath = abstractionPath;
00082 }
00083
00084
00085
00086
00087
00088 private static Class getClass(Type type) {
00089 Class result = null;
00090 if (type instanceof ArrayType) {
00091 ArrayType arrayType = (ArrayType) type;
00092 type = arrayType.baseType;
00093 String className;
00094 if (type instanceof BooleanType) {
00095 className = "Z";
00096 } else
00097 if (type instanceof ByteType) {
00098 className = "B";
00099 } else
00100 if (type instanceof CharType) {
00101 className = "C";
00102 } else
00103 if (type instanceof ShortType) {
00104 className = "S";
00105 } else
00106 if (type instanceof IntType) {
00107 className = "I";
00108 } else
00109 if (type instanceof LongType) {
00110 className = "J";
00111 } else
00112 if (type instanceof FloatType) {
00113 className = "F";
00114 } else
00115 if (type instanceof DoubleType) {
00116 className = "D";
00117 } else {
00118 className = "L" + ((RefType) type).className + ";";
00119 }
00120 for (int i = 0; i < arrayType.numDimensions; i++) {
00121 className = "[" + className;
00122 }
00123 try {
00124 result = Class.forName(className);
00125 } catch (Exception e) {
00126 }
00127 } else {
00128 if (type instanceof BooleanType) {
00129 result = boolean.class;
00130 } else
00131 if (type instanceof ByteType) {
00132 result = byte.class;
00133 } else
00134 if (type instanceof CharType) {
00135 result = char.class;
00136 } else
00137 if (type instanceof ShortType) {
00138 result = short.class;
00139 } else
00140 if (type instanceof IntType) {
00141 result = int.class;
00142 } else
00143 if (type instanceof LongType) {
00144 result = long.class;
00145 } else
00146 if (type instanceof FloatType) {
00147 result = float.class;
00148 } else
00149 if (type instanceof DoubleType) {
00150 result = double.class;
00151 } else {
00152 try {
00153 getClass(((RefType) type).className);
00154 } catch (Exception e) {
00155 }
00156 }
00157 }
00158 return result;
00159 }
00160
00161
00162
00163
00164
00165 public static Class getClass(String name) {
00166 if ("".equals(abstractionPackage)) {
00167 if (!name.startsWith("integral.") && !name.startsWith("real.") ) {
00168 try {
00169 return Class.forName(name);
00170 } catch (Exception e) {
00171 return null;
00172 }
00173 }
00174 } else {
00175 if (!name.startsWith(abstractionPackage)) {
00176 try {
00177 return Class.forName(name);
00178 } catch (Exception e) {
00179 return null;
00180 }
00181 }
00182 }
00183 String filename = acl.getFilename(name);
00184 File file = new File(filename);
00185 if (!file.exists())
00186 return (Class) acl.abstractionClasses.get(name);
00187 if (acl.abstractionClasses.get(name) != null) {
00188 Class c = (Class) acl.abstractionClasses.get(name);
00189 long lastModified = ((Long) acl.abstractionClasses.get(c)).longValue();
00190 if (lastModified != file.lastModified()) {
00191 acl = new AbstractionClassLoader(acl);
00192 } else {
00193 acl.resolveClass(c);
00194 return c;
00195 }
00196 }
00197 InputStream is = null;
00198 int length = (int) file.length();
00199
00200 byte[] buffer = new byte[length];
00201 try {
00202 is = new FileInputStream(file);
00203 if (is.read(buffer) != length)
00204 System.out.println("Error in reading abstraction file " + file);
00205 } catch (Exception e) {
00206 return null;
00207 } finally {
00208 try {
00209 is.close();
00210 } catch (Exception e) {
00211 }
00212 }
00213
00214 Class abstractionClass = acl.defineClass(name, buffer, 0, length);
00215 acl.abstractionClasses.put(name, abstractionClass);
00216 acl.abstractionClasses.put(abstractionClass, new Long(file.lastModified()));
00217 acl.resolveClass(abstractionClass);
00218 return abstractionClass;
00219 }
00220
00221
00222
00223
00224
00225 private String getFilename(String className) {
00226 int idx = className.lastIndexOf(".");
00227 if (idx < 0) return null;
00228 idx = className.lastIndexOf(".", idx - 1);
00229 if (idx > -1) {
00230 className = className.substring(idx + 1);
00231 }
00232 className = className.replace('.', File.separatorChar);
00233 return abstractionPath + File.separator + className + ".class";
00234 }
00235 public static String getTokenName(Abstraction lt, int v)
00236 {
00237 String result = "";
00238 try {
00239 String clsName = lt.getClass().getName();
00240 result = (String) AbstractionClassLoader.invokeMethod(clsName, "getToken", new Class[] {int.class}, null, new Object[] {new Integer(v)});
00241 } catch (Exception e)
00242 {
00243 System.out.println("Warning: Possibly error in abstraction!!");
00244 }
00245
00246 return result;
00247 }
00248
00249
00250
00251
00252
00253
00254
00255
00256
00257 public static Object invokeMethod(String className, String methodName, Class[] params, Object receiver, Object[] args) {
00258 Object result = null;
00259 if (args.length == params.length) {
00260 try {
00261 Class c = AbstractionClassLoader.getClass(className);
00262 Method m = c.getMethod(methodName, params);
00263 result = m.invoke(receiver, args);
00264 } catch (Exception e) {
00265 }
00266 }
00267 return result;
00268 }
00269
00270
00271
00272
00273
00274
00275
00276 public static Object invokeMethod(String className, String methodName, Object[] params, Object receiver, Vector args) {
00277 Object result = null;
00278 if (args.size() == params.length) {
00279 try {
00280 Class c = getClass(className);
00281 Class[] classParams = new Class[params.length];
00282 for (int i = 0; i < classParams.length; i++) {
00283 classParams[i] = getClass((Type) params[i]);
00284 }
00285 Method m = c.getMethod(methodName, classParams);
00286 result = m.invoke(receiver, args.toArray());
00287 } catch (Exception e) {
00288 }
00289 }
00290 return result;
00291 }
00292
00293
00294
00295
00296 public static void removeClass(String name) {
00297 if (acl.abstractionClasses.get(name) == null) return;
00298 acl.abstractionClasses.remove(name);
00299 acl = new AbstractionClassLoader(acl);
00300 }
00301 }