View Javadoc

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