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.view;
017
018import org.kuali.rice.krad.file.FileMetaBlob;
019import org.kuali.rice.krad.uif.UifConstants.ViewType;
020import org.kuali.rice.krad.uif.component.Component;
021import org.kuali.rice.krad.uif.lifecycle.ViewPostMetadata;
022import org.kuali.rice.krad.uif.service.ViewHelperService;
023import org.kuali.rice.krad.web.form.DialogResponse;
024
025import javax.servlet.http.HttpServletRequest;
026import java.io.Serializable;
027import java.util.List;
028import java.util.Map;
029import java.util.Set;
030
031/**
032 * Interface that must be implemented for classes the provide the backing data (model) for a
033 * {@link org.kuali.rice.krad.uif.view.View}.
034 *
035 * <p>Since the View relies on helper properties from the model it is necessary the backing object implement the
036 * ViewModel interface. Note model objects can extend {@link org.kuali.rice.krad.web.form.UifFormBase} which implements
037 * the ViewModel interface.</p>
038 *
039 * @author Kuali Rice Team (rice.collab@kuali.org)
040 */
041public interface ViewModel extends Serializable {
042
043    /**
044     * Called before Spring binds the request to the form to allow for pre-processing before setting values.
045     *
046     * @param request request object containing the query parameters
047     */
048    void preBind(HttpServletRequest request);
049
050    /**
051     * Called after Spring binds the request to the form and before the controller method is invoked
052     *
053     * @param request request object containing the query parameters
054     */
055    void postBind(HttpServletRequest request);
056
057    /**
058     * Called after the controller has finished executing, but before rendering occurs.
059     *
060     * @param request request object containing the query parameters
061     */
062    void preRender(HttpServletRequest request);
063
064    /**
065     * Unique Id for the <code>View</code> instance. This is specified for a
066     * view in its definition by setting the 'id' property.
067     *
068     * @return String view id
069     */
070    public String getViewId();
071
072    /**
073     * Setter for the unique view id
074     *
075     * @param viewId
076     */
077    public void setViewId(String viewId);
078
079    /**
080     * Name for the <code>View</code> instance. This is specified for a view in
081     * its definition by setting the 'id' property. The name is not necessary
082     * unique and cannot be used by itself to retrieve a view. Typically it is
083     * used with other parameters to identify a view with a certain type (view
084     * type)
085     *
086     * @return String view name
087     */
088    public String getViewName();
089
090    /**
091     * Setter for the view name
092     *
093     * @param viewName
094     */
095    public void setViewName(String viewName);
096
097    /**
098     * Name for the type of view being requested. This can be used to find
099     * <code>View</code> instances by request parameters (not necessary the
100     * unique id)
101     *
102     * @return String view type name
103     */
104    public ViewType getViewTypeName();
105
106    /**
107     * Setter for the view type name
108     *
109     * @param viewTypeName
110     */
111    public void setViewTypeName(ViewType viewTypeName);
112
113    /**
114     * View instance associated with the model. Used to render the user interface
115     *
116     * @return View
117     */
118    public View getView();
119
120    /**
121     * Setter for the view instance
122     *
123     * @param view
124     */
125    public void setView(View view);
126
127    /**
128     * Returns the view helper service instance that was configured for the current view.
129     *
130     * @return instance of view helper service, null if view is null
131     */
132    public ViewHelperService getViewHelperService() throws IllegalAccessException, InstantiationException;
133
134    /**
135     * Gets the {@link org.kuali.rice.krad.uif.lifecycle.ViewPostMetadata} that has been built up from processing
136     * of a view.
137     *
138     * <p>The view post metadata is used to read information about the view that was rendered when a post occurs. For
139     * example, you might need to check whether a particular flag was enabled for the rendered view when processing
140     * the post logic</p>
141     *
142     * @return ViewPostMetadata instance for the previously processed view
143     */
144    public ViewPostMetadata getViewPostMetadata();
145
146    /**
147     * @see ViewModel#getViewPostMetadata()
148     */
149    public void setViewPostMetadata(ViewPostMetadata viewPostMetadata);
150
151    /**
152     * Id for the current page being displayed within the view
153     *
154     * @return String page id
155     */
156    public String getPageId();
157
158    /**
159     * Setter for the current page id
160     *
161     * @param pageId
162     */
163    public void setPageId(String pageId);
164
165    /**
166     * URL the form generated for the view should post to
167     *
168     * @return String form post URL
169     */
170    public String getFormPostUrl();
171
172    /**
173     * Setter for the form post URL
174     *
175     * @param formPostUrl
176     */
177    public void setFormPostUrl(String formPostUrl);
178
179    /**
180     * Map of parameters that was used to configured the <code>View</code>.
181     * Maintained on the form to rebuild the view on posts and session timeout
182     *
183     * @return Map<String, String> view parameters
184     * @see org.kuali.rice.krad.uif.view.View.getViewRequestParameters()
185     */
186    public Map<String, String> getViewRequestParameters();
187
188    /**
189     * Setter for the view's request parameter map
190     *
191     * @param viewRequestParameters map of request parameters
192     */
193    public void setViewRequestParameters(Map<String, String> viewRequestParameters);
194
195    /**
196     * List of fields that should be read only on the view
197     *
198     * <p>
199     * If the view being rendered supports request setting of read-only fields, the readOnlyFields request parameter
200     * can be sent to mark fields as read only that might not have been otherwise
201     * </p>
202     *
203     * <p>
204     * Note the paths specified should be the simple property names (not the full binding path). Therefore if the
205     * property name appears multiple times in the view, all instances will be set as read only
206     * </p>
207     *
208     * @return List<String> read only property names
209     * @see View#isSupportsRequestOverrideOfReadOnlyFields()
210     */
211    public List<String> getReadOnlyFieldsList();
212
213    /**
214     * Setter for the list of read only fields
215     *
216     * @param readOnlyFieldsList
217     */
218    public void setReadOnlyFieldsList(List<String> readOnlyFieldsList);
219
220    /**
221     * Holds instances for collection add lines. The key of the Map gives the
222     * collection name the line instance applies to, the Map value is an
223     * instance of the collection object class that holds the new line data
224     *
225     * @return Map<String, Object> new collection lines
226     */
227    public Map<String, Object> getNewCollectionLines();
228
229    /**
230     * Setter for the new collection lines Map
231     *
232     * @param newCollectionLines
233     */
234    public void setNewCollectionLines(Map<String, Object> newCollectionLines);
235
236    /**
237     * When the request has been triggered by an action component, gives the id for the action.
238     *
239     * @return String action id, or null if request was not triggered by an action component
240     */
241    String getTriggerActionId();
242
243    /**
244     * @see ViewModel#getTriggerActionId()
245     */
246    void setTriggerActionId(String triggerActionId);
247
248    /**
249     * Map of parameters sent for the invoked action
250     *
251     * <p>
252     * Many times besides just setting the method to call actions need to send
253     * additional parameters. For instance the method being called might do a
254     * redirect, in which case the action needs to send parameters for the
255     * redirect URL. An example of this is redirecting to a <code>Lookup</code>
256     * view. In some cases the parameters that need to be sent conflict with
257     * properties already on the form, and putting all the action parameters as
258     * form properties would grow massive (in addition to adds an additional
259     * step from the XML config). So this general map solves those issues.
260     * </p>
261     *
262     * @return Map<String, String> action parameters
263     */
264    public Map<String, String> getActionParameters();
265
266    /**
267     * Setter for the action parameters map
268     *
269     * @param actionParameters
270     */
271    public void setActionParameters(Map<String, String> actionParameters);
272
273    /**
274     * Map that is populated from the component state maintained on the client
275     *
276     * <p>
277     * Used when a request is made that refreshes part of the view. The current state for components (which
278     * have state that can be changed on the client), is populated into this map which is then used by the
279     * <code>ViewHelperService</code> to update the components so that the state is maintained when they render.
280     * </p>
281     *
282     * @return Map<String, Object> map where key is name of property or component id, and value is the property
283     *         value or another map of component key/value pairs
284     */
285    public Map<String, Object> getClientStateForSyncing();
286
287    /**
288     * Holds Set of String identifiers for lines that were selected in a collection from a single page.
289     * selectedCollectionLines are request level values and get reset with every page request
290     *
291     * <p>
292     * When the select field is enabled for a <code>CollectionGroup</code>, the framework will be
293     * default bind the selected identifier strings to this property. The key of the map uniquely identifies the
294     * collection by the full binding path to the collection, and the value is a set of Strings for the checked
295     * lines.
296     * </p>
297     *
298     * @return Map<String, Set<String>> map of collections and their selected lines
299     * @see org.kuali.rice.krad.service.LegacyDataAdapter#getDataObjectIdentifierString(java.lang.Object)
300     */
301    public Map<String, Set<String>> getSelectedCollectionLines();
302
303    /**
304     * Setter for the map that holds selected collection lines
305     *
306     * @param selectedCollectionLines
307     */
308    public void setSelectedCollectionLines(Map<String, Set<String>> selectedCollectionLines);
309
310    /**
311     * Indicates whether default values should be applied.
312     *
313     * <p>
314     * Default field values of a view need to be applied after the view life cycle completes.  Otherwise,
315     * they risk getting over written.
316     * </p>
317     *
318     * @return boolean true if the request was an ajax call, false if not
319     */
320    boolean isApplyDefaultValues();
321
322    /**
323     * Set whether default values should be applied to the view
324     *
325     * @param applyDefaultValues
326     */
327    void setApplyDefaultValues(boolean applyDefaultValues);
328
329    /**
330     * Determines whether edit modes and action flags should be evaluated.
331     *
332     * <p>Initially this will be true causing edit modes and action flags to be evaluated on the initial
333     * request to a view. If these need to be reevaluated at some point (for a particular view instance), this
334     * flag can be set to true and causing the authorization to be reevaluated during the lifecycle.</p>
335     *
336     * @return boolean true if flags and modes should be evaluate during the view lifecycle, false if not
337     */
338    boolean isEvaluateFlagsAndModes();
339
340    /**
341     * @see ViewModel#isEvaluateFlagsAndModes()
342     */
343    void setEvaluateFlagsAndModes(boolean evaluateFlagsAndModes);
344
345    /**
346     * Copy of the edit view flag to be used by subsequent requests (so they don't need to be
347     * evaluated on each request).
348     *
349     * <p>If null, edit check will be performed</p>
350     *
351     * @see org.kuali.rice.krad.uif.component.ComponentBase#setReadOnly(java.lang.Boolean)
352     */
353    Boolean isCanEditView();
354
355    /**
356     * @see ViewModel#isCanEditView()
357     */
358    void setCanEditView(Boolean canEditView);
359
360    /**
361     * Copy of the action flags on the view to be used by subsequent requests (so they don't need to be
362     * evaluated on each request).
363     *
364     * @see ViewModel#isEvaluateFlagsAndModes()
365     * @see org.kuali.rice.krad.uif.view.View#getActionFlags()
366     */
367    Map<String, Boolean> getActionFlags();
368
369    /**
370     * @see ViewModel#getActionFlags()
371     */
372    void setActionFlags(Map<String, Boolean> actionFlags);
373
374    /**
375     * Copy of the edit modes on the view to be used by subsequent requests (so they don't need to be
376     * evaluated on each request).
377     *
378     * @see ViewModel#isEvaluateFlagsAndModes()
379     * @see org.kuali.rice.krad.uif.view.View#getEditModes()()
380     */
381    Map<String, Boolean> getEditModes();
382
383    /**
384     * @see ViewModel#getEditModes()
385     */
386    void setEditModes(Map<String, Boolean> editModes);
387
388    /**
389     * Script that will run on render (view or component) for generating growl messages
390     *
391     * @return String JS growl script
392     */
393    public String getGrowlScript();
394
395    /**
396     * Setter for the script that generates growls on render
397     *
398     * @param growlScript
399     */
400    public void setGrowlScript(String growlScript);
401
402    /**
403     * Gets the state.  This is the default location for state on KRAD forms.
404     *
405     * @return the state
406     */
407    public String getState();
408
409    /**
410     * Set the state
411     *
412     * @param state
413     */
414    public void setState(String state);
415
416    /**
417     * Id for the component that should be updated for a component refresh process
418     *
419     * @return String component id
420     */
421    public String getUpdateComponentId();
422
423    /**
424     * Setter for the component id that should be refreshed
425     *
426     * @param updateComponentId
427     */
428    public void setUpdateComponentId(String updateComponentId);
429
430    /**
431     * Component instance that been built for a refresh/disclosure request.
432     *
433     * <p>This is generally set by org.kuali.rice.krad.uif.lifecycle.ViewLifecycle#performComponentLifecycle(org.kuali.rice.krad.uif.view.View,
434     * java.lang.Object, javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse,
435     * org.kuali.rice.krad.uif.lifecycle.ViewPostMetadata, java.lang.String) after processing the lifecycle. The form
436     * property provides access to the rendering layer.</p>
437     *
438     * @return component instance for updating
439     */
440    public Component getUpdateComponent();
441
442    /**
443     * @see ViewModel#getUpdateComponent()
444     */
445    public void setUpdateComponent(Component updateComponent);
446
447    /**
448     * Indicates whether the request was made by an ajax call
449     *
450     * <p>
451     * Depending on whether the request was made via ajax (versus standard browser submit) the response
452     * will be handled different. For example with an ajax request we can send back partial page updates, which
453     * cannot be done with standard submits
454     * </p>
455     *
456     * <p>
457     * If this indicator is true, {@link #getAjaxReturnType()} will be used to determine how to handling
458     * the ajax return
459     * </p>
460     *
461     * @return boolean true if the request was an ajax call, false if not
462     */
463    boolean isAjaxRequest();
464
465    /**
466     * Set the ajaxRequest
467     *
468     * @param ajaxRequest
469     */
470    void setAjaxRequest(boolean ajaxRequest);
471
472    /**
473     * Gets the return type for the ajax call
474     *
475     * <p>
476     * The ajax return type indicates how the response content will be handled in the client. Typical
477     * examples include updating a component, the page, or doing a redirect.
478     * </p>
479     *
480     * @return String return type
481     * @see org.kuali.rice.krad.uif.UifConstants.AjaxReturnTypes
482     */
483    String getAjaxReturnType();
484
485    /**
486     * Setter for the type of ajax return
487     *
488     * @param ajaxReturnType
489     */
490    void setAjaxReturnType(String ajaxReturnType);
491
492    /**
493     * Indicates whether the request is to update a component (only applicable for ajax requests)
494     *
495     * @return boolean true if the request is for update component, false if not
496     */
497    boolean isUpdateComponentRequest();
498
499    /**
500     * Indicates whether the request is to update a page (only applicable for ajax requests)
501     *
502     * @return boolean true if the request is for update page, false if not
503     */
504    boolean isUpdatePageRequest();
505
506    /**
507     * Indicates whether the request is to update a dialog (only applicable for ajax requests)
508     *
509     * @return boolean true if the request is for update dialog, false if not
510     */
511    boolean isUpdateDialogRequest();
512
513    /**
514     * Indicates whether the request is for a non-update of the view (only applicable for ajax requests)
515     *
516     * <p>
517     * Examples of requests that do not update the view are ajax queries or requests that download a file
518     * </p>
519     *
520     * @return boolean true if the request is for non-update, false if not
521     */
522    boolean isUpdateNoneRequest();
523
524    /**
525     * Indicates whether the request should return a JSON string
526     *
527     * <p>
528     * When this indicator is true, the rendering process will invoke the template
529     * given by {@link #getRequestJsonTemplate()} which should return a JSON string
530     * </p>
531     *
532     * <p>
533     * For JSON requests the view is not built, however a component can be retrieved and
534     * exported in the request by setting {@link #getUpdateComponentId()}
535     * </p>
536     *
537     * @return boolean true if request is for JSON, false if not
538     */
539    boolean isJsonRequest();
540
541    /**
542     * Template the will be invoked to return a JSON string
543     *
544     * <p>
545     * Certain templates can be rendered to build JSON for a JSON request. The template
546     * set here (by a controller) will be rendered
547     * </p>
548     *
549     * @return path to template
550     */
551    String getRequestJsonTemplate();
552
553    /**
554     * Setter for the template to render for the request
555     *
556     * @param requestJsonTemplate
557     */
558    void setRequestJsonTemplate(String requestJsonTemplate);
559
560    /**
561     * Indicates whether the request is for paging a collection (or sorting).
562     *
563     * @return boolean true if a paging request is present, false if not
564     */
565    boolean isCollectionPagingRequest();
566
567    /**
568     * @see ViewModel#isCollectionPagingRequest()
569     */
570    void setCollectionPagingRequest(boolean collectionPagingRequest);
571
572    /**
573     * Contains values for dialog explanation fields present on the page.
574     *
575     * <p>Since multiple dialogs can be present on the same page using the generic explanation field, the values
576     * are maintained in this map using the dialog id as the key. Values are cleared on each request.</p>
577     *
578     * @return map of dialog explanations, where key is the dialog id and map value is the explanation
579     */
580    Map<String, String> getDialogExplanations();
581
582    /**
583     * @see ViewModel#getDialogExplanations()
584     */
585    void setDialogExplanations(Map<String, String> dialogExplanations);
586
587    /**
588     * Map containing dialog responses for a request 'conversation'.
589     *
590     * <p>When a controller methods requests a dialog, the response is collected on the return call and placed
591     * into this map. The key to the map is the id for the dialog. Since a single controller method can spawn multiple
592     * dialogs in a single conversation (these are actually multiple requests/responses, but part of the same action
593     * request), the responses are collected in this map. Whenever a request is encountered that is not a return, the
594     * map is cleared. This means the responses will be cleared in case the action is triggered action.</p>
595     *
596     * @return map of dialog responses, where map key is the dialog id and the map value is the dialog response
597     * object
598     */
599    Map<String, DialogResponse> getDialogResponses();
600
601    /**
602     * Helper method to get a dialog response for the given dialog id.
603     *
604     * @param dialogId id of the dialog to get response for
605     * @return dialog response object, or null if response does not exist
606     * @see ViewModel#getDialogResponses()
607     */
608    DialogResponse getDialogResponse(String dialogId);
609
610    /**
611     * @see ViewModel#getDialogResponses()
612     */
613    void setDialogResponses(Map<String, DialogResponse> dialogResponses);
614
615    /**
616     * A generic map for framework pieces (such as component modifiers) that need to dynamically store
617     * data to the form
618     *
619     * @return Map<String, Object>
620     */
621    public Map<String, Object> getExtensionData();
622
623    /**
624     * Setter for the generic extension data map
625     *
626     * @param extensionData
627     */
628    public void setExtensionData(Map<String, Object> extensionData);
629
630}