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 }