public void testNewArray() throws Exception { ExprEditor ed = new ExprEditor() { int dim[] = {1, 2, 2, 1, 2, 2, 3}; int cdim[] = {1, 1, 2, 1, 1, 2, 2}; int counter = 0; public void edit(NewArray expr) throws CannotCompileException { try { CtClass str = sloader.get("java.lang.String"); if (counter < 3) assertEquals(str, expr.getComponentType()); else assertEquals(CtClass.intType, expr.getComponentType()); assertEquals(dim[counter], expr.getDimension()); assertEquals(cdim[counter], expr.getCreatedDimensions()); expr.replace("{ i += $1; $_ = $proceed($$); }"); ++counter; } catch (NotFoundException e) { throw new CannotCompileException(e); } } }; CtClass cc = sloader.get("test2.NewArray"); CtMethod m1 = cc.getDeclaredMethod("foo"); m1.instrument(ed); cc.writeFile(); Object obj = make(cc.getName()); assertEquals(48, invoke(obj, "run")); }
public void testInsertLocal() throws Exception { CtClass cc = sloader.get("test2.InsertLocal"); CtMethod m1 = cc.getDeclaredMethod("foo"); m1.insertBefore("{ i = s.length(); d = 0.14; }"); m1.insertAfter("{ field = i; }"); CtMethod m2 = cc.getDeclaredMethod("run2"); m2.insertAt(22, "{ s = \"12\"; k = 5; }"); CtMethod m3 = cc.getDeclaredMethod("run3"); m3.instrument( new ExprEditor() { public void edit(NewExpr n) throws CannotCompileException { n.replace("{ i++; $_ = $proceed($$); }"); } public void edit(FieldAccess f) throws CannotCompileException { f.replace("{ i++; $_ = $proceed($$); }"); } public void edit(MethodCall m) throws CannotCompileException { m.replace("{ i++; $_ = $proceed($$); }"); } }); cc.writeFile(); Object obj = make(cc.getName()); assertEquals(317, invoke(obj, "run")); assertEquals(7, invoke(obj, "run2")); assertEquals(3, invoke(obj, "run3")); }
public void testSuperCall() throws Exception { CtClass cc = sloader.get("test2.SuperCall"); CtMethod m1 = cc.getDeclaredMethod("foo"); m1.instrument( new ExprEditor() { public void edit(MethodCall m) throws CannotCompileException { m.replace("{ $_ = $proceed($$); }"); } }); cc.writeFile(); Object obj = make(cc.getName()); invoke(obj, "bar"); }
public void testRemoveCall() throws Exception { CtClass cc = sloader.get("test2.RemoveCall"); CtMethod m1 = cc.getDeclaredMethod("bar"); m1.instrument( new ExprEditor() { public void edit(MethodCall m) throws CannotCompileException { m.replace("{ $_ = ($r)null; }"); } }); cc.writeFile(); Object obj = make(cc.getName()); assertEquals(0, invoke(obj, "bar")); }
public void testProceedToDefaultMethod() throws Exception { CtClass cc = ClassPool.getDefault().get("test5.ProceedDefault"); CtMethod mth = cc.getDeclaredMethod("bar"); mth.instrument( new ExprEditor() { public void edit(MethodCall c) throws CannotCompileException { c.replace("$_ = $proceed($$) + 10000;"); } }); cc.writeFile(); Object obj = make(cc.getName()); assertEquals(21713, invoke(obj, "run")); }
public void testNewExprInTry() throws Exception { ExprEditor ed = new ExprEditor() { public void edit(NewExpr expr) throws CannotCompileException { expr.replace("$_ = new test2.HashMapWrapper($1, 1);"); } }; CtClass cc = sloader.get("test2.NewExprInTry"); CtMethod m1 = cc.getDeclaredMethod("foo"); m1.instrument(ed); cc.writeFile(); Object obj = make(cc.getName()); assertEquals(1, invoke(obj, "run")); }
public void testMethodCall() throws Exception { CtClass cc = sloader.get("test2.MethodCall"); CtMethod m1 = cc.getDeclaredMethod("bar"); m1.instrument( new ExprEditor() { public void edit(MethodCall m) throws CannotCompileException { if ("clone".equals(m.getMethodName())) methodCallData = m.getClassName(); } }); cc.writeFile(); assertEquals("java.lang.String[]", methodCallData); assertEquals("java.lang.String[]", sloader.get("[Ljava/lang/String;").getName()); assertEquals("int[][]", sloader.get("[[I").getName()); }
public void testNewExprTry() throws Exception { ExprEditor ed = new ExprEditor() { public void edit(NewExpr expr) throws CannotCompileException { StringBuffer code = new StringBuffer(300); code.append("{ try "); code.append("{ $_ = $proceed($$); }"); code.append("catch (OutOfMemoryError e) {}}"); expr.replace(code.toString()); } }; CtClass cc = sloader.get("test2.NewExprTry"); CtMethod m1 = cc.getDeclaredMethod("foo"); m1.instrument(ed); cc.writeFile(); Object obj = make(cc.getName()); assertEquals(16, invoke(obj, "run")); }
private void preprocessMethods(CtClass cc, boolean insertLoad, boolean wrapFieldAccess) throws CannotCompileException { CtMethod[] methods = cc.getDeclaredMethods(); for (int i = 0; i < methods.length; i++) { CtMethod m = methods[i]; if (wrapFieldAccess) { m.instrument( new ExprEditor() { public void edit(FieldAccess fa) throws CannotCompileException { try { if ((fa.getField().getModifiers() & (Modifier.TRANSIENT | Modifier.STATIC)) == 0 && fa.getField().getDeclaringClass().subtypeOf(persistentInterface)) { if (fa.isWriter()) { fa.replace("{ $0.loadAndModify(); $proceed($$); }"); } // isSelfReader is my extension of JAssist, if you // use original version of JAssist comment the // branch below or replace "else if" with "else". // In first case Perst will not be able to handle // access to foreign (non-this) fields. You should use // getter/setter methods instead. // In second case access to foreign fields still will be possible, // but with significant degradation of performance and // increased code size, because in this case before ALL access // to fields of persistent capable object call of load() method // will be inserted. else if (!fa.isSelfReader()) { fa.replace("{ $0.load(); $_ = $proceed($$); }"); } } } catch (NotFoundException x) { } } }); } if (insertLoad && !"recursiveLoading".equals(m.getName()) && (m.getModifiers() & (Modifier.STATIC | Modifier.ABSTRACT)) == 0) { m.insertBefore("load();"); } } }