deltaspike-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From rmannibu...@apache.org
Subject deltaspike git commit: DELTASPIKE-1138 ensuring @Futureable works with weld1 - note: we can desire to move the hack in a higher level to benefit to all interceptors
Date Fri, 29 Apr 2016 14:01:31 GMT
Repository: deltaspike
Updated Branches:
  refs/heads/master 8e23c8205 -> cf140a98c


DELTASPIKE-1138 ensuring @Futureable works with weld1 - note: we can desire to move the hack
in a higher level to benefit to all interceptors


Project: http://git-wip-us.apache.org/repos/asf/deltaspike/repo
Commit: http://git-wip-us.apache.org/repos/asf/deltaspike/commit/cf140a98
Tree: http://git-wip-us.apache.org/repos/asf/deltaspike/tree/cf140a98
Diff: http://git-wip-us.apache.org/repos/asf/deltaspike/diff/cf140a98

Branch: refs/heads/master
Commit: cf140a98c4496f976e4a4fea9b84d58f795983a7
Parents: 8e23c82
Author: Romain manni-Bucau <rmannibucau@gmail.com>
Authored: Fri Apr 29 16:01:11 2016 +0200
Committer: Romain manni-Bucau <rmannibucau@gmail.com>
Committed: Fri Apr 29 16:01:11 2016 +0200

----------------------------------------------------------------------
 .../impl/future/DefaultFutureableStrategy.java  | 113 +++++++++++++++++++
 1 file changed, 113 insertions(+)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/deltaspike/blob/cf140a98/deltaspike/core/impl/src/main/java/org/apache/deltaspike/core/impl/future/DefaultFutureableStrategy.java
----------------------------------------------------------------------
diff --git a/deltaspike/core/impl/src/main/java/org/apache/deltaspike/core/impl/future/DefaultFutureableStrategy.java
b/deltaspike/core/impl/src/main/java/org/apache/deltaspike/core/impl/future/DefaultFutureableStrategy.java
index 7a51cc4..70ee7b7 100644
--- a/deltaspike/core/impl/src/main/java/org/apache/deltaspike/core/impl/future/DefaultFutureableStrategy.java
+++ b/deltaspike/core/impl/src/main/java/org/apache/deltaspike/core/impl/future/DefaultFutureableStrategy.java
@@ -31,6 +31,8 @@ import javax.inject.Inject;
 import javax.interceptor.InvocationContext;
 import java.lang.reflect.InvocationTargetException;
 import java.lang.reflect.Method;
+import java.util.Arrays;
+import java.util.LinkedList;
 import java.util.concurrent.Callable;
 import java.util.concurrent.ConcurrentHashMap;
 import java.util.concurrent.ConcurrentMap;
@@ -44,6 +46,17 @@ public class DefaultFutureableStrategy implements FutureableStrategy
     private static final Class<?> COMPLETABLE_FUTURE;
     private static final Method COMPLETABLE_STAGE_TO_FUTURE;
 
+    // only for weld1
+    private static final boolean IS_WELD1;
+    private static final ThreadLocal<LinkedList<CallKey>> STACK = new ThreadLocal<LinkedList<CallKey>>()
+    {
+        @Override
+        protected LinkedList<CallKey> initialValue()
+        {
+            return new LinkedList<CallKey>();
+        }
+    };
+
     static
     {
         Class<?> completionStageClass = null;
@@ -63,6 +76,23 @@ public class DefaultFutureableStrategy implements FutureableStrategy
         COMPLETION_STAGE = completionStageClass;
         COMPLETABLE_FUTURE = completableFutureClass;
         COMPLETABLE_STAGE_TO_FUTURE = completionStageClassToCompletableFuture;
+
+        { // workaround for weld -> use a thread local to track the invocations
+            boolean weld1 = false;
+            try
+            {
+                final Class<?> impl = Thread.currentThread().getContextClassLoader()
+                        .loadClass("org.jboss.weld.manager.BeanManagerImpl");
+                final Package pck = impl.getPackage();
+                weld1 = "Weld Implementation".equals(pck.getImplementationTitle())
+                        && pck.getSpecificationVersion() != null && pck.getSpecificationVersion().startsWith("1.1.");
+            }
+            catch (final Throwable cnfe)
+            {
+                // no-op
+            }
+            IS_WELD1 = weld1;
+        }
     }
 
     @Inject
@@ -78,6 +108,33 @@ public class DefaultFutureableStrategy implements FutureableStrategy
     @Override
     public Object execute(final InvocationContext ic) throws Exception
     {
+        final CallKey invocationKey;
+        if (IS_WELD1)
+        {
+            invocationKey = new CallKey(ic);
+            { // weld1 workaround
+                final LinkedList<CallKey> stack = STACK.get();
+                if (!stack.isEmpty() && stack.getLast().equals(invocationKey))
+                {
+                    try
+                    {
+                        return ic.proceed();
+                    }
+                    finally
+                    {
+                        if (stack.isEmpty())
+                        {
+                            STACK.remove();
+                        }
+                    }
+                }
+            }
+        }
+        else
+        {
+            invocationKey = null;
+        }
+
         // validate usage
         final Class<?> returnType = ic.getMethod().getReturnType();
         if (!Future.class.isAssignableFrom(returnType) &&
@@ -104,6 +161,16 @@ public class DefaultFutureableStrategy implements FutureableStrategy
             @Override
             public Object call() throws Exception
             {
+                final LinkedList<CallKey> callStack;
+                if (IS_WELD1)
+                {
+                    callStack = STACK.get();
+                    callStack.add(invocationKey);
+                }
+                else
+                {
+                    callStack = null;
+                }
                 try
                 {
                     final Object proceed = ic.proceed();
@@ -120,6 +187,17 @@ public class DefaultFutureableStrategy implements FutureableStrategy
                 {
                     throw ExceptionUtils.throwAsRuntimeException(e);
                 }
+                finally
+                {
+                    if (IS_WELD1)
+                    {
+                        callStack.removeLast();
+                        if (callStack.isEmpty())
+                        {
+                            STACK.remove();
+                        }
+                    }
+                }
             }
         };
 
@@ -152,4 +230,39 @@ public class DefaultFutureableStrategy implements FutureableStrategy
         }
         return executorService;
     }
+
+    private static final class CallKey
+    {
+        private final InvocationContext ic;
+        private final int hash;
+
+        private CallKey(final InvocationContext ic)
+        {
+            this.ic = ic;
+
+            final Object[] parameters = ic.getParameters();
+            this.hash = ic.getMethod().hashCode() + (parameters == null ? 0 : Arrays.hashCode(parameters));
+        }
+
+        @Override
+        public boolean equals(final Object o)
+        {
+            return this == o || !(o == null || getClass() != o.getClass()) && equals(ic,
CallKey.class.cast(o).ic);
+        }
+
+        @Override
+        public int hashCode()
+        {
+            return hash;
+        }
+
+        private boolean equals(final InvocationContext ic1, final InvocationContext ic2)
+        {
+            final Object[] parameters1 = ic1.getParameters();
+            final Object[] parameters2 = ic2.getParameters();
+            return ic2.getMethod().equals(ic1.getMethod()) &&
+                    (parameters1 == parameters2 ||
+                    (parameters1 != null && parameters2 != null && Arrays.equals(parameters1,
ic2.getParameters())));
+        }
+    }
 }


Mime
View raw message