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         getAbstractTypeClasses().put(UifPropertyPaths.CRITERIA_FIELDS, getDataObjectClassName());
112         if (StringUtils.isNotBlank(getDefaultBindingObjectPath())) {
113             getAbstractTypeClasses().put(getDefaultBindingObjectPath(), getDataObjectClassName());
114         }
115     }
116 
117     protected void initializeGroups() {
118         if ((getCriteriaGroup() != null) && (getCriteriaGroup().getItems().isEmpty())) {
119             getCriteriaGroup().setItems(getCriteriaFields());
120         }
121         if (getResultsGroup() != null) {
122             if ((getResultsGroup().getItems().isEmpty()) && (getResultFields() != null)) {
123                 getResultsGroup().setItems(getResultFields());
124             }
125             if (getResultsGroup().getCollectionObjectClass() == null) {
126                 getResultsGroup().setCollectionObjectClass(getDataObjectClassName());
127             }
128         }
129     }
130 
131     /**
132      * @see org.kuali.rice.krad.uif.container.ContainerBase#performApplyModel(org.kuali.rice.krad.uif.view.View,
133      *      java.lang.Object)
134      */
135     @Override
136     public void performApplyModel(View view, Object model, Component parent) {
137         LookupForm lookupForm = (LookupForm) model;
138 
139         // TODO: need to check lookupForm.isAtLeastOneRowHasActions() somewhere
140         if (!isSuppressActions() && isShowMaintenanceLinks()) {
141             ((List<Field>) getResultsGroup().getItems()).add(0, getResultsActionsField());
142         }
143 
144         if (StringUtils.isNotBlank(lookupForm.getReturnFormKey()) &&
145                 StringUtils.isNotBlank(lookupForm.getReturnLocation()) && !isHideReturnLinks()) {
146             ((List<Field>) getResultsGroup().getItems()).add(0, getResultsReturnField());
147         }
148 
149         super.performApplyModel(view, model, parent);
150     }
151 
152     /**
153      * @see org.kuali.rice.krad.uif.component.Component#getComponentPrototypes()
154      */
155     @Override
156     public List<Component> getComponentPrototypes() {
157         List<Component> components = super.getComponentPrototypes();
158 
159         components.add(criteriaGroup);
160         components.add(resultsGroup);
161         components.add(resultsActionsField);
162         components.add(resultsReturnField);
163         components.addAll(criteriaFields);
164         components.addAll(resultFields);
165 
166         return components;
167     }
168 
169     public void applyConditionalLogicForFieldDisplay() {
170         // TODO: work into view lifecycle
171 //	    LookupViewHelperService lookupViewHelperService = (LookupViewHelperService) getViewHelperService();
172 //		Set<String> readOnlyFields = lookupViewHelperService.getConditionallyReadOnlyPropertyNames();
173 //		Set<String> requiredFields = lookupViewHelperService.getConditionallyRequiredPropertyNames();
174 //		Set<String> hiddenFields = lookupViewHelperService.getConditionallyHiddenPropertyNames();
175 //		if ( (readOnlyFields != null && !readOnlyFields.isEmpty()) ||
176 //			 (requiredFields != null && !requiredFields.isEmpty()) ||
177 //			 (hiddenFields != null && !hiddenFields.isEmpty())
178 //			) {
179 //			for (Field field : getResultsGroup().getItems()) {
180 //				if (InputField.class.isAssignableFrom(field.getClass())) {
181 //					InputField attributeField = (InputField) field;
182 //					if (readOnlyFields != null && readOnlyFields.contains(attributeField.getBindingInfo().getBindingName())) {
183 //						attributeField.setReadOnly(true);
184 //					}
185 //					if (requiredFields != null && requiredFields.contains(attributeField.getBindingInfo().getBindingName())) {
186 //						attributeField.setRequired(Boolean.TRUE);
187 //					}
188 //					if (hiddenFields != null && hiddenFields.contains(attributeField.getBindingInfo().getBindingName())) {
189 //						attributeField.setControl(LookupInquiryUtils.generateCustomLookupControlFromExisting(HiddenControl.class, null));
190 //					}
191 //				}
192 //	        }
193 //		}
194     }
195 
196     /**
197      * Class name for the object the lookup applies to
198      *
199      * <p>
200      * The object class name is used to pick up a dictionary entry which will
201      * feed the attribute field definitions and other configuration. In addition
202      * it is to configure the <code>Lookupable</code> which will carry out the
203      * lookup action
204      * </p>
205      *
206      * @return Class<?> lookup data object class
207      */
208     public Class<?> getDataObjectClassName() {
209         return this.dataObjectClassName;
210     }
211 
212     /**
213      * Setter for the object class name
214      *
215      * @param dataObjectClassName
216      */
217     public void setDataObjectClassName(Class<?> dataObjectClassName) {
218         this.dataObjectClassName = dataObjectClassName;
219     }
220 
221     /**
222      * @return the hideReturnLinks
223      */
224     public boolean isHideReturnLinks() {
225         return this.hideReturnLinks;
226     }
227 
228     /**
229      * @param hideReturnLinks the hideReturnLinks to set
230      */
231     public void setHideReturnLinks(boolean hideReturnLinks) {
232         this.hideReturnLinks = hideReturnLinks;
233     }
234 
235     /**
236      * @return the suppressActions
237      */
238     public boolean isSuppressActions() {
239         return this.suppressActions;
240     }
241 
242     /**
243      * @param suppressActions the suppressActions to set
244      */
245     public void setSuppressActions(boolean suppressActions) {
246         this.suppressActions = suppressActions;
247     }
248 
249     /**
250      * @return the showMaintenanceLinks
251      */
252     public boolean isShowMaintenanceLinks() {
253         return this.showMaintenanceLinks;
254     }
255 
256     /**
257      * @param showMaintenanceLinks the showMaintenanceLinks to set
258      */
259     public void setShowMaintenanceLinks(boolean showMaintenanceLinks) {
260         this.showMaintenanceLinks = showMaintenanceLinks;
261     }
262 
263     /**
264      * Indicates whether multiple values select should be enabled for the lookup
265      *
266      * <p>
267      * When set to true, the select field is enabled for the lookup results group that allows the user
268      * to select one or more rows for returning
269      * </p>
270      *
271      * @return boolean true if multiple values should be enabled, false otherwise
272      */
273     public boolean isMultipleValuesSelect() {
274         return multipleValuesSelect;
275     }
276 
277     /**
278      * Setter for the multiple values select indicator
279      *
280      * @param multipleValuesSelect
281      */
282     public void setMultipleValuesSelect(boolean multipleValuesSelect) {
283         this.multipleValuesSelect = multipleValuesSelect;
284     }
285 
286     /**
287      * @return the resultsActionsField
288      */
289     public Field getResultsActionsField() {
290         return this.resultsActionsField;
291     }
292 
293     /**
294      * @param resultsActionsField the resultsActionsField to set
295      */
296     public void setResultsActionsField(Field resultsActionsField) {
297         this.resultsActionsField = resultsActionsField;
298     }
299 
300     /**
301      * @return the resultsReturnField
302      */
303     public Field getResultsReturnField() {
304         return this.resultsReturnField;
305     }
306 
307     /**
308      * @param resultsReturnField the resultsReturnField to set
309      */
310     public void setResultsReturnField(Field resultsReturnField) {
311         this.resultsReturnField = resultsReturnField;
312     }
313 
314     public Group getCriteriaGroup() {
315         return this.criteriaGroup;
316     }
317 
318     public void setCriteriaGroup(Group criteriaGroup) {
319         this.criteriaGroup = criteriaGroup;
320     }
321 
322     public CollectionGroup getResultsGroup() {
323         return this.resultsGroup;
324     }
325 
326     public void setResultsGroup(CollectionGroup resultsGroup) {
327         this.resultsGroup = resultsGroup;
328     }
329 
330     public List<Component> getCriteriaFields() {
331         return this.criteriaFields;
332     }
333 
334     public void setCriteriaFields(List<Component> criteriaFields) {
335         this.criteriaFields = criteriaFields;
336     }
337 
338     public List<Component> getResultFields() {
339         return this.resultFields;
340     }
341 
342     public void setResultFields(List<Component> resultFields) {
343         this.resultFields = resultFields;
344     }
345 
346     public List<String> getDefaultSortAttributeNames() {
347         return this.defaultSortAttributeNames;
348     }
349 
350     public void setDefaultSortAttributeNames(List<String> defaultSortAttributeNames) {
351         this.defaultSortAttributeNames = defaultSortAttributeNames;
352     }
353 
354     public boolean isDefaultSortAscending() {
355         return this.defaultSortAscending;
356     }
357 
358     public void setDefaultSortAscending(boolean defaultSortAscending) {
359         this.defaultSortAscending = defaultSortAscending;
360     }
361 
362     /**
363      * Retrieves the maximum number of records that will be listed
364      * as a result of the lookup search
365      *
366      * @return Integer result set limit
367      */
368     public Integer getResultSetLimit() {
369         return resultSetLimit;
370     }
371 
372     /**
373      * Setter for the result list limit
374      *
375      * @param resultSetLimit Integer specifying limit
376      */
377     public void setResultSetLimit(Integer resultSetLimit) {
378         this.resultSetLimit = resultSetLimit;
379     }
380 
381     /**
382      * Indicates whether a result set limit has been specified for the
383      * view
384      *
385      * @return true if this instance has a result set limit
386      */
387     public boolean hasResultSetLimit() {
388         return (resultSetLimit != null);
389     }
390 
391     /**
392      * @param returnTarget the returnTarget to set
393      */
394     public void setReturnTarget(String returnTarget) {
395         this.returnTarget = returnTarget;
396     }
397 
398     /**
399      * @return the returnTarget
400      */
401     public String getReturnTarget() {
402         return returnTarget;
403     }
404 
405     /**
406      * @return the returnByScript
407      */
408     public boolean isReturnByScript() {
409         return returnByScript;
410     }
411 
412     /**
413      * Setter for the flag to indicate that lookups will return the value
414      * by script and not a post
415      *
416      * @param returnByScript the returnByScript flag
417      */
418     public void setReturnByScript(boolean returnByScript) {
419         this.returnByScript = returnByScript;
420     }
421 
422     /**
423      * String that maps to the maintenance controller for the maintenance document (if any) associated with the
424      * lookup data object class
425      *
426      * <p>
427      * Mapping will be used to build the maintenance action links (such as edit, copy, and new). If not given, the
428      * default maintenance mapping will be used
429      * </p>
430      *
431      * @return String mapping string
432      */
433     public String getMaintenanceUrlMapping() {
434         return maintenanceUrlMapping;
435     }
436 
437     /**
438      * Setter for the URL mapping string that will be used to build up maintenance action URLs
439      *
440      * @param maintenanceUrlMapping
441      */
442     public void setMaintenanceUrlMapping(String maintenanceUrlMapping) {
443         this.maintenanceUrlMapping = maintenanceUrlMapping;
444     }
445 }