001// Licensed under the Apache License, Version 2.0 (the "License");002// you may not use this file except in compliance with the License.003// You may obtain a copy of the License at004//005// http://www.apache.org/licenses/LICENSE-2.0006//007// Unless required by applicable law or agreed to in writing, software008// distributed under the License is distributed on an "AS IS" BASIS,009// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.010// See the License for the specific language governing permissions and011// limitations under the License.012013package org.apache.tapestry5;014015import org.apache.tapestry5.annotations.ImmutableSessionPersistedObject;016import org.apache.tapestry5.internal.InternalConstants;017import org.apache.tapestry5.ioc.internal.util.InternalUtils;018import org.apache.tapestry5.services.PageRenderLinkSource;019020import java.io.Serializable;021022/**023 * A way of capturing the name of a page and the page activation context so that, at a future date,024 * the page can be invoked with that data. This kind of callback is very useful when creating more025 * complicated workflows, where access to a page is "interrupted" with some operation before026 * returning (via a callback) to the original flow.027 *028 * Since the callback is serializable, it can be stored in the session.029 * 030 * @since 5.2.0031 */032@ImmutableSessionPersistedObject033public class PageCallback implements Serializable034{035 private static final long serialVersionUID = -8067619978636824702L;036037 private String pageName;038039 private String[] activationContext;040041 public PageCallback(String pageName, String[] activationContext)042 {043 assert InternalUtils.isNonBlank(pageName);044 this.pageName = pageName;045 assert activationContext != null;046 this.activationContext = activationContext;047 }048049 public PageCallback(String pageName, EventContext activationContext)050 {051 this(pageName, activationContext.toStrings());052 }053054 public PageCallback(String pageName)055 {056 this(pageName, InternalConstants.EMPTY_STRING_ARRAY);057 }058059 public String getPageName()060 {061 return pageName;062 }063064 @Override065 public String toString()066 {067 if (hasActivationContext())068 return String.format("PageCallback[%s %s]", pageName, activationContextDescription());069070 return String.format("PageCallback[%s]", pageName);071 }072073 /** Does the activation context have any values? Used, typically, inside an override of {@link #toString()}. */074 protected final boolean hasActivationContext()075 {076 return activationContext.length > 0;077 }078079 /**080 * Returns the activation context as a string of value separated by slashes. Typically used inside081 * an override of {@link #toString()}.082 */083 protected final String activationContextDescription()084 {085 StringBuilder builder = new StringBuilder();086087 String sep = "";088089 for (String c : activationContext)090 {091 builder.append(sep);092 builder.append(c);093094 sep = "/";095 }096097 return builder.toString();098 }099100 /**101 * Converts the callback (the page name and activation context) to a link; such a link may be102 * returned from a event handler method to cause Tapestry to redirect to the page. Most of the103 * details104 * are encapsulated inside the {@link PageRenderLinkSource} service.105 * 106 * @param linkSource107 * used to generate the link108 * @return link corresponding to this callback109 */110 public Link toLink(PageRenderLinkSource linkSource)111 {112 return linkSource.createPageRenderLinkWithContext(pageName, (Object[]) activationContext);113 }114}