001// Copyright 2006, 2007, 2008, 2009, 2010 The Apache Software Foundation
002//
003// Licensed under the Apache License, Version 2.0 (the "License");
004// you may not use this file except in compliance with the License.
005// You may obtain a copy of the License at
006//
007// http://www.apache.org/licenses/LICENSE-2.0
008//
009// Unless required by applicable law or agreed to in writing, software
010// distributed under the License is distributed on an "AS IS" BASIS,
011// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
012// See the License for the specific language governing permissions and
013// limitations under the License.
014
015package org.apache.tapestry5.internal.services;
016
017import java.io.IOException;
018
019import org.apache.tapestry5.TrackableComponentEventCallback;
020import org.apache.tapestry5.internal.structure.ComponentPageElement;
021import org.apache.tapestry5.internal.structure.Page;
022import org.apache.tapestry5.ioc.annotations.Primary;
023import org.apache.tapestry5.ioc.internal.util.TapestryException;
024import org.apache.tapestry5.services.ComponentEventRequestHandler;
025import org.apache.tapestry5.services.ComponentEventRequestParameters;
026import org.apache.tapestry5.services.ComponentEventResultProcessor;
027import org.apache.tapestry5.services.Environment;
028import org.apache.tapestry5.services.Response;
029import org.apache.tapestry5.services.Traditional;
030
031@SuppressWarnings("unchecked")
032public class ComponentEventRequestHandlerImpl implements ComponentEventRequestHandler
033{
034    private final ComponentEventResultProcessor resultProcessor;
035
036    private final RequestPageCache cache;
037
038    private final Response response;
039
040    private final PageActivator pageActivator;
041
042    private final ActionRenderResponseGenerator generator;
043
044    private final Environment environment;
045
046    public ComponentEventRequestHandlerImpl(@Traditional
047    @Primary
048    ComponentEventResultProcessor resultProcessor,
049
050    RequestPageCache cache, Response response,
051
052    PageActivator pageActivator,
053
054    ActionRenderResponseGenerator generator, Environment environment)
055    {
056        this.resultProcessor = resultProcessor;
057        this.cache = cache;
058        this.response = response;
059        this.pageActivator = pageActivator;
060        this.generator = generator;
061        this.environment = environment;
062    }
063
064    public void handle(ComponentEventRequestParameters parameters) throws IOException
065    {
066        Page activePage = cache.get(parameters.getActivePageName());
067
068        if (pageActivator.activatePage(activePage.getRootElement().getComponentResources(), parameters
069                .getPageActivationContext(), resultProcessor))
070            return;
071
072        Page containerPage = cache.get(parameters.getContainingPageName());
073
074        TrackableComponentEventCallback callback = new ComponentResultProcessorWrapper(resultProcessor);
075
076        environment.push(ComponentEventResultProcessor.class, resultProcessor);
077        environment.push(TrackableComponentEventCallback.class, callback);
078
079        ComponentPageElement element = containerPage.getComponentElementByNestedId(parameters.getNestedComponentId());
080
081        boolean handled = element
082                .triggerContextEvent(parameters.getEventType(), parameters.getEventContext(), callback);
083
084        if (!handled)
085            throw new TapestryException(ServicesMessages.eventNotHandled(element, parameters.getEventType()), element,
086                    null);
087
088        environment.pop(TrackableComponentEventCallback.class);
089        environment.pop(ComponentEventResultProcessor.class);
090
091        if (callback.isAborted())
092        {
093            callback.rethrow();
094            return;
095        }
096
097        if (!response.isCommitted())
098            generator.generateResponse(activePage);
099    }
100}