View Javadoc

1   /**
2    * Copyright 2005-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  package org.kuali.rice.core.api.uif;
17  
18  import org.apache.commons.lang.StringUtils;
19  import org.kuali.rice.core.api.CoreConstants;
20  import org.kuali.rice.core.api.mo.AbstractDataTransferObject;
21  import org.kuali.rice.core.api.mo.ModelBuilder;
22  import org.w3c.dom.Element;
23  
24  import javax.xml.bind.annotation.XmlAccessType;
25  import javax.xml.bind.annotation.XmlAccessorType;
26  import javax.xml.bind.annotation.XmlAnyElement;
27  import javax.xml.bind.annotation.XmlElement;
28  import javax.xml.bind.annotation.XmlElementWrapper;
29  import javax.xml.bind.annotation.XmlElements;
30  import javax.xml.bind.annotation.XmlRootElement;
31  import javax.xml.bind.annotation.XmlType;
32  import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter;
33  import java.util.ArrayList;
34  import java.util.Collection;
35  import java.util.Collections;
36  import java.util.List;
37  
38  /**
39   * @see AttributeField for more info.
40   */
41  @XmlRootElement(name = RemotableAttributeField.Constants.ROOT_ELEMENT_NAME)
42  @XmlAccessorType(XmlAccessType.NONE)
43  @XmlType(name = RemotableAttributeField.Constants.TYPE_NAME, propOrder = {
44  		RemotableAttributeField.Elements.NAME,
45  		RemotableAttributeField.Elements.DATA_TYPE,
46  		RemotableAttributeField.Elements.SHORT_LABEL,
47  		RemotableAttributeField.Elements.LONG_LABEL,
48  		RemotableAttributeField.Elements.HELP_SUMMARY,
49  		RemotableAttributeField.Elements.HELP_CONSTRAINT,
50  		RemotableAttributeField.Elements.HELP_DESCRIPTION,
51  		RemotableAttributeField.Elements.FORCE_UPPERCASE,
52  		RemotableAttributeField.Elements.MIN_LENGTH,
53  		RemotableAttributeField.Elements.MAX_LENGTH,
54  		RemotableAttributeField.Elements.MIN_VALUE,
55  		RemotableAttributeField.Elements.MAX_VALUE,
56  		RemotableAttributeField.Elements.REGEX_CONSTRAINT,
57  		RemotableAttributeField.Elements.REGEX_CONSTRAINT_MSG,
58  		RemotableAttributeField.Elements.REQUIRED,
59  		RemotableAttributeField.Elements.DEFAULT_VALUES,
60          RemotableAttributeField.Elements.ATTRIBUTE_LOOKUP_SETTINGS,
61  		RemotableAttributeField.Elements.CONTROL,
62  		RemotableAttributeField.Elements.WIDGETS,
63  		CoreConstants.CommonElements.FUTURE_ELEMENTS })
64  public final class RemotableAttributeField extends AbstractDataTransferObject implements AttributeField {
65  
66      @XmlElement(name = Elements.NAME, required = true)
67      private final String name;
68  
69      @XmlJavaTypeAdapter(DataType.Adapter.class)
70      @XmlElement(name = Elements.DATA_TYPE, required = false)
71      private final String dataType;
72  
73      @XmlElement(name = Elements.SHORT_LABEL, required = false)
74      private final String shortLabel;
75  
76      @XmlElement(name = Elements.LONG_LABEL, required = false)
77      private final String longLabel;
78  
79      @XmlElement(name = Elements.HELP_SUMMARY, required = false)
80      private final String helpSummary;
81  
82      @XmlElement(name = Elements.HELP_CONSTRAINT, required = false)
83      private final String helpConstraint;
84  
85      @XmlElement(name = Elements.HELP_DESCRIPTION, required = false)
86      private final String helpDescription;
87  
88      @XmlElement(name = Elements.FORCE_UPPERCASE, required = false)
89      private final boolean forceUpperCase;
90  
91      @XmlElement(name = Elements.MIN_LENGTH, required = false)
92      private final Integer minLength;
93  
94      @XmlElement(name = Elements.MAX_LENGTH, required = false)
95      private final Integer maxLength;
96  
97      @XmlElement(name = Elements.MIN_VALUE, required = false)
98      private final Double minValue;
99  
100     @XmlElement(name = Elements.MAX_VALUE, required = false)
101     private final Double maxValue;
102 
103     @XmlElement(name = Elements.REGEX_CONSTRAINT, required = false)
104     private final String regexConstraint;
105 
106     @XmlElement(name = Elements.REGEX_CONSTRAINT_MSG, required = false)
107     private final String regexContraintMsg;
108 
109     @XmlElement(name = Elements.REQUIRED, required = false)
110     private final boolean required;
111 
112     @XmlElementWrapper(name = Elements.DEFAULT_VALUES, required = false)
113     @XmlElement(name = Elements.DEFAULT_VALUE, required = false)
114     private final Collection<String> defaultValues;
115 
116     @XmlElement(name = Elements.ATTRIBUTE_LOOKUP_SETTINGS, required = false)
117     private final RemotableAttributeLookupSettings attributeLookupSettings;
118 
119     @XmlElements(value = {
120         @XmlElement(name = RemotableCheckboxGroup.Constants.ROOT_ELEMENT_NAME, type = RemotableCheckboxGroup.class, required = false),
121         @XmlElement(name = RemotableHiddenInput.Constants.ROOT_ELEMENT_NAME, type = RemotableHiddenInput.class, required = false),
122         @XmlElement(name = RemotablePasswordInput.Constants.ROOT_ELEMENT_NAME, type = RemotablePasswordInput.class, required = false),
123         @XmlElement(name = RemotableRadioButtonGroup.Constants.ROOT_ELEMENT_NAME, type = RemotableRadioButtonGroup.class, required = false),
124         @XmlElement(name = RemotableSelect.Constants.ROOT_ELEMENT_NAME, type = RemotableSelect.class, required = false),
125         @XmlElement(name = RemotableTextarea.Constants.ROOT_ELEMENT_NAME, type = RemotableTextarea.class, required = false),
126         @XmlElement(name = RemotableTextInput.Constants.ROOT_ELEMENT_NAME, type = RemotableTextInput.class, required = false)
127     })
128     private final RemotableAbstractControl control;
129 
130     @XmlElementWrapper(name = Elements.WIDGETS, required = false)
131     @XmlElements(value = {
132         @XmlElement(name = RemotableDatepicker.Constants.ROOT_ELEMENT_NAME, type = RemotableDatepicker.class, required = false),
133         @XmlElement(name = RemotableQuickFinder.Constants.ROOT_ELEMENT_NAME, type = RemotableQuickFinder.class, required = false),
134         @XmlElement(name = RemotableTextExpand.Constants.ROOT_ELEMENT_NAME, type = RemotableTextExpand.class, required = false)
135     })
136     private final Collection<? extends RemotableAbstractWidget> widgets;
137 
138     @SuppressWarnings("unused")
139     @XmlAnyElement
140     private final Collection<Element> _futureElements = null;
141 
142     /**
143      * Should only be invoked by JAXB.
144      */
145     @SuppressWarnings("unused")
146     private RemotableAttributeField() {
147         this.name = null;
148         this.dataType = null;
149         this.shortLabel = null;
150         this.longLabel = null;
151         this.helpSummary = null;
152         this.helpConstraint = null;
153         this.helpDescription = null;
154         this.forceUpperCase = false;
155         this.minLength = null;
156         this.maxLength = null;
157         this.minValue = null;
158         this.maxValue = null;
159         this.regexConstraint = null;
160         this.regexContraintMsg = null;
161         this.required = false;
162         this.defaultValues = null;
163         this.attributeLookupSettings = null;
164         this.control = null;
165         this.widgets = null;
166     }
167 
168     private RemotableAttributeField(Builder b) {
169         this.name = b.name;
170         if (b.dataType == null) {
171             this.dataType = null;
172         } else {
173             this.dataType = b.dataType.name();
174         }
175         this.shortLabel = b.shortLabel;
176         this.longLabel = b.longLabel;
177         this.helpSummary = b.helpSummary;
178         this.helpConstraint = b.helpConstraint;
179         this.helpDescription = b.helpDescription;
180         this.forceUpperCase = b.forceUpperCase;
181         this.minLength = b.minLength;
182         this.maxLength = b.maxLength;
183         this.minValue = b.minValue;
184         this.maxValue = b.maxValue;
185         this.regexConstraint = b.regexConstraint;
186         this.regexContraintMsg = b.regexContraintMsg;
187         this.required = b.required;
188         if (b.defaultValues == null) {
189             this.defaultValues = Collections.emptyList();
190         } else {
191             List<String> defaultValuesCopy = new ArrayList<String>(b.defaultValues);
192             this.defaultValues = Collections.unmodifiableList(defaultValuesCopy);
193         }
194         if (b.attributeLookupSettings == null) {
195             this.attributeLookupSettings = null;
196         } else {
197             this.attributeLookupSettings = b.attributeLookupSettings.build();
198         }
199         if (b.control == null) {
200             this.control = null;
201         } else {
202             this.control = b.control.build();
203         }
204 
205         final List<RemotableAbstractWidget> temp = new ArrayList<RemotableAbstractWidget>();
206         if (b.widgets != null) {
207             for (RemotableAbstractWidget.Builder attr : b.widgets) {
208                 temp.add(attr.build());
209             }
210         }
211         this.widgets = Collections.unmodifiableList(temp);
212     }
213 
214     @Override
215     public String getName() {
216         return name;
217     }
218 
219     @Override
220     public DataType getDataType() {
221         if (dataType == null) {
222             return null;
223         }
224         return DataType.valueOf(dataType);
225     }
226 
227     @Override
228     public String getShortLabel() {
229         return shortLabel;
230     }
231 
232     @Override
233     public String getLongLabel() {
234         return longLabel;
235     }
236 
237     @Override
238     public String getHelpSummary() {
239         return helpSummary;
240     }
241 
242     @Override
243     public String getHelpConstraint() {
244         return helpConstraint;
245     }
246 
247     @Override
248     public String getHelpDescription() {
249         return helpDescription;
250     }
251 
252     @Override
253     public boolean isForceUpperCase() {
254         return forceUpperCase;
255     }
256 
257     @Override
258     public Integer getMinLength() {
259         return minLength;
260     }
261 
262     @Override
263     public Integer getMaxLength() {
264         return maxLength;
265     }
266 
267     @Override
268     public Double getMinValue() {
269         return minValue;
270     }
271 
272     @Override
273     public Double getMaxValue() {
274         return maxValue;
275     }
276 
277     @Override
278     public String getRegexConstraint() {
279         return regexConstraint;
280     }
281 
282     @Override
283     public String getRegexContraintMsg() {
284         return regexContraintMsg;
285     }
286 
287     @Override
288     public boolean isRequired() {
289         return required;
290     }
291 
292     @Override
293     public Collection<String> getDefaultValues() {
294         return defaultValues;
295     }
296 
297     @Override
298     public Control getControl() {
299         return control;
300     }
301 
302     @Override
303     public Collection<? extends RemotableAbstractWidget> getWidgets() {
304         return widgets;
305     }
306 
307     @Override
308     public AttributeLookupSettings getAttributeLookupSettings() {
309         return attributeLookupSettings;
310     }
311 
312     /**
313      * Utility method to search a collection of attribute fields and returns
314      * a field for a give attribute name.
315      *
316      * @param attributeName the name of the attribute to search for.  Cannot be blank or null.
317      * @param fields cannot be null.
318      *
319      * @return the attribute field or null if not found.
320      */
321     public static RemotableAttributeField findAttribute(String attributeName, Collection<RemotableAttributeField> fields) {
322         if (StringUtils.isBlank(attributeName)) {
323             throw new IllegalArgumentException("attributeName is blank");
324         }
325 
326         if (fields == null) {
327             throw new IllegalArgumentException("errors is null");
328         }
329 
330         for (RemotableAttributeField field : fields) {
331             if (attributeName.equals(field.getName())) {
332                 return field;
333             }
334         }
335         return null;
336     }
337     
338     public static final class Builder implements AttributeField, ModelBuilder {
339         private String name;
340         private DataType dataType;
341         private String shortLabel;
342         private String longLabel;
343 
344         private String helpSummary;
345         private String helpConstraint;
346         private String helpDescription;
347 
348         private boolean forceUpperCase;
349 
350         private Integer minLength;
351         private Integer maxLength;
352 
353         private Double minValue;
354         private Double maxValue;
355         private String regexConstraint;
356         private String regexContraintMsg;
357 
358         private boolean required;
359 
360         private Collection<String> defaultValues = new ArrayList<String>();
361         private RemotableAttributeLookupSettings.Builder attributeLookupSettings;
362         private RemotableAbstractControl.Builder control;
363 
364         private Collection<RemotableAbstractWidget.Builder> widgets = new ArrayList<RemotableAbstractWidget.Builder>();
365 
366         private Builder(String name) {
367             setName(name);
368         }
369 
370         public static Builder create(String name) {
371             return new Builder(name);
372         }
373 
374         public static Builder create(AttributeField field) {
375             if (field == null) {
376                 throw new IllegalArgumentException("field was null");
377             }
378 
379             Builder b = new Builder(field.getName());
380             b.setDataType(field.getDataType());
381             b.setShortLabel(field.getShortLabel());
382             b.setLongLabel(field.getLongLabel());
383             b.setHelpSummary(field.getHelpSummary());
384             b.setHelpConstraint(field.getHelpConstraint());
385             b.setHelpDescription(field.getHelpDescription());
386             b.setForceUpperCase(field.isForceUpperCase());
387             b.setMinLength(field.getMinLength());
388             b.setMaxLength(field.getMaxLength());
389             b.setMinValue(field.getMinValue());
390             b.setMaxValue(field.getMaxValue());
391             b.setRegexConstraint(field.getRegexConstraint());
392             b.setRegexContraintMsg(field.getRegexContraintMsg());
393             b.setRequired(field.isRequired());
394             b.setDefaultValues(field.getDefaultValues());
395             if (field.getAttributeLookupSettings() != null) {
396                 b.setAttributeLookupSettings(RemotableAttributeLookupSettings.Builder.create(
397                         field.getAttributeLookupSettings()));
398             }
399             if (field.getControl() != null) {
400                 b.setControl(ControlCopy.toBuilder(field.getControl()));
401             }
402 
403             final List<RemotableAbstractWidget.Builder> temp = new ArrayList<RemotableAbstractWidget.Builder>();
404             if (field.getWidgets() != null) {
405                 for (Widget w : field.getWidgets()) {
406                     temp.add(WidgetCopy.toBuilder(w));
407                 }
408             }
409             b.setWidgets(temp);
410 
411             return b;
412         }
413 
414         @Override
415         public String getName() {
416             return name;
417         }
418 
419         public void setName(String name) {
420             if (StringUtils.isBlank(name)) {
421                 throw new IllegalArgumentException("name is blank");
422             }
423 
424             this.name = name;
425         }
426 
427         @Override
428         public DataType getDataType() {
429             return dataType;
430         }
431 
432         public void setDataType(DataType dataType) {
433             this.dataType = dataType;
434         }
435 
436         @Override
437         public String getShortLabel() {
438             return shortLabel;
439         }
440 
441         public void setShortLabel(String shortLabel) {
442             this.shortLabel = shortLabel;
443         }
444 
445         @Override
446         public String getLongLabel() {
447             return longLabel;
448         }
449 
450         public void setLongLabel(String longLabel) {
451             this.longLabel = longLabel;
452         }
453 
454         @Override
455         public String getHelpSummary() {
456             return helpSummary;
457         }
458 
459         public void setHelpSummary(String helpSummary) {
460             this.helpSummary = helpSummary;
461         }
462 
463         @Override
464         public String getHelpConstraint() {
465             return helpConstraint;
466         }
467 
468         public void setHelpConstraint(String helpConstraint) {
469             this.helpConstraint = helpConstraint;
470         }
471 
472         @Override
473         public String getHelpDescription() {
474             return helpDescription;
475         }
476 
477         public void setHelpDescription(String helpDescription) {
478             this.helpDescription = helpDescription;
479         }
480 
481         @Override
482         public boolean isForceUpperCase() {
483             return forceUpperCase;
484         }
485 
486         public void setForceUpperCase(boolean forceUpperCase) {
487             this.forceUpperCase = forceUpperCase;
488         }
489 
490         @Override
491         public Integer getMinLength() {
492             return minLength;
493         }
494 
495         public void setMinLength(Integer minLength) {
496             if (minLength != null && minLength < 1) {
497                 throw new IllegalArgumentException("minLength was < 1");
498             }
499             
500             this.minLength = minLength;
501         }
502 
503         @Override
504         public Integer getMaxLength() {
505             return maxLength;
506         }
507 
508         public void setMaxLength(Integer maxLength) {
509             if (maxLength != null && maxLength < 1) {
510                 throw new IllegalArgumentException("maxLength was < 1");
511             }
512             
513             this.maxLength = maxLength;
514         }
515 
516         @Override
517         public Double getMinValue() {
518             return minValue;
519         }
520 
521         public void setMinValue(Double minValue) {
522             this.minValue = minValue;
523         }
524 
525         @Override
526         public Double getMaxValue() {
527             return maxValue;
528         }
529 
530         public void setMaxValue(Double maxValue) {
531             this.maxValue = maxValue;
532         }
533 
534         @Override
535         public String getRegexConstraint() {
536             return regexConstraint;
537         }
538 
539         public void setRegexConstraint(String regexConstraint) {
540             this.regexConstraint = regexConstraint;
541         }
542 
543         @Override
544         public String getRegexContraintMsg() {
545             return regexContraintMsg;
546         }
547 
548         public void setRegexContraintMsg(String regexContraintMsg) {
549             this.regexContraintMsg = regexContraintMsg;
550         }
551 
552         @Override
553         public boolean isRequired() {
554             return required;
555         }
556 
557         public void setRequired(boolean required) {
558             this.required = required;
559         }
560 
561         @Override
562         public Collection<String> getDefaultValues() {
563             return defaultValues;
564         }
565 
566         public void setDefaultValues(Collection<String> defaultValues) {
567             this.defaultValues = defaultValues;
568         }
569 
570         @Override
571         public RemotableAttributeLookupSettings.Builder getAttributeLookupSettings() {
572             return attributeLookupSettings;
573         }
574 
575         public void setAttributeLookupSettings(RemotableAttributeLookupSettings.Builder attributeLookupSettings) {
576             this.attributeLookupSettings = attributeLookupSettings;
577         }
578 
579         @Override
580         public RemotableAbstractControl.Builder getControl() {
581             return control;
582         }
583 
584         public void setControl(RemotableAbstractControl.Builder control) {
585             this.control = control;
586         }
587 
588         @Override
589         public Collection<RemotableAbstractWidget.Builder> getWidgets() {
590             return widgets;
591         }
592 
593         public void setWidgets(Collection<RemotableAbstractWidget.Builder> widgets) {
594             this.widgets = widgets;
595         }
596 
597         @Override
598         public RemotableAttributeField build() {
599             return new RemotableAttributeField(this);
600         }
601     }
602 
603     /**
604      * Defines some internal constants used on this class.
605      */
606     static final class Constants {
607         static final String TYPE_NAME = "AttributeFieldType";
608         final static String ROOT_ELEMENT_NAME = "attributeField";
609     }
610 
611     static final class Elements {
612         static final String NAME = "name";
613         static final String DATA_TYPE = "dataType";
614         static final String SHORT_LABEL = "shortLabel";
615         static final String LONG_LABEL = "longLabel";
616         static final String HELP_SUMMARY = "helpSummary";
617         static final String HELP_CONSTRAINT = "helpConstraint";
618         static final String HELP_DESCRIPTION = "helpDescription";
619         static final String FORCE_UPPERCASE = "forceUpperCase";
620         static final String MIN_LENGTH = "minLength";
621         static final String MAX_LENGTH = "maxLength";
622         static final String MIN_VALUE = "minValue";
623         static final String MAX_VALUE = "maxValue";
624         static final String REGEX_CONSTRAINT = "regexConstraint";
625         static final String REGEX_CONSTRAINT_MSG = "regexContraintMsg";
626         static final String REQUIRED = "required";
627         static final String DEFAULT_VALUES = "defaultValues";
628         static final String DEFAULT_VALUE = "defaultValue";
629         static final String ATTRIBUTE_LOOKUP_SETTINGS = "attributeLookupSettings";
630         static final String CONTROL = "control";
631         static final String WIDGETS = "widgets";
632     }
633 }