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}