View Javadoc

1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one
3    * or more contributor license agreements.  See the NOTICE file
4    * distributed with this work for additional information
5    * regarding copyright ownership.  The ASF licenses this file
6    * to you under the Apache License, Version 2.0 (the
7    * "License"); you may not use this file except in compliance
8    * with the License.  You may obtain a copy of the License at
9    *
10   *   http://www.apache.org/licenses/LICENSE-2.0
11   *
12   * Unless required by applicable law or agreed to in writing,
13   * software distributed under the License is distributed on an
14   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15   * KIND, either express or implied.  See the License for the
16   * specific language governing permissions and limitations
17   * under the License.
18   */
19  package org.apache.myfaces.trinidad.context;
20  
21  import java.util.Map;
22  import javax.faces.component.UIComponent;
23  import javax.faces.component.UIViewRoot;
24  import javax.faces.context.FacesContext;
25  
26  import org.apache.myfaces.trinidad.event.ReturnEvent;
27  
28  
29  
30  /**
31   * The DialogService API defines a number of
32   * APIs that are needed to implement Apache Trinidad dialogs,
33   * but will only rarely be called by page authors.
34   * They are instead intended for developers of controller
35   * frameworks and component developers.
36   */
37  abstract public class DialogService
38  {
39    /**
40     * Configuration parameter for setting the prefix used in
41     * dialog navigation.
42     */
43    public static final String DIALOG_NAVIGATION_PREFIX_PARAM_NAME =
44      "org.apache.myfaces.trinidad.DIALOG_NAVIGATION_PREFIX";
45  
46    /**
47     * Configuration parameter for setting the prefix used in
48     * dialog navigation.  This can either be set as a WEB-INF/web.xml
49     * or programatically set as a ServletContext attribute.
50     */
51    public static final String DISABLE_DIALOG_OUTCOMES_PARAM_NAME =
52      "org.apache.myfaces.trinidad.DISABLE_DIALOG_OUTCOMES";
53  
54    /**
55     * Create an DialogService.
56     */
57    protected DialogService()
58    {
59    }
60  
61    /**
62     * Push a UIViewRoot onto a stack in preparation
63     * for navigating to a subflow.
64     */
65    public abstract void pushView(UIViewRoot viewRoot);
66  
67    /**
68     * Pop a UIViewRoot from a stack.  If <code>navigateToPopped</code> is true,
69     * this method may result in calls to
70     * <code>FacesContext.renderResponse()</code> or even
71     * <code>FacesContext.responseComplete()</code>.
72     *
73     * @param navigateToPopped If true, navigate to the view popped
74     * of the stack with <code>FacesContext.setViewRoot()</code>.
75     * If false, simply drop the view.
76     */
77    public abstract void popView(boolean navigateToPopped);
78  
79  
80    /**
81     * Returns the UIViewRoot that is topmost on the stack,
82     * of pushed view, without popping it.
83     */
84    public abstract UIViewRoot peekView();
85  
86    /**
87     * Creates a {@link org.apache.myfaces.trinidad.event.ReturnEvent} for
88     * a component.  This method will generally be called from
89     * a Renderer's or UIComponent's decode() method if there is
90     * any possibility that it launched a dialog on a prior request.
91     * There is no requirement that the component directly supports
92     * {@link org.apache.myfaces.trinidad.event.ReturnListener};  decode()
93     * can simply use the return value and discard the event.
94     * <p>
95     * This method will return null in the case where no dialog
96     * had been launched with this component as the source.  If
97     * it returns a non-null event, the component or renderer should
98     * not process the request any further in decode(), but simply
99     * process the ReturnEvent, either by using its return value
100    * or queueing it for delivery.
101    *
102    * @param source the component that may have launched a dialog
103    * @return a ReturnEvent containing the
104    * {@link RequestContext#returnFromDialog return value} from the
105    * dialog.
106    */
107   public abstract ReturnEvent getReturnEvent(UIComponent source);
108 
109   /**
110    * Returns the value last set by {@link #setCurrentLaunchSource}.
111    * =-=AEW Make this abstract?
112    */
113   public UIComponent getCurrentLaunchSource()
114   {
115     return _currentLaunchSource;
116   }
117 
118   /**
119    * A component that is
120    * delivering an ActionEvent to the default ActionListener
121    * should call this method to allow a NavigationHandler to
122    * properly launch a dialog, and should reset the
123    * value to null afterwards.
124    * =-=AEW Make this abstract?
125    */
126   public void setCurrentLaunchSource(UIComponent component)
127   {
128     _currentLaunchSource = component;
129   }
130 
131 
132   /**
133    * Launches a dialog without pushing a process scope.
134    * This method should only be used by controller framework
135    * code;  all others should use
136    * {@link RequestContext#launchDialog RequestContext.launchDialog()}.
137    * The process scope must be {@link PageFlowScopeProvider#pushPageFlowScope pushed}
138    * <em>before</em> calling this method.
139    */
140   public abstract void launchDialog(
141     UIViewRoot  dialogRoot,
142     Map<String, Object> dialogParameters,
143     UIComponent source,
144     boolean     useWindow,
145     Map<String, Object> windowProperties);
146 
147 
148   /**
149    * Returns from a dialog without popping a process scope.
150    * This method should only be used by controller framework
151    * code;  all others should use
152    * {@link RequestContext#returnFromDialog RequestContext.returnFromDialog()}.
153    * The process scope must be {@link PageFlowScopeProvider#popPageFlowScope popped}
154    * <em>after</em> calling this method.
155    *
156    * @return true if pages accessing that dialog are necessarily permanently
157    *   inaccessible.  For example, a dialog displayed in a popup
158    *   window is inacessible once the window has closed, but a dialog
159    *   displayed within the same window might be reached by the back button.
160    */
161   public abstract boolean returnFromDialog(Object returnValue,
162                                            Map<Object, Object> returnParameters);
163 
164 
165   /**
166    * Queues a LaunchEvent that will result in a dialog being started, using
167    * {@link #getCurrentLaunchSource current launch source} as the source
168    * for launching the dialogRoot parameter.
169    * The process scope must be {@link PageFlowScopeProvider#pushPageFlowScope pushed}
170    * <em>before</em> calling this method.  If {@link #getCurrentLaunchSource}
171    * returns <code>null</code>, a basic dialog will be started without
172    * using a window or passing any additional parameters.  Developers
173    * <em>should not</em> call
174    * {@link javax.faces.context.FacesContext#setViewRoot
175    * FacesContext.setViewRoot()} when using this method.
176    */
177   public abstract void queueLaunchEvent(UIViewRoot dialogRoot);
178 
179  /**
180    * Queues a ReturnEvent, using
181    * {@link #getCurrentLaunchSource current launch source} as the source
182    * for launching the dialogRoot parameter.  This method should
183    * be used by a <code>NavigationHandler</code> that can identify
184    * a return value from a dialog without actually launching the dialog.
185    */
186   public abstract void queueReturnEvent(
187     Object returnValue,
188     Map<Object, Object> returnParams);
189 
190   /**
191    * Returns the prefix that, when used for navigational outcomes,
192    * will trigger the dialog framework.
193    */
194   public String getDialogNavigationPrefix()
195   {
196     if (_dialogPrefix == null)
197     {
198       FacesContext context = FacesContext.getCurrentInstance();
199       _dialogPrefix = context.getExternalContext().getInitParameter(
200                                 DIALOG_NAVIGATION_PREFIX_PARAM_NAME);
201       
202       if(_dialogPrefix == null)
203       {
204         _dialogPrefix = _DEFAULT_DIALOG_NAVIGATION_PREFIX;
205       }
206     }
207 
208     return _dialogPrefix;
209   }
210 
211   private UIComponent _currentLaunchSource;
212   private static String _dialogPrefix;
213 
214   private static final String _DEFAULT_DIALOG_NAVIGATION_PREFIX = "dialog:";
215 }