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.kns.datadictionary;
17  
18  import org.apache.commons.lang.StringUtils;
19  import org.kuali.rice.kns.service.BusinessObjectMetaDataService;
20  import org.kuali.rice.kns.service.KNSServiceLocator;
21  import org.kuali.rice.krad.datadictionary.DataDictionary;
22  import org.kuali.rice.krad.datadictionary.DataDictionaryDefinitionBase;
23  import org.kuali.rice.krad.datadictionary.RelationshipDefinition;
24  import org.kuali.rice.krad.datadictionary.exception.AttributeValidationException;
25  import org.kuali.rice.krad.datadictionary.exception.ClassValidationException;
26  import org.kuali.rice.krad.datadictionary.mask.Mask;
27  import org.kuali.rice.krad.valuefinder.ValueFinder;
28  
29  /**
30   * Contains field-related information for DataDictionary entries.  Used by lookups and inquiries.
31   *
32   * Note: the setters do copious amounts of validation, to facilitate generating errors during the parsing process.
33   */
34  @Deprecated
35  public class FieldDefinition extends DataDictionaryDefinitionBase implements FieldDefinitionI {
36      private static final long serialVersionUID = -3426603523049661524L;
37      
38  	protected String attributeName;
39      protected boolean required = false;
40      protected boolean forceInquiry = false;
41      protected boolean noInquiry = false;
42      protected boolean noDirectInquiry = false;
43      protected boolean forceLookup = false;
44      protected boolean noLookup = false;
45      protected boolean useShortLabel = false;
46      protected String defaultValue;
47      protected Class<? extends ValueFinder> defaultValueFinderClass;
48      protected String quickfinderParameterString;
49      protected Class<? extends ValueFinder> quickfinderParameterStringBuilderClass;
50  
51      protected Integer maxLength = null;
52  
53      protected String displayEditMode;
54      protected Mask displayMask;
55  
56  	protected boolean hidden 	= false;
57  	protected boolean readOnly 	= false;
58  
59  	protected boolean treatWildcardsAndOperatorsAsLiteral = false;
60  	
61      protected String alternateDisplayAttributeName;
62      protected String additionalDisplayAttributeName;
63  	
64  	protected boolean triggerOnChange;
65  	protected boolean total = false;
66  	
67      public FieldDefinition() {
68      }
69  
70  
71      /**
72       * @return attributeName
73       */
74      public String getAttributeName() {
75          return attributeName;
76      }
77  
78      /**
79       * Sets attributeName to the given value.
80       *
81       * @param attributeName
82       * @throws IllegalArgumentException if the given attributeName is blank
83       */
84      public void setAttributeName(String attributeName) {
85          if (StringUtils.isBlank(attributeName)) {
86              throw new IllegalArgumentException("invalid (blank) attributeName");
87          }
88          this.attributeName = attributeName;
89      }
90  
91  
92      /**
93       * @return true if this attribute is required
94       */
95      public boolean isRequired() {
96          return required;
97      }
98  
99  
100     /**
101                     required = true means that the user must enter something
102                         into the search criterion lookup field
103      */
104     public void setRequired(boolean required) {
105         this.required = required;
106     }
107 
108 
109     /**
110      * @return Returns the forceInquiry.
111      */
112     public boolean isForceInquiry() {
113         return forceInquiry;
114     }
115 
116 
117     /**
118      * forceInquiry = true means that the displayed field value will
119                     always be made inquirable (this attribute is not used within the code).
120      */
121     public void setForceInquiry(boolean forceInquiry) {
122         this.forceInquiry = forceInquiry;
123     }
124 
125     /**
126      * @return Returns the forceLookup.
127      */
128     public boolean isForceLookup() {
129         return forceLookup;
130     }
131 
132     /**
133      * forceLookup = this attribute is not used
134      */
135     public void setForceLookup(boolean forceLookup) {
136         this.forceLookup = forceLookup;
137     }
138 
139     /**
140      * @return Returns the noInquiry.
141      */
142     public boolean isNoInquiry() {
143         return noInquiry;
144     }
145 
146     /**
147      * @return Returns a boolean value indicating whether or not to provide
148      *          a direct inquiry for the lookup field
149      */
150     public boolean isNoDirectInquiry()
151     {
152         return noDirectInquiry;
153     }
154 
155     /**
156      * noInquiry = true means that the displayed field will never be made inquirable.
157      */
158     public void setNoInquiry(boolean noInquiry) {
159         this.noInquiry = noInquiry;
160     }
161 
162     /**
163      * @param noInquiry If true, the displayed field will not have a direct
164 	 *     inquiry facility
165      */
166     public void setNoDirectInquiry(boolean noDirectInquiry) {
167         this.noDirectInquiry = noDirectInquiry;
168     }
169 
170     /**
171      * @return Returns the noLookup.
172      */
173     public boolean isNoLookup() {
174         return noLookup;
175     }
176 
177     /**
178      * noLookup = true means that field should not include magnifying glass (i.e. quickfinder)
179      */
180     public void setNoLookup(boolean noLookup) {
181         this.noLookup = noLookup;
182     }
183 
184 
185     /**
186 	 * @return the useShortLabel
187 	 */
188 	public boolean isUseShortLabel() {
189 		return this.useShortLabel;
190 	}
191 
192 
193 	/**
194 	 * @param useShortLabel the useShortLabel to set
195 	 */
196 	public void setUseShortLabel(boolean useShortLabel) {
197 		this.useShortLabel = useShortLabel;
198 	}
199 
200 
201 	/**
202      * @return Returns the defaultValue.
203      */
204     public String getDefaultValue() {
205         return defaultValue;
206     }
207 
208 
209     /**
210            The defaultValue element will pre-load the specified value
211            into the field.
212      */
213     public void setDefaultValue(String defaultValue) {
214         this.defaultValue = defaultValue;
215     }
216 
217     /**
218 	 * the quickfinderParameterString is a comma separated list of parameter/value pairs, of the format
219 	 * "param1=value1,param2=value2", where the parameters correspond to attributes of the target class
220 	 * for the quickfinder, and the values to literals that those attributes will default to when the
221 	 * quickfinder is used.
222 	 * @return the quickfinderParameterString
223 	 */
224 	public String getQuickfinderParameterString() {
225 		return this.quickfinderParameterString;
226 	}
227 
228 	/**
229 	 * @param quickfinderParameterString the quickfinderParameterString to set.  See {@link #getQuickfinderParameterString()}
230 	 */
231 	public void setQuickfinderParameterString(String quickfinderParameterString) {
232 		this.quickfinderParameterString = quickfinderParameterString;
233 	}
234 
235 
236     /**
237      * the quickfinderParameterStringBuilderClass specifies the java class that will be used
238      * to determine the default value(s) for field(s) on the target lookup when the quickfinder
239      * is used. The classname specified in this field must implement
240      * {@link org.kuali.rice.krad.valuefinder.ValueFinder}.  See {@link #getQuickfinderParameterString()}
241      * for the result string format.
242 	 * @return the quickfinderParameterStringBuilderClass
243 	 */
244 	public Class<? extends ValueFinder> getQuickfinderParameterStringBuilderClass() {
245 		return this.quickfinderParameterStringBuilderClass;
246 	}
247 
248     /**
249      * See {@link #getQuickfinderParameterStringBuilderClass()}
250 	 * @param quickfinderParameterStringBuilderClass the quickfinderParameterStringBuilderClass to set
251      */
252 	public void setQuickfinderParameterStringBuilderClass(
253 			Class<? extends ValueFinder> quickfinderParameterStringBuilderClass) {
254         if (quickfinderParameterStringBuilderClass == null) {
255             throw new IllegalArgumentException("invalid (null) quickfinderParameterStringBuilderClass");
256         }
257 		this.quickfinderParameterStringBuilderClass = quickfinderParameterStringBuilderClass;
258     }
259 
260     /**
261      * Directly validate simple fields.
262      *
263      * @see org.kuali.rice.krad.datadictionary.DataDictionaryDefinition#completeValidation(java.lang.Class, java.lang.Object)
264      */
265     public void completeValidation(Class rootBusinessObjectClass, Class otherBusinessObjectClass) {
266     	BusinessObjectMetaDataService boMetadataService = KNSServiceLocator.getBusinessObjectMetaDataService();
267 
268         if (!DataDictionary.isPropertyOf(rootBusinessObjectClass, getAttributeName())) {
269             throw new AttributeValidationException("unable to find attribute '" + attributeName + "' in rootBusinessObjectClass '" + rootBusinessObjectClass.getName() + "' (" + "" + ")");
270         }
271 
272         if (StringUtils.isNotBlank(getAlternateDisplayAttributeName())) {
273             if (!DataDictionary.isPropertyOf(rootBusinessObjectClass, getAlternateDisplayAttributeName())) {
274                 throw new AttributeValidationException("unable to find attribute named '" + getName() + "' in rootBusinessObjectClass '" + rootBusinessObjectClass.getName() + "' (" + "" + ")");
275             }
276         }
277         
278         if (StringUtils.isNotBlank(getAdditionalDisplayAttributeName())) {
279             if (!DataDictionary.isPropertyOf(rootBusinessObjectClass, getAdditionalDisplayAttributeName())) {
280                 throw new AttributeValidationException("unable to find attribute named '" + getName() + "' in rootBusinessObjectClass '" + rootBusinessObjectClass.getName() + "' (" + "" + ")");
281             }
282         }
283 
284         if (defaultValueFinderClass != null && defaultValue != null) {
285             throw new AttributeValidationException("Both defaultValue and defaultValueFinderClass can not be specified on attribute " + getAttributeName() + " in rootBusinessObjectClass " + rootBusinessObjectClass.getName());
286         }
287 
288         validateQuickfinderParameters(rootBusinessObjectClass, boMetadataService);
289 
290         if (forceInquiry == true && noInquiry == true) {
291             throw new AttributeValidationException("Both forceInquiry and noInquiry can not be set to true on attribute " + getAttributeName() + " in rootBusinessObjectClass " + rootBusinessObjectClass.getName());
292         }
293         if (forceLookup == true && noLookup == true) {
294             throw new AttributeValidationException("Both forceLookup and noLookup can not be set to true on attribute " + getAttributeName() + " in rootBusinessObjectClass " + rootBusinessObjectClass.getName());
295         }
296     }
297 
298 
299     /**
300 	 * This method does validation on the quickfinderParameterString and quickfinderParameterStringBuilderClass members
301 	 *
302 	 * @param rootBusinessObjectClass
303 	 * @param boMetadataService
304 	 */
305 	private void validateQuickfinderParameters(Class rootBusinessObjectClass,
306 			BusinessObjectMetaDataService boMetadataService) {
307 		if (quickfinderParameterStringBuilderClass != null && quickfinderParameterString != null) {
308             throw new AttributeValidationException("Both quickfinderParameterString and quickfinderParameterStringBuilderClass can not be specified on attribute " + getAttributeName() + " in rootBusinessObjectClass " + rootBusinessObjectClass.getName());
309         }
310 
311         // String used for building exception messages
312         String quickfinderParameterStringSource = "quickfinderParameterString";
313 
314         if (quickfinderParameterStringBuilderClass != null) {
315         	try {
316 		        quickfinderParameterStringSource = "quickfinderParameterStringBuilderClass " + quickfinderParameterStringBuilderClass.getCanonicalName();
317 				quickfinderParameterString = quickfinderParameterStringBuilderClass.newInstance().getValue();
318 			} catch (InstantiationException e) {
319 				throw new ClassValidationException("unable to create new instance of "+  quickfinderParameterStringSource +" while validating rootBusinessObjectClass '"+ rootBusinessObjectClass.getName() +"'", e);
320 			} catch (IllegalAccessException e) {
321 				throw new ClassValidationException("unable to create new instance of "+  quickfinderParameterStringSource +" while validating rootBusinessObjectClass '"+ rootBusinessObjectClass.getName() +"'", e);
322 			}
323         }
324 
325         if (!StringUtils.isEmpty(quickfinderParameterString)) {
326         	// quickfinderParameterString will look something like "campusTypeCode=P,active=Y"
327         	for (String quickfinderParam : quickfinderParameterString.split(",")) { // this is guaranteed to return at least one
328         		if (quickfinderParam.contains("=")) {
329         			String propertyName = quickfinderParam.split("=")[0];
330         			RelationshipDefinition relationship = boMetadataService.getBusinessObjectRelationshipDefinition(rootBusinessObjectClass, attributeName);
331         			Class targetClass = relationship.getTargetClass();
332 
333         			// This is insufficient to ensure the property is valid for a lookup default, but it's better than nothing.
334             		if (!DataDictionary.isPropertyOf(targetClass, propertyName)) {
335             			throw new ClassValidationException("malformed parameter string  '"+ quickfinderParameterString +"' from "+ quickfinderParameterStringSource +
336             					", '"+ propertyName +"' is not a property of "+ targetClass +"' for rootBusinessObjectClass '"+ rootBusinessObjectClass.getName() +"'");
337             		}
338 
339         		} else {
340         			throw new ClassValidationException("malformed parameter string '"+ quickfinderParameterString +"' from "+ quickfinderParameterStringSource +
341         					" for rootBusinessObjectClass '"+ rootBusinessObjectClass.getName() +"'");
342         		}
343         	}
344         }
345 	}
346 
347 
348     /**
349      * @see java.lang.Object#toString()
350      */
351     public String toString() {
352         return "FieldDefinition for attribute " + getAttributeName();
353     }
354 
355 
356     public String getName() {
357         return attributeName;
358     }
359 
360 
361     public String getDisplayEditMode() {
362         return displayEditMode;
363     }
364 
365 
366     /*
367                         The document authorizer classes have a method getEditMode, which is a map of edit mode to
368                         value mappings.  Depending on the context, the value of the mapping may be relevant, and the logic determining
369                         whether the value is relevant is often implemented in the JSP/tag layer.
370 
371                         Fields on a document (particularily maintenance documents) may be associated with
372                         an edit mode.  If the edit mode is mapped to a relevant value, then the all fields associated with the edit mode
373                         will be rendered unhidden.
374 
375                         The displayEditMode element is used to specify the edit mode that will be associated with the field.
376                         If the document authorizer returns a map with this edit mode mapped to a proper value, then the field will be unhidden to the user.
377      */
378     public void setDisplayEditMode(String displayEditMode) {
379         this.displayEditMode = displayEditMode;
380     }
381 
382 
383     public Mask getDisplayMask() {
384         return displayMask;
385     }
386 
387     /**
388      * The displayMask element specifies the type of masking to
389                     be used to hide the value from un-authorized users.
390                     There are three types of masking.
391      */
392     public void setDisplayMask(Mask displayMask) {
393         this.displayMask = displayMask;
394     }
395 
396 
397 
398     public boolean isReadOnlyAfterAdd() {
399         return false;
400     }
401 
402 
403     /**
404      * Gets the maxLength attribute.
405      * @return Returns the maxLength.
406      */
407     public Integer getMaxLength() {
408         return maxLength;
409     }
410 
411 
412     /**
413      * maxLength = the maximum allowable length of the field in the lookup result fields.  In other contexts,
414                     like inquiries, this field has no effect.
415      */
416     public void setMaxLength(Integer maxLength) {
417         this.maxLength = maxLength;
418     }
419 
420     /**
421      * @return custom defaultValue class
422      */
423     public Class<? extends ValueFinder> getDefaultValueFinderClass() {
424         return this.defaultValueFinderClass;
425     }
426 
427     /**
428                       The defaultValueFinderClass specifies the java class that will be
429                       used to determine the default value of a field.  The classname
430                       specified in this field must implement ValueFinder
431      */
432     public void setDefaultValueFinderClass(Class<? extends ValueFinder> defaultValueFinderClass) {
433         if (defaultValueFinderClass == null) {
434             throw new IllegalArgumentException("invalid (null) defaultValueFinderClass");
435         }
436         this.defaultValueFinderClass = defaultValueFinderClass;
437     }
438     
439 	/**
440 	 * @return the hidden
441 	 */
442 	public boolean isHidden() {
443 		return this.hidden;
444 	}
445 
446 	/**
447 	 * @param hidden
448      *  If the ControlDefinition.isHidden == true then a corresponding LookupDefinition would
449      *  automatically be removed from the search criteria.  In some cases you might want the
450      *  hidden field to be used as a search criteria.  For example, in PersonImpl.xml a client
451      *  might want to have the campus code hidden and preset to Bloomington.  So when the search
452      *  is run, only people from the bloomington campus are returned.
453      *
454      *   So, if you want to have a hidden search criteria, set this variable to true. Defaults to
455      *   false.
456      */
457 	public void setHidden(boolean hidden) {
458 		this.hidden = hidden;
459 	}
460 	
461 	/**
462 	 * @return the readOnly
463 	 */
464 	public boolean isReadOnly() {
465 		return this.readOnly;
466 	}
467 	
468 	/**
469 	 * @param readOnly the readOnly to set
470 	 */
471 	public void setReadOnly(boolean readOnly) {
472 		this.readOnly = readOnly;
473 	}
474 	
475 	public boolean isTriggerOnChange() {
476 		return this.triggerOnChange;
477 	}
478 
479 	public void setTriggerOnChange(boolean triggerOnChange) {
480 		this.triggerOnChange = triggerOnChange;
481 	}
482 
483 	/**
484 	 * @return the treatWildcardsAndOperatorsAsLiteralOnLookups
485 	 */
486 	public boolean isTreatWildcardsAndOperatorsAsLiteral() {
487 		return this.treatWildcardsAndOperatorsAsLiteral;
488 	}
489 
490 
491 	/**
492 	 * @param treatWildcardsAndOperatorsAsLiteralOnLookups the treatWildcardsAndOperatorsAsLiteralOnLookups to set
493 	 */
494 	public void setTreatWildcardsAndOperatorsAsLiteral(
495 			boolean treatWildcardsAndOperatorsAsLiteralOnLookups) {
496 		this.treatWildcardsAndOperatorsAsLiteral = treatWildcardsAndOperatorsAsLiteralOnLookups;
497 	}
498 
499 
500 	public String getAlternateDisplayAttributeName() {
501 		return this.alternateDisplayAttributeName;
502 	}
503 
504 
505 	public void setAlternateDisplayAttributeName(String alternateDisplayAttributeName) {
506 		this.alternateDisplayAttributeName = alternateDisplayAttributeName;
507 	}
508 
509 
510 	public String getAdditionalDisplayAttributeName() {
511 		return this.additionalDisplayAttributeName;
512 	}
513 
514 
515 	public void setAdditionalDisplayAttributeName(String additionalDisplayAttributeName) {
516 		this.additionalDisplayAttributeName = additionalDisplayAttributeName;
517 	}
518 
519 
520 	public boolean isTotal() {
521 		return this.total;
522 	}
523 
524 
525 	public void setTotal(boolean total) {
526 		this.total = total;
527 	}
528 	
529 }