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.uif.view;
17  
18  import org.apache.commons.lang.StringUtils;
19  import org.kuali.rice.krad.uif.UifConstants.ViewType;
20  import org.kuali.rice.krad.uif.UifPropertyPaths;
21  import org.kuali.rice.krad.uif.container.CollectionGroup;
22  import org.kuali.rice.krad.uif.container.Group;
23  import org.kuali.rice.krad.uif.component.Component;
24  import org.kuali.rice.krad.uif.component.RequestParameter;
25  import org.kuali.rice.krad.uif.element.Link;
26  import org.kuali.rice.krad.uif.field.Field;
27  import org.kuali.rice.krad.uif.field.FieldGroup;
28  import org.kuali.rice.krad.web.form.LookupForm;
29  
30  import java.util.Arrays;
31  import java.util.List;
32  
33  /**
34   * View type for Maintenance documents
35   *
36   * <p>
37   * Supports doing a search against a data object class or performing a more advanced query. The view
38   * type is primarily made up of two groups, the search (or criteria) group and the results group. Many
39   * options are supported on the view to enable/disable certain features, like what actions are available
40   * on the search results.
41   * </p>
42   *
43   * <p>
44   * Works in conjunction with <code>LookupableImpl</code> which customizes the view and carries out the
45   * business functionality
46   * </p>
47   *
48   * @author Kuali Rice Team (rice.collab@kuali.org)
49   */
50  public class LookupView extends FormView {
51      private static final long serialVersionUID = 716926008488403616L;
52  
53      private Class<?> dataObjectClassName;
54  
55      private Group criteriaGroup;
56      private CollectionGroup resultsGroup;
57  
58      private FieldGroup resultsActionsFieldGroup;
59      private Field resultsReturnField;
60  
61      private List<Component> criteriaFields;
62      private List<Component> resultFields;
63      private List<String> defaultSortAttributeNames;
64  
65      protected boolean defaultSortAscending = true;
66  
67      @RequestParameter
68      private boolean hideReturnLinks = false;
69      @RequestParameter
70      private boolean suppressActions = false;
71      @RequestParameter
72      private boolean showMaintenanceLinks = false;
73      @RequestParameter
74      private boolean multipleValuesSelect = false;
75  
76      @RequestParameter
77      private String returnTarget;
78  
79      @RequestParameter
80      private boolean returnByScript;
81  
82      private boolean lookupCriteriaEnabled = true;
83      private boolean supplementalActionsEnabled = false;
84      private boolean disableSearchButtons = false;
85  
86      private Integer resultSetLimit = null;
87  
88      private String maintenanceUrlMapping;
89  
90      public LookupView() {
91          super();
92  
93          setViewTypeName(ViewType.LOOKUP);
94          setApplyDirtyCheck(false);
95      }
96  
97      /**
98       * The following initialization is performed:
99       *
100      * <ul>
101      * <li>Set the abstractTypeClasses map for the lookup object path</li>
102      * </ul>
103      *
104      * @see org.kuali.rice.krad.uif.container.ContainerBase#performInitialization(org.kuali.rice.krad.uif.view.View,
105      *      java.lang.Object)
106      */
107     @Override
108     public void performInitialization(View view, Object model) {
109         initializeGroups();
110         if (getItems().isEmpty()) {
111             setItems(Arrays.asList(getCriteriaGroup(), getResultsGroup()));
112         }
113 
114         super.performInitialization(view, model);
115 
116         // if this is a multi-value lookup, don't show return column
117         if (multipleValuesSelect) {
118             hideReturnLinks = true;
119         }
120 
121         getObjectPathToConcreteClassMapping().put(UifPropertyPaths.LOOKUP_CRITERIA, getDataObjectClassName());
122         if (StringUtils.isNotBlank(getDefaultBindingObjectPath())) {
123             getObjectPathToConcreteClassMapping().put(getDefaultBindingObjectPath(), getDataObjectClassName());
124         }
125     }
126 
127     protected void initializeGroups() {
128         if ((getCriteriaGroup() != null) && (getCriteriaGroup().getItems().isEmpty())) {
129             getCriteriaGroup().setItems(getCriteriaFields());
130         }
131 
132         if (getResultsGroup() != null) {
133             if ((getResultsGroup().getItems().isEmpty()) && (getResultFields() != null)) {
134                 getResultsGroup().setItems(getResultFields());
135             }
136             if (getResultsGroup().getCollectionObjectClass() == null) {
137                 getResultsGroup().setCollectionObjectClass(getDataObjectClassName());
138             }
139         }
140     }
141 
142     /**
143      * @see org.kuali.rice.krad.uif.container.ContainerBase#performApplyModel(org.kuali.rice.krad.uif.view.View,
144      *      java.lang.Object)
145      */
146     @Override
147     public void performApplyModel(View view, Object model, Component parent) {
148         LookupForm lookupForm = (LookupForm) model;
149 
150         // TODO: need to check lookupForm.isAtLeastOneRowHasActions() somewhere
151         if (!isSuppressActions() && isShowMaintenanceLinks()) {
152             ((List<Component>) getResultsGroup().getItems()).add(0, getResultsActionsFieldGroup());
153         }
154 
155         if (StringUtils.isNotBlank(lookupForm.getReturnFormKey()) &&
156                 StringUtils.isNotBlank(lookupForm.getReturnLocation()) && !isHideReturnLinks()) {
157             ((List<Component>) getResultsGroup().getItems()).add(0, getResultsReturnField());
158         }
159 
160         super.performApplyModel(view, model, parent);
161     }
162 
163     /**
164      * @see org.kuali.rice.krad.uif.component.Component#getComponentPrototypes()
165      */
166     @Override
167     public List<Component> getComponentPrototypes() {
168         List<Component> components = super.getComponentPrototypes();
169 
170         components.add(criteriaGroup);
171         components.add(resultsGroup);
172         components.add(resultsActionsFieldGroup);
173         components.add(resultsReturnField);
174         components.addAll(criteriaFields);
175         components.addAll(resultFields);
176 
177         return components;
178     }
179 
180     public void applyConditionalLogicForFieldDisplay() {
181         // TODO: work into view lifecycle
182         //	    LookupViewHelperService lookupViewHelperService = (LookupViewHelperService) getViewHelperService();
183         //		Set<String> readOnlyFields = lookupViewHelperService.getConditionallyReadOnlyPropertyNames();
184         //		Set<String> requiredFields = lookupViewHelperService.getConditionallyRequiredPropertyNames();
185         //		Set<String> hiddenFields = lookupViewHelperService.getConditionallyHiddenPropertyNames();
186         //		if ( (readOnlyFields != null && !readOnlyFields.isEmpty()) ||
187         //			 (requiredFields != null && !requiredFields.isEmpty()) ||
188         //			 (hiddenFields != null && !hiddenFields.isEmpty())
189         //			) {
190         //			for (Field field : getResultsGroup().getItems()) {
191         //				if (InputField.class.isAssignableFrom(field.getClass())) {
192         //					InputField attributeField = (InputField) field;
193         //					if (readOnlyFields != null && readOnlyFields.contains(attributeField.getBindingInfo().getBindingName())) {
194         //						attributeField.setReadOnly(true);
195         //					}
196         //					if (requiredFields != null && requiredFields.contains(attributeField.getBindingInfo().getBindingName())) {
197         //						attributeField.setRequired(Boolean.TRUE);
198         //					}
199         //					if (hiddenFields != null && hiddenFields.contains(attributeField.getBindingInfo().getBindingName())) {
200         //						attributeField.setControl(LookupInquiryUtils.generateCustomLookupControlFromExisting(HiddenControl.class, null));
201         //					}
202         //				}
203         //	        }
204         //		}
205     }
206 
207     /**
208      * Class name for the object the lookup applies to
209      *
210      * <p>
211      * The object class name is used to pick up a dictionary entry which will
212      * feed the attribute field definitions and other configuration. In addition
213      * it is to configure the <code>Lookupable</code> which will carry out the
214      * lookup action
215      * </p>
216      *
217      * @return Class<?> lookup data object class
218      */
219     public Class<?> getDataObjectClassName() {
220         return this.dataObjectClassName;
221     }
222 
223     /**
224      * Setter for the object class name
225      *
226      * @param dataObjectClassName
227      */
228     public void setDataObjectClassName(Class<?> dataObjectClassName) {
229         this.dataObjectClassName = dataObjectClassName;
230     }
231 
232     /**
233      * @return the hideReturnLinks
234      */
235     public boolean isHideReturnLinks() {
236         return this.hideReturnLinks;
237     }
238 
239     /**
240      * @param hideReturnLinks the hideReturnLinks to set
241      */
242     public void setHideReturnLinks(boolean hideReturnLinks) {
243         this.hideReturnLinks = hideReturnLinks;
244     }
245 
246     /**
247      * @return the suppressActions
248      */
249     public boolean isSuppressActions() {
250         return this.suppressActions;
251     }
252 
253     /**
254      * @param suppressActions the suppressActions to set
255      */
256     public void setSuppressActions(boolean suppressActions) {
257         this.suppressActions = suppressActions;
258     }
259 
260     /**
261      * @return the showMaintenanceLinks
262      */
263     public boolean isShowMaintenanceLinks() {
264         return this.showMaintenanceLinks;
265     }
266 
267     /**
268      * @param showMaintenanceLinks the showMaintenanceLinks to set
269      */
270     public void setShowMaintenanceLinks(boolean showMaintenanceLinks) {
271         this.showMaintenanceLinks = showMaintenanceLinks;
272     }
273 
274     /**
275      * Indicates whether multiple values select should be enabled for the lookup
276      *
277      * <p>
278      * When set to true, the select field is enabled for the lookup results group that allows the user
279      * to select one or more rows for returning
280      * </p>
281      *
282      * @return boolean true if multiple values should be enabled, false otherwise
283      */
284     public boolean isMultipleValuesSelect() {
285         return multipleValuesSelect;
286     }
287 
288     /**
289      * Setter for the multiple values select indicator
290      *
291      * @param multipleValuesSelect
292      */
293     public void setMultipleValuesSelect(boolean multipleValuesSelect) {
294         this.multipleValuesSelect = multipleValuesSelect;
295     }
296 
297     /**
298      * @return the resultsActionsField
299      */
300     public FieldGroup getResultsActionsFieldGroup() {
301         return this.resultsActionsFieldGroup;
302     }
303 
304     /**
305      * @param resultsActionsFieldGroup the resultsActionsField to set
306      */
307     public void setResultsActionsFieldGroup(FieldGroup resultsActionsFieldGroup) {
308         this.resultsActionsFieldGroup = resultsActionsFieldGroup;
309     }
310 
311     /**
312      * @return the resultsReturnField
313      */
314     public Field getResultsReturnField() {
315         return this.resultsReturnField;
316     }
317 
318     /**
319      * @param resultsReturnField the resultsReturnField to set
320      */
321     public void setResultsReturnField(Field resultsReturnField) {
322         this.resultsReturnField = resultsReturnField;
323     }
324 
325     public Group getCriteriaGroup() {
326         return this.criteriaGroup;
327     }
328 
329     public void setCriteriaGroup(Group criteriaGroup) {
330         this.criteriaGroup = criteriaGroup;
331     }
332 
333     public CollectionGroup getResultsGroup() {
334         return this.resultsGroup;
335     }
336 
337     public void setResultsGroup(CollectionGroup resultsGroup) {
338         this.resultsGroup = resultsGroup;
339     }
340 
341     public List<Component> getCriteriaFields() {
342         return this.criteriaFields;
343     }
344 
345     public void setCriteriaFields(List<Component> criteriaFields) {
346         this.criteriaFields = criteriaFields;
347     }
348 
349     public List<Component> getResultFields() {
350         return this.resultFields;
351     }
352 
353     public void setResultFields(List<Component> resultFields) {
354         this.resultFields = resultFields;
355     }
356 
357     public List<String> getDefaultSortAttributeNames() {
358         return this.defaultSortAttributeNames;
359     }
360 
361     public void setDefaultSortAttributeNames(List<String> defaultSortAttributeNames) {
362         this.defaultSortAttributeNames = defaultSortAttributeNames;
363     }
364 
365     public boolean isDefaultSortAscending() {
366         return this.defaultSortAscending;
367     }
368 
369     public void setDefaultSortAscending(boolean defaultSortAscending) {
370         this.defaultSortAscending = defaultSortAscending;
371     }
372 
373     /**
374      * Retrieves the maximum number of records that will be listed
375      * as a result of the lookup search
376      *
377      * @return Integer result set limit
378      */
379     public Integer getResultSetLimit() {
380         return resultSetLimit;
381     }
382 
383     /**
384      * Setter for the result list limit
385      *
386      * @param resultSetLimit Integer specifying limit
387      */
388     public void setResultSetLimit(Integer resultSetLimit) {
389         this.resultSetLimit = resultSetLimit;
390     }
391 
392     /**
393      * Indicates whether a result set limit has been specified for the
394      * view
395      *
396      * @return true if this instance has a result set limit
397      */
398     public boolean hasResultSetLimit() {
399         return (resultSetLimit != null);
400     }
401 
402     /**
403      * @param returnTarget the returnTarget to set
404      */
405     public void setReturnTarget(String returnTarget) {
406         this.returnTarget = returnTarget;
407     }
408 
409     /**
410      * @return the returnTarget
411      */
412     public String getReturnTarget() {
413         return returnTarget;
414     }
415 
416     /**
417      * @return the returnByScript
418      */
419     public boolean isReturnByScript() {
420         return returnByScript;
421     }
422 
423     /**
424      * Setter for the flag to indicate that lookups will return the value
425      * by script and not a post
426      *
427      * @param returnByScript the returnByScript flag
428      */
429     public void setReturnByScript(boolean returnByScript) {
430         this.returnByScript = returnByScript;
431     }
432 
433     /**
434      * String that maps to the maintenance controller for the maintenance document (if any) associated with the
435      * lookup data object class
436      *
437      * <p>
438      * Mapping will be used to build the maintenance action links (such as edit, copy, and new). If not given, the
439      * default maintenance mapping will be used
440      * </p>
441      *
442      * @return String mapping string
443      */
444     public String getMaintenanceUrlMapping() {
445         return maintenanceUrlMapping;
446     }
447 
448     /**
449      * Setter for the URL mapping string that will be used to build up maintenance action URLs
450      *
451      * @param maintenanceUrlMapping
452      */
453     public void setMaintenanceUrlMapping(String maintenanceUrlMapping) {
454         this.maintenanceUrlMapping = maintenanceUrlMapping;
455     }
456 }