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