1
2
3
4
5
6
7
8
9
10
11
12
13
14
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
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
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
314
315
316
317
318
319
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
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 }