001/**
002 * Copyright 2005-2018 The Kuali Foundation
003 *
004 * Licensed under the Educational Community License, Version 2.0 (the "License");
005 * you may not use this file except in compliance with the License.
006 * You may obtain a copy of the License at
007 *
008 * http://www.opensource.org/licenses/ecl2.php
009 *
010 * Unless required by applicable law or agreed to in writing, software
011 * distributed under the License is distributed on an "AS IS" BASIS,
012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013 * See the License for the specific language governing permissions and
014 * limitations under the License.
015 */
016package org.kuali.rice.krad.uif.service;
017
018import java.util.Map;
019
020import org.kuali.rice.krad.uif.component.Component;
021import org.kuali.rice.krad.uif.container.CollectionGroup;
022import org.kuali.rice.krad.uif.container.Container;
023import org.kuali.rice.krad.uif.field.DataField;
024import org.kuali.rice.krad.uif.util.ComponentFactory;
025import org.kuali.rice.krad.uif.util.LifecycleElement;
026import org.kuali.rice.krad.uif.view.ExpressionEvaluatorFactory;
027import org.kuali.rice.krad.uif.view.ViewModel;
028import org.kuali.rice.krad.uif.widget.Inquiry;
029import org.kuali.rice.krad.web.service.impl.CollectionControllerServiceImpl.CollectionActionParameters;
030
031/**
032 * Provides customization methods at various points of the view lifecycle.
033 *
034 * <p>Custom view helpers can be configured with view property
035 * {@link org.kuali.rice.krad.uif.view.View#getViewHelperServiceClass()}</p>
036 *
037 * @author Kuali Rice Team (rice.collab@kuali.org)
038 */
039public interface ViewHelperService {
040
041    /**
042     * Uses reflection to find all fields defined on the <code>View</code> instance that have the
043     * <code>RequestParameter</code> annotation (which indicates the field may be populated by the
044     * request).
045     *
046     * <p>
047     * The <code>View</code> instance is inspected for fields that have the
048     * <code>RequestParameter</code> annotation and if corresponding parameters are found in the
049     * request parameter map, the request value is used to set the view property. The Map of
050     * parameter name/values that match are placed in the view so they can be later retrieved to
051     * rebuild the view. Custom <code>ViewServiceHelper</code> implementations can add additional
052     * parameter key/value pairs to the returned map if necessary.
053     * </p>
054     *
055     * <p>
056     * For each field found, if there is a corresponding key/value pair in the request parameters,
057     * the value is used to populate the field. In addition, any conditional properties of
058     * <code>PropertyReplacers</code> configured for the field are cleared so that the request
059     * parameter value does not get overridden by the dictionary conditional logic
060     * </p>
061     *
062     * @param parameters The request parameters that apply to the view.
063     * @see org.kuali.rice.krad.uif.component.RequestParameter
064     */
065    void populateViewFromRequestParameters(Map<String, String> parameters);
066    
067    /**
068     * Hook for service overrides to perform custom initialization prior to view initialization.
069     * 
070     * @param model The model.
071     */
072    void performCustomViewInitialization(Object model);
073
074    /**
075     * Hook for service overrides to perform custom initialization on the component
076     * 
077     * @param component component instance to initialize
078     */
079    void performCustomInitialization(LifecycleElement component);
080
081    /**
082     * Hook for service overrides to perform custom apply model logic on the component
083     * 
084     * @param component component instance to apply model to
085     * @param model Top level object containing the data (could be the model or a top level business
086     *        object, dto)
087     */
088    void performCustomApplyModel(LifecycleElement component, Object model);
089
090    /**
091     * Hook for service overrides to perform custom component finalization
092     * 
093     * @param component component instance to update
094     * @param model Top level object containing the data
095     * @param parent Parent component for the component being finalized
096     */
097    void performCustomFinalize(LifecycleElement component, Object model, LifecycleElement parent);
098
099    /**
100     * Hook for service overrides to perform view component finalization
101     * 
102     * @param model Top level object containing the data
103     */
104    void performCustomViewFinalize(Object model);
105
106    /**
107     * Hook for service overrides to process the new collection line before it is added to the
108     * collection
109     *
110     * @param model object instance that contain's the view's data
111     * @param addLine the new line instance to be processed
112     * @param collectionId the id of the collection being added to
113     * @param collectionPath the path to the collection being modified
114     */
115    void processBeforeAddLine(ViewModel model, Object addLine, String collectionId, String collectionPath);
116
117    /**
118     * Hook for service overrides to process the new collection line after it has been added to the
119     * collection
120     *
121     * @param model object instance that contain's the views data
122     * @param addLine the new line that was added
123     * @param collectionId the id of the collection being added to
124     * @param collectionPath the path to the collection being modified
125     * @param isValidLine indicates if the line is valid
126     */
127    void processAfterAddLine(ViewModel model, Object addLine, String collectionId, String collectionPath,
128            boolean isValidLine);
129
130    /**
131     * Hook for service overrides to process the edit collection line before it is validated
132     *
133     * @param model object instance that contain's the views data
134     * @param lineObject the line instance to be processed
135     * @param collectionId the id of the collection being edited from
136     * @param collectionPath the path to the collection being modified
137     */
138    void processBeforeEditLine(ViewModel model, Object lineObject, String collectionId, String collectionPath);
139
140    /**
141     * Hook for service overrides to process the edit collection line after it has been validated
142     *
143     * @param model object instance that contains the views data
144     * @param lineObject the line instance to be processed
145     * @param collectionId the id of the collection being edited from
146     * @param collectionPath the path to the collection being modified
147     */
148    void processAfterEditLine(ViewModel model, Object lineObject, String collectionId, String collectionPath);
149
150    /**
151     * Hook for service overrides to process the save collection line before it is validated
152     *
153     * @param model object instance that contain's the views data
154     * @param lineObject the line instance to be processed
155     * @param collectionId the id of the collection being added to
156     * @param collectionPath the path to the collection being modified
157     */
158    void processBeforeSaveLine(ViewModel model, Object lineObject, String collectionId, String collectionPath);
159
160    /**
161     * Hook for service overrides to process the save collection line after it has been validated
162     *
163     * @param model object instance that contains the views data
164     * @param lineObject the line instance to be processed
165     * @param collectionId the id of the collection being added to
166     * @param collectionPath the path to the collection being modified
167     */
168    void processAfterSaveLine(ViewModel model, Object lineObject, String collectionId, String collectionPath);
169
170    /**
171     * Hook for service overrides to process the collection line after it has been deleted
172     *
173     * @param model object instance that contains the views data
174     * @param collectionId the id of the collection being added to
175     * @param collectionPath the path to the collection being modified
176     * @param lineIndex index of the line that was deleted
177     */
178    void processAfterDeleteLine(ViewModel model, String collectionId, String collectionPath, int lineIndex);
179
180    /**
181     * Hook for creating new components with code and adding them to a container
182     * 
183     * <p>
184     * Subclasses can override this method to check for one or more containers by id and then adding
185     * components created in code. This is invoked before the initialize method on the container
186     * component, so the full lifecycle will be run on the components returned.
187     * </p>
188     * 
189     * <p>
190     * New components instances can be retrieved using {@link ComponentFactory}
191     * </p>
192     * 
193     * @param model object containing the view data
194     * @param container container instance to add components to
195     */
196    void addCustomContainerComponents(ViewModel model, Container container);
197
198    /**
199     * Invoked when the add line action is chosen for a collection. The
200     * collection path gives the full path to the collection that action was
201     * selected for. Here validation can be performed on the line as well as
202     * further processing on the line such as defaults. If the action is valid
203     * the line should be added to the collection, otherwise errors should be
204     * added to the global <code>MessageMap</code>
205     *
206     * @param model Top level object containing the view data including the
207     * collection and new line
208     * @param collectionId the id of the collection being added to
209     * @param collectionPath the path to the collection being modified
210     */
211    void processCollectionAddLine(ViewModel model, String collectionId, String collectionPath);
212
213    void processAndAddLineObject(ViewModel viewModel, Object newLine, String collectionId,
214                String collectionPath);
215
216    /**
217     * Adds a blank line to the collection
218     *
219     * <p>
220     * Adds a new collection item to the collection and applies any default values.
221     * </p>
222     *
223     * @param model Top level object containing the view data including the collection and new line
224     * @param collectionId the id of the collection being added to
225     * @param collectionPath the path to the collection being modified
226     */
227    void processCollectionAddBlankLine(ViewModel model, String collectionId, String collectionPath);
228
229    /**
230     * Invoked when the retrieve edit line dialog action is chosen for a collection. This method only does server side
231     * validation by default but creates hook for client applications to add additional logic like persisting data.
232     *
233     * @param model Top level object containing the view data including the collection and new line
234     * @param collectionId the id of the collection being added to
235     * @param collectionPath the path to the collection being modified
236     * @param selectedLineIndex The index within the collection of the line to edit.
237     */
238    void processCollectionRetrieveEditLineDialog(ViewModel model, String collectionId,
239            String collectionPath, int selectedLineIndex);
240
241    /**
242     * Invoked when the edit line action is chosen for a collection. This method only does server side validation by
243     * default but creates hook for client applications to add additional logic like persisting data.
244     *
245     * @param model Top level object containing the view data including the collection and new line
246     * @param parameters the parameters for edit line request
247     */
248    void processCollectionEditLine(ViewModel model, CollectionActionParameters parameters);
249
250    /**
251     * Invoked when the close edit line dialog action is chosen for a collection.
252     *
253     * @param model Top level object containing the view data including the collection and new line
254     * @param collectionId the id of the collection being added to
255     * @param collectionPath the path to the collection being modified
256     * @param selectedLineIndex The index within the collection of the line to edit.
257     */
258    void processCollectionCloseEditLineDialog(ViewModel model, String collectionId,
259            String collectionPath, int selectedLineIndex);
260
261    /**
262     * Invoked when the save line action is chosen for a collection. This method only does server side validation by
263     * default but creates hook for client applications to add additional logic like persisting data.
264     *
265     * @param model Top level object containing the view data including the collection and new line
266     * @param parameters the parameters for save line request
267     */
268    void processCollectionSaveLine(ViewModel model, CollectionActionParameters parameters);
269
270    /**
271     * Invoked when the delete line action is chosen for a collection. The
272     * collection path gives the full path to the collection that action was
273     * selected for. Here validation can be performed to make sure the action is
274     * allowed. If the action is valid the line should be deleted from the
275     * collection, otherwise errors should be added to the global
276     * <code>MessageMap</code>
277     *
278     * @param model Top level object containing the view data including the collection
279     * @param collectionId the id of the collection being added to
280     * @param collectionPath the path to the collection being modified
281     * @param lineIndex index of the collection line that was selected for removal
282     */
283    void processCollectionDeleteLine(ViewModel model, String collectionId, String collectionPath, int lineIndex);
284
285    /**
286     * Process the results returned from a multi-value lookup populating the lines for the collection given
287     * by the path
288     *
289     * @param model object containing the view data
290     * @param collectionId the id of the collection being added to
291     * @param collectionPath the path to the collection being modified
292     * @param multiValueReturnFields String containing the selected line field names
293     * @param lookupResultValues String containing the selected line values
294     */
295    void processMultipleValueLookupResults(ViewModel model, String collectionId, String collectionPath,
296            String multiValueReturnFields, String lookupResultValues);
297
298    /**
299     * Invoked by the <code>Inquiry</code> widget to build the inquiry link
300     *
301     * <p>
302     * Note this is used primarily for custom <code>Inquirable</code>
303     * implementations to customize the inquiry class or parameters for an
304     * inquiry. Instead of building the full inquiry link, implementations can
305     * make a callback to
306     * org.kuali.rice.krad.uif.widget.Inquiry.buildInquiryLink(Object, String,
307     * Class<?>, Map<String, String>) given an inquiry class and parameters to
308     * build the link field.
309     * </p>
310     *
311     * @param dataObject parent object for the inquiry property
312     * @param propertyName name of the property the inquiry is being built for
313     * @param inquiry instance of the inquiry widget being built for the property
314     */
315    void buildInquiryLink(Object dataObject, String propertyName, Inquiry inquiry);
316
317    /**
318     * Sets up the view context which will be available to other components through their context
319     * for conditional logic evaluation.
320     */
321    void setViewContext();
322
323    /**
324     * Invoked to set up the context for an element.
325     *
326     * <p>Context is primarily used for expression evaluation. Any object in the context for a component
327     * will be available as a variable within expressions.</p>
328     *
329     * @param element element to setup context for
330     * @param parent parent of the given element
331     */
332    void setElementContext(LifecycleElement element, LifecycleElement parent);
333
334    /**
335     * Invokes the configured <code>PresentationController</code> and </code>Authorizer</code> for
336     * the view to get the exported action flags and edit modes that can be used in conditional
337     * logic
338     */
339    void retrieveEditModesAndActionFlags();
340
341    /**
342     * Perform a database or data dictionary based refresh of a specific property object
343     * 
344     * <p>
345     * The object needs to be of type PersistableBusinessObject.
346     * </p>
347     * 
348     * @param parentObject parent object that references the object to be refreshed
349     * @param referenceObjectName property name of the parent object to be refreshed
350     */
351    void refreshReference(Object parentObject, String referenceObjectName);
352
353    /**
354     * Update the reference objects listed in referencesToRefresh of the model
355     * 
356     * <p>
357     * The the individual references in the referencesToRefresh string are separated by
358     * KRADConstants.REFERENCES_TO_REFRESH_SEPARATOR).
359     * </p>
360     * 
361     * @param referencesToRefresh list of references to refresh (
362     */
363    void refreshReferences(String referencesToRefresh);
364    
365    /**
366     * Retrieves the default value that is configured for the given data field
367     * 
368     * <p>
369     * The field's default value is determined in the following order:
370     * 
371     * <ol>
372     * <li>If default value on field is non-blank</li>
373     * <li>If expression is found for default value</li>
374     * <li>If default value finder class is configured for field</li>
375     * <li>If an expression is found for default values</li>
376     * <li>If default values on field is not null</li>
377     * </ol>
378     * </p>
379     * 
380     * @param object object that should be populated
381     * @param dataField field to retrieve default value for
382     * @return Object default value for field or null if value was not found
383     */
384    Object getDefaultValueForField(Object object, DataField dataField);
385
386    /**
387     * Applies the default value configured for the given field (if any) to the line given object
388     * property that is determined by the given binding path
389     * 
390     * @param object object that should be populated
391     * @param dataField field to check for configured default value
392     * @param bindingPath path to the property on the object that should be populated
393     */
394    void populateDefaultValueForField(Object object, DataField dataField, String bindingPath);
395
396    /**
397     * Builds JS script that will invoke the show growl method to display a growl message when the
398     * page is rendered
399     * 
400     * <p>
401     * A growl call will be created for any explicit growl messages added to the message map.
402     * </p>
403     * 
404     * <p>
405     * Growls are only generated if @{link
406     * org.kuali.rice.krad.uif.view.View#isGrowlMessagingEnabled()} is enabled. If not, the growl
407     * messages are set as info messages for the page
408     * </p>
409     * 
410     * @return JS script string for generated growl messages
411     */
412    String buildGrowlScript();
413
414    /**
415     * Iterates through the view components picking up data fields and applying an default value
416     * configured
417     * 
418     * @param component component that should be checked for default values
419     */
420    void applyDefaultValues(Component component);
421
422    /**
423     * Populate default values the model backing a line in a collection group.
424     * 
425     * @param collectionGroup The collection group.
426     * @param line The model object backing the line.
427     */
428    void applyDefaultValuesForCollectionLine(CollectionGroup collectionGroup, Object line);
429
430    /**
431     * Gets an expression evaluator factory for use with the current view.
432     *
433     * @return expression evaluator factory
434     */
435    ExpressionEvaluatorFactory getExpressionEvaluatorFactory();
436
437}