001// Copyright 2010, 2011 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.services;
016
017/**
018 * An event handler method may return an instance of this class to trigger the rendering
019 * of a particular page without causing a redirect to that page; the rendering takes place as part
020 * of the original component event request, thus forming the opposite of Tapestry's normal
021 * redirect-after-event behavior.
022 * <p>
023 * The page will be activated using the provided page activation context (or an empty page activation
024 * context). Starting with 5.3, the page activation step can be bypassed. Rendering occurs using
025 * the standard {@link PageRenderRequestHandler} pipeline.
026 * </p>
027 *
028 * @since 5.2.0
029 */
030public final class StreamPageContent
031{
032    private final Class<?> pageClass;
033
034    private final Object[] pageActivationContext;
035
036    private final boolean bypassActivation;
037
038    /**
039     * Creates an instance that streams the activate page's content (that is, {@link #getPageClass()} will be null).
040     * Unless otherwise configured, page activation will take place.
041     *
042     * @since 5.4
043     */
044    public StreamPageContent()
045    {
046        this(null);
047    }
048
049    /**
050     * Renders the page using an empty page activation context.
051     *
052     * @param pageClass class of the page to render
053     */
054    public StreamPageContent(final Class<?> pageClass)
055    {
056        this(pageClass, (Object[]) null);
057    }
058
059    /**
060     * Renders the page using the supplied page activation context.
061     *
062     * @param pageClass             class of the page to render, or null to render the currently active page (as per
063     *                              {@link org.apache.tapestry5.services.RequestGlobals#getActivePageName()})
064     * @param pageActivationContext activation context of the page
065     */
066    public StreamPageContent(final Class<?> pageClass, final Object... pageActivationContext)
067    {
068        this(pageClass, pageActivationContext, false);
069    }
070
071    private StreamPageContent(Class<?> pageClass, Object[] pageActivationContext, boolean bypassActivation)
072    {
073        this.pageClass = pageClass;
074        this.pageActivationContext = pageActivationContext;
075        this.bypassActivation = bypassActivation;
076    }
077
078    /**
079     * Returns the class of the page to render, or null to indicate that the active page for the request should simply
080     * be re-rendered.
081     */
082    public Class<?> getPageClass()
083    {
084        return this.pageClass;
085    }
086
087    /**
088     * Returns the activation context of the page. May return null to indicate an empty activation context.
089     */
090    public Object[] getPageActivationContext()
091    {
092        return this.pageActivationContext;
093    }
094
095    /**
096     * Returns a new StreamPageInstance with the {@linkplain #isBypassActivation bypass activation flag} set to true, such that
097     * page activation will be bypassed when the page is rendered.
098     *
099     * @return new instance
100     */
101    public StreamPageContent withoutActivation()
102    {
103        if (pageActivationContext != null)
104        {
105            throw new IllegalStateException("A StreamPageContext instance created with a page activation context may not be converted to bypass page activation.");
106        }
107
108        return new StreamPageContent(pageClass, null, true);
109    }
110
111    /**
112     * @return true if configured to bypass activation
113     */
114    public boolean isBypassActivation()
115    {
116        return bypassActivation;
117    }
118}