    001// Copyright 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.ComponentResources;
    020import org.apache.tapestry5.EventConstants;
    021import org.apache.tapestry5.EventContext;
    022import org.apache.tapestry5.MetaDataConstants;
    023import org.apache.tapestry5.TrackableComponentEventCallback;
    024import org.apache.tapestry5.http.services.Request;
    025import org.apache.tapestry5.internal.InternalConstants;
    026import org.apache.tapestry5.services.ComponentEventResultProcessor;
    027import org.apache.tapestry5.services.MetaDataLocator;
    028import org.slf4j.Logger;
    029
    030public class PageActivatorImpl implements PageActivator
    031{
    032    private final Logger logger;
    033
    034    private final MetaDataLocator metaDataLocator;
    035
    036    private final UnknownActivationContextHandler unknownActivationContextHandler;
    037
    038    private final Request request;
    039
    040    public PageActivatorImpl(Logger logger, MetaDataLocator metaDataLocator,
    041                             UnknownActivationContextHandler unknownActivationContextHandler,
    042                             Request request)
    043    {
    044        this.logger = logger;
    045        this.metaDataLocator = metaDataLocator;
    046        this.unknownActivationContextHandler = unknownActivationContextHandler;
    047        this.request = request;
    048    }
    049
    050    @SuppressWarnings("rawtypes")
    051    public boolean activatePage(ComponentResources pageResources, EventContext activationContext,
    052            ComponentEventResultProcessor resultProcessor) throws IOException
    053    {
    054        TrackableComponentEventCallback callback = new ComponentResultProcessorWrapper(resultProcessor);
    055
    056        boolean handled = pageResources.triggerContextEvent(EventConstants.ACTIVATE, activationContext, callback);
    057
    058        boolean acceptEmpty = !pageResources.getComponentModel().handlesEvent(EventConstants.ACTIVATE) &&
    059                                activationContext.getCount() == 0;
    060
    061        boolean checkUnknown = metaDataLocator.findMeta(MetaDataConstants.UNKNOWN_ACTIVATION_CONTEXT_CHECK,
    062                                                        pageResources, Boolean.class);
    063
    064        if ( !handled && !acceptEmpty && checkUnknown &&
    065                !pageResources.getComponentModel().handleActivationEventContext())
    066        {
    067            logger.info("Page {} required an exact activation context, let's handle this", pageResources.getPageName());
    068            unknownActivationContextHandler.handleUnknownContext(pageResources, activationContext);
    069            return true;
    070        }
    071
    072        if (callback.isAborted())
    073        {
    074            callback.rethrow();
    075            return true;
    076        }
    077        else
    078        {
    079            if (InternalConstants.TRUE.equals(pageResources.getComponentModel().getMeta(
    080                    InternalConstants.REST_ENDPOINT_EVENT_HANDLER_METHOD_PRESENT)))
    081            {
    082                callback = new ComponentResultProcessorWrapper(resultProcessor);
    083                handled = pageResources.triggerContextEvent(
    084                        InternalConstants.HTTP_METHOD_EVENT_PREFIX + request.getMethod(), activationContext, callback);
    085                if (callback.isAborted())
    086                {
    087                    callback.rethrow();
    088                    return true;
    089                }
    090                else
    091                {
    092                    throw new RestEndpointNotFoundException(
    093                            String.format("Page %s (%s) has at least one REST endpoint event handler method "
    094                                    + "but none handled %s for this request", pageResources.getPageName(),
    095                                    pageResources.getPage().getClass().getName(), request.getMethod()));
    096                }
    097            }
    098        }
    099
    100        return false;
    101    }
    102
    103}