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