1 /**
2 * Copyright 2005-2014 The Kuali Foundation
3 *
4 * Licensed under the Educational Community License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.opensource.org/licenses/ecl2.php
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16 package org.kuali.rice.krad.uif.service;
17
18 import java.util.List;
19 import java.util.Map;
20
21 import org.kuali.rice.krad.uif.component.Component;
22 import org.kuali.rice.krad.uif.container.CollectionGroup;
23 import org.kuali.rice.krad.uif.container.Container;
24 import org.kuali.rice.krad.uif.field.DataField;
25 import org.kuali.rice.krad.uif.util.ComponentFactory;
26 import org.kuali.rice.krad.uif.view.ExpressionEvaluatorFactory;
27 import org.kuali.rice.krad.uif.util.LifecycleElement;
28 import org.kuali.rice.krad.uif.view.ViewModel;
29 import org.kuali.rice.krad.uif.widget.Inquiry;
30
31 /**
32 * Provides methods for implementing the various phases of a <code>View</code>
33 *
34 * <ul>
35 * <li>Initialize Phase: Invoked when the view is first requested to setup
36 * necessary state</li>
37 * </ul>
38 *
39 * @author Kuali Rice Team (rice.collab@kuali.org)
40 */
41 public interface ViewHelperService {
42
43 /**
44 * Hook for service overrides to perform custom initialization prior to view initialization.
45 *
46 * @param model The model.
47 */
48 void performCustomViewInitialization(Object model);
49
50 /**
51 * Hook for service overrides to perform custom initialization on the component
52 *
53 * @param component component instance to initialize
54 */
55 void performCustomInitialization(LifecycleElement component);
56
57 /**
58 * Hook for service overrides to perform custom apply model logic on the component
59 *
60 * @param component component instance to apply model to
61 * @param model Top level object containing the data (could be the model or a top level business
62 * object, dto)
63 */
64 void performCustomApplyModel(LifecycleElement component, Object model);
65
66 /**
67 * Hook for service overrides to perform custom component finalization
68 *
69 * @param component component instance to update
70 * @param model Top level object containing the data
71 * @param parent Parent component for the component being finalized
72 */
73 void performCustomFinalize(LifecycleElement component, Object model, LifecycleElement parent);
74
75 /**
76 * Hook for service overrides to perform view component finalization
77 *
78 * @param model Top level object containing the data
79 */
80 void performCustomViewFinalize(Object model);
81
82 /**
83 * Hook for service overrides to process the new collection line before it is added to the
84 * collection
85 *
86 * @param model object instance that contain's the view's data
87 * @param addLine the new line instance to be processed
88 * @param collectionId the id of the collection being added to
89 * @param collectionPath the path to the collection being modified
90 */
91 void processBeforeAddLine(ViewModel model, Object addLine, String collectionId, String collectionPath);
92
93 /**
94 * Hook for service overrides to process the new collection line after it has been added to the
95 * collection
96 *
97 * @param model object instance that contain's the views data
98 * @param addLine the new line that was added
99 * @param collectionId the id of the collection being added to
100 * @param collectionPath the path to the collection being modified
101 * @param isValidLine indicates if the line is valid
102 */
103 void processAfterAddLine(ViewModel model, Object addLine, String collectionId, String collectionPath,
104 boolean isValidLine);
105
106 /**
107 * Hook for service overrides to process the save collection line before it is validated
108 *
109 * @param model object instance that contain's the views data
110 * @param lineObject the line instance to be processed
111 * @param collectionId the id of the collection being added to
112 * @param collectionPath the path to the collection being modified
113 */
114 void processBeforeSaveLine(ViewModel model, Object lineObject, String collectionId, String collectionPath);
115
116 /**
117 * Hook for service overrides to process the save collection line after it has been validated
118 *
119 * @param model object instance that contains the views data
120 * @param lineObject the line instance to be processed
121 * @param collectionId the id of the collection being added to
122 * @param collectionPath the path to the collection being modified
123 */
124 void processAfterSaveLine(ViewModel model, Object lineObject, String collectionId, String collectionPath);
125
126 /**
127 * Hook for service overrides to process the collection line after it has been deleted
128 *
129 * @param model object instance that contains the views data
130 * @param collectionId the id of the collection being added to
131 * @param collectionPath the path to the collection being modified
132 * @param lineIndex index of the line that was deleted
133 */
134 void processAfterDeleteLine(ViewModel model, String collectionId, String collectionPath, int lineIndex);
135
136 /**
137 * Hook for creating new components with code and adding them to a container
138 *
139 * <p>
140 * Subclasses can override this method to check for one or more containers by id and then adding
141 * components created in code. This is invoked before the initialize method on the container
142 * component, so the full lifecycle will be run on the components returned.
143 * </p>
144 *
145 * <p>
146 * New components instances can be retrieved using {@link ComponentFactory}
147 * </p>
148 *
149 * @param model object containing the view data
150 * @param container container instance to add components to
151 */
152 void addCustomContainerComponents(ViewModel model, Container container);
153
154 /**
155 * Invoked when the add line action is chosen for a collection. The
156 * collection path gives the full path to the collection that action was
157 * selected for. Here validation can be performed on the line as well as
158 * further processing on the line such as defaults. If the action is valid
159 * the line should be added to the collection, otherwise errors should be
160 * added to the global <code>MessageMap</code>
161 *
162 * @param model Top level object containing the view data including the
163 * collection and new line
164 * @param collectionId the id of the collection being added to
165 * @param collectionPath the path to the collection being modified
166 */
167 void processCollectionAddLine(ViewModel model, String collectionId, String collectionPath);
168
169 /**
170 * Adds a blank line to the collection
171 *
172 * <p>
173 * Adds a new collection item to the collection and applies any default values.
174 * </p>
175 *
176 * @param model Top level object containing the view data including the collection and new line
177 * @param collectionId the id of the collection being added to
178 * @param collectionPath the path to the collection being modified
179 */
180 void processCollectionAddBlankLine(ViewModel model, String collectionId, String collectionPath);
181
182 /**
183 * Invoked when the save line action is chosen for a collection. This method only does server side validation by
184 * default but creates hook for client applications to add additional logic like persisting data.
185 *
186 * @param model Top level object containing the view data including the collection and new line
187 * @param collectionId the id of the collection being added to
188 * @param collectionPath the path to the collection being modified
189 * @param selectedLineIndex The index within the collection of the line to save.
190 */
191 void processCollectionSaveLine(ViewModel model, String collectionId, String collectionPath, int selectedLineIndex);
192
193 /**
194 * Invoked when the delete line action is chosen for a collection. The
195 * collection path gives the full path to the collection that action was
196 * selected for. Here validation can be performed to make sure the action is
197 * allowed. If the action is valid the line should be deleted from the
198 * collection, otherwise errors should be added to the global
199 * <code>MessageMap</code>
200 *
201 * @param model Top level object containing the view data including the collection
202 * @param collectionId the id of the collection being added to
203 * @param collectionPath the path to the collection being modified
204 * @param lineIndex index of the collection line that was selected for removal
205 */
206 void processCollectionDeleteLine(ViewModel model, String collectionId, String collectionPath, int lineIndex);
207
208 /**
209 * Process the results returned from a multi-value lookup populating the lines for the collection given
210 * by the path
211 *
212 * @param model object containing the view data
213 * @param collectionId the id of the collection being added to
214 * @param collectionPath the path to the collection being modified
215 * @param multiValueReturnFields String containing the selected line field names
216 * @param lookupResultValues String containing the selected line values
217 */
218 void processMultipleValueLookupResults(ViewModel model, String collectionId, String collectionPath,
219 String multiValueReturnFields, String lookupResultValues);
220
221 /**
222 * Invoked by the <code>Inquiry</code> widget to build the inquiry link
223 *
224 * <p>
225 * Note this is used primarily for custom <code>Inquirable</code>
226 * implementations to customize the inquiry class or parameters for an
227 * inquiry. Instead of building the full inquiry link, implementations can
228 * make a callback to
229 * org.kuali.rice.krad.uif.widget.Inquiry.buildInquiryLink(Object, String,
230 * Class<?>, Map<String, String>) given an inquiry class and parameters to
231 * build the link field.
232 * </p>
233 *
234 * @param dataObject parent object for the inquiry property
235 * @param propertyName name of the property the inquiry is being built for
236 * @param inquiry instance of the inquiry widget being built for the property
237 */
238 void buildInquiryLink(Object dataObject, String propertyName, Inquiry inquiry);
239
240 /**
241 * Sets up the view context which will be available to other components through their context
242 * for conditional logic evaluation.
243 */
244 void setViewContext();
245
246 /**
247 * Invokes the configured <code>PresentationController</code> and </code>Authorizer</code> for
248 * the view to get the exported action flags and edit modes that can be used in conditional
249 * logic
250 */
251 void retrieveEditModesAndActionFlags();
252
253 /**
254 * Perform a database or data dictionary based refresh of a specific property object
255 *
256 * <p>
257 * The object needs to be of type PersistableBusinessObject.
258 * </p>
259 *
260 * @param parentObject parent object that references the object to be refreshed
261 * @param referenceObjectName property name of the parent object to be refreshed
262 */
263 void refreshReference(Object parentObject, String referenceObjectName);
264
265 /**
266 * Update the reference objects listed in referencesToRefresh of the model
267 *
268 * <p>
269 * The the individual references in the referencesToRefresh string are separated by
270 * KRADConstants.REFERENCES_TO_REFRESH_SEPARATOR).
271 * </p>
272 *
273 * @param referencesToRefresh list of references to refresh (
274 */
275 void refreshReferences(String referencesToRefresh);
276
277 /**
278 * Retrieves the default value that is configured for the given data field
279 *
280 * <p>
281 * The field's default value is determined in the following order:
282 *
283 * <ol>
284 * <li>If default value on field is non-blank</li>
285 * <li>If expression is found for default value</li>
286 * <li>If default value finder class is configured for field</li>
287 * <li>If an expression is found for default values</li>
288 * <li>If default values on field is not null</li>
289 * </ol>
290 * </p>
291 *
292 * @param object object that should be populated
293 * @param dataField field to retrieve default value for
294 * @return Object default value for field or null if value was not found
295 */
296 Object getDefaultValueForField(Object object, DataField dataField);
297
298 /**
299 * Applies the default value configured for the given field (if any) to the line given object
300 * property that is determined by the given binding path
301 *
302 * @param object object that should be populated
303 * @param dataField field to check for configured default value
304 * @param bindingPath path to the property on the object that should be populated
305 */
306 void populateDefaultValueForField(Object object, DataField dataField, String bindingPath);
307
308 /**
309 * Builds JS script that will invoke the show growl method to display a growl message when the
310 * page is rendered
311 *
312 * <p>
313 * A growl call will be created for any explicit growl messages added to the message map.
314 * </p>
315 *
316 * <p>
317 * Growls are only generated if @{link
318 * org.kuali.rice.krad.uif.view.View#isGrowlMessagingEnabled()} is enabled. If not, the growl
319 * messages are set as info messages for the page
320 * </p>
321 *
322 * @return JS script string for generated growl messages
323 */
324 String buildGrowlScript();
325
326 /**
327 * Iterates through the view components picking up data fields and applying an default value
328 * configured
329 *
330 * @param component component that should be checked for default values
331 */
332 void applyDefaultValues(Component component);
333
334 /**
335 * Populate default values the model backing a line in a collection group.
336 *
337 * @param collectionGroup The collection group.
338 * @param line The model object backing the line.
339 */
340 void applyDefaultValuesForCollectionLine(CollectionGroup collectionGroup, Object line);
341
342 /**
343 * Uses reflection to find all fields defined on the <code>View</code> instance that have the
344 * <code>RequestParameter</code> annotation (which indicates the field may be populated by the
345 * request).
346 *
347 * <p>
348 * The <code>View</code> instance is inspected for fields that have the
349 * <code>RequestParameter</code> annotation and if corresponding parameters are found in the
350 * request parameter map, the request value is used to set the view property. The Map of
351 * parameter name/values that match are placed in the view so they can be later retrieved to
352 * rebuild the view. Custom <code>ViewServiceHelper</code> implementations can add additional
353 * parameter key/value pairs to the returned map if necessary.
354 * </p>
355 *
356 * <p>
357 * For each field found, if there is a corresponding key/value pair in the request parameters,
358 * the value is used to populate the field. In addition, any conditional properties of
359 * <code>PropertyReplacers</code> configured for the field are cleared so that the request
360 * parameter value does not get overridden by the dictionary conditional logic
361 * </p>
362 *
363 * @param parameters The request parameters that apply to the view.
364 * @see org.kuali.rice.krad.uif.component.RequestParameter
365 */
366 void populateViewFromRequestParameters(Map<String, String> parameters);
367
368 /**
369 * Gets an expression evaluator factory for use with the current view.
370 *
371 * @return expression evaluator factory
372 */
373 ExpressionEvaluatorFactory getExpressionEvaluatorFactory();
374
375 }