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 }