You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@isis.apache.org by ah...@apache.org on 2018/05/29 19:39:09 UTC
[isis] branch master updated: ISIS-1950: codegen-bytebuddy plugin:
first give-it-a-try implementation
This is an automated email from the ASF dual-hosted git repository.
ahuber pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/isis.git
The following commit(s) were added to refs/heads/master by this push:
new 3008d7b ISIS-1950: codegen-bytebuddy plugin: first give-it-a-try implementation
3008d7b is described below
commit 3008d7ba01afcb4274daab5257f14b054c088b40
Author: Andi Huber <ah...@apache.org>
AuthorDate: Tue May 29 21:38:44 2018 +0200
ISIS-1950: codegen-bytebuddy plugin: first give-it-a-try implementation
Task-Url: https://issues.apache.org/jira/browse/ISIS-1950
---
core/plugins/codegen-bytebuddy/pom.xml | 5 +
.../codegen/ProxyFactoryPluginUsingByteBuddy.java | 107 +++++++++++++++++++--
2 files changed, 106 insertions(+), 6 deletions(-)
diff --git a/core/plugins/codegen-bytebuddy/pom.xml b/core/plugins/codegen-bytebuddy/pom.xml
index 0732c78..02c58e3 100644
--- a/core/plugins/codegen-bytebuddy/pom.xml
+++ b/core/plugins/codegen-bytebuddy/pom.xml
@@ -61,6 +61,11 @@
<artifactId>byte-buddy</artifactId>
<version>${bytebuddy.version}</version>
</dependency>
+
+ <dependency>
+ <groupId>org.objenesis</groupId>
+ <artifactId>objenesis</artifactId>
+ </dependency>
<dependency>
<groupId>org.apache.isis.core</groupId>
diff --git a/core/plugins/codegen-bytebuddy/src/main/java/org/apache/isis/core/plugins/codegen/ProxyFactoryPluginUsingByteBuddy.java b/core/plugins/codegen-bytebuddy/src/main/java/org/apache/isis/core/plugins/codegen/ProxyFactoryPluginUsingByteBuddy.java
index dbe3da7..e9fdf46 100644
--- a/core/plugins/codegen-bytebuddy/src/main/java/org/apache/isis/core/plugins/codegen/ProxyFactoryPluginUsingByteBuddy.java
+++ b/core/plugins/codegen-bytebuddy/src/main/java/org/apache/isis/core/plugins/codegen/ProxyFactoryPluginUsingByteBuddy.java
@@ -1,11 +1,24 @@
package org.apache.isis.core.plugins.codegen;
+import java.lang.reflect.InvocationHandler;
+import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
+import java.util.function.Function;
import java.util.function.Predicate;
-import org.apache.isis.commons.internal.exceptions._Exceptions;
-import org.apache.isis.core.plugins.codegen.ProxyFactory;
-import org.apache.isis.core.plugins.codegen.ProxyFactoryPlugin;
+import javax.annotation.Nullable;
+
+import org.apache.isis.commons.internal._Constants;
+import org.apache.isis.commons.internal.base._Casts;
+import org.apache.isis.commons.internal.base._NullSafe;
+import org.objenesis.Objenesis;
+import org.objenesis.ObjenesisStd;
+
+import net.bytebuddy.ByteBuddy;
+import net.bytebuddy.NamingStrategy;
+import net.bytebuddy.dynamic.DynamicType.Builder.MethodDefinition.ImplementationDefinition;
+import net.bytebuddy.implementation.InvocationHandlerAdapter;
+import net.bytebuddy.matcher.ElementMatchers;
public class ProxyFactoryPluginUsingByteBuddy implements ProxyFactoryPlugin {
@@ -16,9 +29,91 @@ public class ProxyFactoryPluginUsingByteBuddy implements ProxyFactoryPlugin {
Predicate<Method> methodFilter,
Class<?>[] constructorArgTypes) {
- _Exceptions.throwNotImplemented();
- // TODO Auto-generated method stub
- return null;
+ final Objenesis objenesis = new ObjenesisStd();
+
+ final ImplementationDefinition<T> proxyDef = new ByteBuddy()
+ .with(new NamingStrategy.SuffixingRandom("bb"))
+ .subclass(base)
+ .implement(interfaces)
+ .method(ElementMatchers.any());
+
+ final Function<InvocationHandler, Class<? extends T>> proxyClassFactory = handler->
+ proxyDef.intercept(InvocationHandlerAdapter.of(handler))
+ .make()
+ .load(base.getClassLoader())
+ .getLoaded();
+
+ return new ProxyFactory<T>() {
+
+ @Override
+ public T createInstance(InvocationHandler handler, boolean initialize) {
+
+ try {
+
+ if(initialize) {
+ ensureSameSize(constructorArgTypes, null);
+ return _Casts.uncheckedCast( createUsingConstructor(handler, null) );
+ } else {
+ return _Casts.uncheckedCast( createNotUsingConstructor(handler) );
+ }
+
+ } catch (NoSuchMethodException | IllegalArgumentException | InstantiationException |
+ IllegalAccessException | InvocationTargetException e) {
+ throw new RuntimeException(e);
+ }
+
+ }
+
+ @Override
+ public T createInstance(InvocationHandler handler, Object[] constructorArgs) {
+
+ ensureNonEmtpy(constructorArgs);
+ ensureSameSize(constructorArgTypes, constructorArgs);
+
+ try {
+ return _Casts.uncheckedCast( createUsingConstructor(handler, constructorArgs) );
+ } catch (NoSuchMethodException | InstantiationException | IllegalAccessException |
+ IllegalArgumentException | InvocationTargetException | SecurityException e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+ // -- HELPER (create w/o initialize)
+
+ private Object createNotUsingConstructor(InvocationHandler invocationHandler) {
+ final Class<? extends T> proxyClass = proxyClassFactory.apply(invocationHandler);
+ final Object object = objenesis.newInstance(proxyClass);
+ return object;
+ }
+
+ // -- HELPER (create with initialize)
+
+ private Object createUsingConstructor(InvocationHandler invocationHandler, @Nullable Object[] constructorArgs)
+ throws InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException, NoSuchMethodException, SecurityException {
+ final Class<? extends T> proxyClass = proxyClassFactory.apply(invocationHandler);
+ return proxyClass
+ .getConstructor(constructorArgTypes==null ? _Constants.emptyClasses : constructorArgTypes)
+ .newInstance(constructorArgs==null ? _Constants.emptyObjects : constructorArgs);
+ }
+
+ };
+
+ }
+
+ // -- HELPER
+
+ private static void ensureSameSize(Class<?>[] a, Object[] b) {
+ if(_NullSafe.size(a) != _NullSafe.size(b)) {
+ throw new IllegalArgumentException(String.format("Constructor arg count expected %d, got %d.",
+ _NullSafe.size(a), _NullSafe.size(b) ));
+ }
+ }
+
+ private static void ensureNonEmtpy(Object[] a) {
+ if(_NullSafe.isEmpty(a)) {
+ throw new IllegalArgumentException(String.format("Contructor args count expected > 0, got %d.",
+ _NullSafe.size(a) ));
+ }
}
}
--
To stop receiving notification emails like this one, please contact
ahuber@apache.org.