public Object execute()

in deltaspike/core/impl/src/main/java/org/apache/deltaspike/core/impl/future/DefaultFutureableStrategy.java [109:223]


    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) &&
                !void.class.isAssignableFrom(returnType) &&
                (COMPLETION_STAGE == null || !COMPLETION_STAGE.isAssignableFrom(returnType)))
        {
            throw new IllegalArgumentException("Return type should be a CompletableStage, Future or void");
        }

        if (configByMethod == null)
        {
            synchronized (this)
            {
                if (configByMethod == null)
                {
                    configByMethod = new ConcurrentHashMap<Method, ExecutorService>();
                }
            }
        }

        // running < j8 we cant have cancellation
        //final AtomicReference<Callable<?>> cancelHook = new AtomicReference<Callable<?>>();
        final Callable<Object> invocation = new Callable<Object>()
        {
            @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();
                    final Future<?> future = COMPLETION_STAGE == null || !COMPLETION_STAGE.isInstance(proceed) ?
                            Future.class.cast(proceed) :
                            Future.class.cast(COMPLETABLE_STAGE_TO_FUTURE.invoke(proceed));
                    return future.get();
                }
                catch (final InvocationTargetException e)
                {
                    throw ExceptionUtils.throwAsRuntimeException(e.getCause());
                }
                catch (final Exception e)
                {
                    throw ExceptionUtils.throwAsRuntimeException(e);
                }
                finally
                {
                    if (IS_WELD1)
                    {
                        callStack.removeLast();
                        if (callStack.isEmpty())
                        {
                            STACK.remove();
                        }
                    }
                }
            }
        };

        final ExecutorService pool = getOrCreatePool(ic);
        
        if (void.class.isAssignableFrom(returnType))
        {
            pool.submit(invocation);
            return null;
        }
        
        if (COMPLETABLE_FUTURE == null)  // not on java 8 can only be a future
        {
            return pool.submit(invocation);
        }

        // java 8, use CompletableFuture, it impl CompletionStage and Future so everyone is happy
        final Object completableFuture = COMPLETABLE_FUTURE.newInstance();
        pool.submit(new J8PromiseCompanionTask(completableFuture, invocation));
        // TODO: handle cancel
        return completableFuture;
    }