private void generateMethod(ClassStructureBuilder<?> classBuilder, MetaMethod method) { final List<Class<?>> interceptors = interceptorProvider.getInterceptors(remote, method); final boolean intercepted = !interceptors.isEmpty(); final Parameter[] parms = DefParameters.from(method).getParameters().toArray(new Parameter[0]); final Parameter[] finalParms = new Parameter[parms.length]; final List<Statement> parmVars = new ArrayList<Statement>(); for (int i = 0; i < parms.length; i++) { finalParms[i] = Parameter.of(parms[i].getType().getErased(), parms[i].getName(), true); parmVars.add(Stmt.loadVariable(parms[i].getName())); } final Statement parameters = (intercepted) ? new StringStatement("getParameters()", MetaClassFactory.get(Object[].class)) : Stmt.newArray(Object.class).initialize(parmVars.toArray()); final BlockBuilder<?> methodBlock = classBuilder.publicMethod(method.getReturnType().getErased(), method.getName(), finalParms); if (intercepted) { methodBlock.append(generateInterceptorLogic(classBuilder, method, generateRequest(classBuilder, method, parameters, true), parmVars, interceptors)); } else { methodBlock.append(generateRequest(classBuilder, method, parameters, false)); } final Statement returnStmt = ProxyUtil.generateProxyMethodReturnStatement(method); if (returnStmt != null) { methodBlock.append(returnStmt); } methodBlock.finish(); }
final long time = System.currentTimeMillis(); final MethodBlockBuilder<?> loadProxies = classBuilder.publicMethod(void.class, "loadProxies", Parameter.of(MessageBus.class, "bus", true));
private void maybeImplementFactoryInit(final ClassStructureBuilder<?> bodyBlockBuilder, final Injectable injectable, final List<Statement> factoryInitStatements) { if (!factoryInitStatements.isEmpty()) { bodyBlockBuilder.publicMethod(void.class, "init", finalOf(Context.class, "context")).appendAll(factoryInitStatements).finish(); } }
private void maybeImplementInvokePostConstructs(final ClassStructureBuilder<?> bodyBlockBuilder, final Injectable injectable, final List<Statement> invokePostConstructStatements) { if (!invokePostConstructStatements.isEmpty()) { bodyBlockBuilder .publicMethod(MetaClassFactory.get(void.class), "invokePostConstructs", finalOf(injectable.getInjectedType(), "instance")) .appendAll(invokePostConstructStatements).finish(); } }
private void implementInitProxyProperties(final ClassStructureBuilder<?> proxyImpl, final Injectable injectable) { final BlockBuilder<?> initBody = proxyImpl .publicMethod(void.class, "initProxyProperties", finalOf(injectable.getInjectedType(), "instance")).body(); for (final Entry<String, Statement> prop : controller.getProxyProperties()) { proxyImpl.privateField(prop.getKey(), prop.getValue().getType()).finish(); initBody.append(loadVariable(prop.getKey()).assignValue(prop.getValue())); } initBody.finish(); }
private void implementClearInstance(final ClassStructureBuilder<?> proxyImpl, final Injectable injectable) { proxyImpl.publicMethod(void.class, "clearInstance") .body() .append(loadVariable("proxyHelper").invoke("clearInstance")) .finish(); }
private void implementGetContext(final ClassStructureBuilder<?> proxyImpl, final Injectable injectable) { proxyImpl.publicMethod(Context.class, "getProxyContext") .body() .append(loadVariable("proxyHelper").invoke("getProxyContext").returnValue()) .finish(); }
private void implementAsBeanType(final ClassStructureBuilder<?> proxyImpl, final Injectable injectable) { proxyImpl.publicMethod(injectable.getInjectedType(), "asBeanType") .body() .append(loadVariable("this").returnValue()) .finish(); }
private void maybeImplementDestroyInstance(final ClassStructureBuilder<?> bodyBlockBuilder, final Injectable injectable, final List<Statement> destroyInstanceStatements) { if (!destroyInstanceStatements.isEmpty()) { bodyBlockBuilder .publicMethod(void.class, "generatedDestroyInstance", finalOf(Object.class, "instance"), finalOf(ContextManager.class, "contextManager")) .append(loadVariable("this").invoke("destroyInstanceHelper", Stmt.castTo(injectable.getInjectedType(), loadVariable("instance")), loadVariable("contextManager"))) .finish(); bodyBlockBuilder.publicMethod(void.class, "destroyInstanceHelper", finalOf(injectable.getInjectedType(), "instance"), finalOf(ContextManager.class, "contextManager")) .appendAll(destroyInstanceStatements).finish(); } }
private void implementUnwrappedInstance(final ClassStructureBuilder<?> proxyImpl, final Injectable injectable) { proxyImpl.publicMethod(Object.class, "unwrap") .body() .append(loadVariable("proxyHelper").invoke("getInstance", loadVariable("this")).returnValue()) .finish(); }
private void implementSetContext(final ClassStructureBuilder<?> proxyImpl, final Injectable injectable) { proxyImpl.publicMethod(void.class, "setProxyContext", finalOf(Context.class, "context")) .body() .append(loadVariable("proxyHelper").invoke("setProxyContext", loadVariable("context"))) .finish(); }
private void implementSetInstance(final ClassStructureBuilder<?> proxyImpl, final Injectable injectable) { proxyImpl.publicMethod(void.class, "setInstance", finalOf(injectable.getInjectedType(), "instance")) .body() .append(loadVariable("proxyHelper").invoke("setInstance", loadVariable("instance"))) .finish(); }
@Test public void testDefineClassByImplementingInterface() { final String cls = ClassBuilder.implement(Baz.class) .publicMethod(void.class, "someMethod") .finish().toJavaString(); assertEquals("failed to generate class by implementing an interface", CLASS_DEFINITION_BY_IMPLEMENTING_INTERFACE, cls); }
/** * Generates a getter method for the provided property plus the corresponding code for the * implementation of {@link HasProperties#get(String)}. */ private void generateGetter(final ClassStructureBuilder<?> classBuilder, final String property, final CaseBlockBuilder switchBlock) { final MetaMethod getterMethod = bindable.getBeanDescriptor().getReadMethodForProperty(property); if (getterMethod != null && !getterMethod.isFinal() && getterMethod.isPublic()) { BlockBuilder<CaseBlockBuilder> caseBlock = switchBlock.case_(property); caseBlock.append(Stmt.loadVariable("this").invoke(getterMethod.getName()).returnValue()).finish(); classBuilder.publicMethod(getterMethod.getReturnType(), getterMethod.getName()) .append(target().invoke(getterMethod.getName()).returnValue()) .finish(); proxiedAccessorMethods.add(getterMethod); } }
private void implementEquals(final ClassStructureBuilder<?> proxyImpl) { proxyImpl.publicMethod(boolean.class, "equals", Parameter.of(Object.class, "obj")).body() .append(loadVariable("obj").assignValue(invokeStatic(Factory.class, "maybeUnwrapProxy", loadVariable("obj")))) .append(loadVariable("proxyHelper").invoke("getInstance", loadVariable("this")).invoke("equals", loadVariable("obj")).returnValue()) .finish(); }
@Test public void testDefineClassWithMethodCallingMethodOnThis() { final String cls = ClassBuilder.define("org.foo.Foo") .publicScope() .body() .publicMethod(void.class, "bar") .append(Stmt.loadVariable("this").invoke("foo")) .finish() .publicMethod(String.class, "foo") .append(Stmt.load(null).returnValue()) .finish() .toJavaString(); assertEquals("failed to generate class with method calling method on this", CLASS_WITH_METHOD_CALLING_METHOD_ON_THIS, cls); }
@Test public void testDefineClassWithMethodCallingMethodOnSuper() { final String cls = ClassBuilder.define("org.foo.Foo") .publicScope() .body() .publicMethod(void.class, "bar") .append(Stmt.loadVariable("this").invoke("foo")) .finish() .publicMethod(String.class, "foo") .append(Stmt.loadVariable("super").invoke("toString").returnValue()) .finish() .toJavaString(); assertEquals("failed to generate class with method calling method on this", CLASS_WITH_METHOD_CALLING_METHOD_ON_SUPER, cls); }
@Test public void testDefineClassWithMethodHavingThrowsDeclaration() { @SuppressWarnings("unchecked") final String cls = ClassBuilder .define("org.foo.Foo") .publicScope() .body() .publicMethod(void.class, "initialize") .throws_(Exception.class, IllegalArgumentException.class) .finish() .toJavaString(); assertEquals("failed to generate class with method having throws declaration", CLASS_WITH_METHOD_HAVING_THROWS_DECLARATION, cls); }
@Test public void testDefineClassWithStaticMethod() { final String cls = ClassBuilder.define("my.test.Clazz") .publicScope().body() .publicMethod(void.class, "test").modifiers(Modifier.Static) .body() .append(Stmt.loadStatic(System.class, "out").invoke("println", "Hello, World!")) .finish() .toJavaString(); assertEquals("failed to generate class with static method", CLASS_WITH_STATIC_METHOD, cls); }
@Test public void testDefineClassWithJSNIMethod() { final String cls = ClassBuilder.define("my.test.Clazz") .publicScope().body() .publicMethod(void.class, "test").modifiers(Modifier.JSNI) .body() .append(Stmt.loadStatic(System.class, "out").invoke("println", "Hello, World!")) .finish() .toJavaString(); assertEquals("failed to generate class with JSNI method", CLASS_WITH_JSNI_METHOD, cls); }