Coverage Report - org.apache.tapestry5.internal.services.AjaxComponentEventRequestHandler
 
Classes in this File Line Coverage Branch Coverage Complexity
AjaxComponentEventRequestHandler
91%
31/34
75%
6/8
0
AjaxComponentEventRequestHandler$1
100%
4/4
N/A
0
 
 1  
 // Copyright 2007, 2008 The Apache Software Foundation
 2  
 //
 3  
 // Licensed under the Apache License, Version 2.0 (the "License");
 4  
 // you may not use this file except in compliance with the License.
 5  
 // You may obtain a copy of the License at
 6  
 //
 7  
 //     http://www.apache.org/licenses/LICENSE-2.0
 8  
 //
 9  
 // Unless required by applicable law or agreed to in writing, software
 10  
 // distributed under the License is distributed on an "AS IS" BASIS,
 11  
 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 12  
 // See the License for the specific language governing permissions and
 13  
 // limitations under the License.
 14  
 
 15  
 package org.apache.tapestry5.internal.services;
 16  
 
 17  
 import org.apache.tapestry5.ContentType;
 18  
 import org.apache.tapestry5.EventConstants;
 19  
 import org.apache.tapestry5.internal.InternalConstants;
 20  
 import org.apache.tapestry5.internal.structure.ComponentPageElement;
 21  
 import org.apache.tapestry5.internal.structure.Page;
 22  
 import org.apache.tapestry5.internal.util.Holder;
 23  
 import org.apache.tapestry5.ioc.internal.util.TapestryException;
 24  
 import org.apache.tapestry5.json.JSONObject;
 25  
 import org.apache.tapestry5.services.*;
 26  
 
 27  
 import java.io.IOException;
 28  
 
 29  
 /**
 30  
  * Similar to {@link ComponentEventRequestHandlerImpl}, but built around the Ajax request cycle, where the action
 31  
  * request sends back an immediate JSON response containing the new content.
 32  
  */
 33  44
 public class AjaxComponentEventRequestHandler implements ComponentEventRequestHandler
 34  
 {
 35  
     private final RequestPageCache cache;
 36  
 
 37  
     private final Request request;
 38  
 
 39  
     private final PageRenderQueue queue;
 40  
 
 41  
     private final ComponentEventResultProcessor resultProcessor;
 42  
 
 43  
     private final PageContentTypeAnalyzer pageContentTypeAnalyzer;
 44  
 
 45  
     private final Environment environment;
 46  
 
 47  
     private final AjaxPartialResponseRenderer partialRenderer;
 48  
 
 49  
     public AjaxComponentEventRequestHandler(RequestPageCache cache, Request request, PageRenderQueue queue,
 50  
                                             @Ajax ComponentEventResultProcessor resultProcessor,
 51  
                                             PageContentTypeAnalyzer pageContentTypeAnalyzer, Environment environment,
 52  
                                             AjaxPartialResponseRenderer partialRenderer)
 53  2
     {
 54  2
         this.cache = cache;
 55  2
         this.queue = queue;
 56  2
         this.resultProcessor = resultProcessor;
 57  2
         this.pageContentTypeAnalyzer = pageContentTypeAnalyzer;
 58  2
         this.request = request;
 59  2
         this.environment = environment;
 60  2
         this.partialRenderer = partialRenderer;
 61  2
     }
 62  
 
 63  
     public void handle(ComponentEventRequestParameters parameters) throws IOException
 64  
     {
 65  50
         Page activePage = cache.get(parameters.getActivePageName());
 66  
 
 67  50
         final Holder<Boolean> resultProcessorInvoked = Holder.create();
 68  50
         resultProcessorInvoked.put(false);
 69  
 
 70  50
         ComponentEventResultProcessor interceptor = new ComponentEventResultProcessor()
 71  
         {
 72  50
             public void processResultValue(Object value) throws IOException
 73  
             {
 74  44
                 resultProcessorInvoked.put(true);
 75  
 
 76  44
                 resultProcessor.processResultValue(value);
 77  44
             }
 78  
         };
 79  
 
 80  50
         ComponentResultProcessorWrapper callback = new ComponentResultProcessorWrapper(interceptor);
 81  
 
 82  50
         activePage.getRootElement().triggerContextEvent(EventConstants.ACTIVATE,
 83  
                                                         parameters.getPageActivationContext(), callback);
 84  
 
 85  
 
 86  50
         if (callback.isAborted()) return;
 87  
 
 88  
         // If we end up doing a partial render, the page render queue service needs to know the
 89  
         // page that will be rendered (for logging purposes, if nothing else).
 90  
 
 91  50
         queue.setRenderingPage(activePage);
 92  
 
 93  50
         ContentType contentType = pageContentTypeAnalyzer.findContentType(activePage);
 94  
 
 95  50
         request.setAttribute(InternalConstants.CONTENT_TYPE_ATTRIBUTE_NAME, contentType);
 96  
 
 97  50
         Page containerPage = cache.get(parameters.getContainingPageName());
 98  
 
 99  50
         ComponentPageElement element = containerPage.getComponentElementByNestedId(parameters.getNestedComponentId());
 100  
 
 101  
         // In many cases, the triggered element is a Form that needs to be able to
 102  
         // pass its event handler return values to the correct result processor.
 103  
         // This is certainly the case for forms.
 104  
 
 105  50
         environment.push(ComponentEventResultProcessor.class, interceptor);
 106  
 
 107  50
         boolean handled = element.triggerContextEvent(parameters.getEventType(), parameters.getEventContext(),
 108  
                                                       callback);
 109  
 
 110  48
         if (!handled)
 111  2
             throw new TapestryException(ServicesMessages.eventNotHandled(element, parameters.getEventType()), element,
 112  
                                         null);
 113  
 
 114  46
         environment.pop(ComponentEventResultProcessor.class);
 115  
 
 116  46
         if (queue.isPartialRenderInitialized())
 117  
         {
 118  36
             partialRenderer.renderPartialPageMarkup();
 119  36
             return;
 120  
         }
 121  
 
 122  
         // If  some other form of return value that's not a partial page render was send through to the
 123  
         // Ajax ComponentEventResultProcessor, then there's nothing more to do.
 124  
 
 125  10
         if (resultProcessorInvoked.get()) return;
 126  
 
 127  
         // Send an empty JSON reply if no value was returned from the component event handler method.
 128  
 
 129  0
         JSONObject reply = new JSONObject();
 130  
 
 131  0
         resultProcessor.processResultValue(reply);
 132  0
     }
 133  
 }