001: /*
002: * Copyright 2005-2007 The Kuali Foundation.
003: *
004: * Licensed under the Educational Community License, Version 1.0 (the "License");
005: * you may not use this file except in compliance with the License.
006: * You may obtain a copy of the License at
007: *
008: * http://www.opensource.org/licenses/ecl1.php
009: *
010: * Unless required by applicable law or agreed to in writing, software
011: * distributed under the License is distributed on an "AS IS" BASIS,
012: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013: * See the License for the specific language governing permissions and
014: * limitations under the License.
015: */
016:
017: package org.kuali.core.datadictionary;
018:
019: import java.math.BigDecimal;
020: import java.util.regex.Pattern;
021:
022: import org.apache.commons.lang.StringUtils;
023: import org.apache.commons.logging.Log;
024: import org.apache.commons.logging.LogFactory;
025: import org.kuali.core.datadictionary.control.ControlDefinition;
026: import org.kuali.core.datadictionary.exception.AttributeValidationException;
027: import org.kuali.core.datadictionary.exception.ClassValidationException;
028: import org.kuali.core.datadictionary.mask.Mask;
029: import org.kuali.core.datadictionary.mask.MaskFormatter;
030: import org.kuali.core.datadictionary.validation.ValidationPattern;
031: import org.kuali.core.web.format.Formatter;
032:
033: /**
034: * A single attribute definition in the DataDictionary, which contains information relating to the display, validation, and general
035: * maintenance of a specific attribute of an entry.
036: *
037: *
038: */
039: public class AttributeDefinition extends DataDictionaryDefinitionBase {
040: protected final static Pattern MATCH_ANYTHING = Pattern
041: .compile(".*");
042:
043: // logger
044: private static Log LOG = LogFactory
045: .getLog(AttributeDefinition.class);
046:
047: private Boolean override = Boolean.FALSE;
048:
049: private Boolean forceUppercase;
050:
051: private String name;
052: private String label;
053: private String shortLabel;
054: private String displayLabelAttribute;
055:
056: private Integer maxLength;
057:
058: private BigDecimal exclusiveMin;
059: private BigDecimal inclusiveMax;
060:
061: private ValidationPattern validationPattern;
062: private Boolean required;
063:
064: private ControlDefinition control;
065:
066: private String displayWorkgroup;
067: private Mask displayMask;
068:
069: private String summary;
070: private String description;
071:
072: private Class formatterClass;
073: private Class attributeClass;
074:
075: public AttributeDefinition() {
076: super ();
077:
078: LOG.debug("creating new AttributeDefinition");
079:
080: this .displayWorkgroup = "";
081: }
082:
083: public void setForceUppercase(Boolean forceUppercase) {
084: this .forceUppercase = forceUppercase;
085: }
086:
087: public Boolean getForceUppercase() {
088: return this .forceUppercase;
089: }
090:
091: public void setOverride(Boolean override) {
092: this .override = override;
093: }
094:
095: public Boolean getOverride() {
096: return this .override;
097: }
098:
099: public String getName() {
100: return name;
101: }
102:
103: public void setName(String name) {
104: if (StringUtils.isBlank(name)) {
105: throw new IllegalArgumentException("invalid (blank) name");
106: }
107: LOG.debug("calling setName '" + name + "'");
108:
109: this .name = name;
110: }
111:
112: public String getLabel() {
113: return label;
114: }
115:
116: public void setLabel(String label) {
117: if (StringUtils.isBlank(label)) {
118: throw new IllegalArgumentException("invalid (blank) label");
119: }
120: LOG.debug("calling setLabel '" + label + "'");
121:
122: this .label = label;
123: }
124:
125: /**
126: * @return the shortLabel, or the label if no shortLabel has been set
127: */
128: public String getShortLabel() {
129: return (shortLabel != null) ? shortLabel : getLabel();
130: }
131:
132: /**
133: * @return the shortLabel directly, without substituting in the label
134: */
135: protected String getDirectShortLabel() {
136: return shortLabel;
137: }
138:
139: public void setShortLabel(String shortLabel) {
140: if (StringUtils.isBlank(shortLabel)) {
141: throw new IllegalArgumentException(
142: "invalid (blank) shortLabel");
143: }
144: LOG.debug("calling setShortLabel '" + shortLabel + "'");
145:
146: this .shortLabel = shortLabel;
147: }
148:
149: public Integer getMaxLength() {
150: return maxLength;
151: }
152:
153: public void setMaxLength(Integer maxLength) {
154: LOG.debug("calling setMaxLength " + maxLength + "");
155:
156: this .maxLength = maxLength;
157: }
158:
159: public BigDecimal getExclusiveMin() {
160: return exclusiveMin;
161: }
162:
163: public void setExclusiveMin(BigDecimal exclusiveMin) {
164: this .exclusiveMin = exclusiveMin;
165: }
166:
167: public BigDecimal getInclusiveMax() {
168: return inclusiveMax;
169: }
170:
171: public void setInclusiveMax(BigDecimal inclusiveMax) {
172: this .inclusiveMax = inclusiveMax;
173: }
174:
175: /**
176: * @return true if a validationPattern has been set
177: */
178: public boolean hasValidationPattern() {
179: return (validationPattern != null);
180: }
181:
182: public ValidationPattern getValidationPattern() {
183: return this .validationPattern;
184: }
185:
186: public void setValidationPattern(ValidationPattern validationPattern) {
187: this .validationPattern = validationPattern;
188: }
189:
190: public void setRequired(Boolean required) {
191: this .required = required;
192: }
193:
194: public Boolean isRequired() {
195: return this .required;
196: }
197:
198: /**
199: * @return control
200: */
201: public ControlDefinition getControl() {
202: return control;
203: }
204:
205: /**
206: * @param control
207: * @throws IllegalArgumentException if the given control is null
208: */
209: public void setControl(ControlDefinition control) {
210: if (control == null) {
211: throw new IllegalArgumentException("invalid (null) control");
212: }
213: LOG.debug("calling setControl '" + control + "'");
214:
215: this .control = control;
216: }
217:
218: /**
219: * Gets the displayMask attribute.
220: *
221: * @return Returns the displayMask.
222: */
223: public Mask getDisplayMask() {
224: return displayMask;
225: }
226:
227: /**
228: * Sets the displayMask attribute value.
229: *
230: * @param displayMask The displayMask to set.
231: */
232: public void setDisplayMask(Mask displayMask) {
233: this .displayMask = displayMask;
234: }
235:
236: /**
237: * Gets the displayWorkgroup attribute.
238: *
239: * @return Returns the displayWorkgroup.
240: */
241: public String getDisplayWorkgroup() {
242: return displayWorkgroup;
243: }
244:
245: /**
246: * Sets the displayWorkgroup attribute value.
247: *
248: * @param displayWorkgroup The displayWorkgroup to set.
249: */
250: public void setDisplayWorkgroup(String displayWorkgroup) {
251: this .displayWorkgroup = displayWorkgroup;
252: }
253:
254: public String getSummary() {
255: return summary;
256: }
257:
258: public void setSummary(String summary) {
259: if (StringUtils.isBlank(summary)) {
260: throw new IllegalArgumentException(
261: "invalid (blank) summary");
262: }
263: LOG.debug("calling setSummary '" + summary + "'");
264:
265: this .summary = summary;
266: }
267:
268: public String getDescription() {
269: return description;
270: }
271:
272: public void setDescription(String description) {
273: if (StringUtils.isBlank(description)) {
274: throw new IllegalArgumentException(
275: "invalid (blank) description");
276: }
277: LOG.debug("calling setDescription '" + description + "'");
278:
279: this .description = description;
280: }
281:
282: public boolean hasFormatterClass() {
283: return (formatterClass != null);
284: }
285:
286: public boolean hasDisplayMask() {
287: return (displayMask != null);
288: }
289:
290: public Class getFormatterClass() {
291: return formatterClass;
292: }
293:
294: public void setFormatterClass(Class formatterClass) {
295: if (formatterClass == null) {
296: throw new IllegalArgumentException(
297: "invalid (null) formatterClass");
298: }
299: LOG.debug("calling setFormatterClass '"
300: + formatterClass.getName() + "'");
301:
302: this .formatterClass = formatterClass;
303: }
304:
305: public Class getAttributeClass() {
306: return attributeClass;
307: }
308:
309: /**
310: * Directly validate simple fields, call completeValidation on Definition fields.
311: *
312: * @see org.kuali.core.datadictionary.DataDictionaryEntry#completeValidation()
313: */
314: public void completeValidation(Class rootObjectClass,
315: Class otherObjectClass,
316: ValidationCompletionUtils validationCompletionUtils) {
317:
318: if (!validationCompletionUtils.isPropertyOf(rootObjectClass,
319: getName())) {
320: throw new AttributeValidationException("property '"
321: + getName() + "' is not a property of class '"
322: + rootObjectClass.getName() + "' ("
323: + getParseLocation() + ")");
324: }
325:
326: if (hasFormatterClass()) {
327: if (!Formatter.class.isAssignableFrom(getFormatterClass())) {
328: throw new ClassValidationException(
329: "formatterClass '"
330: + getFormatterClass().getName()
331: + "' for attribute '"
332: + getName()
333: + "' is not a subclass of pojo.format.Formatter ("
334: + getParseLocation() + ")");
335: }
336: }
337:
338: getControl().completeValidation(rootObjectClass,
339: otherObjectClass, validationCompletionUtils);
340:
341: if (StringUtils.isNotBlank(getDisplayWorkgroup())
342: && !hasDisplayMask()) {
343: throw new AttributeValidationException(
344: "property '"
345: + getName()
346: + "' has a display workgroup defined but not a valid display mask '"
347: + rootObjectClass.getName() + "' ("
348: + getParseLocation() + ")");
349: }
350:
351: if (hasDisplayMask()) {
352: if (getDisplayMask().getMaskFormatter() == null
353: && getDisplayMask().getMaskFormatterClass() == null) {
354: throw new AttributeValidationException(
355: "No mask formatter or formatter class specified for secure attribute "
356: + getName() + "' ("
357: + getParseLocation() + ")");
358: }
359:
360: if (getDisplayMask().getMaskFormatterClass() != null) {
361: if (!MaskFormatter.class
362: .isAssignableFrom(getDisplayMask()
363: .getMaskFormatterClass())) {
364: throw new ClassValidationException(
365: "Class '"
366: + getDisplayMask()
367: .getMaskFormatterClass()
368: .getName()
369: + "' for secure attribute '"
370: + getName()
371: + "' does not implement org.kuali.core.datadictionary.mask.MaskFormatter ("
372: + getParseLocation() + ")");
373: }
374: }
375: }
376:
377: // set default values
378: if (getForceUppercase() == null) {
379: setForceUppercase(Boolean.FALSE);
380: }
381: if (isRequired() == null) {
382: setRequired(Boolean.FALSE);
383:
384: }
385:
386: // lookup and set attribute class
387: attributeClass = rootObjectClass;
388: }
389:
390: /**
391: * @see java.lang.Object#toString()
392: */
393: @Override
394: public String toString() {
395: return "AttributeDefinition for attribute " + getName();
396: }
397:
398: public String getDisplayLabelAttribute() {
399: return displayLabelAttribute;
400: }
401:
402: public void setDisplayLabelAttribute(String displayLabelAttribute) {
403: this.displayLabelAttribute = displayLabelAttribute;
404: }
405: }
|