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.model;
20  
21  import java.beans.IntrospectionException;
22  
23  
24   /**
25    *
26    *
27    *  <p>
28    *         There are two common scenarios for processes,
29    *         "Plus One" and "Max Visited" which are explained below.
30    *           <ul>
31    *             <li>"Plus One" - from the current step the user can
32    *             navigate to any previous page and the next page.
33    *             If the user is on the 5th step of a process
34    *             and goes back to step 2, then the user can only
35    *             navigate from step 2 to step 1 and step 3.
36    *             </li>
37    *             <li>"Max Visited" - the user can navigate to the max
38    *             visited page. If the user is currently on the max
39    *             visited page then the user can also navigate to
40    *             the next page. If the user is on the 5th step of a
41    *             process and goes back to step 2, then the user can
42    *             navigate from step 2 to steps 1, 2, 3, 4, and 5.
43    *             </li>
44    *           </ul>
45    *
46    *           </p>
47    *           <p>
48    *           A node in a process should be readOnly
49    *           if that step of the process is not reachable from the current
50    *           step. The {@link #isReadOnly} method can be used to
51    *           bind the node's readOnly attribute.
52    *           </p>
53    *           <p>
54    *           A node in a process should be immediate if the values
55    *           in the current step don't need to be validated.
56    *           The {@link #isImmediate} method can be used to
57    *           bind the node's immediate attribute.
58    *           </p>
59    *           <p>
60    *
61    *
62    *
63    * @see ProcessUtils
64    *
65    */
66  public class ProcessMenuModel extends ViewIdPropertyMenuModel
67  {
68  
69    /**
70     * No-arg constructor for use with managed-beans.
71     * Must call the {@link #setViewIdProperty} and
72     * {@link #setWrappedData} methods after constructing this instance.
73     */
74    public ProcessMenuModel()
75    {
76      super();
77    }
78  
79    /**
80     *
81     * The "Plus One" behavior will be used with this constructor.
82     *
83     * @param instance a treeModel. This object will be passed to
84     * {@link ModelUtils#toTreeModel}
85     * @param viewIdProperty the property to use to retrieve a viewId
86     * from a node in the tree
87     * @throws IntrospectionException
88     */
89    public ProcessMenuModel(
90      Object instance,
91      String viewIdProperty
92    )throws IntrospectionException
93    {
94      super(instance, viewIdProperty);
95    }
96  
97  
98    /**
99     *
100    * @param instance a treeModel. This object will be passed to
101    * {@link ModelUtils#toTreeModel}
102    * @param viewIdProperty the property to use to retrieve a viewId
103    * from a node in the tree
104    * @param maxPathKey if the "Max Visited" behavior is desired, this
105    * is the key that will be used to get and set the maxPath value
106    * on the session and request. For the "Plus One" behavior pass in null.
107    * @throws IntrospectionException
108    */
109   public ProcessMenuModel(
110     Object instance,
111     String viewIdProperty,
112     String maxPathKey
113   )throws IntrospectionException
114   {
115     super(instance, viewIdProperty);
116     setMaxPathKey(maxPathKey);
117   }
118 
119  /**
120   *           <p>
121   *           A node in a process should be immediate if the values
122   *           in the current step don't need to be validated.
123   *           This method can be used to
124   *           bind the node's immediate attribute. If a user will have to
125   *           return to the current page then immediate can be set to true.
126   *           For example in a "Plus One" process, if the user is on step 5
127   *           and goes back to step 2, the user will have to come back
128   *           to step 5 again, so the fields on page 5 don't need to
129   *           be validated when going back to steps 1,2,3,4, but should be
130   *           validated when going to step 6.
131   *           </p>
132   *           <p>
133   *
134   *
135   *           <ul>
136   *             <li>"Plus One"
137   *               <ul>
138   *                 <li>immediate - immediate will be true for any previous step,
139   *                                 and false otherwise.</li>
140   *               </ul>
141   *             </li>
142   *             <li>"Max Visited" - when the current step and the max step
143   *                  are the same, "max visited" behaves like "plus one". If
144   *                  the current step is before the max step, then:
145   *               <ul>
146   *                 <li>immediate - immediate is false. </li>
147   *               </ul>
148   *             </li>
149   *           </ul>
150   *         </p>
151   */
152   public boolean isImmediate()
153   {
154     String maxPathKey = getMaxPathKey();
155     if ( maxPathKey == null)
156       return ProcessUtils.isImmediate(this, false);
157     else
158     {
159       Object  maxPath = ProcessUtils.getMaxVisitedRowKey(this, maxPathKey);
160       return ProcessUtils.isImmediate(this, maxPath, false);
161     }
162   }
163 
164  /**
165   *           <p>
166   *           A node in a process should be readOnly
167   *           if that step of the process is not reachable from the current
168   *           step. This method can be used to
169   *           bind the node's readOnly attribute.
170   *           </p>
171   *
172   *           <ul>
173   *             <li>"Plus One"
174   *               <ul>
175   *                 <li>readOnly - readOnly will be true for any step past
176   *                                the next available step</li>
177   *               </ul>
178   *             </li>
179   *             <li>"Max Visited" - when the current step and the max step
180   *                  are the same, "max visited" behaves like "plus one". If
181   *                  the current step is before the max step, then:
182   *               <ul>
183   *                 <li>readOnly - readOnly will be true for any step
184   *                                past the max step</li>
185   *               </ul>
186   *             </li>
187   *           </ul>
188   *         </p>
189   */
190   public boolean isReadOnly()
191   {
192     String maxPathKey = getMaxPathKey();
193     if (maxPathKey == null)
194       return ProcessUtils.isReadOnly(this, true);
195     else
196     {
197       Object maxPath = ProcessUtils.getMaxVisitedRowKey(this, maxPathKey);
198       return ProcessUtils.isReadOnly(this, maxPath, true);
199     }
200   }
201   
202   /**
203    * For the Max Visited case, a stop is considered visited if
204    *   - a stop is before the max visited stop
205    *   - or is the max visited stop
206    *   
207    * For the Plus One case, a stop is considered visited if, 
208    *   - it's before the current or,
209    *   - is the current stop itself
210    */
211   public boolean isVisited()
212   {
213     // Max Visited
214     String maxPathKey = getMaxPathKey();
215     if ( maxPathKey == null)
216     {
217       return ProcessUtils.isVisited(this, false);
218     }
219     else
220     {
221       Object maxPath = ProcessUtils.getMaxVisitedRowKey(this, maxPathKey);
222       return ProcessUtils.isVisited(this, maxPath, false);
223     }
224   }  
225 
226   /**
227    * to clear the max visited path out of the session
228    */
229   public void clearMaxPath()
230   {
231     String maxPathKey = getMaxPathKey();
232     if ( maxPathKey != null)
233       ProcessUtils.clearMaxPath(maxPathKey);
234   }
235 
236   public void setMaxPathKey(String maxPathKey)
237   {
238     _maxPathKey = maxPathKey;
239   }
240 
241   public String getMaxPathKey()
242   {
243     return _maxPathKey;
244   }
245 
246   private String _maxPathKey;
247 }