Search in sources :

Example 6 with Invokable

use of org.apache.tapestry5.ioc.Invokable in project tapestry-5 by apache.

the class ModuleImpl method create.

/**
 * Creates the service and updates the cache of created services.
 *
 * @param eagerLoadProxies a list into which any eager loaded proxies should be added
 */
private Object create(final ServiceDef3 def, final Collection<EagerLoadServiceProxy> eagerLoadProxies) {
    final String serviceId = def.getServiceId();
    final Logger logger = registry.getServiceLogger(serviceId);
    final Class serviceInterface = def.getServiceInterface();
    final boolean canBeProxied = canBeProxiedPredicate.test(serviceInterface);
    String description = String.format("Creating %s service %s", canBeProxied ? "proxy for" : "non-proxied instance of", serviceId);
    if (logger.isDebugEnabled())
        logger.debug(description);
    final Module module = this;
    Invokable operation = new Invokable() {

        @Override
        public Object invoke() {
            try {
                ServiceBuilderResources resources = new ServiceResourcesImpl(registry, module, def, proxyFactory, logger);
                // Build up a stack of operations that will be needed to realize the service
                // (by the proxy, at a later date).
                ObjectCreator creator = def.createServiceCreator(resources);
                // For non-proxyable services, we immediately create the service implementation
                // and return it. There's no interface to proxy, which throws out the possibility of
                // deferred instantiation, service lifecycles, and decorators.
                ServiceLifecycle2 lifecycle = registry.getServiceLifecycle(def.getServiceScope());
                if (!canBeProxied) {
                    if (lifecycle.requiresProxy())
                        throw new IllegalArgumentException(String.format("Service scope '%s' requires a proxy, but the service does not have a service interface (necessary to create a proxy). Provide a service interface or select a different service scope.", def.getServiceScope()));
                    return creator.createObject();
                }
                creator = new OperationTrackingObjectCreator(registry, String.format("Instantiating service %s implementation via %s", serviceId, creator), creator);
                creator = new LifecycleWrappedServiceCreator(lifecycle, resources, creator);
                // Marked services (or services inside marked modules) are not decorated.
                // TapestryIOCModule prevents decoration of its services. Note that all decorators will decorate
                // around the aspect interceptor, which wraps around the core service implementation.
                boolean allowDecoration = !def.isPreventDecoration();
                if (allowDecoration) {
                    creator = new AdvisorStackBuilder(def, creator, getAspectDecorator(), registry);
                    creator = new InterceptorStackBuilder(def, creator, registry);
                }
                // Add a wrapper that checks for recursion.
                creator = new RecursiveServiceCreationCheckWrapper(def, creator, logger);
                creator = new OperationTrackingObjectCreator(registry, "Realizing service " + serviceId, creator);
                JustInTimeObjectCreator delegate = new JustInTimeObjectCreator(tracker, creator, serviceId);
                Object proxy = createProxy(resources, delegate, def.isPreventDecoration());
                registry.addRegistryShutdownListener(delegate);
                if (def.isEagerLoad() && eagerLoadProxies != null)
                    eagerLoadProxies.add(delegate);
                tracker.setStatus(serviceId, Status.VIRTUAL);
                return proxy;
            } catch (Exception ex) {
                ex.printStackTrace();
                throw new RuntimeException(IOCMessages.errorBuildingService(serviceId, def, ex), ex);
            }
        }
    };
    return registry.invoke(description, operation);
}
Also used : JustInTimeObjectCreator(org.apache.tapestry5.ioc.internal.services.JustInTimeObjectCreator) Logger(org.slf4j.Logger) ServiceBuilderResources(org.apache.tapestry5.ioc.ServiceBuilderResources) InvocationTargetException(java.lang.reflect.InvocationTargetException) ObjectStreamException(java.io.ObjectStreamException) JustInTimeObjectCreator(org.apache.tapestry5.ioc.internal.services.JustInTimeObjectCreator) ServiceLifecycle2(org.apache.tapestry5.ioc.ServiceLifecycle2) Invokable(org.apache.tapestry5.ioc.Invokable)

Example 7 with Invokable

use of org.apache.tapestry5.ioc.Invokable in project tapestry-5 by apache.

the class OnEventWorker method createRequestBodyProvider.

@SuppressWarnings({ "unchecked", "rawtypes" })
private EventHandlerMethodParameterProvider createRequestBodyProvider(PlasticMethod method, final int parameterIndex, final String parameterTypeName, final boolean allowEmpty) {
    final String methodIdentifier = method.getMethodIdentifier();
    return (event) -> {
        Invokable<Object> operation = () -> {
            Class parameterType = classCache.forName(parameterTypeName);
            Optional result = restSupport.getRequestBodyAs(parameterType);
            if (!allowEmpty && !result.isPresent()) {
                throw new RuntimeException(String.format("The request has an empty body and %s has one parameter with @RequestBody(allowEmpty=false)", methodIdentifier));
            }
            return result.orElse(null);
        };
        return operationTracker.invoke("Converting HTTP request body for @RequestBody parameter", operation);
    };
}
Also used : PlasticField(org.apache.tapestry5.plastic.PlasticField) Arrays(java.util.Arrays) Array(java.lang.reflect.Array) Flow(org.apache.tapestry5.func.Flow) JSONObject(org.apache.tapestry5.json.JSONObject) MethodInvocation(org.apache.tapestry5.plastic.MethodInvocation) ComponentClassCache(org.apache.tapestry5.internal.services.ComponentClassCache) ExceptionUtils(org.apache.tapestry5.commons.util.ExceptionUtils) PublishServerSideEvents(org.apache.tapestry5.corelib.mixins.PublishServerSideEvents) CollectionFactory(org.apache.tapestry5.commons.util.CollectionFactory) Map(java.util.Map) TransformConstants(org.apache.tapestry5.services.TransformConstants) LocalVariable(org.apache.tapestry5.plastic.LocalVariable) JSONArray(org.apache.tapestry5.json.JSONArray) ValueEncoder(org.apache.tapestry5.ValueEncoder) Event(org.apache.tapestry5.runtime.Event) PageLifecycleListener(org.apache.tapestry5.runtime.PageLifecycleListener) Predicate(org.apache.tapestry5.func.Predicate) Set(java.util.Set) Invokable(org.apache.tapestry5.ioc.Invokable) ComponentEvent(org.apache.tapestry5.runtime.ComponentEvent) MutableComponentModel(org.apache.tapestry5.model.MutableComponentModel) MethodAdvice(org.apache.tapestry5.plastic.MethodAdvice) List(java.util.List) ComponentClassTransformWorker2(org.apache.tapestry5.services.transform.ComponentClassTransformWorker2) Optional(java.util.Optional) Pattern(java.util.regex.Pattern) EventContext(org.apache.tapestry5.EventContext) InternalConstants(org.apache.tapestry5.internal.InternalConstants) RequestBody(org.apache.tapestry5.annotations.RequestBody) PublishEvent(org.apache.tapestry5.annotations.PublishEvent) MethodParameter(org.apache.tapestry5.plastic.MethodParameter) Request(org.apache.tapestry5.http.services.Request) OnEvent(org.apache.tapestry5.annotations.OnEvent) LocalVariableCallback(org.apache.tapestry5.plastic.LocalVariableCallback) ComponentResources(org.apache.tapestry5.ComponentResources) RequestParameter(org.apache.tapestry5.annotations.RequestParameter) ValueEncoderSource(org.apache.tapestry5.services.ValueEncoderSource) RestSupport(org.apache.tapestry5.http.services.RestSupport) StaticActivationContextValue(org.apache.tapestry5.annotations.StaticActivationContextValue) PlasticMethod(org.apache.tapestry5.plastic.PlasticMethod) UnknownValueException(org.apache.tapestry5.commons.util.UnknownValueException) Condition(org.apache.tapestry5.plastic.Condition) MethodDescription(org.apache.tapestry5.plastic.MethodDescription) InstructionBuilderCallback(org.apache.tapestry5.plastic.InstructionBuilderCallback) InstructionBuilder(org.apache.tapestry5.plastic.InstructionBuilder) PlasticClass(org.apache.tapestry5.plastic.PlasticClass) TransformationSupport(org.apache.tapestry5.services.transform.TransformationSupport) OperationTracker(org.apache.tapestry5.ioc.OperationTracker) DisableStrictChecks(org.apache.tapestry5.annotations.DisableStrictChecks) F(org.apache.tapestry5.func.F) InternalUtils(org.apache.tapestry5.ioc.internal.util.InternalUtils) Mapper(org.apache.tapestry5.func.Mapper) TapestryException(org.apache.tapestry5.commons.internal.util.TapestryException) Optional(java.util.Optional) Invokable(org.apache.tapestry5.ioc.Invokable) PlasticClass(org.apache.tapestry5.plastic.PlasticClass)

Example 8 with Invokable

use of org.apache.tapestry5.ioc.Invokable in project tapestry-5 by apache.

the class PersistenceContextSpecificEntityTransactionManager method invokeInTransaction.

public <T> T invokeInTransaction(Invokable<T> invokable) {
    if (transactionBeingCommitted) {
        // to be executed later
        if (invokable instanceof VoidInvokable) {
            invokableUnitsForSequentialTransactions.push(invokable);
            return null;
        } else {
            rollbackTransaction(getTransaction());
            throw new RuntimeException("Current transaction is already being committed. Transactions started @PostCommit are not allowed to return a value");
        }
    }
    final boolean topLevel = invokableUnits.isEmpty();
    invokableUnits.push(invokable);
    if (!topLevel) {
        if (logger.isWarnEnabled()) {
            logger.warn("Nested transaction detected, current depth = " + invokableUnits.size());
        }
    }
    final EntityTransaction transaction = getTransaction();
    try {
        T result = invokable.invoke();
        if (topLevel && invokableUnits.peek().equals(invokable)) {
            if (transaction.isActive()) {
                invokeBeforeCommit(transaction);
            }
            if (transaction.isActive()) {
                transactionBeingCommitted = true;
                transaction.commit();
                transactionBeingCommitted = false;
                invokableUnits.clear();
                invokeAfterCommit();
                if (invokableUnitsForSequentialTransactions.size() > 0)
                    invokeInTransaction(invokableUnitsForSequentialTransactions.pop());
            }
        }
        return result;
    } catch (final RuntimeException e) {
        if (transaction != null && transaction.isActive()) {
            rollbackTransaction(transaction);
        }
        throw e;
    } finally {
        invokableUnits.remove(invokable);
    }
}
Also used : EntityTransaction(javax.persistence.EntityTransaction) VoidInvokable(org.apache.tapestry5.jpa.EntityTransactionManager.VoidInvokable)

Example 9 with Invokable

use of org.apache.tapestry5.ioc.Invokable in project tapestry-5 by apache.

the class SpringModuleDef method createContributionToMasterObjectProvider.

private ContributionDef createContributionToMasterObjectProvider() {
    ContributionDef def = new AbstractContributionDef() {

        @Override
        public String getServiceId() {
            return "MasterObjectProvider";
        }

        @Override
        public void contribute(ModuleBuilderSource moduleSource, ServiceResources resources, OrderedConfiguration configuration) {
            final OperationTracker tracker = resources.getTracker();
            final ApplicationContext context = resources.getService(SERVICE_ID, ApplicationContext.class);
            final ObjectProvider springBeanProvider = new ObjectProvider() {

                @Override
                public <T> T provide(Class<T> objectType, AnnotationProvider annotationProvider, ObjectLocator locator) {
                    Map beanMap = context.getBeansOfType(objectType);
                    switch(beanMap.size()) {
                        case 0:
                            return null;
                        case 1:
                            Object bean = beanMap.values().iterator().next();
                            return objectType.cast(bean);
                        default:
                            String message = String.format("Spring context contains %d beans assignable to type %s: %s.", beanMap.size(), PlasticUtils.toTypeName(objectType), InternalUtils.joinSorted(beanMap.keySet()));
                            throw new IllegalArgumentException(message);
                    }
                }
            };
            final ObjectProvider springBeanProviderInvoker = new ObjectProvider() {

                @Override
                public <T> T provide(final Class<T> objectType, final AnnotationProvider annotationProvider, final ObjectLocator locator) {
                    return tracker.invoke("Resolving dependency by searching Spring ApplicationContext", new Invokable<T>() {

                        @Override
                        public T invoke() {
                            return springBeanProvider.provide(objectType, annotationProvider, locator);
                        }
                    });
                }
            };
            ObjectProvider outerCheck = new ObjectProvider() {

                @Override
                public <T> T provide(Class<T> objectType, AnnotationProvider annotationProvider, ObjectLocator locator) {
                    if (!applicationContextCreated.get())
                        return null;
                    return springBeanProviderInvoker.provide(objectType, annotationProvider, locator);
                }
            };
            configuration.add("SpringBean", outerCheck, "after:AnnotationBasedContributions", "after:ServiceOverride");
        }
    };
    return def;
}
Also used : OperationTracker(org.apache.tapestry5.ioc.OperationTracker) ModuleBuilderSource(org.apache.tapestry5.ioc.ModuleBuilderSource) ContributionDef(org.apache.tapestry5.ioc.def.ContributionDef) AbstractContributionDef(org.apache.tapestry5.http.internal.AbstractContributionDef) ConfigurableApplicationContext(org.springframework.context.ConfigurableApplicationContext) WebApplicationContext(org.springframework.web.context.WebApplicationContext) ApplicationContext(org.springframework.context.ApplicationContext) ConfigurableWebApplicationContext(org.springframework.web.context.ConfigurableWebApplicationContext) AbstractContributionDef(org.apache.tapestry5.http.internal.AbstractContributionDef) ServiceResources(org.apache.tapestry5.ioc.ServiceResources) Map(java.util.Map)

Aggregations

Invokable (org.apache.tapestry5.ioc.Invokable)4 Map (java.util.Map)2 OperationTracker (org.apache.tapestry5.ioc.OperationTracker)2 ObjectStreamException (java.io.ObjectStreamException)1 Array (java.lang.reflect.Array)1 InvocationTargetException (java.lang.reflect.InvocationTargetException)1 Arrays (java.util.Arrays)1 List (java.util.List)1 Optional (java.util.Optional)1 Set (java.util.Set)1 Pattern (java.util.regex.Pattern)1 EntityTransaction (javax.persistence.EntityTransaction)1 ComponentResources (org.apache.tapestry5.ComponentResources)1 EventContext (org.apache.tapestry5.EventContext)1 ValueEncoder (org.apache.tapestry5.ValueEncoder)1 DisableStrictChecks (org.apache.tapestry5.annotations.DisableStrictChecks)1 OnEvent (org.apache.tapestry5.annotations.OnEvent)1 PublishEvent (org.apache.tapestry5.annotations.PublishEvent)1 RequestBody (org.apache.tapestry5.annotations.RequestBody)1 RequestParameter (org.apache.tapestry5.annotations.RequestParameter)1