00001
00011 package edu.mit.csail.sdg.squander;
00012
00013 import edu.mit.csail.sdg.squander.engine.ISquander;
00014 import edu.mit.csail.sdg.squander.engine.ISquanderResult;
00015 import edu.mit.csail.sdg.squander.log.Log;
00016 import edu.mit.csail.sdg.squander.options.GlobalOptions;
00017 import edu.mit.csail.sdg.squander.parser.JFSLParserException;
00018 import edu.mit.csail.sdg.squander.spec.TypeCheckException;
00019
00025 public final class Squander {
00026
00027 private Squander() {
00028 throw new UnsupportedOperationException("instantiation forbidden");
00029 }
00030
00031 private static ISquander lastSqImpl;
00032
00033
00034
00035
00036
00052 @SuppressWarnings("unchecked")
00053 public static <R> R exe(Object caller, Object ... methodArgs) {
00054 Class<?>[] methodParamTypes = new Class<?>[methodArgs.length];
00055 for (int i = 0; i < methodArgs.length; i++)
00056 if (methodArgs[i] == null)
00057 methodParamTypes[i] = Object.class;
00058 else
00059 methodParamTypes[i] = methodArgs[i].getClass();
00060 return (R) exe(caller, methodParamTypes, methodArgs);
00061 }
00062
00077 @SuppressWarnings("unchecked")
00078 public static <R> R exe(Object caller, Class<?>[] methodParamTypes, Object[] methodArgs) {
00079 Throwable t = new Throwable();
00080 String clsName = getCallerClassName(t);
00081 String methodName = getCallerMethod(t);
00082 return (R) exe(caller, clsName, methodName, methodParamTypes, methodArgs);
00083 }
00084
00095 @SuppressWarnings("unchecked")
00096 public static <R> R exe(Object caller, String clsName, String methodName) {
00097 return (R) exe(caller, clsName, methodName, new Class<?>[0], new Object[0]);
00098 }
00099
00111 @SuppressWarnings("unchecked")
00112 public static <R> R exe(Object caller, String clsName, String methodName,
00113 Class<?>[] methodParamTypes, Object[] methodArgs) {
00114 Log.log("Using %s engine", GlobalOptions.INSTANCE.engine);
00115 ISquander sq = GlobalOptions.INSTANCE.getSquanderImpl();
00116 lastSqImpl = sq;
00117 try {
00118 return (R) sq.magic(caller, clsName, methodName, methodParamTypes, methodArgs);
00119 } catch (TypeCheckException e) {
00120 StringBuilder msg = new StringBuilder("Typecheck Error:\n");
00121 msg.append(e.getMessage()).append("\n");
00122 if (e.source() != null ) {
00123 msg.append(e.source()).append("\n");
00124 }
00125 throw new TypeCheckException(msg.toString(), e);
00126 } catch (JFSLParserException e) {
00127 StringBuilder msg = new StringBuilder("Parser Error:\n");
00128 msg.append(e.getMessage()).append("\n");
00129 if (e.source() != null) {
00130 msg.append(e.source()).append("\n");
00131 int col = e.column();
00132 for (int i = 0; i < e.source().length(); i++)
00133 msg.append(i == col ? "^" : "-");
00134 }
00135 throw new JFSLParserException(msg.toString(), e);
00136 }
00137 }
00138
00142 public static ISquanderResult getLastResult() {
00143 if (lastSqImpl != null)
00144 return lastSqImpl.getLastResult();
00145 return null;
00146 }
00147
00148 private static String getCallerMethod(Throwable t) {
00149 return getRightStackTraceElem(t).getMethodName();
00150 }
00151
00152 private static String getCallerClassName(Throwable t) {
00153 return getRightStackTraceElem(t).getClassName();
00154 }
00155
00156 private static StackTraceElement getRightStackTraceElem(Throwable t) {
00157 StackTraceElement[] trace = t.getStackTrace();
00158 for (int i = 0; i < trace.length; i++) {
00159 if (!trace[i].getClassName().equals(Squander.class.getName()))
00160 return trace[i];
00161 }
00162 return null;
00163 }
00164 }
00165