View Javadoc
1   /**
2    * Copyright 2005-2016 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.kns.datadictionary;
17  
18  import org.apache.commons.lang.StringUtils;
19  import org.kuali.rice.core.api.config.property.ConfigurationService;
20  import org.kuali.rice.krad.datadictionary.DataDictionaryDefinitionBase;
21  import org.kuali.rice.krad.datadictionary.HelpDefinition;
22  import org.kuali.rice.krad.datadictionary.SortDefinition;
23  import org.kuali.rice.krad.datadictionary.exception.DuplicateEntryException;
24  import org.kuali.rice.krad.service.KRADServiceLocator;
25  import org.kuali.rice.krad.util.KRADConstants;
26  
27  import java.util.ArrayList;
28  import java.util.LinkedHashMap;
29  import java.util.List;
30  import java.util.Map;
31  
32  /**
33   * Contains lookup-related information relating to the parent BusinessObject.
34   * <p/>
35   * The lookup element is used to specify the rules for "looking up"
36   * a business object.  These specifications define the following:
37   * How to specify the search criteria used to locate a set of business objects
38   * How to display the search results
39   * <p/>
40   * DD: See LookupDefinition.java
41   * <p/>
42   * JSTL: The lookup element is a Map which is accessed using
43   * a key of "lookup".  This map contains the following keys:
44   * lookupableID (String, optional)
45   * title (String)
46   * menubar (String, optional)
47   * defaultSort (Map, optional)
48   * lookupFields (Map)
49   * resultFields (Map)
50   * resultSetLimit (String, optional)
51   * <p/>
52   * See LookupMapBuilder.java
53   * <p/>
54   * Note: the setters do copious amounts of validation, to facilitate generating errors during the parsing process.
55   */
56  @Deprecated
57  public class LookupDefinition extends DataDictionaryDefinitionBase {
58      private static final long serialVersionUID = 6733008572890721359L;
59  
60      protected String lookupableID;
61      protected String title;
62      protected String menubar;
63      protected SortDefinition defaultSort;
64  
65      protected List<FieldDefinition> lookupFields = new ArrayList<FieldDefinition>();
66      protected Map<String, FieldDefinition> lookupFieldMap = new LinkedHashMap<String, FieldDefinition>();
67      protected List<FieldDefinition> resultFields = new ArrayList<FieldDefinition>();
68      protected Map<String, FieldDefinition> resultFieldMap = new LinkedHashMap<String, FieldDefinition>();
69  
70      protected Integer resultSetLimit = null;
71      protected Integer multipleValuesResultSetLimit = null;
72  
73      protected String extraButtonSource;
74      protected String extraButtonParams;
75  
76      protected String searchIconOverride;
77  
78      protected int numOfColumns;
79  
80      protected HelpDefinition helpDefinition;
81      protected String helpUrl;
82  
83      protected boolean translateCodes = false;
84      protected boolean disableSearchButtons = false;
85  
86      public LookupDefinition() {
87      }
88  
89      /**
90       * The lookupableID element identifies the name of the Spring bean which
91       * will be used to obtain the lookupable helper service for the business object.
92       * For example, the Balance.xml file has a lookupableId = "glBalanceLookupable".
93       * The KualiSpringBeansGL.xml file determines that the helper service will be an
94       * instance of BalanceLookupableHelperServiceImpl.
95       * <p/>
96       * If this field is omitted, the default bean id used will be kualiLookupable which uses
97       * the KualiLookupableHelperServiceImpl helper service.
98       */
99      public void setLookupableID(String lookupableID) {
100         if (lookupableID == null) {
101             throw new IllegalArgumentException("invalid (null) lookupableID");
102         }
103 
104         this.lookupableID = lookupableID;
105     }
106 
107     /**
108      * @return custom lookupable id
109      */
110     public String getLookupableID() {
111         return this.lookupableID;
112     }
113 
114     /**
115      * @return title
116      */
117     public String getTitle() {
118         return title;
119     }
120 
121     /**
122      * Sets title to the given value.
123      *
124      * @param title
125      * @throws IllegalArgumentException if the given title is blank
126      */
127     public void setTitle(String title) {
128         if (StringUtils.isBlank(title)) {
129             throw new IllegalArgumentException("invalid (blank) title");
130         }
131         this.title = title;
132     }
133 
134     /**
135      * @return true if this instance has a menubar
136      */
137     public boolean hasMenubar() {
138         return (menubar != null);
139     }
140 
141     /**
142      * @return menubar
143      */
144     public String getMenubar() {
145         return menubar;
146     }
147 
148     /**
149      * The menubar element is used to add additional html code
150      * to the header line on the lookup screen.
151      * <p/>
152      * For example, Account.xml uses this element to
153      * add the "create new global" button to the Account Lookup header.
154      *
155      * @throws IllegalArgumentException if the given menubar is blank
156      */
157     public void setMenubar(String menubar) {
158         if (StringUtils.isBlank(menubar)) {
159             throw new IllegalArgumentException("invalid (blank) menubar");
160         }
161         // TODO: catch exception if service locator call fails
162         ConfigurationService kualiConfigurationservice = KRADServiceLocator.getKualiConfigurationService();
163         this.menubar = menubar.replace("${kr.externalizable.images.url}",
164                 kualiConfigurationservice.getPropertyValueAsString(KRADConstants.EXTERNALIZABLE_IMAGES_URL_KEY)).replace("${externalizable.images.url}",
165                 kualiConfigurationservice.getPropertyValueAsString(
166                         KRADConstants.APPLICATION_EXTERNALIZABLE_IMAGES_URL_KEY));
167         this.menubar = this.menubar.replace("${application.url}", kualiConfigurationservice.getPropertyValueAsString(
168                 KRADConstants.APPLICATION_URL_KEY));
169     }
170 
171 
172     /**
173      * @return true if this instance has a default sort defined
174      */
175     public boolean hasDefaultSort() {
176         return (defaultSort != null);
177     }
178 
179     /**
180      * @return defaultSort
181      */
182     public SortDefinition getDefaultSort() {
183         return defaultSort;
184     }
185 
186     /**
187      * The defaultSort element specifies the sequence in which the
188      * lookup search results should be displayed.  It contains an
189      * ascending/descending indicator and a list of attribute names.
190      * <p/>
191      * DD: See SortDefinition.java
192      * <p/>
193      * JSTL: defaultSort is a Map with the following keys:
194      * sortAscending (boolean String)
195      * sortAttributes (Map)
196      * <p/>
197      * By the time JSTL export occurs, the optional attributeName from the defaultSort
198      * tag will have been converted into the first contained sortAttribute
199      * <p/>
200      * See LookupMapBuilder.java
201      *
202      * @throws IllegalArgumentException if the given defaultSort is blank
203      */
204     public void setDefaultSort(SortDefinition defaultSort) {
205         if (defaultSort == null) {
206             throw new IllegalArgumentException("invalid (null) defaultSort");
207         }
208         this.defaultSort = defaultSort;
209     }
210 
211     /**
212      * @return List of attributeNames of all lookupField FieldDefinitions associated with this LookupDefinition, in the order in
213      *         which they were added
214      */
215     public List getLookupFieldNames() {
216         List fieldNames = new ArrayList();
217         fieldNames.addAll(this.lookupFieldMap.keySet());
218 
219         return fieldNames;
220     }
221 
222     /**
223      * @return Collection of all lookupField FieldDefinitions associated with this LookupDefinition, in the order in which they were
224      *         added
225      */
226     public List<FieldDefinition> getLookupFields() {
227         return lookupFields;
228     }
229 
230     /**
231      * @param fieldName
232      * @return FieldDefinition associated with the named lookup field, or null if there is none
233      */
234     public FieldDefinition getLookupField(String attributeName) {
235         return lookupFieldMap.get(attributeName);
236     }
237 
238     /**
239      * @return List of attributeNames of all resultField FieldDefinitions associated with this LookupDefinition, in the order in
240      *         which they were added
241      */
242     public List<String> getResultFieldNames() {
243         List<String> fieldNames = new ArrayList<String>();
244         fieldNames.addAll(resultFieldMap.keySet());
245 
246         return fieldNames;
247     }
248 
249     /**
250      * @return Collection of all resultField FieldDefinitions associated with this LookupDefinition, in the order in which they were
251      *         added
252      */
253     public List<FieldDefinition> getResultFields() {
254         return resultFields;
255     }
256 
257 
258     /**
259      * @param fieldName
260      * @return FieldDefinition associated with the named result field, or null if there is none
261      */
262     public FieldDefinition getResultField(String attributeName) {
263         return resultFieldMap.get(attributeName);
264     }
265 
266     /**
267      * The resultSetLimit element specifies the maximum number of records that will be listed
268      * as a result of the lookup search.
269      */
270     public void setResultSetLimit(Integer resultSetLimit) {
271         this.resultSetLimit = resultSetLimit;
272     }
273 
274     /**
275      * @return true if this instance has a result set limit
276      */
277     public boolean hasResultSetLimit() {
278         return (resultSetLimit != null);
279     }
280 
281 
282     /**
283      * The resultSetLimit element specifies the maximum number of records that will be listed
284      * as a result of the lookup search.
285      */
286     public Integer getResultSetLimit() {
287         return resultSetLimit;
288     }
289   
290     /**
291      * The multipleValuesResultSetLimit element specifies the maximum number of records that will be listed
292      * as a result of a multiple values lookup search.
293      */
294     public void setMultipleValuesResultSetLimit(Integer multipleValuesResultSetLimit) {
295     	this.multipleValuesResultSetLimit = multipleValuesResultSetLimit;
296 	}
297 
298     /**
299      * @return true if this instance has a multiple values result set limit
300      */
301     public boolean hasMultipleValuesResultSetLimit() {
302     	return (multipleValuesResultSetLimit != null);
303     }
304 
305 
306     /**
307      * The multipleValuesResultSetLimit element specifies the maximum number of records that will be listed
308      * as a result of a multiple values lookup search.
309      */
310     public Integer getMultipleValuesResultSetLimit() {
311     	return multipleValuesResultSetLimit;
312     }
313     
314     /**
315      * Directly validate simple fields, call completeValidation on Definition fields.
316      *
317      * @see org.kuali.rice.krad.datadictionary.DataDictionaryDefinition#completeValidation(java.lang.Class, java.lang.Object)
318      */
319     public void completeValidation(Class rootBusinessObjectClass, Class otherBusinessObjectClass) {
320         if (hasDefaultSort()) {
321             defaultSort.completeValidation(rootBusinessObjectClass, null);
322         }
323 
324         for (FieldDefinition lookupField : lookupFields) {
325             lookupField.completeValidation(rootBusinessObjectClass, null);
326         }
327 
328         for (FieldDefinition resultField : resultFields) {
329             resultField.completeValidation(rootBusinessObjectClass, null);
330         }
331     }
332 
333     /**
334      * @return true if this instance has extraButtonSource
335      */
336     public boolean hasExtraButtonSource() {
337         return extraButtonSource != null;
338     }
339 
340     /**
341      * @return extraButtonSource
342      */
343     public String getExtraButtonSource() {
344         return extraButtonSource;
345     }
346 
347     /**
348      * The extraButton element is used to define additional buttons which will
349      * appear on the lookup screen next to the Search and Clear buttons.
350      * You can define the image source and additional html parameters for
351      * each button.
352      * <p/>
353      * The extraButtonSource element defines the location of an image file
354      * to use for the extra button.
355      *
356      * @throws IllegalArgumentException if the given source is blank
357      */
358     public void setExtraButtonSource(String extraButtonSource) {
359         if (StringUtils.isBlank(extraButtonSource)) {
360             throw new IllegalArgumentException("invalid (blank) button source");
361         }
362         this.extraButtonSource = extraButtonSource;
363     }
364 
365     /**
366      * @return true if this instance has extraButtonParams
367      */
368     public boolean hasExtraButtonParams() {
369         return extraButtonParams != null;
370     }
371 
372     /**
373      * @return extraButtonParams
374      */
375     public String getExtraButtonParams() {
376         return extraButtonParams;
377     }
378 
379     /**
380      * The extraButton element is used to define additional buttons which will
381      * appear on the lookup screen next to the Search and Clear buttons.
382      * You can define the image source and additional html parameters for
383      * each button.
384      * <p/>
385      * The extraButtonParams contains extra HTML parameters that be associated
386      * with the button.
387      */
388     public void setExtraButtonParams(String extraButtonParams) {
389         this.extraButtonParams = extraButtonParams;
390     }
391 
392 
393     /**
394      * @return true if this instance has an alternate icon to use for lookup icon
395      */
396     public boolean hasSearchIconOverride() {
397         return searchIconOverride != null;
398     }
399 
400     /**
401      * @return search icon override url
402      */
403     public String getSearchIconOverride() {
404         return searchIconOverride;
405     }
406 
407     /**
408      * The searchIconOverride element is used to define alternative icons
409      * appear on the lookup screen next to the Search and Clear buttons.
410      * You can define the image source.
411      *
412      * @throws IllegalArgumentException if the given source is blank
413      */
414     public void setSearchIconOverride(String searchIconOverride) {
415         if (StringUtils.isBlank(searchIconOverride)) {
416             throw new IllegalArgumentException("invalid (blank) search icon override");
417         }
418         this.searchIconOverride = searchIconOverride;
419     }
420 
421 
422     public String toString() {
423         return "LookupDefinition '" + getTitle() + "'";
424     }
425 
426     /**
427      * The lookupFields element defines the set of fields in which the user
428      * can enter values representing search selection criteria.  A search result
429      * record will be returned only if the criteria entered in all the
430      * lookup fields are met.
431      * <p/>
432      * DD:  See LookupDefinition.java
433      * <p/>
434      * JSTL: lookupFields is a Map which is accessed using a key of "lookupFields".
435      * This map contains the following keys:
436      * attributeName of first lookup field
437      * attributeName of second lookup field
438      * etc.
439      * The corresponding values are lookupField Export Maps.
440      * See LookupMapBuilder.java.
441      * <p/>
442      * The lookupField element defines one lookup search
443      * criterion field.
444      * DD: See LookupDefinition.java.
445      * <p/>
446      * JSTL: lookupField is a Map which is accessed by a key
447      * which is the attributeName of a lookup field.  This map contains
448      * entries with the following keys:
449      * "attributeName" (String)
450      * "required" (boolean String)
451      * <p/>
452      * lookupField attribute definitions:
453      * <p/>
454      * required = true means that the user must enter something
455      * into the search criterion lookup field
456      * forceLookup = this attribute is not used
457      * noLookup = true means that field should not include magnifying glass (i.e. quickfinder)
458      */
459     public void setLookupFields(List<FieldDefinition> lookupFields) {
460         lookupFieldMap.clear();
461         for (FieldDefinition lookupField : lookupFields) {
462             if (lookupField == null) {
463                 throw new IllegalArgumentException("invalid (null) lookupField");
464             }
465             String keyName = lookupField.getAttributeName();
466             if (lookupFieldMap.containsKey(keyName)) {
467                 throw new DuplicateEntryException("duplicate lookupField entry for attribute '" + keyName + "'");
468             }
469 
470             lookupFieldMap.put(keyName, lookupField);
471         }
472         this.lookupFields = lookupFields;
473     }
474 
475     /**
476      * The resultFields element specifies the list of fields that are shown as a result
477      * of the lookup search.
478      * <p/>
479      * JSTL: resultFields is a Map which is accesseed by a key of "resultFields".
480      * This map contains entries with the following keys:
481      * attributeName of first result field
482      * attributeName of second result field
483      * etc.
484      * The corresponding values are ExportMap's
485      * <p/>
486      * The ExportMaps are accessed using a key of attributeName.
487      * Each ExportMap contains a single entry as follows:
488      * "attributeName"
489      * The corresponding value is the attributeName of the field.
490      * <p/>
491      * See LookupMapBuilder.java.
492      */
493     public void setResultFields(List<FieldDefinition> resultFields) {
494         resultFieldMap.clear();
495         for (FieldDefinition resultField : resultFields) {
496             if (resultField == null) {
497                 throw new IllegalArgumentException("invalid (null) resultField");
498             }
499 
500             String keyName = resultField.getAttributeName();
501             if (resultFieldMap.containsKey(keyName)) {
502                 throw new DuplicateEntryException("duplicate resultField entry for attribute '" + keyName + "'");
503             }
504 
505             resultFieldMap.put(keyName, resultField);
506         }
507         this.resultFields = resultFields;
508     }
509 
510     /**
511      * @return the numOfColumns
512      */
513     public int getNumOfColumns() {
514         return this.numOfColumns;
515     }
516 
517     /**
518      * @param numOfColumns the numOfColumns to set
519      */
520     public void setNumOfColumns(int numOfColumns) {
521         this.numOfColumns = numOfColumns;
522     }
523 
524     /**
525      * @return the helpDefinition
526      */
527     public HelpDefinition getHelpDefinition() {
528         return this.helpDefinition;
529     }
530 
531     /**
532      * @param helpDefinition the helpDefinition to set
533      */
534     public void setHelpDefinition(HelpDefinition helpDefinition) {
535         this.helpDefinition = helpDefinition;
536     }
537 
538     /**
539      * @return the helpUrl
540      */
541     public String getHelpUrl() {
542         return this.helpUrl;
543     }
544 
545     /**
546      * @param helpUrl the helpUrl to set
547      */
548     public void setHelpUrl(String helpUrl) {
549         this.helpUrl = helpUrl;
550     }
551 
552     public boolean isTranslateCodes() {
553         return this.translateCodes;
554     }
555 
556     public void setTranslateCodes(boolean translateCodes) {
557         this.translateCodes = translateCodes;
558     }
559 
560     public boolean isDisableSearchButtons() {
561         return this.disableSearchButtons;
562     }
563 
564     public void setDisableSearchButtons(boolean disableSearchButtons) {
565         this.disableSearchButtons = disableSearchButtons;
566     }
567 
568 }