Search in sources :

Example 6 with ComponentEventRequestParameters

use of org.apache.tapestry5.services.ComponentEventRequestParameters in project tapestry-5 by apache.

the class ComponentEventLinkEncoderImpl method createComponentEventLink.

public Link createComponentEventLink(ComponentEventRequestParameters parameters, boolean forForm) {
    StringBuilder builder = new StringBuilder(BUFFER_SIZE);
    // Build up the absolute URI.
    String activePageName = parameters.getActivePageName();
    String containingPageName = parameters.getContainingPageName();
    String eventType = parameters.getEventType();
    String nestedComponentId = parameters.getNestedComponentId();
    boolean hasComponentId = InternalUtils.isNonBlank(nestedComponentId);
    builder.append(contextPath);
    encodeAppFolderAndLocale(builder);
    builder.append(SLASH);
    builder.append(activePageName.toLowerCase());
    if (hasComponentId) {
        builder.append('.');
        builder.append(nestedComponentId);
    }
    if (!hasComponentId || !eventType.equals(EventConstants.ACTION)) {
        builder.append(':');
        builder.append(encodePageName(eventType));
    }
    appendContext(true, parameters.getEventContext(), builder);
    Link result = new LinkImpl(builder.toString(), forForm, requestSecurityManager.checkPageSecurity(activePageName), response, contextPathEncoder, baseURLSource);
    EventContext pageActivationContext = parameters.getPageActivationContext();
    if (pageActivationContext.getCount() != 0) {
        // Reuse the builder
        builder.setLength(0);
        appendContext(true, pageActivationContext, builder);
        // Omit that first slash
        result.addParameter(InternalConstants.PAGE_CONTEXT_NAME, builder.substring(1));
    }
    if (!containingPageName.equalsIgnoreCase(activePageName))
        result.addParameter(InternalConstants.CONTAINER_PAGE_NAME, encodePageName(containingPageName));
    return result;
}
Also used : Link(org.apache.tapestry5.http.Link)

Example 7 with ComponentEventRequestParameters

use of org.apache.tapestry5.services.ComponentEventRequestParameters in project tapestry-5 by apache.

the class ComponentEventLinkEncoderImpl method decodeComponentEventRequest.

public ComponentEventRequestParameters decodeComponentEventRequest(Request request) {
    String explicitLocale = null;
    // Split the path around slashes into a mutable list of terms, which will be consumed term by term.
    String requestPath = request.getPath();
    if (applicationFolderPrefix != null) {
        requestPath = removeApplicationPrefix(requestPath);
    }
    List<String> path = splitPath(requestPath);
    if (path.isEmpty()) {
        return null;
    }
    // Next up: the locale (which is optional)
    String potentialLocale = path.get(0);
    if (localizationSetter.isSupportedLocaleName(potentialLocale)) {
        explicitLocale = potentialLocale;
        path.remove(0);
    }
    StringBuilder pageName = new StringBuilder(100);
    String sep = "";
    while (!path.isEmpty()) {
        String name = path.remove(0);
        String eventType = EventConstants.ACTION;
        String nestedComponentId = "";
        boolean found = false;
        // First, look for an explicit action name.
        int colonx = name.lastIndexOf(':');
        if (colonx > 0) {
            found = true;
            eventType = name.substring(colonx + 1);
            name = name.substring(0, colonx);
        }
        int dotx = name.indexOf('.');
        if (dotx > 0) {
            found = true;
            nestedComponentId = name.substring(dotx + 1);
            name = name.substring(0, dotx);
        }
        pageName.append(sep).append(name);
        if (found) {
            ComponentEventRequestParameters result = validateAndConstructComponentEventRequest(request, pageName.toString(), nestedComponentId, eventType, path);
            if (result == null) {
                return result;
            }
            if (explicitLocale == null) {
                setLocaleFromRequest(request);
            } else {
                localizationSetter.setLocaleFromLocaleName(explicitLocale);
            }
            return result;
        }
        // Continue on to the next name in the path
        sep = "/";
    }
    return null;
}
Also used : ComponentEventRequestParameters(org.apache.tapestry5.services.ComponentEventRequestParameters)

Example 8 with ComponentEventRequestParameters

use of org.apache.tapestry5.services.ComponentEventRequestParameters in project tapestry-5 by apache.

the class ComponentEventRequestHandlerImpl method handle.

public void handle(ComponentEventRequestParameters parameters) throws IOException {
    Page activePage = cache.get(parameters.getActivePageName());
    if (pageActivator.activatePage(activePage.getRootElement().getComponentResources(), parameters.getPageActivationContext(), resultProcessor)) {
        return;
    }
    Page containerPage = cache.get(parameters.getContainingPageName());
    TrackableComponentEventCallback callback = new ComponentResultProcessorWrapper(resultProcessor);
    environment.push(ComponentEventResultProcessor.class, resultProcessor);
    environment.push(TrackableComponentEventCallback.class, callback);
    ComponentPageElement element = containerPage.getComponentElementByNestedId(parameters.getNestedComponentId());
    boolean handled = element.triggerContextEvent(parameters.getEventType(), parameters.getEventContext(), callback);
    if (!handled) {
        throw new TapestryException(String.format("Request event '%s' (on component %s) was not handled; you must provide a matching event handler method in the component or in one of its containers.", parameters.getEventType(), element.getCompleteId()), element, null);
    }
    environment.pop(TrackableComponentEventCallback.class);
    environment.pop(ComponentEventResultProcessor.class);
    if (callback.isAborted()) {
        callback.rethrow();
        return;
    }
    if (!response.isCommitted()) {
        resultProcessor.processResultValue(activePage.getName());
    }
}
Also used : ComponentPageElement(org.apache.tapestry5.internal.structure.ComponentPageElement) TrackableComponentEventCallback(org.apache.tapestry5.TrackableComponentEventCallback) Page(org.apache.tapestry5.internal.structure.Page) TapestryException(org.apache.tapestry5.commons.internal.util.TapestryException)

Example 9 with ComponentEventRequestParameters

use of org.apache.tapestry5.services.ComponentEventRequestParameters in project tapestry-5 by apache.

the class LinkSourceImplTest method testEventLinkCreation2.

private void testEventLinkCreation2(String pageName, String nestedId, String eventType, boolean forForm, Object... context) {
    Page primaryPage = mockPage();
    PageRenderQueue queue = mockPageRenderQueue();
    PageActivationContextCollector collector = mockPageActivationContextCollector();
    LinkCreationListener2 listener = mockLinkCreationListener2();
    ComponentEventLinkEncoder linkEncoder = mockComponentEventLinkEncoder();
    Link link = mockLink();
    ArrayEventContext eventContext = new ArrayEventContext(typeCoercer, context);
    ArrayEventContext pageEventContext = new ArrayEventContext(typeCoercer, "a", "b");
    train_getRenderingPage(queue, null);
    train_getName(primaryPage, pageName);
    train_collectPageActivationContext(collector, pageName, "a", "b");
    ComponentEventRequestParameters parameters = new ComponentEventRequestParameters(pageName, pageName, nestedId, eventType, pageEventContext, eventContext);
    expect(linkEncoder.createComponentEventLink(parameters, forForm)).andReturn(link);
    listener.createdComponentEventLink(link, parameters);
    List<LinkCreationListener2> configuration = CollectionFactory.newList(listener);
    replay();
    LinkSource source = new LinkSourceImpl(queue, collector, typeCoercer, null, linkEncoder, null, null, configuration);
    Link returnedLink = source.createComponentEventLink(primaryPage, nestedId, eventType, forForm, context);
    // Make sure the same link is returned.
    assertSame(returnedLink, link);
    verify();
}
Also used : ComponentEventLinkEncoder(org.apache.tapestry5.services.ComponentEventLinkEncoder) ComponentEventRequestParameters(org.apache.tapestry5.services.ComponentEventRequestParameters) Page(org.apache.tapestry5.internal.structure.Page) LinkCreationListener2(org.apache.tapestry5.services.LinkCreationListener2) Link(org.apache.tapestry5.http.Link)

Example 10 with ComponentEventRequestParameters

use of org.apache.tapestry5.services.ComponentEventRequestParameters in project tapestry-5 by apache.

the class AjaxComponentEventRequestHandler method handle.

public void handle(ComponentEventRequestParameters parameters) throws IOException {
    Page activePage = cache.get(parameters.getActivePageName());
    final Holder<Boolean> resultProcessorInvoked = Holder.create();
    resultProcessorInvoked.put(false);
    ComponentEventResultProcessor interceptor = new ComponentEventResultProcessor() {

        public void processResultValue(Object value) throws IOException {
            resultProcessorInvoked.put(true);
            resultProcessor.processResultValue(value);
        }
    };
    // If we end up doing a partial render, the page render queue service needs to know the
    // page that will be rendered (for logging purposes, if nothing else).
    queue.setRenderingPage(activePage);
    request.setAttribute(InternalConstants.PAGE_NAME_ATTRIBUTE_NAME, parameters.getActivePageName());
    if (pageActivator.activatePage(activePage.getRootElement().getComponentResources(), parameters.getPageActivationContext(), interceptor))
        return;
    Page containerPage = cache.get(parameters.getContainingPageName());
    ComponentPageElement element = containerPage.getComponentElementByNestedId(parameters.getNestedComponentId());
    // In many cases, the triggered element is a Form that needs to be able to
    // pass its event handler return values to the correct result processor.
    // This is certainly the case for forms.
    TrackableComponentEventCallback callback = new ComponentResultProcessorWrapper(interceptor);
    environment.push(ComponentEventResultProcessor.class, interceptor);
    environment.push(TrackableComponentEventCallback.class, callback);
    boolean handled = element.triggerContextEvent(parameters.getEventType(), parameters.getEventContext(), callback);
    if (!handled)
        throw new TapestryException(String.format("Request event '%s' (on component %s) was not handled; you must provide a matching event handler method in the component or in one of its containers.", parameters.getEventType(), element.getCompleteId()), element, null);
    environment.pop(TrackableComponentEventCallback.class);
    environment.pop(ComponentEventResultProcessor.class);
    // If the result processor was passed a value, then it will already have rendered. Otherwise it was not passed a value,
    // but it's still possible that we still want to do a partial page render ... if filters were added to the render queue.
    // In that event, run the partial page render now and return.
    boolean wasInvoked = resultProcessorInvoked.get();
    if ((!wasInvoked) && queue.isPartialRenderInitialized()) {
        partialRenderer.renderPartialPageMarkup();
        return;
    }
    if (wasInvoked) {
        return;
    }
    // Send an empty JSON reply if no value was returned from the component event handler method.
    // This is the typical behavior when an Ajax component event handler returns null. It still
    // will go through a pipeline that will add information related to partial page rendering.
    resultProcessor.processResultValue(new JSONObject());
}
Also used : ComponentPageElement(org.apache.tapestry5.internal.structure.ComponentPageElement) ComponentEventResultProcessor(org.apache.tapestry5.services.ComponentEventResultProcessor) JSONObject(org.apache.tapestry5.json.JSONObject) TrackableComponentEventCallback(org.apache.tapestry5.TrackableComponentEventCallback) Page(org.apache.tapestry5.internal.structure.Page) JSONObject(org.apache.tapestry5.json.JSONObject) TapestryException(org.apache.tapestry5.commons.internal.util.TapestryException)

Aggregations

ComponentEventRequestParameters (org.apache.tapestry5.services.ComponentEventRequestParameters)13 Link (org.apache.tapestry5.http.Link)7 Page (org.apache.tapestry5.internal.structure.Page)7 Request (org.apache.tapestry5.http.services.Request)6 ComponentClassResolver (org.apache.tapestry5.services.ComponentClassResolver)6 LocalizationSetter (org.apache.tapestry5.services.LocalizationSetter)6 MetaDataLocator (org.apache.tapestry5.services.MetaDataLocator)6 Test (org.testng.annotations.Test)6 Response (org.apache.tapestry5.http.services.Response)5 Dispatcher (org.apache.tapestry5.http.services.Dispatcher)4 EmptyEventContext (org.apache.tapestry5.internal.EmptyEventContext)4 ComponentRequestHandler (org.apache.tapestry5.services.ComponentRequestHandler)4 ComponentEventLinkEncoder (org.apache.tapestry5.services.ComponentEventLinkEncoder)3 LinkCreationListener2 (org.apache.tapestry5.services.LinkCreationListener2)3 TrackableComponentEventCallback (org.apache.tapestry5.TrackableComponentEventCallback)2 TapestryException (org.apache.tapestry5.commons.internal.util.TapestryException)2 URLEventContext (org.apache.tapestry5.internal.URLEventContext)2 ComponentPageElement (org.apache.tapestry5.internal.structure.ComponentPageElement)2 ComponentEventRequestHandler (org.apache.tapestry5.services.ComponentEventRequestHandler)2 Locale (java.util.Locale)1