1
2
3
4
5
6
7
8
9
10
11
12
13
14 package org.exolab.castor.xml.util;
15
16 import org.exolab.castor.mapping.ClassDescriptor;
17 import org.exolab.castor.mapping.FieldDescriptor;
18 import org.exolab.castor.mapping.FieldHandler;
19 import org.exolab.castor.mapping.MapItem;
20 import org.exolab.castor.mapping.MappingException;
21 import org.exolab.castor.mapping.loader.FieldDescriptorImpl;
22 import org.exolab.castor.mapping.loader.FieldHandlerImpl;
23 import org.exolab.castor.xml.FieldValidator;
24 import org.exolab.castor.xml.NodeType;
25 import org.exolab.castor.xml.XMLClassDescriptor;
26 import org.exolab.castor.xml.XMLFieldDescriptor;
27 import org.exolab.castor.xml.descriptors.CoreDescriptors;
28 import org.exolab.castor.xml.handlers.DateFieldHandler;
29
30 import java.util.ArrayList;
31 import java.util.List;
32 import java.util.StringTokenizer;
33 import java.util.Properties;
34
35
36
37
38
39
40
41
42
43
44
45
46 public class XMLFieldDescriptorImpl extends FieldDescriptorImpl implements XMLFieldDescriptor {
47 private static final String WILD_CARD = "*";
48
49 private static final String NULL_CLASS_ERR = "The 'type' argument passed to the constructor of "
50 + "XMLFieldDescriptorImpl may not be null.";
51
52 private static final String NULL_NAME_ERR =
53 "The 'fieldName' argument passed to the constructor of "
54 + "XMLFieldDescriptorImpl may not be null.";
55
56
57
58
59
60
61 private int _argIndex = -1;
62
63
64 private boolean _container = false;
65
66
67
68
69
70 private boolean _incremental = false;
71
72
73 public boolean _isReference = false;
74
75 private boolean _isWild = false;
76
77
78 private boolean _mapped = false;
79
80 private String[] _matches = null;
81
82
83 private boolean _nillable = false;
84
85
86 private NodeType _nodeType = null;
87
88
89 private String _nsPrefix = null;
90
91
92 private String _nsURI = null;
93
94
95 private Properties _xmlProperties = null;
96
97
98 private String _schemaType = null;
99
100
101 private String _componentType = null;
102
103
104 private String _qNamePrefix = null;
105
106
107 private boolean _useParentClassNamespace = false;
108
109 private FieldValidator _validator = null;
110
111
112
113
114 private String _xmlName = null;
115
116
117
118
119
120 private String _xmlPath = null;
121
122 private List<String> _substitutes;
123
124
125
126
127
128 private boolean _derivedFromXSList;
129
130
131
132
133
134
135 public XMLFieldDescriptorImpl(final Class<?> fieldType, final String fieldName,
136 final String xmlName, final NodeType nodeType) {
137 _matches = new String[0];
138
139 if (fieldName == null) {
140 throw new IllegalArgumentException(NULL_NAME_ERR);
141 }
142 if (fieldType == null) {
143 throw new IllegalArgumentException(NULL_CLASS_ERR);
144 }
145
146 setFieldName(fieldName);
147
148 if (fieldType == org.exolab.castor.types.AnyNode.class) {
149
150
151 setFieldType(java.lang.Object.class);
152 } else {
153 setFieldType(fieldType);
154 }
155
156 _nodeType = ((nodeType == null) ? NodeType.Attribute : nodeType);
157
158
159 setXMLName(xmlName);
160 }
161
162
163
164
165
166
167
168
169
170
171
172 public XMLFieldDescriptorImpl(final FieldDescriptor fieldDesc, final String xmlName,
173 final NodeType nodeType, final NodeType primitiveNodeType) throws MappingException {
174 _matches = new String[0];
175
176 if (fieldDesc instanceof XMLFieldDescriptor) {
177 setContainingClassDescriptor(fieldDesc.getContainingClassDescriptor());
178 }
179
180 setFieldName(fieldDesc.getFieldName());
181
182 if (fieldDesc.getFieldType() == org.exolab.castor.types.AnyNode.class) {
183
184
185 setFieldType(java.lang.Object.class);
186 } else {
187 setFieldType(fieldDesc.getFieldType());
188 }
189
190 ClassDescriptor cd = fieldDesc.getClassDescriptor();
191 if (cd != null) {
192 if (cd instanceof XMLClassDescriptor) {
193 setClassDescriptor(cd);
194 } else {
195 setClassDescriptor(new XMLClassDescriptorAdapter(cd, null, primitiveNodeType));
196 }
197 }
198
199 setHandler(fieldDesc.getHandler());
200
201
202
203 if (getFieldType() != null) {
204 if (java.util.Date.class.isAssignableFrom(getFieldType())) {
205 if (getHandler() instanceof FieldHandlerImpl) {
206 setHandler(new DateFieldHandler(getHandler()));
207 }
208 }
209 }
210
211 setTransient(fieldDesc.isTransient());
212 setImmutable(fieldDesc.isImmutable());
213 setRequired(fieldDesc.isRequired());
214 setMultivalued(fieldDesc.isMultivalued());
215
216
217 if (xmlName == null) {
218 setXMLName(getFieldName());
219 } else {
220 setXMLName(xmlName);
221 }
222
223 if (nodeType == null) {
224 if (isMultivalued()) {
225 _nodeType = NodeType.Element;
226 } else {
227 _nodeType = NodeType.Attribute;
228 }
229 } else {
230 _nodeType = nodeType;
231 }
232
233 if (isRequired()) {
234 _validator = new FieldValidator();
235 _validator.setMinOccurs(1);
236 _validator.setDescriptor(this);
237 }
238 }
239
240
241
242
243
244
245
246
247
248
249
250 public void setConstructorArgumentIndex(final int index) {
251 if (_nodeType != NodeType.Attribute) {
252 String err = "constructor arguments only valid for attribute mapped fields.";
253 throw new IllegalStateException(err);
254 }
255 _argIndex = index;
256 }
257
258
259
260
261 public int getConstructorArgumentIndex() {
262 return _argIndex;
263 }
264
265
266
267
268 public boolean isConstructorArgument() {
269 return (_argIndex >= 0);
270 }
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308 public void setLocationPath(final String path) {
309
310 _xmlPath = path;
311 }
312
313
314
315
316 public String getLocationPath() {
317 return _xmlPath;
318 }
319
320
321
322
323
324
325 public void setNameSpacePrefix(final String nsPrefix) {
326 _nsPrefix = nsPrefix;
327 }
328
329
330
331
332 public String getNameSpacePrefix() {
333 return _nsPrefix;
334 }
335
336
337
338
339
340 public void setUseParentsNamespace(final boolean useParentsNamespace) {
341 _useParentClassNamespace = useParentsNamespace;
342 }
343
344
345
346
347
348
349 public void setNameSpaceURI(final String nsURI) {
350 _nsURI = nsURI;
351 }
352
353
354
355
356 public String getNameSpaceURI() {
357 ClassDescriptor parent = getContainingClassDescriptor();
358 if ((_nsURI == null) && (parent != null) && _useParentClassNamespace) {
359 Class<?> type = getFieldType();
360 boolean test = !(isAnyNode(type));
361 if ((_nodeType == NodeType.Element) && test) {
362 if (parent instanceof XMLClassDescriptor) {
363 return ((XMLClassDescriptor) parent).getNameSpaceURI();
364 }
365 }
366 }
367 return _nsURI;
368 }
369
370
371
372
373
374
375 public void setNodeType(final NodeType nodeType) {
376 _nodeType = ((nodeType == null) ? NodeType.Attribute : nodeType);
377 }
378
379
380
381
382 public NodeType getNodeType() {
383 return _nodeType;
384 }
385
386
387
388
389
390
391
392
393 public void setXMLProperty(final String propertyName, final String value) {
394 if (propertyName == null) {
395 String err = "The argument 'propertyName' must not be null.";
396 throw new IllegalArgumentException(err);
397 }
398
399 if (_xmlProperties == null) {
400 _xmlProperties = new Properties();
401 }
402
403 if (value == null) {
404 _xmlProperties.remove(propertyName);
405 } else {
406 _xmlProperties.put(propertyName, value);
407 }
408 }
409
410
411
412
413 public String getXMLProperty(final String propertyName) {
414 if ((_xmlProperties == null) || (propertyName == null)) {
415 return null;
416 }
417 return _xmlProperties.getProperty(propertyName);
418 }
419
420
421
422
423
424
425 public void setSchemaType(final String schemaType) {
426 _schemaType = schemaType;
427 }
428
429
430
431
432
433
434 public void setComponentType(final String componentType) {
435 _componentType = componentType;
436 }
437
438
439
440
441 public String getSchemaType() {
442 return _schemaType;
443 }
444
445
446
447
448
449
450 public String getComponentType() {
451 return _componentType;
452 }
453
454 public void setValidator(final FieldValidator validator) {
455 if (_validator != null) {
456 _validator.setDescriptor(null);
457 }
458 _validator = validator;
459 if (_validator != null) {
460 _validator.setDescriptor(this);
461 }
462 }
463
464
465
466
467 public FieldValidator getValidator() {
468 return _validator;
469 }
470
471
472
473
474
475
476 public void setXMLName(final String xmlName) {
477 _xmlName = xmlName;
478 }
479
480
481
482
483 public String getXMLName() {
484 return _xmlName;
485 }
486
487
488
489
490
491
492 public void setContainer(final boolean isContainer) {
493 _container = isContainer;
494 }
495
496
497
498
499 public boolean isContainer() {
500 return _container;
501 }
502
503
504
505
506
507
508
509
510 public void setIncremental(final boolean incremental) {
511 _incremental = incremental;
512 }
513
514
515
516
517 public boolean isIncremental() {
518 return _incremental;
519 }
520
521
522
523
524
525
526 public void setMapped(final boolean mapped) {
527 _mapped = mapped;
528 }
529
530
531
532
533 public boolean isMapped() {
534 return _mapped;
535 }
536
537
538
539
540
541
542
543
544 public void setNillable(final boolean nillable) {
545 _nillable = nillable;
546 }
547
548
549
550
551 public boolean isNillable() {
552 return _nillable;
553 }
554
555
556
557
558
559
560
561 public void setReference(final boolean isReference) {
562 _isReference = isReference;
563 }
564
565
566
567
568 public boolean isReference() {
569 return _isReference;
570 }
571
572
573
574
575
576
577
578 public void setQNamePrefix(final String qNamePrefix) {
579 _qNamePrefix = qNamePrefix;
580 }
581
582
583
584
585
586
587
588 public String getQNamePrefix() {
589 return _qNamePrefix;
590 }
591
592
593
594
595
596
597 public void setMatches(String matchExpr) {
598 _isWild = false;
599
600 if ((matchExpr == null) || (matchExpr.length() == 0)) {
601 return;
602 }
603
604 StringTokenizer st = new StringTokenizer(matchExpr);
605 List<String> names = new ArrayList<String>();
606 while (st.hasMoreTokens()) {
607 String token = st.nextToken();
608 if (WILD_CARD.equals(token)) {
609 _isWild = true;
610 break;
611 }
612 names.add(token);
613 }
614 _matches = new String[names.size()];
615 names.toArray(_matches);
616 }
617
618
619
620
621 public boolean matches(final String xmlName) {
622 if (xmlName != null) {
623 if (_isWild) {
624 return true;
625 } else if (_matches.length > 0) {
626 for (int i = 0; i < _matches.length; i++) {
627 if (xmlName.equals(_matches[i])) {
628 return true;
629 }
630 }
631 } else {
632 return xmlName.equals(_xmlName);
633 }
634 }
635 return false;
636 }
637
638
639
640
641
642 public boolean matches(final String xmlName, final String namespace) {
643
644 if (namespace == null) {
645 if ((_nsURI != null) && (_nsURI.length() > 0)) {
646 return false;
647 }
648 } else if (_nsURI == null) {
649 if ((namespace.length() > 0) && (!_isWild)) {
650 return false;
651 }
652 } else if (!_nsURI.equals(namespace)) {
653 return false;
654 }
655
656
657 return matches(xmlName);
658 }
659
660
661
662
663
664
665
666
667
668 public boolean equals(final Object obj) {
669 if (obj == this) {
670 return true;
671 }
672
673 if ((obj == null) || (!(obj instanceof XMLFieldDescriptor))) {
674 return false;
675 }
676
677 XMLFieldDescriptor descriptor = (XMLFieldDescriptor) obj;
678
679
680 if (!getFieldName().equals(descriptor.getFieldName())) {
681 return false;
682 }
683
684
685 if (!getFieldType().equals(descriptor.getFieldType())) {
686 return false;
687 }
688
689
690 FieldHandler tmpHandler = descriptor.getHandler();
691 if (getHandler() == null) {
692 return (tmpHandler == null);
693 } else if (tmpHandler == null) {
694 return false;
695 }
696
697
698
699
700
701
702 return (getHandler().getClass().isInstance(tmpHandler));
703 }
704
705
706
707
708
709
710 public int hashCode() {
711 int hash = 17;
712 hash = 17 * getFieldName().hashCode();
713 hash = hash * 17 * getFieldType().hashCode();
714 if (getHandler() != null) {
715 hash = hash * 17 * getHandler().hashCode();
716 }
717 return hash;
718 }
719
720 public String toString() {
721 StringBuilder buffer = new StringBuilder(32).append("XMLFieldDesciptor: ")
722 .append(getFieldName()).append(" AS ").append(_xmlName);
723 if (getNameSpaceURI() != null) {
724 buffer.append('{').append(getNameSpaceURI()).append('}');
725 }
726 return buffer.toString();
727 }
728
729
730
731
732
733
734
735 private static boolean isPrimitive(final Class<?> type) {
736 if (type == null) {
737 return false;
738 }
739 if (type.isPrimitive()) {
740 return true;
741 }
742 if (type == String.class) {
743 return true;
744 }
745 if ((type == Boolean.class) || (type == Character.class)) {
746 return true;
747 }
748
749
750 return (type.getSuperclass() == Number.class);
751 }
752
753
754
755
756
757
758
759
760 private static boolean isBuiltInType(final Class<?> type) {
761 if (type == null) {
762 return false;
763 }
764
765
766 return (CoreDescriptors.getDescriptor(type) != null);
767 }
768
769 private static boolean isMappedItem(final Class<?> fieldType) {
770 return (fieldType == MapItem.class);
771 }
772
773 private static boolean isAnyNode(final Class<?> type) {
774 return (type == Object.class);
775 }
776
777
778
779
780
781
782 public List<String> getSubstitutes() {
783 return _substitutes;
784 }
785
786
787
788
789
790
791 public void setSubstitutes(List<String> substitutes) {
792 _substitutes = substitutes;
793 }
794
795
796
797
798
799
800 public void setDerivedFromXSList(final boolean derivedFromXSList) {
801 _derivedFromXSList = derivedFromXSList;
802 }
803
804
805
806
807
808
809 public boolean isDerivedFromXSList() {
810 return _derivedFromXSList;
811 }
812
813 }