View Javadoc
1   /**
2    * Copyright 2005-2016 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.web.form;
17  
18  import org.apache.commons.lang.StringUtils;
19  import org.apache.commons.logging.Log;
20  import org.apache.commons.logging.LogFactory;
21  import org.codehaus.jackson.map.ObjectMapper;
22  import org.kuali.rice.krad.service.KRADServiceLocatorWeb;
23  import org.kuali.rice.krad.uif.UifConstants;
24  import org.kuali.rice.krad.uif.UifConstants.ViewType;
25  import org.kuali.rice.krad.uif.UifParameters;
26  import org.kuali.rice.krad.uif.service.ViewService;
27  import org.kuali.rice.krad.uif.util.SessionTransient;
28  import org.kuali.rice.krad.uif.view.DialogManager;
29  import org.kuali.rice.krad.uif.view.View;
30  import org.kuali.rice.krad.uif.view.ViewModel;
31  import org.kuali.rice.krad.util.KRADUtils;
32  import org.springframework.web.multipart.MultipartFile;
33  
34  import javax.servlet.http.HttpServletRequest;
35  import java.io.IOException;
36  import java.util.ArrayList;
37  import java.util.HashMap;
38  import java.util.List;
39  import java.util.Map;
40  import java.util.Properties;
41  import java.util.Set;
42  import java.util.UUID;
43  
44  /**
45   * Base form class for views within the KRAD User Interface Framework
46   *
47   * <p>
48   * Holds properties necessary to determine the {@code View} instance that
49   * will be used to render the UI
50   * </p>
51   *
52   * @author Kuali Rice Team (rice.collab@kuali.org)
53   */
54  public class UifFormBase implements ViewModel {
55      private static final long serialVersionUID = 8432543267099454434L;
56  
57      // logger
58      private static final Log LOG = LogFactory.getLog(UifFormBase.class);
59  
60      // current view
61      protected String viewId;
62      protected String viewName;
63      protected ViewType viewTypeName;
64      protected String pageId;
65      protected String methodToCall;
66      protected String formKey;
67      @SessionTransient
68      protected String requestedFormKey;
69      protected String flowKey;
70      protected String sessionId;
71      protected int sessionTimeoutInterval;
72  
73      @SessionTransient
74      protected HistoryFlow historyFlow;
75      @SessionTransient
76      protected HistoryManager historyManager;
77  
78      @SessionTransient
79      protected String jumpToId;
80      @SessionTransient
81      protected String jumpToName;
82      @SessionTransient
83      protected String focusId;
84      @SessionTransient
85      protected boolean dirtyForm;
86  
87      protected String formPostUrl;
88      protected String controllerMapping;
89  
90      @SessionTransient
91      private String requestUrl;
92      private Map<String, String> initialRequestParameters;
93  
94      protected String state;
95      protected boolean defaultsApplied;
96      protected boolean renderedInLightBox;
97  
98      @SessionTransient
99      protected String growlScript;
100     @SessionTransient
101     protected String lightboxScript;
102 
103     protected View view;
104     protected View postedView;
105 
106     protected Map<String, String> viewRequestParameters;
107     protected List<String> readOnlyFieldsList;
108     protected Map<String, Object> newCollectionLines;
109 
110     @SessionTransient
111     protected Map<String, String> actionParameters;
112     protected Map<String, Object> clientStateForSyncing;
113     @SessionTransient
114     protected Map<String, Set<String>> selectedCollectionLines;
115 
116     protected List<Object> addedCollectionItems;
117 
118     @SessionTransient
119     protected MultipartFile attachmentFile;
120 
121     // navigation
122     protected String returnLocation;
123     protected String returnFormKey;
124 
125     @SessionTransient
126     protected boolean ajaxRequest;
127     @SessionTransient
128     protected String ajaxReturnType;
129     @SessionTransient
130     private String requestJsonTemplate;
131     @SessionTransient
132     private boolean originalComponentRequest;
133 
134     // dialog fields
135     @SessionTransient
136     protected String dialogExplanation;
137     @SessionTransient
138     protected String dialogResponse;
139     protected DialogManager dialogManager;
140 
141     @SessionTransient
142     protected boolean requestRedirected;
143     @SessionTransient
144     protected String updateComponentId;
145 
146     protected Map<String, Object> extensionData;
147 
148     public UifFormBase() {
149         defaultsApplied = false;
150         renderedInLightBox = false;
151         requestRedirected = false;
152 
153         readOnlyFieldsList = new ArrayList<String>();
154         viewRequestParameters = new HashMap<String, String>();
155         newCollectionLines = new HashMap<String, Object>();
156         actionParameters = new HashMap<String, String>();
157         clientStateForSyncing = new HashMap<String, Object>();
158         selectedCollectionLines = new HashMap<String, Set<String>>();
159         addedCollectionItems = new ArrayList();
160         dialogManager = new DialogManager();
161         extensionData = new HashMap<String, Object>();
162     }
163 
164     /**
165      * @see org.kuali.rice.krad.uif.view.ViewModel#postBind(javax.servlet.http.HttpServletRequest)
166      */
167     @Override
168     public void postBind(HttpServletRequest request) {
169         // assign form key if this is a new form or the requested form key is not in session
170         UifFormManager uifFormManager = (UifFormManager) request.getSession().getAttribute(UifParameters.FORM_MANAGER);
171         if (StringUtils.isBlank(formKey) || !uifFormManager.hasSessionForm(formKey)) {
172             formKey = generateFormKey();
173         }
174 
175         // default form post URL to request URL
176         formPostUrl = request.getRequestURL().toString();
177 
178         if (request.getSession() != null) {
179             sessionId = request.getSession().getId();
180             sessionTimeoutInterval = request.getSession().getMaxInactiveInterval();
181         }
182 
183         //set controller mapping property
184         controllerMapping = request.getPathInfo();
185 
186         // get any sent client view state and parse into map
187         if (request.getParameterMap().containsKey(UifParameters.CLIENT_VIEW_STATE)) {
188             String clientStateJSON = request.getParameter(UifParameters.CLIENT_VIEW_STATE);
189             if (StringUtils.isNotBlank(clientStateJSON)) {
190                 // change single quotes to double quotes (necessary because the reverse was done for sending)
191                 clientStateJSON = StringUtils.replace(clientStateJSON, "'", "\"");
192 
193                 ObjectMapper mapper = new ObjectMapper();
194                 try {
195                     clientStateForSyncing = mapper.readValue(clientStateJSON, Map.class);
196                 } catch (IOException e) {
197                     throw new RuntimeException("Unable to decode client side state JSON", e);
198                 }
199             }
200         }
201 
202         // populate read only fields list
203         if (request.getParameter(UifParameters.READ_ONLY_FIELDS) != null) {
204             String readOnlyFields = request.getParameter(UifParameters.READ_ONLY_FIELDS);
205             setReadOnlyFieldsList(KRADUtils.convertStringParameterToList(readOnlyFields));
206         }
207 
208         // clean parameters from XSS attacks that will be written out as hiddens
209         this.pageId = KRADUtils.stripXSSPatterns(this.pageId);
210         this.methodToCall = KRADUtils.stripXSSPatterns(this.methodToCall);
211         this.formKey = KRADUtils.stripXSSPatterns(this.formKey);
212         this.requestedFormKey = KRADUtils.stripXSSPatterns(this.requestedFormKey);
213         this.flowKey = KRADUtils.stripXSSPatterns(this.flowKey);
214         this.sessionId = KRADUtils.stripXSSPatterns(this.sessionId);
215         this.formPostUrl = KRADUtils.stripXSSPatterns(this.formPostUrl);
216         this.returnLocation = KRADUtils.stripXSSPatterns(this.returnLocation);
217         this.returnFormKey = KRADUtils.stripXSSPatterns(this.returnFormKey);
218         this.requestUrl = KRADUtils.stripXSSPatterns(this.requestUrl);
219     }
220 
221     /**
222      * Creates the unique id used to store this "conversation" in the session.
223      * The default method generates a java UUID.
224      *
225      * @return UUID
226      */
227     protected String generateFormKey() {
228         return UUID.randomUUID().toString();
229     }
230 
231     /**
232      * @see org.kuali.rice.krad.uif.view.ViewModel#getViewId()
233      */
234     @Override
235     public String getViewId() {
236         return this.viewId;
237     }
238 
239     /**
240      * @see org.kuali.rice.krad.uif.view.ViewModel#setViewId(String)
241      */
242     @Override
243     public void setViewId(String viewId) {
244         this.viewId = viewId;
245     }
246 
247     /**
248      * @see org.kuali.rice.krad.uif.view.ViewModel#getViewName()
249      */
250     @Override
251     public String getViewName() {
252         return this.viewName;
253     }
254 
255     /**
256      * @see org.kuali.rice.krad.uif.view.ViewModel#setViewName(String)
257      */
258     @Override
259     public void setViewName(String viewName) {
260         this.viewName = viewName;
261     }
262 
263     /**
264      * @see org.kuali.rice.krad.uif.view.ViewModel#getViewTypeName()
265      */
266     @Override
267     public ViewType getViewTypeName() {
268         return this.viewTypeName;
269     }
270 
271     /**
272      * @see org.kuali.rice.krad.uif.view.ViewModel#setViewTypeName(org.kuali.rice.krad.uif.UifConstants.ViewType)
273      */
274     @Override
275     public void setViewTypeName(ViewType viewTypeName) {
276         this.viewTypeName = viewTypeName;
277     }
278 
279     /**
280      * @see org.kuali.rice.krad.uif.view.ViewModel#getPageId()
281      */
282     @Override
283     public String getPageId() {
284         return this.pageId;
285     }
286 
287     /**
288      * @see org.kuali.rice.krad.uif.view.ViewModel#setPageId(String)
289      */
290     @Override
291     public void setPageId(String pageId) {
292         this.pageId = pageId;
293     }
294 
295     /**
296      * @see org.kuali.rice.krad.uif.view.ViewModel#getFormPostUrl()
297      */
298     @Override
299     public String getFormPostUrl() {
300         return this.formPostUrl;
301     }
302 
303     /**
304      * @see org.kuali.rice.krad.uif.view.ViewModel#setFormPostUrl(String)
305      */
306     @Override
307     public void setFormPostUrl(String formPostUrl) {
308         this.formPostUrl = formPostUrl;
309     }
310 
311     /**
312      * Name of the controllerMapping for this form (includes slash)
313      *
314      * @return the controllerMapping string
315      */
316     public String getControllerMapping() {
317         return controllerMapping;
318     }
319 
320     /**
321      * The current {@link HistoryFlow} for this form which stores a trail of urls/breadcrumbs primarily used for
322      * path-based breadcrumb display
323      *
324      * @return the {@link HistoryFlow}
325      */
326     public HistoryFlow getHistoryFlow() {
327         return historyFlow;
328     }
329 
330     /**
331      * Set the current HistoryFlow for this form
332      *
333      * @param historyFlow
334      */
335     public void setHistoryFlow(HistoryFlow historyFlow) {
336         this.historyFlow = historyFlow;
337     }
338 
339     /**
340      * The current {@link HistoryManager} that was pulled from session which store all {@link HistoryFlow} objects in
341      * the current session to keep track of the path the user has taken across views (primarily used by path-based
342      * breadcrumbs)
343      *
344      * @return the HistoryManager
345      */
346     public HistoryManager getHistoryManager() {
347         return historyManager;
348     }
349 
350     /**
351      * Set the current HistoryManager
352      *
353      * @param historyManager
354      */
355     public void setHistoryManager(HistoryManager historyManager) {
356         this.historyManager = historyManager;
357     }
358 
359     /**
360      * The flowKey representing the HistoryFlow this form may be in.
361      *
362      * <p>This allows for a flow to continue by key or start (if set to "start").
363      * If null or blank, no flow (or path based
364      * breadcrumbs) are being tracked.</p>
365      *
366      * @return the flowKey
367      */
368     public String getFlowKey() {
369         return flowKey;
370     }
371 
372     /**
373      * Set the flowKey
374      *
375      * @param flowKey
376      */
377     public void setFlowKey(String flowKey) {
378         this.flowKey = flowKey;
379     }
380 
381     /**
382      * The original requestUrl for the View represented by this form (url received by the controller for initial
383      * request)
384      *
385      * @return the requestUrl
386      */
387     public String getRequestUrl() {
388         return requestUrl;
389     }
390 
391     /**
392      * Set the requestUrl
393      *
394      * @param requestUrl
395      */
396     public void setRequestUrl(String requestUrl) {
397         this.requestUrl = requestUrl;
398     }
399 
400     /**
401      * The requestParameters represent all the parameters in the query string that were initially passed to this View
402      * by the initial request
403      *
404      * @return the requestParameters
405      */
406     public Map<String, String> getInitialRequestParameters() {
407         return initialRequestParameters;
408     }
409 
410     /**
411      * Set the requestParameters
412      *
413      * @param requestParameters
414      */
415     public void setInitialRequestParameters(Map<String, String> requestParameters) {
416         this.initialRequestParameters = requestParameters;
417     }
418 
419     public String getReturnLocation() {
420         return this.returnLocation;
421     }
422 
423     public void setReturnLocation(String returnLocation) {
424         this.returnLocation = returnLocation;
425     }
426 
427     public String getReturnFormKey() {
428         return this.returnFormKey;
429     }
430 
431     public void setReturnFormKey(String returnFormKey) {
432         this.returnFormKey = returnFormKey;
433     }
434 
435     /**
436      * Holds the id for the user's current session
437      *
438      * <p>
439      * The user's session id is used to track when a timeout has occurred and enforce the policy
440      * configured with the {@link org.kuali.rice.krad.uif.view.ViewSessionPolicy}. This property gets initialized
441      * in the {@link #postBind(javax.servlet.http.HttpServletRequest)} method and then is written out as a
442      * hidden on the view. Therefore each post done on the view will send back the session id when the view was
443      * rendering, and the {@link org.kuali.rice.krad.web.filter.UifSessionTimeoutFilter} can use that to determine
444      * if a timeout has occurred
445      * </p>
446      *
447      * @return id for the user's current session
448      */
449     public String getSessionId() {
450         return sessionId;
451     }
452 
453     /**
454      * Holds the configured session timeout interval
455      *
456      * <p>
457      * Holds the session timeout interval so it can be referenced to give the user notifications (for example the
458      * session timeout warning reads this property). This is initialized from the session object in
459      * {@link #postBind(javax.servlet.http.HttpServletRequest)}
460      * </p>
461      *
462      * @return amount of time in milliseconds before the session will timeout
463      */
464     public int getSessionTimeoutInterval() {
465         return sessionTimeoutInterval;
466     }
467 
468     /**
469      * Identifies the controller method that should be invoked to fulfill a
470      * request. The value will be matched up against the 'params' setting on the
471      * {@code RequestMapping} annotation for the controller method
472      *
473      * @return String method to call
474      */
475     public String getMethodToCall() {
476         return this.methodToCall;
477     }
478 
479     /**
480      * Setter for the method to call
481      *
482      * @param methodToCall
483      */
484     public void setMethodToCall(String methodToCall) {
485         this.methodToCall = methodToCall;
486     }
487 
488     /**
489      * @see org.kuali.rice.krad.uif.view.ViewModel#getViewRequestParameters()
490      */
491     @Override
492     public Map<String, String> getViewRequestParameters() {
493         return this.viewRequestParameters;
494     }
495 
496     /**
497      * @see org.kuali.rice.krad.uif.view.ViewModel#setViewRequestParameters(java.util.Map<String,String>)
498      */
499     @Override
500     public void setViewRequestParameters(Map<String, String> viewRequestParameters) {
501         this.viewRequestParameters = viewRequestParameters;
502     }
503 
504     /**
505      * @see org.kuali.rice.krad.uif.view.ViewModel#getReadOnlyFieldsList()
506      */
507     @Override
508     public List<String> getReadOnlyFieldsList() {
509         return readOnlyFieldsList;
510     }
511 
512     /**
513      * @see org.kuali.rice.krad.uif.view.ViewModel#setReadOnlyFieldsList(java.util.List<String>)
514      */
515     @Override
516     public void setReadOnlyFieldsList(List<String> readOnlyFieldsList) {
517         this.readOnlyFieldsList = readOnlyFieldsList;
518     }
519 
520     /**
521      * @see org.kuali.rice.krad.uif.view.ViewModel#getNewCollectionLines()
522      */
523     @Override
524     public Map<String, Object> getNewCollectionLines() {
525         return this.newCollectionLines;
526     }
527 
528     /**
529      * @see org.kuali.rice.krad.uif.view.ViewModel#setNewCollectionLines(java.util.Map<String,Object>)
530      */
531     @Override
532     public void setNewCollectionLines(Map<String, Object> newCollectionLines) {
533         this.newCollectionLines = newCollectionLines;
534     }
535 
536     /**
537      * @see org.kuali.rice.krad.uif.view.ViewModel#getActionParameters()
538      */
539     @Override
540     public Map<String, String> getActionParameters() {
541         return this.actionParameters;
542     }
543 
544     /**
545      * Returns the action parameters map as a {@code Properties} instance
546      *
547      * @return Properties action parameters
548      */
549     public Properties getActionParametersAsProperties() {
550         return KRADUtils.convertMapToProperties(actionParameters);
551     }
552 
553     /**
554      * @see org.kuali.rice.krad.uif.view.ViewModel#setActionParameters(java.util.Map<String,String>)
555      */
556     @Override
557     public void setActionParameters(Map<String, String> actionParameters) {
558         this.actionParameters = actionParameters;
559     }
560 
561     /**
562      * Retrieves the value for the given action parameter, or empty string if
563      * not found
564      *
565      * @param actionParameterName - name of the action parameter to retrieve value for
566      * @return String parameter value or empty string
567      */
568     public String getActionParamaterValue(String actionParameterName) {
569         if ((actionParameters != null) && actionParameters.containsKey(actionParameterName)) {
570             return actionParameters.get(actionParameterName);
571         }
572 
573         return "";
574     }
575 
576     /**
577      * Returns the action event that was sent in the action parameters (if any)
578      *
579      * <p>
580      * The action event is a special action parameter that can be sent to indicate a type of action being taken. This
581      * can be looked at by the view or components to render differently
582      * </p>
583      *
584      * TODO: make sure action parameters are getting reinitialized on each request
585      *
586      * @return String action event name or blank if action event was not sent
587      */
588     public String getActionEvent() {
589         if ((actionParameters != null) && actionParameters.containsKey(UifConstants.UrlParams.ACTION_EVENT)) {
590             return actionParameters.get(UifConstants.UrlParams.ACTION_EVENT);
591         }
592 
593         return "";
594     }
595 
596     /**
597      * @see org.kuali.rice.krad.uif.view.ViewModel#getClientStateForSyncing()
598      */
599     @Override
600     public Map<String, Object> getClientStateForSyncing() {
601         return clientStateForSyncing;
602     }
603 
604     /**
605      * Setter for the client state
606      *
607      * @param clientStateForSyncing
608      */
609     public void setClientStateForSyncing(Map<String, Object> clientStateForSyncing) {
610         this.clientStateForSyncing = clientStateForSyncing;
611     }
612 
613     /**
614      * @see org.kuali.rice.krad.uif.view.ViewModel#getSelectedCollectionLines()
615      */
616     @Override
617     public Map<String, Set<String>> getSelectedCollectionLines() {
618         return selectedCollectionLines;
619     }
620 
621     /**
622      * @see org.kuali.rice.krad.uif.view.ViewModel#setSelectedCollectionLines(java.util.Map<String,java.util.Set<String>>)
623      */
624     @Override
625     public void setSelectedCollectionLines(Map<String, Set<String>> selectedCollectionLines) {
626         this.selectedCollectionLines = selectedCollectionLines;
627     }
628 
629     /**
630      * Key string that identifies the form instance in session storage
631      *
632      * <p>
633      * When the view is posted, the previous form instance is retrieved and then
634      * populated from the request parameters. This key string is retrieve the
635      * session form from the session service
636      * </p>
637      *
638      * @return String form session key
639      */
640     public String getFormKey() {
641         return this.formKey;
642     }
643 
644     /**
645      * Setter for the form's session key
646      *
647      * @param formKey
648      */
649     public void setFormKey(String formKey) {
650         this.formKey = formKey;
651     }
652 
653     /**
654      * This is the formKey sent on the original request.  It may differ from the actual form key stored in formKey
655      * based on if the form still exists in session by this key or not.
656      *
657      * @return the original requested form key
658      */
659     public String getRequestedFormKey() {
660         return requestedFormKey;
661     }
662 
663     /**
664      * Set the requestedFormKey
665      *
666      * @param requestedFormKey
667      */
668     public void setRequestedFormKey(String requestedFormKey) {
669         this.requestedFormKey = requestedFormKey;
670     }
671 
672     /**
673      * @see org.kuali.rice.krad.uif.view.ViewModel#isDefaultsApplied()
674      */
675     @Override
676     public boolean isDefaultsApplied() {
677         return this.defaultsApplied;
678     }
679 
680     /**
681      * @see org.kuali.rice.krad.uif.view.ViewModel#setDefaultsApplied(boolean)
682      */
683     @Override
684     public void setDefaultsApplied(boolean defaultsApplied) {
685         this.defaultsApplied = defaultsApplied;
686     }
687 
688     /**
689      * Indicates whether a redirect has been requested for the view
690      *
691      * @return boolean true if redirect was requested, false if not
692      */
693     public boolean isRequestRedirected() {
694         return requestRedirected;
695     }
696 
697     /**
698      * Setter for the request redirect indicator
699      *
700      * @param requestRedirected
701      */
702     public void setRequestRedirected(boolean requestRedirected) {
703         this.requestRedirected = requestRedirected;
704     }
705 
706     /**
707      * Holder for files that are attached through the view
708      *
709      * @return MultipartFile representing the attachment
710      */
711     public MultipartFile getAttachmentFile() {
712         return this.attachmentFile;
713     }
714 
715     /**
716      * Setter for the form's attachment file
717      *
718      * @param attachmentFile
719      */
720     public void setAttachmentFile(MultipartFile attachmentFile) {
721         this.attachmentFile = attachmentFile;
722     }
723 
724     /**
725      * @see org.kuali.rice.krad.uif.view.ViewModel#getUpdateComponentId()
726      */
727     public String getUpdateComponentId() {
728         return updateComponentId;
729     }
730 
731     /**
732      * @see org.kuali.rice.krad.uif.view.ViewModel#setUpdateComponentId(java.lang.String)
733      */
734     public void setUpdateComponentId(String updateComponentId) {
735         this.updateComponentId = updateComponentId;
736     }
737 
738     /**
739      * @see org.kuali.rice.krad.uif.view.ViewModel#getView()
740      */
741     @Override
742     public View getView() {
743         return this.view;
744     }
745 
746     /**
747      * @see org.kuali.rice.krad.uif.view.ViewModel#setView(org.kuali.rice.krad.uif.view.View)
748      */
749     @Override
750     public void setView(View view) {
751         this.view = view;
752     }
753 
754     /**
755      * @see org.kuali.rice.krad.uif.view.ViewModel#getPostedView()
756      */
757     @Override
758     public View getPostedView() {
759         return this.postedView;
760     }
761 
762     /**
763      * @see org.kuali.rice.krad.uif.view.ViewModel#setPostedView(org.kuali.rice.krad.uif.view.View)
764      */
765     @Override
766     public void setPostedView(View postedView) {
767         this.postedView = postedView;
768     }
769 
770     /**
771      * Instance of the {@code ViewService} that can be used to retrieve
772      * {@code View} instances
773      *
774      * @return ViewService implementation
775      */
776     protected ViewService getViewService() {
777         return KRADServiceLocatorWeb.getViewService();
778     }
779 
780     /**
781      * The jumpToId for this form, the element with this id will be jumped to automatically
782      * when the form is loaded in the view.
783      * Using "TOP" or "BOTTOM" will jump to the top or the bottom of the resulting page.
784      * jumpToId always takes precedence over jumpToName, if set.
785      *
786      * @return the jumpToId
787      */
788     public String getJumpToId() {
789         return this.jumpToId;
790     }
791 
792     /**
793      * @param jumpToId the jumpToId to set
794      */
795     public void setJumpToId(String jumpToId) {
796         this.jumpToId = jumpToId;
797     }
798 
799     /**
800      * The jumpToName for this form, the element with this name will be jumped to automatically
801      * when the form is loaded in the view.
802      * WARNING: jumpToId always takes precedence over jumpToName, if set.
803      *
804      * @return the jumpToName
805      */
806     public String getJumpToName() {
807         return this.jumpToName;
808     }
809 
810     /**
811      * @param jumpToName the jumpToName to set
812      */
813     public void setJumpToName(String jumpToName) {
814         this.jumpToName = jumpToName;
815     }
816 
817     /**
818      * Field to place focus on when the page loads
819      * An empty focusId will result in focusing on the first visible input element by default.
820      *
821      * @return the focusId
822      */
823     public String getFocusId() {
824         return this.focusId;
825     }
826 
827     /**
828      * @param focusId the focusId to set
829      */
830     public void setFocusId(String focusId) {
831         this.focusId = focusId;
832     }
833 
834     /**
835      * True when the form is considered dirty (data has changed from original value), false otherwise
836      *
837      * <p>For most scenarios, this flag should NOT be set to true.
838      * If this is set, it must be managed explicitly by the application.  This flag exists for marking a
839      * form dirty from a server call, so it must be changed to false when the form is no longer considered dirty.
840      * The krad save Action and navigate methodToCall resets this flag back to false, but any other setting of
841      * this flag must be managed by custom configuration/methods, if custom dirtyForm management is needed.</p>
842      *
843      * @return true if the form is considered dirty, false otherwise
844      */
845     public boolean isDirtyForm() {
846         return dirtyForm;
847     }
848 
849     /**
850      * Sets the dirtyForm flag
851      *
852      * <p>For most scenarios, this flag should NOT be set to true.
853      * If this is set, it must be managed explicitly by the application.  This flag exists for marking a
854      * form dirty from a server call, so it must be changed to false when the form is no longer considered dirty.
855      * The krad save Action and navigate methodToCall resets this flag back to false, but any other setting of
856      * this flag must be managed by custom configuration/methods, if custom dirtyForm management is needed.</p>
857      *
858      * @param dirtyForm
859      */
860     public void setDirtyForm(boolean dirtyForm) {
861         this.dirtyForm = dirtyForm;
862     }
863 
864     /**
865      * Set the dirtyForm flag using a String that will be converted to boolean
866      *
867      * @param dirtyForm
868      */
869     public void setDirtyForm(String dirtyForm) {
870         if(dirtyForm != null){
871             this.dirtyForm = Boolean.parseBoolean(dirtyForm);
872         }
873     }
874 
875     /**
876      * Indicates whether the view is rendered within a lightbox
877      *
878      * <p>
879      * Some discussion (for example how a close button behaves) need to change based on whether the
880      * view is rendered within a lightbox or the standard browser window. This boolean is true when it is
881      * within a lightbox
882      * </p>
883      *
884      * @return boolean true if view is rendered within a lightbox, false if not
885      */
886     public boolean isRenderedInLightBox() {
887         return this.renderedInLightBox;
888     }
889 
890     /**
891      * Setter for the rendered within lightbox indicator
892      *
893      * @param renderedInLightBox
894      */
895     public void setRenderedInLightBox(boolean renderedInLightBox) {
896         this.renderedInLightBox = renderedInLightBox;
897     }
898 
899     /**
900      * @see org.kuali.rice.krad.uif.view.ViewModel#getGrowlScript()
901      */
902     @Override
903     public String getGrowlScript() {
904         return growlScript;
905     }
906 
907     /**
908      * @see org.kuali.rice.krad.uif.view.ViewModel#setGrowlScript(String)
909      */
910     @Override
911     public void setGrowlScript(String growlScript) {
912         this.growlScript = growlScript;
913     }
914 
915     /**
916      * @see org.kuali.rice.krad.uif.view.ViewModel#getState()
917      */
918     public String getState() {
919         return state;
920     }
921 
922     /**
923      * @see org.kuali.rice.krad.uif.view.ViewModel#setState(String)
924      */
925     public void setState(String state) {
926         this.state = state;
927     }
928 
929     /**
930      * @see org.kuali.rice.krad.uif.view.ViewModel#getLightboxScript()
931      */
932     @Override
933     public String getLightboxScript() {
934         return lightboxScript;
935     }
936 
937     /**
938      * @see org.kuali.rice.krad.uif.view.ViewModel#setLightboxScript(String)
939      */
940     @Override
941     public void setLightboxScript(String lightboxScript) {
942         this.lightboxScript = lightboxScript;
943     }
944 
945     /**
946      * @see org.kuali.rice.krad.uif.view.ViewModel#isAjaxRequest()
947      */
948     @Override
949     public boolean isAjaxRequest() {
950         return ajaxRequest;
951     }
952 
953     /**
954      * @see org.kuali.rice.krad.uif.view.ViewModel#setAjaxRequest(boolean)
955      */
956     @Override
957     public void setAjaxRequest(boolean ajaxRequest) {
958         this.ajaxRequest = ajaxRequest;
959     }
960 
961     /**
962      * @see org.kuali.rice.krad.uif.view.ViewModel#getAjaxReturnType()
963      */
964     @Override
965     public String getAjaxReturnType() {
966         return ajaxReturnType;
967     }
968 
969     /**
970      * @see org.kuali.rice.krad.uif.view.ViewModel#isUpdateComponentRequest()
971      */
972     @Override
973     public boolean isUpdateComponentRequest() {
974         return isAjaxRequest() && StringUtils.isNotBlank(getAjaxReturnType()) && getAjaxReturnType().equals(
975                 UifConstants.AjaxReturnTypes.UPDATECOMPONENT.getKey());
976     }
977 
978     /**
979      * @see org.kuali.rice.krad.uif.view.ViewModel#isUpdateDialogRequest()
980      */
981     @Override
982     public boolean isUpdateDialogRequest() {
983         return isAjaxRequest() && StringUtils.isNotBlank(getAjaxReturnType()) && getAjaxReturnType().equals(
984                 UifConstants.AjaxReturnTypes.UPDATEDIALOG.getKey());
985     }
986 
987     /**
988      * @see org.kuali.rice.krad.uif.view.ViewModel#isUpdatePageRequest()
989      */
990     @Override
991     public boolean isUpdatePageRequest() {
992         return isAjaxRequest() && StringUtils.isNotBlank(getAjaxReturnType()) && getAjaxReturnType().equals(
993                 UifConstants.AjaxReturnTypes.UPDATEPAGE.getKey());
994     }
995 
996     /**
997      * @see org.kuali.rice.krad.uif.view.ViewModel#isUpdateNoneRequest()
998      */
999     @Override
1000     public boolean isUpdateNoneRequest() {
1001         return isAjaxRequest() && StringUtils.isNotBlank(getAjaxReturnType()) && getAjaxReturnType().equals(
1002                 UifConstants.AjaxReturnTypes.UPDATENONE.getKey());
1003     }
1004 
1005     /**
1006      * @see org.kuali.rice.krad.uif.view.ViewModel#isBuildViewRequest()
1007      */
1008     @Override
1009     public boolean isBuildViewRequest() {
1010         return !isAjaxRequest() || (StringUtils.isNotBlank(getAjaxReturnType()) && (getAjaxReturnType().equals(
1011                 UifConstants.AjaxReturnTypes.UPDATEVIEW.getKey()) || isUpdatePageRequest()));
1012     }
1013 
1014     /**
1015      * @see org.kuali.rice.krad.uif.view.ViewModel#isUpdateViewRequest()
1016      */
1017     @Override
1018     public boolean isUpdateViewRequest() {
1019         return isAjaxRequest() &&
1020                 StringUtils.isNotBlank(getAjaxReturnType()) &&
1021                 (isUpdateComponentRequest() || getAjaxReturnType().equals(
1022                         UifConstants.AjaxReturnTypes.DISPLAYLIGHTBOX.getKey()));
1023     }
1024 
1025     /**
1026      * @see org.kuali.rice.krad.uif.view.ViewModel#setAjaxReturnType(String)
1027      */
1028     @Override
1029     public void setAjaxReturnType(String ajaxReturnType) {
1030         this.ajaxReturnType = ajaxReturnType;
1031     }
1032 
1033     /**
1034      * @see org.kuali.rice.krad.uif.view.ViewModel#isJsonRequest()
1035      */
1036     public boolean isJsonRequest() {
1037         return StringUtils.isNotBlank(getRequestJsonTemplate());
1038     }
1039 
1040     /**
1041      * @see org.kuali.rice.krad.uif.view.ViewModel#getRequestJsonTemplate()
1042      */
1043     public String getRequestJsonTemplate() {
1044         return requestJsonTemplate;
1045     }
1046 
1047     /**
1048      * @see org.kuali.rice.krad.uif.view.ViewModel#setRequestJsonTemplate
1049      */
1050     public void setRequestJsonTemplate(String requestJsonTemplate) {
1051         this.requestJsonTemplate = requestJsonTemplate;
1052     }
1053 
1054     /**
1055      * True if the current request is attempting to retrieve the originally generated component; the request
1056      * must be an update-component request for this to be taken into account
1057      *
1058      * @return true if retrieving the original component
1059      */
1060     public boolean isOriginalComponentRequest() {
1061         return originalComponentRequest;
1062     }
1063 
1064     /**
1065      * Set the originalComponentRequest flag
1066      *
1067      * @param originalComponentRequest
1068      */
1069     public void setOriginalComponentRequest(boolean originalComponentRequest) {
1070         this.originalComponentRequest = originalComponentRequest;
1071     }
1072 
1073     /**
1074      * Returns the String entered by the user when presented a dialog
1075      *
1076      * <p>
1077      * Field defined here so all forms will be able to bind to a dialog using the same property
1078      * </p>
1079      *
1080      * @return String - the text entered by a user as a reply in a modal dialog.
1081      */
1082     public String getDialogExplanation() {
1083         return dialogExplanation;
1084     }
1085 
1086     /**
1087      * Sets the dialogExplanation text value.
1088      *
1089      * @param dialogExplanation - text entered by user when replying to a modal dialog
1090      */
1091     public void setDialogExplanation(String dialogExplanation) {
1092         this.dialogExplanation = dialogExplanation;
1093     }
1094 
1095     /**
1096      * Represents the option chosen by the user when interacting with a modal dialog
1097      *
1098      * <p>
1099      * This is used to determine which option was chosen by the user. The value is the key in the key/value pair
1100      * selected in the control.
1101      * </p>
1102      *
1103      * @return - String key selected by the user
1104      */
1105     public String getDialogResponse() {
1106         return dialogResponse;
1107     }
1108 
1109     /**
1110      * Sets the response key text selected by the user as a response to a modal dialog
1111      *
1112      * @param dialogResponse - the key of the option chosen by the user
1113      */
1114     public void setDialogResponse(String dialogResponse) {
1115         this.dialogResponse = dialogResponse;
1116     }
1117 
1118     /**
1119      * Gets the DialogManager for this view/form
1120      *
1121      * <p>
1122      * The DialogManager tracks modal dialog interactions with the user
1123      * </p>
1124      *
1125      * @return
1126      */
1127     public DialogManager getDialogManager() {
1128         return dialogManager;
1129     }
1130 
1131     /**
1132      * Sets the DialogManager for this view
1133      *
1134      * @param dialogManager - DialogManager instance for this view
1135      */
1136     public void setDialogManager(DialogManager dialogManager) {
1137         this.dialogManager = dialogManager;
1138     }
1139 
1140     /**
1141      * @see org.kuali.rice.krad.uif.view.ViewModel#getExtensionData()
1142      */
1143     public Map<String, Object> getExtensionData() {
1144         return extensionData;
1145     }
1146 
1147     /**
1148      * @see org.kuali.rice.krad.uif.view.ViewModel#setExtensionData(java.util.Map<String,Object>)
1149      */
1150     public void setExtensionData(Map<String, Object> extensionData) {
1151         this.extensionData = extensionData;
1152     }
1153 
1154     /**
1155      * The {@code List} that contains all newly added items for the collections on the model
1156      *
1157      * <p>
1158      * This list contains the new items for all the collections on the model.
1159      * </p>
1160      *
1161      * @return List of the newly added item lists
1162      */
1163     public List getAddedCollectionItems() {
1164         return addedCollectionItems;
1165     }
1166 
1167     /**
1168      * Setter for the newly added item list
1169      *
1170      * @param addedCollectionItems
1171      */
1172     public void setAddedCollectionItems(List addedCollectionItems) {
1173         this.addedCollectionItems = addedCollectionItems;
1174     }
1175 
1176     /**
1177      * Indicates whether an collection item has been newly added
1178      *
1179      * <p>
1180      * Tests collection items against the list of newly added items on the model. This list gets cleared when the view
1181      * is submitted and the items are persisted.
1182      * </p>
1183      *
1184      * @param item - the item to test against list of newly added items
1185      * @return boolean true if the item has been newly added
1186      */
1187     public boolean isAddedCollectionItem(Object item) {
1188         return addedCollectionItems.contains(item);
1189     }
1190 
1191 }