View Javadoc

1   /**
2    * Copyright 2005-2012 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.codehaus.jackson.map.ObjectMapper;
20  import org.kuali.rice.krad.service.KRADServiceLocatorWeb;
21  import org.kuali.rice.krad.uif.UifConstants;
22  import org.kuali.rice.krad.uif.UifParameters;
23  import org.kuali.rice.krad.uif.util.SessionTransient;
24  import org.kuali.rice.krad.uif.view.DialogManager;
25  import org.kuali.rice.krad.uif.view.History;
26  import org.kuali.rice.krad.uif.view.View;
27  import org.kuali.rice.krad.uif.service.ViewService;
28  import org.kuali.rice.krad.uif.view.ViewModel;
29  import org.kuali.rice.krad.util.KRADUtils;
30  import org.springframework.web.multipart.MultipartFile;
31  import org.kuali.rice.krad.uif.UifConstants.ViewType;
32  
33  import javax.servlet.http.HttpServletRequest;
34  import java.io.IOException;
35  import java.util.ArrayList;
36  import java.util.HashMap;
37  import java.util.List;
38  import java.util.Map;
39  import java.util.Properties;
40  import java.util.Set;
41  import java.util.UUID;
42  
43  /**
44   * Base form class for views within the KRAD User Interface Framework
45   *
46   * <p>
47   * Holds properties necessary to determine the {@code View} instance that
48   * will be used to render the UI
49   * </p>
50   *
51   * @author Kuali Rice Team (rice.collab@kuali.org)
52   */
53  public class UifFormBase implements ViewModel {
54      private static final long serialVersionUID = 8432543267099454434L;
55  
56      // current view
57  
58      protected String viewId;
59  
60      protected String viewName;
61  
62      protected ViewType viewTypeName;
63  
64      protected String pageId;
65  
66      protected String methodToCall;
67  
68      protected String formKey;
69  
70      @SessionTransient
71      protected String jumpToId;
72  
73      @SessionTransient
74      protected String jumpToName;
75  
76      @SessionTransient
77      protected String focusId;
78  
79      protected String formPostUrl;
80  
81      protected String state;
82  
83      protected boolean defaultsApplied;
84  
85      protected boolean validateDirty;
86  
87      protected boolean renderedInLightBox;
88  
89      @SessionTransient
90      protected String growlScript;
91  
92      @SessionTransient
93      protected String lightboxScript;
94  
95      protected View view;
96  
97      protected View postedView;
98  
99      protected Map<String, String> viewRequestParameters;
100 
101     protected List<String> readOnlyFieldsList;
102 
103     protected Map<String, Object> newCollectionLines;
104 
105     @SessionTransient
106     protected Map<String, String> actionParameters;
107 
108     @SessionTransient
109     protected Map<String, Object> clientStateForSyncing;
110 
111     @SessionTransient
112     protected Map<String, Set<String>> selectedCollectionLines;
113 
114     private List<Object> addedCollectionItems;
115 
116     protected MultipartFile attachmentFile;
117 
118     // navigation
119 
120     protected String returnLocation;
121 
122     protected String returnFormKey;
123 
124     @SessionTransient
125     protected boolean ajaxRequest;
126 
127     @SessionTransient
128     protected String ajaxReturnType;
129 
130   
131     protected History formHistory;
132 
133     // dialog fields
134     @SessionTransient
135     protected String dialogExplanation;
136 
137     @SessionTransient
138     protected String dialogResponse;
139 
140     private DialogManager dialogManager;
141 
142     @SessionTransient
143     protected boolean skipViewInit;
144 
145     @SessionTransient
146     protected boolean requestRedirect;
147 
148     @SessionTransient
149     protected String updateComponentId;
150 
151     @SessionTransient
152     protected boolean renderFullView;
153 
154     public UifFormBase() {
155         formKey = generateFormKey();
156         renderFullView = true;
157         defaultsApplied = false;
158         renderedInLightBox = false;
159         skipViewInit = false;
160         requestRedirect = false;
161 
162         readOnlyFieldsList = new ArrayList<String>();
163         viewRequestParameters = new HashMap<String, String>();
164         newCollectionLines = new HashMap<String, Object>();
165         actionParameters = new HashMap<String, String>();
166         clientStateForSyncing = new HashMap<String, Object>();
167         selectedCollectionLines = new HashMap<String, Set<String>>();
168         addedCollectionItems = new ArrayList();
169         dialogManager = new DialogManager();
170     }
171 
172     /**
173      * Creates the unique id used to store this "conversation" in the session.
174      * The default method generates a java UUID.
175      *
176      * @return
177      */
178     protected String generateFormKey() {
179         return UUID.randomUUID().toString();
180     }
181 
182     /**
183      * @see org.kuali.rice.krad.uif.view.ViewModel#postBind(javax.servlet.http.HttpServletRequest)
184      */
185     @Override
186     public void postBind(HttpServletRequest request) {
187         // default form post URL to request URL
188         formPostUrl = request.getRequestURL().toString();
189 
190         // get any sent client view state and parse into map
191         if (request.getParameterMap().containsKey(UifParameters.CLIENT_VIEW_STATE)) {
192             String clientStateJSON = request.getParameter(UifParameters.CLIENT_VIEW_STATE);
193             if (StringUtils.isNotBlank(clientStateJSON)) {
194                 // change single quotes to double quotes (necessary because the reverse was done for sending)
195                 clientStateJSON = StringUtils.replace(clientStateJSON, "'", "\"");
196 
197                 ObjectMapper mapper = new ObjectMapper();
198                 try {
199                     clientStateForSyncing = mapper.readValue(clientStateJSON, Map.class);
200                 } catch (IOException e) {
201                     throw new RuntimeException("Unable to decode client side state JSON", e);
202                 }
203             }
204         }
205 
206         // populate read only fields list
207         if (request.getParameter(UifParameters.READ_ONLY_FIELDS) != null) {
208             String readOnlyFields = request.getParameter(UifParameters.READ_ONLY_FIELDS);
209             setReadOnlyFieldsList(KRADUtils.convertStringParameterToList(readOnlyFields));
210         }
211 
212         // reset skip view init parameter if not passed
213         if (!request.getParameterMap().containsKey(UifParameters.SKIP_VIEW_INIT)) {
214             skipViewInit = false;
215         }
216     }
217 
218     /**
219      * @see org.kuali.rice.krad.uif.view.ViewModel#getViewId()
220      */
221     @Override
222     public String getViewId() {
223         return this.viewId;
224     }
225 
226     /**
227      * @see org.kuali.rice.krad.uif.view.ViewModel#setViewId(java.lang.String)
228      */
229     @Override
230     public void setViewId(String viewId) {
231         this.viewId = viewId;
232     }
233 
234     /**
235      * @see org.kuali.rice.krad.uif.view.ViewModel#getViewName()
236      */
237     @Override
238     public String getViewName() {
239         return this.viewName;
240     }
241 
242     /**
243      * @see org.kuali.rice.krad.uif.view.ViewModel#setViewName(java.lang.String)
244      */
245     @Override
246     public void setViewName(String viewName) {
247         this.viewName = viewName;
248     }
249 
250     /**
251      * @see org.kuali.rice.krad.uif.view.ViewModel#getViewTypeName()
252      */
253     @Override
254     public ViewType getViewTypeName() {
255         return this.viewTypeName;
256     }
257 
258     /**
259      * @see org.kuali.rice.krad.uif.view.ViewModel#setViewTypeName(org.kuali.rice.krad.uif.UifConstants.ViewType)
260      */
261     @Override
262     public void setViewTypeName(ViewType viewTypeName) {
263         this.viewTypeName = viewTypeName;
264     }
265 
266     /**
267      * @see org.kuali.rice.krad.uif.view.ViewModel#getPageId()
268      */
269     @Override
270     public String getPageId() {
271         return this.pageId;
272     }
273 
274     /**
275      * @see org.kuali.rice.krad.uif.view.ViewModel#setPageId(java.lang.String)
276      */
277     @Override
278     public void setPageId(String pageId) {
279         this.pageId = pageId;
280     }
281 
282     /**
283      * @see org.kuali.rice.krad.uif.view.ViewModel#getFormPostUrl()
284      */
285     @Override
286     public String getFormPostUrl() {
287         return this.formPostUrl;
288     }
289 
290     /**
291      * @see org.kuali.rice.krad.uif.view.ViewModel#setFormPostUrl(java.lang.String)
292      */
293     @Override
294     public void setFormPostUrl(String formPostUrl) {
295         this.formPostUrl = formPostUrl;
296     }
297 
298     public String getReturnLocation() {
299         return this.returnLocation;
300     }
301 
302     public void setReturnLocation(String returnLocation) {
303         this.returnLocation = returnLocation;
304     }
305 
306     public String getReturnFormKey() {
307         return this.returnFormKey;
308     }
309 
310     public void setReturnFormKey(String returnFormKey) {
311         this.returnFormKey = returnFormKey;
312     }
313 
314     /**
315      * Identifies the controller method that should be invoked to fulfill a
316      * request. The value will be matched up against the 'params' setting on the
317      * {@code RequestMapping} annotation for the controller method
318      *
319      * @return String method to call
320      */
321     public String getMethodToCall() {
322         return this.methodToCall;
323     }
324 
325     /**
326      * Setter for the method to call
327      *
328      * @param methodToCall
329      */
330     public void setMethodToCall(String methodToCall) {
331         this.methodToCall = methodToCall;
332     }
333 
334     /**
335      * @see org.kuali.rice.krad.uif.view.ViewModel#getViewRequestParameters()
336      */
337     @Override
338     public Map<String, String> getViewRequestParameters() {
339         return this.viewRequestParameters;
340     }
341 
342     /**
343      * @see org.kuali.rice.krad.uif.view.ViewModel#setViewRequestParameters(java.util.Map<java.lang.String,java.lang.String>)
344      */
345     @Override
346     public void setViewRequestParameters(Map<String, String> viewRequestParameters) {
347         this.viewRequestParameters = viewRequestParameters;
348     }
349 
350     /**
351      * @see org.kuali.rice.krad.uif.view.ViewModel#getReadOnlyFieldsList()
352      */
353     @Override
354     public List<String> getReadOnlyFieldsList() {
355         return readOnlyFieldsList;
356     }
357 
358     /**
359      * @see org.kuali.rice.krad.uif.view.ViewModel#setReadOnlyFieldsList(java.util.List<java.lang.String>)
360      */
361     @Override
362     public void setReadOnlyFieldsList(List<String> readOnlyFieldsList) {
363         this.readOnlyFieldsList = readOnlyFieldsList;
364     }
365 
366     /**
367      * @see org.kuali.rice.krad.uif.view.ViewModel#getNewCollectionLines()
368      */
369     @Override
370     public Map<String, Object> getNewCollectionLines() {
371         return this.newCollectionLines;
372     }
373 
374     /**
375      * @see org.kuali.rice.krad.uif.view.ViewModel#setNewCollectionLines(java.util.Map<java.lang.String,java.lang.Object>)
376      */
377     @Override
378     public void setNewCollectionLines(Map<String, Object> newCollectionLines) {
379         this.newCollectionLines = newCollectionLines;
380     }
381 
382     /**
383      * @see org.kuali.rice.krad.uif.view.ViewModel#getActionParameters()
384      */
385     @Override
386     public Map<String, String> getActionParameters() {
387         return this.actionParameters;
388     }
389 
390     /**
391      * Returns the action parameters map as a {@code Properties} instance
392      *
393      * @return Properties action parameters
394      */
395     public Properties getActionParametersAsProperties() {
396         return KRADUtils.convertMapToProperties(actionParameters);
397     }
398 
399     /**
400      * @see org.kuali.rice.krad.uif.view.ViewModel#setActionParameters(java.util.Map<java.lang.String,java.lang.String>)
401      */
402     @Override
403     public void setActionParameters(Map<String, String> actionParameters) {
404         this.actionParameters = actionParameters;
405     }
406 
407     /**
408      * Retrieves the value for the given action parameter, or empty string if
409      * not found
410      *
411      * @param actionParameterName - name of the action parameter to retrieve value for
412      * @return String parameter value or empty string
413      */
414     public String getActionParamaterValue(String actionParameterName) {
415         if ((actionParameters != null) && actionParameters.containsKey(actionParameterName)) {
416             return actionParameters.get(actionParameterName);
417         }
418 
419         return "";
420     }
421 
422     /**
423      * Returns the action event that was sent in the action parameters (if any)
424      *
425      * <p>
426      * The action event is a special action parameter that can be sent to indicate a type of action being taken. This
427      * can be looked at by the view or components to render differently
428      * </p>
429      *
430      * TODO: make sure action parameters are getting reinitialized on each request
431      *
432      * @return String action event name or blank if action event was not sent
433      */
434     public String getActionEvent() {
435         if ((actionParameters != null) && actionParameters.containsKey(UifConstants.UrlParams.ACTION_EVENT)) {
436             return actionParameters.get(UifConstants.UrlParams.ACTION_EVENT);
437         }
438 
439         return "";
440     }
441 
442     /**
443      * @see org.kuali.rice.krad.uif.view.ViewModel#getClientStateForSyncing()
444      */
445     @Override
446     public Map<String, Object> getClientStateForSyncing() {
447         return clientStateForSyncing;
448     }
449 
450     /**
451      * @see org.kuali.rice.krad.uif.view.ViewModel#getSelectedCollectionLines()
452      */
453     @Override
454     public Map<String, Set<String>> getSelectedCollectionLines() {
455         return selectedCollectionLines;
456     }
457 
458     /**
459      * @see org.kuali.rice.krad.uif.view.ViewModel#setSelectedCollectionLines(java.util.Map<java.lang.String,java.util.Set<java.lang.String>>)
460      */
461     @Override
462     public void setSelectedCollectionLines(Map<String, Set<String>> selectedCollectionLines) {
463         this.selectedCollectionLines = selectedCollectionLines;
464     }
465 
466     /**
467      * Key string that identifies the form instance in session storage
468      *
469      * <p>
470      * When the view is posted, the previous form instance is retrieved and then
471      * populated from the request parameters. This key string is retrieve the
472      * session form from the session service
473      * </p>
474      *
475      * @return String form session key
476      */
477     public String getFormKey() {
478         return this.formKey;
479     }
480 
481     /**
482      * Setter for the form's session key
483      *
484      * @param formKey
485      */
486     public void setFormKey(String formKey) {
487         this.formKey = formKey;
488     }
489 
490     /**
491      * @see org.kuali.rice.krad.uif.view.ViewModel#isDefaultsApplied()
492      */
493     @Override
494     public boolean isDefaultsApplied() {
495         return this.defaultsApplied;
496     }
497 
498     /**
499      * @see org.kuali.rice.krad.uif.view.ViewModel#setDefaultsApplied(boolean)
500      */
501     @Override
502     public void setDefaultsApplied(boolean defaultsApplied) {
503         this.defaultsApplied = defaultsApplied;
504     }
505 
506     /**
507      * Indicates whether a new view is being initialized or the call is refresh (or query) call
508      *
509      * @return boolean true if view initialization was skipped, false if new view is being created
510      */
511     public boolean isSkipViewInit() {
512         return skipViewInit;
513     }
514 
515     /**
516      * Setter for the skip view initialization flag
517      *
518      * @param skipViewInit
519      */
520     public void setSkipViewInit(boolean skipViewInit) {
521         this.skipViewInit = skipViewInit;
522     }
523 
524     /**
525      * Indicates whether a redirect has been requested for the view
526      *
527      * @return boolean true if redirect was requested, false if not
528      */
529     public boolean isRequestRedirect() {
530         return requestRedirect;
531     }
532 
533     /**
534      * Setter for the request redirect indicator
535      *
536      * @param requestRedirect
537      */
538     public void setRequestRedirect(boolean requestRedirect) {
539         this.requestRedirect = requestRedirect;
540     }
541 
542     /**
543      * Holder for files that are attached through the view
544      *
545      * @return MultipartFile representing the attachment
546      */
547     public MultipartFile getAttachmentFile() {
548         return this.attachmentFile;
549     }
550 
551     /**
552      * Setter for the form's attachment file
553      *
554      * @param attachmentFile
555      */
556     public void setAttachmentFile(MultipartFile attachmentFile) {
557         this.attachmentFile = attachmentFile;
558     }
559 
560     /**
561      * Id for the component that should be updated for a component refresh process
562      *
563      * @return String component id
564      */
565     public String getUpdateComponentId() {
566         return updateComponentId;
567     }
568 
569     /**
570      * Setter for the component id that should be refreshed
571      *
572      * @param updateComponentId
573      */
574     public void setUpdateComponentId(String updateComponentId) {
575         this.updateComponentId = updateComponentId;
576     }
577 
578     /**
579      * Indicates if the full view is to be rendered or if its just a component that
580      * needs to be refreshed
581      *
582      * @return the renderFullView
583      */
584     public boolean isRenderFullView() {
585         return this.renderFullView;
586     }
587 
588     /**
589      * Setter for renderFullView
590      *
591      * @param renderFullView
592      */
593     public void setRenderFullView(boolean renderFullView) {
594         this.renderFullView = renderFullView;
595     }
596 
597     /**
598      * @see org.kuali.rice.krad.uif.view.ViewModel#getView()
599      */
600     @Override
601     public View getView() {
602         return this.view;
603     }
604 
605     /**
606      * @see org.kuali.rice.krad.uif.view.ViewModel#setView(org.kuali.rice.krad.uif.view.View)
607      */
608     @Override
609     public void setView(View view) {
610         this.view = view;
611     }
612 
613     /**
614      * @see org.kuali.rice.krad.uif.view.ViewModel#getPostedView()
615      */
616     @Override
617     public View getPostedView() {
618         return this.postedView;
619     }
620 
621     /**
622      * @see org.kuali.rice.krad.uif.view.ViewModel#setPostedView(org.kuali.rice.krad.uif.view.View)
623      */
624     @Override
625     public void setPostedView(View postedView) {
626         this.postedView = postedView;
627     }
628 
629     /**
630      * Instance of the {@code ViewService} that can be used to retrieve
631      * {@code View} instances
632      *
633      * @return ViewService implementation
634      */
635     protected ViewService getViewService() {
636         return KRADServiceLocatorWeb.getViewService();
637     }
638 
639     /**
640      * The jumpToId for this form, the element with this id will be jumped to automatically
641      * when the form is loaded in the view.
642      * Using "TOP" or "BOTTOM" will jump to the top or the bottom of the resulting page.
643      * jumpToId always takes precedence over jumpToName, if set.
644      *
645      * @return the jumpToId
646      */
647     public String getJumpToId() {
648         return this.jumpToId;
649     }
650 
651     /**
652      * @param jumpToId the jumpToId to set
653      */
654     public void setJumpToId(String jumpToId) {
655         this.jumpToId = jumpToId;
656     }
657 
658     /**
659      * The jumpToName for this form, the element with this name will be jumped to automatically
660      * when the form is loaded in the view.
661      * WARNING: jumpToId always takes precedence over jumpToName, if set.
662      *
663      * @return the jumpToName
664      */
665     public String getJumpToName() {
666         return this.jumpToName;
667     }
668 
669     /**
670      * @param jumpToName the jumpToName to set
671      */
672     public void setJumpToName(String jumpToName) {
673         this.jumpToName = jumpToName;
674     }
675 
676     /**
677      * Field to place focus on when the page loads
678      * An empty focusId will result in focusing on the first visible input element by default.
679      *
680      * @return the focusId
681      */
682     public String getFocusId() {
683         return this.focusId;
684     }
685 
686     /**
687      * @param focusId the focusId to set
688      */
689     public void setFocusId(String focusId) {
690         this.focusId = focusId;
691     }
692 
693     /**
694      * History parameter representing the History of views that have come before the
695      * viewing of the current view
696      *
697      * <p>
698      * Used for breadcrumb widget generation on the view and also for navigating back
699      * to previous or hub locations
700      * </p>
701      *
702      * @return History instance giving current history
703      */
704     public History getFormHistory() {
705         return formHistory;
706     }
707 
708     /**
709      * Setter for the current History object
710      *
711      * @param history the history to set
712      */
713     public void setFormHistory(History history) {
714         this.formHistory = history;
715     }
716 
717     /**
718      * Indicates whether the form should be validated for dirtyness
719      *
720      * <p>
721      * For FormView, it's necessary to validate when the user tries to navigate out of the form. If set, all the
722      * InputFields will be validated on refresh, navigate, cancel or close Action or on form
723      * unload and if dirty, displays a message and user can decide whether to continue with
724      * the action or stay on the form
725      * </p>
726      *
727      * @return boolean true if dirty validation should be enabled
728      */
729     public boolean isValidateDirty() {
730         return this.validateDirty;
731     }
732 
733     /**
734      * Setter for dirty validation indicator
735      *
736      * @param validateDirty
737      */
738     public void setValidateDirty(boolean validateDirty) {
739         this.validateDirty = validateDirty;
740     }
741 
742     /**
743      * Indicates whether the view is rendered within a lightbox
744      *
745      * <p>
746      * Some discussion (for example how a close button behaves) need to change based on whether the
747      * view is rendered within a lightbox or the standard browser window. This boolean is true when it is
748      * within a lightbox
749      * </p>
750      *
751      * @return boolean true if view is rendered within a lightbox, false if not
752      */
753     public boolean isRenderedInLightBox() {
754         return this.renderedInLightBox;
755     }
756 
757     /**
758      * Setter for the rendered within lightbox indicator
759      *
760      * @param renderedInLightBox
761      */
762     public void setRenderedInLightBox(boolean renderedInLightBox) {
763         this.renderedInLightBox = renderedInLightBox;
764     }
765 
766     /**
767      * @see org.kuali.rice.krad.uif.view.ViewModel#getGrowlScript()
768      */
769     @Override
770     public String getGrowlScript() {
771         return growlScript;
772     }
773 
774     /**
775      * @see org.kuali.rice.krad.uif.view.ViewModel#setGrowlScript(java.lang.String)
776      */
777     @Override
778     public void setGrowlScript(String growlScript) {
779         this.growlScript = growlScript;
780     }
781 
782     /**
783      * @see org.kuali.rice.krad.uif.view.ViewModel#getState() 
784      */
785     public String getState() {
786         return state;
787     }
788 
789     /**
790      * @see ViewModel#setState(String)
791      */
792     public void setState(String state) {
793         this.state = state;
794     }
795 
796     /**
797      * @see org.kuali.rice.krad.uif.view.ViewModel#getLightboxScript()
798      */
799     @Override
800     public String getLightboxScript() {
801         return lightboxScript;
802     }
803 
804     /**
805      * @see org.kuali.rice.krad.uif.view.ViewModel#setLightboxScript(java.lang.String)
806      */
807     @Override
808     public void setLightboxScript(String lightboxScript) {
809         this.lightboxScript = lightboxScript;
810     }
811 
812     /**
813      * @see org.kuali.rice.krad.uif.view.ViewModel#isAjaxRequest()
814      */
815     @Override
816     public boolean isAjaxRequest() {
817         return ajaxRequest;
818     }
819 
820      /**
821      * @see org.kuali.rice.krad.uif.view.ViewModel#setAjaxRequest(boolean)
822      */
823     @Override
824     public void setAjaxRequest(boolean ajaxRequest) {
825         this.ajaxRequest = ajaxRequest;
826     }
827 
828      /**
829      * @see org.kuali.rice.krad.uif.view.ViewModel#getAjaxReturnType()
830      */
831     @Override
832     public String getAjaxReturnType() {
833         return ajaxReturnType;
834     }
835 
836 
837      /**
838      * @see org.kuali.rice.krad.uif.view.ViewModel#setAjaxReturnType(java.lang.String)
839      */
840     @Override
841     public void setAjaxReturnType(String ajaxReturnType) {
842         this.ajaxReturnType = ajaxReturnType;
843     }
844 
845     /**
846      * Returns the String entered by the user when presented a dialog
847      *
848      * <p>
849      * Field defined here so all forms will be able to bind to a dialog using the same property
850      * </p>
851      *
852      * @return String - the text entered by a user as a reply in a modal dialog.
853      */
854     public String getDialogExplanation() {
855         return dialogExplanation;
856     }
857 
858     /**
859      * Sets the dialogExplanation text value.
860      *
861      * @param dialogExplanation - text entered by user when replying to a modal dialog
862      */
863     public void setDialogExplanation(String dialogExplanation) {
864         this.dialogExplanation = dialogExplanation;
865     }
866 
867     /**
868      * Represents the option chosen by the user when interacting with a modal dialog
869      *
870      * <p>
871      * This is used to determine which option was chosen by the user. The value is the key in the key/value pair
872      * selected in the control.
873      * </p>
874      *
875      * @return - String key selected by the user
876      */
877     public String getDialogResponse() {
878         return dialogResponse;
879     }
880 
881     /**
882      * Sets the response key text selected by the user as a response to a modal dialog
883      *
884      * @param dialogResponse - the key of the option chosen by the user
885      */
886     public void setDialogResponse(String dialogResponse) {
887         this.dialogResponse = dialogResponse;
888     }
889 
890     /**
891      * Gets the DialogManager for this view/form
892      *
893      * <p>
894      * The DialogManager tracks modal dialog interactions with the user
895      * </p>
896      * @return
897      */
898     public DialogManager getDialogManager() {
899         return dialogManager;
900     }
901 
902     /**
903      * Sets the DialogManager for this view
904      *
905      * @param dialogManager - DialogManager instance for this view
906      */
907     public void setDialogManager(DialogManager dialogManager) {
908         this.dialogManager = dialogManager;
909     }
910 
911 
912     /**
913      * The {@code List} that contains all newly added items for the collections on the model
914      * 
915      * <p>
916      * This list contains the new items for all the collections on the model.    
917      * </p>
918      *
919      * @return List of the newly added item lists
920      */
921     public List getAddedCollectionItems() {
922         return addedCollectionItems;
923     }
924 
925     /**
926      * Setter for the newly added item list
927      *
928      * @param addedCollectionItems
929      */
930     public void setAddedCollectionItems(List addedCollectionItems) {
931         this.addedCollectionItems = addedCollectionItems;
932     }
933 
934     /**
935      * Indicates whether an collection item has been newly added
936      *
937      * <p>
938      * Tests collection items against the list of newly added items on the model. This list gets cleared when the view 
939      * is submitted and the items are persisted.
940      * </p>
941      *
942      * @param item - the item to test against list of newly added items
943      * @return boolean true if the item has been newly added
944      */
945     public boolean isAddedCollectionItem(Object item) {
946         return addedCollectionItems.contains(item);
947     }
948 
949 }