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