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 }