001// Copyright 2004, 2005 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.tapestry.callback;
016
017import org.apache.hivemind.ApplicationRuntimeException;
018import org.apache.hivemind.util.Defense;
019import org.apache.tapestry.IExternalPage;
020import org.apache.tapestry.IRequestCycle;
021
022/**
023 * A callback for returning to an {@link org.apache.tapestry.IExternalPage}.
024 * <p>
025 * Example usage of <tt>ExternalCallback</tt>:
026 * <p>
027 * The External page ensure a user is authenticated in the
028 * {@link org.apache.tapestry.IPage#validate(IRequestCycle)} method. If the user is not
029 * authenticated, they are redirected to the Login page, after setting a callback in the Login page.
030 * <p>
031 * The Login page <tt>formSubmit()</tt> {@link org.apache.tapestry.IActionListener} authenticates
032 * the user and then invokes {@link ICallback#performCallback(IRequestCycle)} to the External page.
033 * 
034 * <pre>
035 * 
036 *  
037 *   
038 *    
039 *     
040 *      
041 *       
042 *        
043 *         
044 *          
045 *           
046 *             public class External extends BasePage implements IExternalPage {
047 *            
048 *                 private Integer _itemId;
049 *           
050 *                 public void validate(IRequestCycle cycle) throws RequestCycleException {            
051 *                     Visit visit = (Visit) getVisit();
052 *                 
053 *                     if (!visit.isAuthenticated()) {
054 *                         Login login = (Login) cycle.getPage(&quot;Login&quot;);
055 *           
056 *                         login.setCallback
057 *                             (new ExternalCallback(this, cycle.getServiceParameters()));
058 *                         
059 *                         throw new PageRedirectException(login);
060 *                     }            
061 *                 }
062 *            
063 *                 public void activateExternalPage(Object[] params, IRequestCycle cycle)
064 *                         throws RequestCycleException {            
065 *                     _itemId = (Integer) params[0];
066 *                 }
067 *             }
068 *           
069 *             public Login extends BasePage {
070 *            
071 *                 private ICallback _callback;
072 *           
073 *                 public void setCallback(ICallback _callback) {
074 *                     _callback = callback;
075 *                 }
076 *           
077 *                 public void formSubmit(IRequestCycle cycle) {
078 *                     // Authentication code
079 *                     ..
080 *              
081 *                     Visit visit = (Visit) getVisit();
082 *           
083 *                     visit.setAuthenticated(true);
084 *             
085 *                     if (_callback != null) {
086 *                         _callback.performCallback(cycle);
087 *                     }
088 *                 }
089 *             }    
090 *             
091 *           
092 *          
093 *         
094 *        
095 *       
096 *      
097 *     
098 *    
099 *   
100 *  
101 * </pre>
102 * 
103 * @see org.apache.tapestry.IExternalPage
104 * @see org.apache.tapestry.engine.ExternalService
105 * @author Malcolm Edgar
106 * @since 2.3
107 */
108
109public class ExternalCallback implements ICallback
110{
111    private static final long serialVersionUID = -6783421589702643930L;
112
113    private String _pageName;
114
115    private Object[] _parameters;
116
117    /**
118     * Creates a new ExternalCallback for the named <tt>IExternalPage</tt>. The parameters (which
119     * may be null) is retained, not copied.
120     */
121
122    public ExternalCallback(String pageName, Object[] parameters)
123    {
124        Defense.notNull(pageName, "pageName");
125
126        _pageName = pageName;
127        _parameters = parameters;
128    }
129
130    /**
131     * Creates a new ExternalCallback for the page. The parameters (which may be null) is retained,
132     * not copied.
133     */
134
135    public ExternalCallback(IExternalPage page, Object[] parameters)
136    {
137        Defense.notNull(page, "page");
138
139        _pageName = page.getPageName();
140        _parameters = parameters;
141    }
142
143    /**
144     * Invokes {@link IRequestCycle#setPage(String)} to select the previously identified
145     * <tt>IExternalPage</tt> as the response page and activates the page by invoking
146     * <tt>activateExternalPage()</tt> with the callback parameters and request cycle.
147     */
148
149    public void performCallback(IRequestCycle cycle)
150    {
151        Defense.notNull(cycle, "cycle");
152
153        try
154        {
155            IExternalPage page = (IExternalPage) cycle.getPage(_pageName);
156
157            cycle.activate(page);
158
159            page.activateExternalPage(_parameters, cycle);
160        }
161        catch (ClassCastException ex)
162        {
163            throw new ApplicationRuntimeException(CallbackMessages.pageNotExternal(_pageName), ex);
164        }
165    }
166
167    public String toString()
168    {
169        StringBuffer buffer = new StringBuffer("ExternalCallback[");
170
171        buffer.append(_pageName);
172
173        if (_parameters != null)
174        {
175            for (int i = 0; i < _parameters.length; i++)
176            {
177                if (i == 0)
178                    buffer.append('/');
179                else
180                    buffer.append(", ");
181
182                buffer.append(_parameters[i]);
183            }
184        }
185
186        buffer.append(']');
187
188        return buffer.toString();
189    }
190}