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    
015    package org.apache.tapestry5.internal.services;
016    
017    import java.io.IOException;
018    
019    import org.apache.tapestry5.TrackableComponentEventCallback;
020    import org.apache.tapestry5.internal.structure.ComponentPageElement;
021    import org.apache.tapestry5.internal.structure.Page;
022    import org.apache.tapestry5.ioc.annotations.Primary;
023    import org.apache.tapestry5.ioc.internal.util.TapestryException;
024    import org.apache.tapestry5.services.ComponentEventRequestHandler;
025    import org.apache.tapestry5.services.ComponentEventRequestParameters;
026    import org.apache.tapestry5.services.ComponentEventResultProcessor;
027    import org.apache.tapestry5.services.Environment;
028    import org.apache.tapestry5.services.Response;
029    import org.apache.tapestry5.services.Traditional;
030    
031    @SuppressWarnings("unchecked")
032    public 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    }