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 at 004// 005// http://www.apache.org/licenses/LICENSE-2.0 006// 007// Unless required by applicable law or agreed to in writing, software 008// 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 and 011// limitations under the License. 012 013package org.apache.tapestry5; 014 015import 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; 019 020import java.io.Serializable; 021 022/** 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 more 025 * complicated workflows, where access to a page is "interrupted" with some operation before 026 * 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.0 031 */ 032@ImmutableSessionPersistedObject 033public class PageCallback implements Serializable 034{ 035 private static final long serialVersionUID = -8067619978636824702L; 036 037 private String pageName; 038 039 private String[] activationContext; 040 041 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 } 048 049 public PageCallback(String pageName, EventContext activationContext) 050 { 051 this(pageName, activationContext.toStrings()); 052 } 053 054 public PageCallback(String pageName) 055 { 056 this(pageName, InternalConstants.EMPTY_STRING_ARRAY); 057 } 058 059 public String getPageName() 060 { 061 return pageName; 062 } 063 064 @Override 065 public String toString() 066 { 067 if (hasActivationContext()) 068 return String.format("PageCallback[%s %s]", pageName, activationContextDescription()); 069 070 return String.format("PageCallback[%s]", pageName); 071 } 072 073 /** 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 } 078 079 /** 080 * Returns the activation context as a string of value separated by slashes. Typically used inside 081 * an override of {@link #toString()}. 082 */ 083 protected final String activationContextDescription() 084 { 085 StringBuilder builder = new StringBuilder(); 086 087 String sep = ""; 088 089 for (String c : activationContext) 090 { 091 builder.append(sep); 092 builder.append(c); 093 094 sep = "/"; 095 } 096 097 return builder.toString(); 098 } 099 100 /** 101 * Converts the callback (the page name and activation context) to a link; such a link may be 102 * returned from a event handler method to cause Tapestry to redirect to the page. Most of the 103 * details 104 * are encapsulated inside the {@link PageRenderLinkSource} service. 105 * 106 * @param linkSource 107 * used to generate the link 108 * @return link corresponding to this callback 109 */ 110 public Link toLink(PageRenderLinkSource linkSource) 111 { 112 return linkSource.createPageRenderLinkWithContext(pageName, (Object[]) activationContext); 113 } 114}