View Javadoc

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