1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39 package org.exolab.castor.builder.factory;
40
41 import java.util.ArrayList;
42 import java.util.Enumeration;
43 import java.util.Iterator;
44 import java.util.LinkedList;
45 import java.util.List;
46
47 import org.apache.commons.lang3.StringUtils;
48 import org.castor.core.util.StringUtil;
49 import org.exolab.castor.builder.AnnotationBuilder;
50 import org.exolab.castor.builder.BuilderConfiguration;
51 import org.exolab.castor.builder.FactoryState;
52 import org.exolab.castor.builder.GroupNaming;
53 import org.exolab.castor.builder.SGStateInfo;
54 import org.exolab.castor.builder.SGTypes;
55 import org.exolab.castor.builder.SourceGenerator;
56 import org.exolab.castor.builder.SourceGeneratorConstants;
57 import org.exolab.castor.builder.TypeConversion;
58 import org.exolab.castor.builder.binding.ExtendedBinding;
59 import org.exolab.castor.builder.binding.XMLBindingComponent;
60 import org.exolab.castor.builder.info.ClassInfo;
61 import org.exolab.castor.builder.info.FieldInfo;
62 import org.exolab.castor.builder.info.GroupInfo;
63 import org.exolab.castor.builder.info.XMLInfo;
64 import org.exolab.castor.builder.info.nature.JDOClassInfoNature;
65 import org.exolab.castor.builder.info.nature.JDOFieldInfoNature;
66 import org.exolab.castor.builder.info.nature.SolrjFieldInfoNature;
67 import org.exolab.castor.builder.info.nature.XMLInfoNature;
68 import org.exolab.castor.builder.info.nature.relation.JDOOneToManyNature;
69 import org.exolab.castor.builder.info.nature.relation.JDOOneToOneNature;
70 import org.exolab.castor.builder.types.XSClass;
71 import org.exolab.castor.builder.types.XSString;
72 import org.exolab.castor.builder.types.XSType;
73 import org.exolab.castor.mapping.AccessMode;
74 import org.exolab.castor.xml.schema.Annotated;
75 import org.exolab.castor.xml.schema.Annotation;
76 import org.exolab.castor.xml.schema.AppInfo;
77 import org.exolab.castor.xml.schema.AppInfoJpaNature;
78 import org.exolab.castor.xml.schema.AppInfoSolrjNature;
79 import org.exolab.castor.xml.schema.AttributeDecl;
80 import org.exolab.castor.xml.schema.AttributeGroupDecl;
81 import org.exolab.castor.xml.schema.ComplexType;
82 import org.exolab.castor.xml.schema.ContentModelGroup;
83 import org.exolab.castor.xml.schema.ContentType;
84 import org.exolab.castor.xml.schema.Documentation;
85 import org.exolab.castor.xml.schema.ElementDecl;
86 import org.exolab.castor.xml.schema.Facet;
87 import org.exolab.castor.xml.schema.Group;
88 import org.exolab.castor.xml.schema.ModelGroup;
89 import org.exolab.castor.xml.schema.Order;
90 import org.exolab.castor.xml.schema.Particle;
91 import org.exolab.castor.xml.schema.Schema;
92 import org.exolab.castor.xml.schema.SimpleContent;
93 import org.exolab.castor.xml.schema.SimpleType;
94 import org.exolab.castor.xml.schema.SimpleTypesFactory;
95 import org.exolab.castor.xml.schema.Structure;
96 import org.exolab.castor.xml.schema.Wildcard;
97 import org.exolab.castor.xml.schema.XMLType;
98 import org.exolab.castor.xml.schema.annotations.jdo.Column;
99 import org.exolab.castor.xml.schema.annotations.jdo.OneToMany;
100 import org.exolab.castor.xml.schema.annotations.jdo.OneToOne;
101 import org.exolab.castor.xml.schema.annotations.jdo.PrimaryKey;
102 import org.exolab.castor.xml.schema.annotations.jdo.Table;
103 import org.exolab.castor.xml.schema.annotations.solrj.Field;
104
105 import org.exolab.javasource.JAnnotation;
106 import org.exolab.javasource.JAnnotationType;
107 import org.exolab.javasource.JClass;
108 import org.exolab.javasource.JCollectionType;
109 import org.exolab.javasource.JConstructor;
110 import org.exolab.javasource.JDocComment;
111 import org.exolab.javasource.JDocDescriptor;
112 import org.exolab.javasource.JEnum;
113 import org.exolab.javasource.JField;
114 import org.exolab.javasource.JMethod;
115 import org.exolab.javasource.JParameter;
116 import org.exolab.javasource.JSourceCode;
117 import org.exolab.javasource.JType;
118
119
120
121
122
123
124
125
126 public final class SourceFactory extends BaseFactory {
127 private static final String ENUM_ACCESS_INTERFACE =
128 "org.exolab.castor.types.EnumeratedTypeAccess";
129
130 private static final short BASE_TYPE_ENUMERATION = 0;
131 private static final short OBJECT_TYPE_ENUMERATION = 1;
132
133 private static final String CLASS_METHOD_SUFFIX = "Class";
134 private static final String CLASS_KEYWORD = "class";
135 private static final String ITEM_NAME = "Item";
136
137
138 private ExtendedBinding _binding = null;
139
140 private MemberFactory _memberFactory = null;
141
142 private short _enumerationType = OBJECT_TYPE_ENUMERATION;
143
144
145
146
147 private boolean _createMarshalMethods = true;
148
149
150
151
152
153 private boolean _testable = false;
154
155 private boolean _sax1 = false;
156
157 private TypeConversion _typeConversion = null;
158
159 private final EnumerationFactory _enumerationFactory;
160
161
162
163
164
165
166
167
168
169 public SourceFactory(final BuilderConfiguration config, final FieldInfoFactory infoFactory,
170 final GroupNaming groupNaming, final SourceGenerator sourceGenerator) {
171 super(config, infoFactory, groupNaming, sourceGenerator);
172
173
174 infoFactory.setBoundProperties(config.boundPropertiesEnabled());
175
176 this._memberFactory = new MemberFactory(config, infoFactory, getGroupNaming(), sourceGenerator);
177 this._typeConversion = new TypeConversion(getConfig());
178 this._enumerationFactory =
179 new EnumerationFactory(getConfig(), getGroupNaming(), sourceGenerator);
180 }
181
182
183
184
185
186
187
188
189
190 public void setCreateMarshalMethods(final boolean createMarshalMethods) {
191 _createMarshalMethods = createMarshalMethods;
192 }
193
194
195
196
197
198
199
200
201 public void setCreateExtraMethods(final boolean extraMethods) {
202 getInfoFactory().setCreateExtraMethods(extraMethods);
203 }
204
205
206
207
208
209
210
211
212 public void setReferenceMethodSuffix(final String suffix) {
213 getInfoFactory().setReferenceMethodSuffix(suffix);
214 }
215
216
217
218
219
220
221 public void setTestable(final boolean testable) {
222 _testable = testable;
223 }
224
225
226
227
228
229
230 public void setSAX1(final boolean sax1) {
231 _sax1 = sax1;
232 }
233
234
235
236
237
238
239 public void setCaseInsensitive(final boolean caseInsensitive) {
240 _enumerationFactory.setCaseInsensitive(caseInsensitive);
241 }
242
243
244
245
246
247
248
249
250
251
252
253
254
255 public JClass[] createSourceCode(final XMLBindingComponent component, final SGStateInfo sgState) {
256 if (component == null) {
257 throw new IllegalStateException("XMLBindingComponent may not be null.");
258 }
259 if (sgState == null) {
260 throw new IllegalStateException("SGStateInfo may not be null.");
261 }
262
263
264 JClass[] classes = sgState.getSourceCode(component.getAnnotated());
265 if (classes != null) {
266 return classes;
267 }
268
269 _binding = component.getBinding();
270
271 if (sgState.verbose()) {
272 String name = component.getXMLName();
273 if (name == null) {
274 name = component.getJavaClassName();
275 }
276 String msg = "Creating classes for: " + name;
277 sgState.getDialog().notify(msg);
278 }
279
280
281 String packageName = component.getJavaPackage();
282 if (packageName == null || packageName.length() == 0) {
283 packageName = sgState.getPackageName();
284 }
285
286
287
288
289 String className = component.getQualifiedName();
290 if (className.indexOf('.') == -1) {
291
292 className = getJavaNaming().toJavaClassName(className);
293 className = resolveClassName(className, packageName);
294 }
295
296
297 boolean createGroupItem = component.createGroupItem();
298 if (createGroupItem) {
299 className += ITEM_NAME;
300 classes = new JClass[2];
301 } else {
302 classes = new JClass[1];
303 }
304
305
306 FactoryState state = new FactoryState(className, sgState, packageName, component);
307 state.setCreateGroupItem(createGroupItem);
308 if (sgState.getCurrentFactoryState() != null) {
309 state.setParent(sgState.getCurrentFactoryState());
310 }
311 sgState.setCurrentFactoryState(state);
312
313
314 if (state.processed(component.getAnnotated())) {
315 return new JClass[0];
316 }
317
318
319
320 state.markAsProcessed(component.getAnnotated());
321
322
323
324
325
326
327
328 ClassInfo classInfo = state.getClassInfo();
329 JClass jClass = state.getJClass();
330 initialize(jClass);
331
332 if (classInfo.hasNature(XMLInfoNature.class.getName())) {
333 final XMLInfoNature xmlNature = new XMLInfoNature(classInfo);
334
335
336 xmlNature.setNodeName(component.getXMLName());
337
338
339 xmlNature.setNamespaceURI(component.getTargetNamespace());
340
341
342 XMLType type = component.getXMLType();
343 boolean createForSingleGroup = false;
344 boolean creatingForAnElement =
345 (component.getAnnotated().getStructureType() == Structure.ELEMENT);
346
347
348 xmlNature.setElementDefinition(creatingForAnElement);
349
350
351 if (creatingForAnElement) {
352 ElementDecl elementDeclaration = (ElementDecl) component.getAnnotated();
353 Enumeration<ElementDecl> possibleSubstitutes =
354 elementDeclaration.getSubstitutionGroupMembers();
355 if (possibleSubstitutes.hasMoreElements()) {
356 List<String> substitutionGroupMembers = new ArrayList<String>();
357 while (possibleSubstitutes.hasMoreElements()) {
358 ElementDecl substitute = possibleSubstitutes.nextElement();
359 substitutionGroupMembers.add(substitute.getName());
360 }
361 xmlNature.setSubstitutionGroups(substitutionGroupMembers);
362 }
363 }
364
365 if (type != null) {
366 if (type.isComplexType()) {
367 processComplexType(component, sgState, state);
368 } else if (type.isSimpleType()) {
369 SimpleType simpleType = (SimpleType) type;
370
371 if (simpleType.hasFacet(Facet.ENUMERATION)) {
372 processSimpleTypeEnumeration(component, sgState, classInfo, simpleType);
373 } else {
374
375
376
377
378 return new JClass[0];
379 }
380 } else if (type.isAnyType()) {
381
382 xmlNature.setSchemaType(new XSClass(SGTypes.OBJECT));
383 return new JClass[0];
384 }
385 } else {
386
387
388 createForSingleGroup = processSchemaGroup(component, state, classInfo);
389 }
390
391
392 if (createGroupItem) {
393
394 if (component.hasBoundProperties()) {
395 createPropertyChangeMethods(jClass);
396 }
397
398 sgState.bindReference(jClass, classInfo);
399
400 classes[1] = jClass;
401
402
403 String fname = component.getJavaClassName() + ITEM_NAME;
404 fname = getJavaNaming().toJavaMemberName(fname, false);
405
406 FieldInfo fInfo = null;
407 if (createForSingleGroup) {
408
409 fInfo = getInfoFactory().createFieldInfo(new XSClass(jClass), fname);
410 } else {
411 fInfo = getInfoFactory().createCollection(new XSClass(jClass), "_items", fname,
412 getJavaNaming(), getConfig().useJava50());
413 }
414 fInfo.setContainer(true);
415 String newClassName = className.substring(0, className.length() - 4);
416 state = new FactoryState(newClassName, sgState, packageName, component);
417 classInfo = state.getClassInfo();
418 jClass = state.getJClass();
419 initialize(jClass);
420 if (type != null && type.isComplexType()) {
421 ComplexType complexType = (ComplexType) type;
422 if (complexType.isTopLevel() ^ creatingForAnElement) {
423
424 Annotated saved = component.getAnnotated();
425 processAttributes(component.getBinding(), complexType, state);
426 component.setView(saved);
427 if (complexType.getContentType() == ContentType.mixed) {
428 FieldInfo fieldInfo = _memberFactory.createFieldInfoForContent(component,
429 new XSString(), getConfig().useJava50());
430 handleField(fieldInfo, state, component);
431 } else if (complexType.getContentType().getType() == ContentType.SIMPLE) {
432 SimpleContent simpleContent = (SimpleContent) complexType.getContentType();
433 SimpleType temp = simpleContent.getSimpleType();
434 XSType xsType =
435 _typeConversion.convertType(temp, packageName, getConfig().useJava50());
436 FieldInfo fieldInfo = _memberFactory.createFieldInfoForContent(component, xsType,
437 getConfig().useJava50());
438 handleField(fieldInfo, state, component);
439 temp = null;
440 } else {
441
442 xmlNature.setSchemaType(new XSClass(jClass));
443 }
444 }
445 }
446
447 classInfo.addFieldInfo(fInfo);
448 fInfo.getMemberAndAccessorFactory().createJavaField(fInfo, jClass);
449 fInfo.getMemberAndAccessorFactory().createAccessMethods(fInfo, jClass,
450 getConfig().useJava50(), getConfig().getAnnotationBuilders());
451 fInfo.getMemberAndAccessorFactory().generateInitializerCode(fInfo,
452 jClass.getConstructor(0).getSourceCode());
453
454
455 XMLInfoNature xmlInfoNature = new XMLInfoNature(classInfo);
456 xmlInfoNature.setNodeName(component.getXMLName());
457
458
459 xmlInfoNature.setContainer(true);
460
461
462
463 String actSuperClass = classes[1].getSuperClassQualifiedName();
464 jClass.setSuperClass(actSuperClass);
465 classes[1].setSuperClass(null);
466 }
467
468 }
469
470 classes[0] = jClass;
471
472
473
474 String baseClass = component.getExtends();
475 if (baseClass != null && baseClass.length() > 0) {
476
477
478
479
480 if (jClass.getSuperClassQualifiedName() == null) {
481 jClass.setSuperClass(baseClass);
482 }
483 }
484
485
486 String[] implemented = component.getImplements();
487 if (implemented != null) {
488 for (String interfaceName : implemented) {
489 if ((interfaceName != null) && (interfaceName.length() > 0)) {
490 jClass.addInterface(interfaceName);
491 }
492 }
493 }
494
495
496 jClass.getModifiers().setFinal(component.isFinal());
497
498
499 if (component.isAbstract()) {
500 jClass.getModifiers().setAbstract(true);
501 classInfo.setAbstract(true);
502 }
503
504 processAppInfo(component.getAnnotated(), classInfo);
505 extractAnnotations(component.getAnnotated(), jClass);
506
507 createContructorForDefaultValueForSimpleContent(component.getAnnotated(), classInfo, sgState);
508 makeMethods(component, sgState, state, jClass, baseClass);
509
510 if (classInfo.hasNature(JDOClassInfoNature.class.getName())) {
511 JDOClassInfoNature jdoNature = new JDOClassInfoNature(classInfo);
512 if (jdoNature.getDetachable()) {
513 createJdoTimestampImplementations(jClass);
514 }
515 }
516
517 sgState.bindReference(jClass, classInfo);
518 sgState.bindReference(component.getAnnotated(), classInfo);
519
520
521 sgState.bindSourceCode(component.getAnnotated(), classes);
522
523
524 AnnotationBuilder[] annotationBuilders = getConfig().getAnnotationBuilders();
525 for (AnnotationBuilder annotationBuilder : annotationBuilders) {
526 annotationBuilder.addClassAnnotations(classInfo, jClass);
527 }
528
529 return classes;
530 }
531
532
533
534
535
536
537
538
539 private void createContructorForDefaultValueForSimpleContent(final Annotated annotated,
540 final ClassInfo classInfo, final SGStateInfo sgStateInfo) {
541 FieldInfo textFieldInfo = classInfo.getTextField();
542
543 boolean generate = false;
544 boolean inherited = false;
545
546
547 if (annotated instanceof ElementDecl) {
548 XMLType type = ((ElementDecl) annotated).getType();
549 ClassInfo typeInfo = sgStateInfo.resolve(type);
550 if (typeInfo != null && typeInfo.getTextField() != null) {
551 textFieldInfo = typeInfo.getTextField();
552 inherited = true;
553 }
554 generate = (type.isComplexType() && ((ComplexType) type).isSimpleContent());
555 }
556
557
558 else if (annotated instanceof ComplexType && ((ComplexType) annotated).isSimpleContent()) {
559 generate = true;
560 }
561
562
563
564 if (textFieldInfo != null) {
565 XSType textFieldType = new XMLInfoNature(textFieldInfo).getSchemaType();
566 if (textFieldType != null && textFieldType.getJType().isArray()) {
567 generate = false;
568 }
569 }
570
571 if (!generate) {
572 return;
573 }
574
575 XMLInfoNature xmlNature = new XMLInfoNature(textFieldInfo);
576
577
578 JClass jClass = classInfo.getJClass();
579 JParameter parameter = new JParameter(new JClass("java.lang.String"), "defaultValue");
580 JConstructor constructor = jClass.createConstructor(new JParameter[] {parameter});
581 JSourceCode sourceCode = new JSourceCode();
582
583 if (inherited) {
584 sourceCode.add("super(defaultValue);");
585 } else {
586 sourceCode.add("try {");
587 String defaultValue = xmlNature.getSchemaType().createDefaultValueWithString("defaultValue");
588 sourceCode.addIndented("setContent(" + defaultValue + ");");
589 sourceCode.add(" } catch(Exception e) {");
590 sourceCode.addIndented(
591 "throw new RuntimeException(\"Unable to cast default value for simple content!\");");
592 sourceCode.add(" } ");
593 }
594
595 constructor.setSourceCode(sourceCode);
596 jClass.addConstructor(constructor);
597 }
598
599
600
601
602
603
604
605 private void extractAnnotations(final Annotated annotated, final JClass jClass) {
606
607 String comment = extractCommentsFromAnnotations(annotated);
608 if (comment != null) {
609 jClass.getJDocComment().setComment(comment);
610
611 if (getConfig().generateExtraDocumentationMethods()) {
612 generateExtraDocumentationMethods(annotated, jClass);
613 }
614 }
615 }
616
617
618
619
620
621
622
623
624 private void generateExtraDocumentationMethods(final Annotated annotated, final JClass jClass) {
625 JField documentationsField =
626 new JField(new JClass("java.util.Map"), "_xmlSchemaDocumentations");
627 documentationsField.setComment("The content of the <xsd:documentation> elements");
628 documentationsField.setInitString("new java.util.HashMap()");
629 jClass.addMember(documentationsField);
630
631 Enumeration<Annotation> annotations = annotated.getAnnotations();
632 while (annotations.hasMoreElements()) {
633 Annotation annotation = annotations.nextElement();
634 Enumeration<Documentation> documentations = annotation.getDocumentation();
635 while (documentations.hasMoreElements()) {
636 Documentation documentation = documentations.nextElement();
637 JConstructor defaultConstructor = jClass.getConstructor(0);
638 String documentationContent = normalize(documentation.getContent());
639 documentationContent = StringUtil.replaceAll(documentationContent, "\n", "\"\n+ \" ");
640 defaultConstructor.getSourceCode().add("_xmlSchemaDocumentations.put(\""
641 + documentation.getSource() + "\", \"" + documentationContent + "\");");
642 }
643 }
644
645 JMethod aMethod = new JMethod("getXmlSchemaDocumentations", new JClass("java.util.Map"),
646 " A collection of documentation elements.");
647 JSourceCode sourceCode = aMethod.getSourceCode();
648 sourceCode.add("return _xmlSchemaDocumentations;");
649 jClass.addMethod(aMethod);
650
651 JMethod anotherMethod = new JMethod("getXmlSchemaDocumentation", new JClass("java.lang.String"),
652 " A specific XML schema documentation element.");
653 JParameter parameter = new JParameter(new JClass("java.lang.String"), "source");
654 anotherMethod.addParameter(parameter);
655 sourceCode = anotherMethod.getSourceCode();
656 sourceCode.add("return (java.lang.String) _xmlSchemaDocumentations.get(source);");
657 jClass.addMethod(anotherMethod);
658 }
659
660
661
662
663
664
665
666
667
668
669 private void makeMethods(final XMLBindingComponent component, final SGStateInfo sgState,
670 final FactoryState state, final JClass jClass, final String baseClass) {
671
672
673 if (_createMarshalMethods) {
674
675 createValidateMethods(jClass);
676
677
678 if (!component.isAbstract()) {
679
680 createMarshalMethods(jClass);
681
682 createUnmarshalMethods(jClass, sgState);
683 }
684 }
685
686
687 if (component.hasEquals()) {
688 createEqualsMethod(jClass);
689 createHashCodeMethod(jClass);
690 }
691
692
693 if (_testable) {
694 createTestableMethods(jClass, state);
695 }
696
697
698
699 String superclassQualifiedName = jClass.getSuperClassQualifiedName();
700 if (superclassQualifiedName == null || superclassQualifiedName.equals(baseClass)) {
701
702 if (component.hasBoundProperties()) {
703 createPropertyChangeMethods(jClass);
704 }
705 }
706 }
707
708 private boolean processSchemaGroup(final XMLBindingComponent component, final FactoryState state,
709 final ClassInfo classInfo) {
710 try {
711 Group group = (Group) component.getAnnotated();
712 processContentModel(group, state);
713 component.setView(group);
714
715
716 Order order = group.getOrder();
717 GroupInfo groupInfo = new XMLInfoNature(classInfo).getGroupInfo();
718 if (order == Order.choice) {
719 groupInfo.setAsChoice();
720 } else if (order == Order.sequence) {
721 groupInfo.setAsSequence();
722 } else {
723 groupInfo.setAsAll();
724 }
725
726 return group.getMaxOccurs() == 1;
727 } catch (ClassCastException ce) {
728
729 throw new IllegalArgumentException("Illegal binding component: " + ce.getMessage());
730 }
731 }
732
733 private void processSimpleTypeEnumeration(final XMLBindingComponent component,
734 final SGStateInfo sgState, final ClassInfo classInfo, final SimpleType simpleType) {
735
736
737 String tns = simpleType.getSchema().getTargetNamespace();
738 boolean create = false;
739 if (tns == null) {
740 create = (component.getTargetNamespace() == null);
741 } else {
742 create = tns.equals(component.getTargetNamespace());
743 }
744
745 if (create) {
746 ClassInfo tmpInfo = sgState.resolve(simpleType);
747 JClass tmpClass = null;
748 if (tmpInfo != null) {
749 tmpClass = tmpInfo.getJClass();
750 } else {
751 tmpClass = createSourceCode(component.getBinding(), simpleType, sgState);
752 }
753 XMLInfoNature xmlNature = new XMLInfoNature(classInfo);
754 xmlNature.setSchemaType(new XSClass(tmpClass));
755 }
756 }
757
758 private void processComplexType(final XMLBindingComponent component, final SGStateInfo sgState,
759 final FactoryState state) {
760 XMLType type = component.getXMLType();
761 ClassInfo classInfo = state.getClassInfo();
762 JClass jClass = state.getJClass();
763 boolean creatingForAnElement =
764 (component.getAnnotated().getStructureType() == Structure.ELEMENT);
765
766 ComplexType complexType = (ComplexType) type;
767 if (complexType.isTopLevel() && creatingForAnElement) {
768
769 Annotated saved = component.getAnnotated();
770 String previousPackage = component.getJavaPackage();
771 XMLBindingComponent baseComponent = new XMLBindingComponent(getConfig(), getGroupNaming());
772 baseComponent.setBinding(component.getBinding());
773 baseComponent.setView(complexType);
774
775 createSourceCode(baseComponent, sgState);
776 String baseClassName = null;
777 String basePackage = baseComponent.getJavaPackage();
778
779
780
781 if (basePackage != null && !basePackage.equals(previousPackage)) {
782 baseClassName = baseComponent.getQualifiedName();
783 if (baseClassName.indexOf('.') == -1) {
784
785 baseClassName = getJavaNaming().toJavaClassName(baseClassName);
786 }
787 } else {
788 baseClassName = baseComponent.getJavaClassName();
789 }
790 jClass.setSuperClass(baseClassName);
791 basePackage = null;
792 baseClassName = null;
793 component.setView(saved);
794 saved = null;
795 } else if (complexType.isTopLevel() || creatingForAnElement) {
796
797
798
799
800
801 if (complexType.getParticleCount() == 1) {
802 Particle particle = complexType.getParticle(0);
803 if (particle.getStructureType() == Structure.GROUP) {
804 Group group = (Group) particle;
805 if (group.getOrder() == Order.choice) {
806 new XMLInfoNature(classInfo).getGroupInfo().setAsChoice();
807 }
808 }
809 }
810 Annotated saved = component.getAnnotated();
811 processComplexType(complexType, state);
812 component.setView(saved);
813 saved = null;
814 }
815 }
816
817
818
819
820
821
822
823
824
825 public JClass createSourceCode(final ExtendedBinding binding, final SimpleType simpleType,
826 final SGStateInfo sgState) {
827 if (SimpleTypesFactory.isBuiltInType(simpleType.getTypeCode())) {
828 String err = "You cannot construct a ClassInfo for a built-in SimpleType.";
829 throw new IllegalArgumentException(err);
830 }
831 if (sgState == null) {
832 throw new IllegalArgumentException("SGStateInfo cannot be null.");
833 }
834
835
836
837
838
839
840 if (simpleType.getStructureType() == Structure.UNION) {
841 if (!sgState.getSuppressNonFatalWarnings()) {
842 String message = "warning: support for unions is incomplete.";
843 sgState.getDialog().notify(message);
844 }
845 return null;
846 }
847
848 ClassInfo cInfo = sgState.resolve(simpleType);
849 if (cInfo != null) {
850 return cInfo.getJClass();
851 }
852
853 boolean enumeration = false;
854
855
856 String typeName = simpleType.getName();
857 if (typeName == null) {
858 Structure struct = simpleType.getParent();
859 FactoryState fstate = null;
860 switch (struct.getStructureType()) {
861 case Structure.ATTRIBUTE:
862 typeName = ((AttributeDecl) struct).getName();
863 fstate = sgState.getCurrentFactoryState();
864 break;
865 case Structure.ELEMENT:
866 typeName = ((ElementDecl) struct).getName();
867 break;
868 default:
869
870 break;
871 }
872
873 if (fstate != null) {
874 typeName = getJavaNaming().toJavaClassName(typeName);
875 Structure attrDeclParent = ((AttributeDecl) struct).getParent();
876 if (attrDeclParent != null
877 && attrDeclParent.getStructureType() == Structure.ATTRIBUTE_GROUP) {
878 typeName = getJavaNaming()
879 .toJavaClassName(((AttributeGroupDecl) attrDeclParent).getName() + typeName);
880 } else {
881 typeName = fstate.getJClass().getLocalName() + typeName;
882 }
883 }
884
885 typeName += "Type";
886 }
887
888 String className = getJavaNaming().toJavaClassName(typeName);
889
890
891
892 XMLBindingComponent comp = new XMLBindingComponent(getConfig(), getGroupNaming());
893 if (binding != null) {
894 comp.setBinding(binding);
895 }
896
897
898 if (simpleType.getName() == null) {
899 Annotated annotated = (Annotated) simpleType.getParent();
900 comp.setView(annotated);
901 } else {
902 comp.setView(simpleType);
903 }
904
905 String packageName = comp.getJavaPackage();
906 if ((packageName == null) || (packageName.length() == 0)) {
907 packageName = sgState.getPackageName();
908 }
909
910
911 if (simpleType.getName() == null) {
912 comp.setView(simpleType);
913 }
914
915 if (simpleType.hasFacet(Facet.ENUMERATION)) {
916 enumeration = true;
917
918
919 if ((packageName != null) && (packageName.length() > 0)) {
920 packageName = packageName + "." + SourceGeneratorConstants.TYPES_PACKAGE;
921 } else {
922 packageName = SourceGeneratorConstants.TYPES_PACKAGE;
923 }
924 }
925
926 String boundClassName = comp.getJavaClassName();
927 if ((boundClassName != null) && (boundClassName.length() > 0)) {
928 className = boundClassName;
929 typeName = boundClassName;
930 }
931
932 className = resolveClassName(className, packageName);
933
934 FactoryState state = new FactoryState(className, sgState, packageName, comp,
935 (enumeration && getConfig().useJava5Enums()));
936
937 state.setParent(sgState.getCurrentFactoryState());
938
939 ClassInfo classInfo = state.getClassInfo();
940 JClass jClass = state.getJClass();
941
942 initialize(jClass);
943
944
945 Schema schema = simpleType.getSchema();
946 XMLInfoNature xmlNature = new XMLInfoNature(classInfo);
947 xmlNature.setNamespaceURI(schema.getTargetNamespace());
948 xmlNature.setNodeName(typeName);
949
950 extractAnnotations(simpleType, jClass);
951
952 XSClass xsClass = new XSClass(jClass, typeName);
953
954 xmlNature.setSchemaType(xsClass);
955
956
957 if (enumeration) {
958 xsClass.setAsEnumerated(true);
959 processEnumeration(binding, simpleType, state);
960 }
961
962
963 if (state.hasBoundProperties() && !enumeration) {
964 createPropertyChangeMethods(jClass);
965 }
966
967 if (classInfo.hasNature(JDOClassInfoNature.class.getName())) {
968 JDOClassInfoNature jdoNature = new JDOClassInfoNature(classInfo);
969 if (jdoNature.getDetachable()) {
970 createJdoTimestampImplementations(jClass);
971 }
972 }
973
974 sgState.bindReference(jClass, classInfo);
975 sgState.bindReference(simpleType, classInfo);
976
977 return jClass;
978 }
979
980 private void createJdoTimestampImplementations(final JClass jClass) {
981
982 jClass.addInterface("org.exolab.castor.jdo.TimeStampable");
983
984 JField jdoTimestamp = new JField(JType.LONG, "_jdoTimeStamp");
985 jClass.addField(jdoTimestamp);
986
987 JMethod getTSMethod =
988 new JMethod("jdoGetTimeStamp", JType.LONG, "returns the current time stamp");
989 JSourceCode getSourceCode = getTSMethod.getSourceCode();
990 getSourceCode.addIndented("return _jdoTimeStamp;");
991 jClass.addMethod(getTSMethod);
992
993 JMethod setTSMethod = new JMethod("jdoSetTimeStamp");
994 JParameter parameter = new JParameter(JType.LONG, "jdoTimeStamp");
995 setTSMethod.addParameter(parameter);
996 JSourceCode setSourceCode = setTSMethod.getSourceCode();
997 setSourceCode.addIndented("this._jdoTimeStamp = jdoTimeStamp;");
998 jClass.addMethod(setTSMethod);
999 }
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011 private void initialize(final JClass jClass) {
1012 jClass.addInterface("java.io.Serializable");
1013
1014 if (getConfig().useJava50()) {
1015 JAnnotation serial = new JAnnotation(new JAnnotationType("SuppressWarnings"));
1016 serial.setValue(new String[] {"\"serial\""});
1017 jClass.addAnnotation(serial);
1018 }
1019
1020
1021 JConstructor con = jClass.createConstructor();
1022 jClass.addConstructor(con);
1023 con.getSourceCode().add("super();");
1024 }
1025
1026
1027
1028
1029
1030
1031 private void createPropertyChangeMethods(final JClass parent) {
1032
1033 String vName = "propertyChangeSupport";
1034 JField field = new JField(SGTypes.PROPERTY_CHANGE_SUPPORT, vName);
1035 field.getModifiers().makePrivate();
1036 parent.addField(field);
1037
1038
1039
1040
1041
1042 JMethod jMethod = new JMethod("notifyPropertyChangeListeners");
1043 jMethod.getModifiers().makeProtected();
1044
1045 JDocComment jdc = jMethod.getJDocComment();
1046 JDocDescriptor jdDesc = null;
1047 String desc = null;
1048
1049 desc = "Notifies all registered PropertyChangeListeners "
1050 + "when a bound property's value changes.";
1051 jdc.appendComment(desc);
1052
1053 jMethod.addParameter(new JParameter(SGTypes.STRING, "fieldName"));
1054 jdDesc = jdc.getParamDescriptor("fieldName");
1055 jdDesc.setDescription("the name of the property that has changed.");
1056
1057 jMethod.addParameter(new JParameter(SGTypes.OBJECT, "oldValue"));
1058 jdDesc = jdc.getParamDescriptor("oldValue");
1059 jdDesc.setDescription("the old value of the property.");
1060
1061 jMethod.addParameter(new JParameter(SGTypes.OBJECT, "newValue"));
1062 jdDesc = jdc.getParamDescriptor("newValue");
1063 jdDesc.setDescription("the new value of the property.");
1064
1065 parent.addMethod(jMethod);
1066 JSourceCode jsc = jMethod.getSourceCode();
1067
1068 jsc.add("if (");
1069 jsc.append(vName);
1070 jsc.append(" == null) return;");
1071
1072 jsc.add(vName);
1073 jsc.append(".firePropertyChange(fieldName,oldValue,newValue);");
1074
1075
1076
1077
1078
1079 JType jType = new JClass("java.beans.PropertyChangeListener");
1080 jMethod = new JMethod("addPropertyChangeListener");
1081
1082 desc = "Registers a PropertyChangeListener with this class.";
1083 jdc = jMethod.getJDocComment();
1084 jdc.appendComment(desc);
1085
1086 jMethod.addParameter(new JParameter(jType, "pcl"));
1087 desc = "The PropertyChangeListener to register.";
1088 jdDesc = jdc.getParamDescriptor("pcl");
1089 jdDesc.setDescription(desc);
1090
1091 parent.addMethod(jMethod);
1092
1093 jsc = jMethod.getSourceCode();
1094
1095 jsc.add("if (");
1096 jsc.append(vName);
1097 jsc.append(" == null) {");
1098 jsc.addIndented(vName + " = new java.beans.PropertyChangeSupport(this);");
1099 jsc.add("}");
1100 jsc.add(vName);
1101 jsc.append(".addPropertyChangeListener(pcl);");
1102
1103
1104
1105
1106
1107 jMethod = new JMethod("removePropertyChangeListener", JType.BOOLEAN,
1108 "always returns true if pcl != null");
1109
1110 desc = "Removes the given PropertyChangeListener "
1111 + "from this classes list of ProperyChangeListeners.";
1112 jdc = jMethod.getJDocComment();
1113 jdc.appendComment(desc);
1114
1115 jMethod.addParameter(new JParameter(jType, "pcl"));
1116 desc = "The PropertyChangeListener to remove.";
1117 jdDesc = jdc.getParamDescriptor("pcl");
1118 jdDesc.setDescription(desc);
1119
1120 parent.addMethod(jMethod);
1121
1122 jsc = jMethod.getSourceCode();
1123 jsc.add("if (");
1124 jsc.append(vName);
1125 jsc.append(" == null) return false;");
1126
1127 jsc.add(vName);
1128 jsc.append(".removePropertyChangeListener(pcl);");
1129 jsc.add("return true;");
1130 }
1131
1132
1133
1134
1135
1136
1137 private void createMarshalMethods(final JClass parent) {
1138 createMarshalMethods(parent, false);
1139 }
1140
1141
1142
1143
1144
1145
1146
1147 private void createMarshalMethods(final JClass parent, final boolean isAbstract) {
1148
1149 JMethod jMethod = new JMethod("marshal");
1150 jMethod.addException(SGTypes.MARSHAL_EXCEPTION,
1151 "if object is null or if any SAXException is thrown during marshaling");
1152 jMethod.addException(SGTypes.VALIDATION_EXCEPTION,
1153 "if this object is an invalid instance according to the schema");
1154 jMethod.addParameter(new JParameter(SGTypes.WRITER, "out"));
1155
1156
1157
1158
1159
1160 parent.addMethod(jMethod);
1161
1162 if (isAbstract) {
1163 jMethod.getModifiers().setAbstract(true);
1164 } else {
1165 JSourceCode jsc = jMethod.getSourceCode();
1166 jsc.add("org.exolab.castor.xml.Marshaller.marshal(this, out);");
1167 }
1168
1169
1170
1171
1172 jMethod = new JMethod("marshal");
1173 JClass jc = null;
1174 if (_sax1) {
1175 jc = new JClass("org.xml.sax.DocumentHandler");
1176 } else {
1177 jc = new JClass("org.xml.sax.ContentHandler");
1178 jMethod.addException(SGTypes.IO_EXCEPTION, "if an IOException occurs during marshaling");
1179 }
1180 jMethod.addException(SGTypes.MARSHAL_EXCEPTION,
1181 "if object is null or if any SAXException is thrown during marshaling");
1182 jMethod.addException(SGTypes.VALIDATION_EXCEPTION,
1183 "if this object is an invalid instance according to the schema");
1184 jMethod.addParameter(new JParameter(jc, "handler"));
1185 parent.addMethod(jMethod);
1186
1187 if (isAbstract) {
1188 jMethod.getModifiers().setAbstract(true);
1189 } else {
1190 JSourceCode jsc = jMethod.getSourceCode();
1191 jsc.add("org.exolab.castor.xml.Marshaller.marshal(this, handler);");
1192 }
1193 }
1194
1195 private void createUnmarshalMethods(final JClass parent, final SGStateInfo sgState) {
1196
1197 String methodName = "unmarshal";
1198 if (sgState.getSourceGenerator().mappingSchemaType2Java()) {
1199 methodName += parent.getLocalName();
1200 }
1201
1202
1203
1204
1205
1206 JClass returnType;
1207 if (!getConfig().useJava50()) {
1208 returnType = findBaseClass(parent, sgState);
1209 } else {
1210 returnType = parent;
1211 }
1212
1213 JMethod jMethod = new JMethod(methodName, returnType, "the unmarshaled " + returnType);
1214 jMethod.getModifiers().setStatic(true);
1215 jMethod.addException(SGTypes.MARSHAL_EXCEPTION,
1216 "if object is null or if any SAXException is thrown during marshaling");
1217 jMethod.addException(SGTypes.VALIDATION_EXCEPTION,
1218 "if this object is an invalid instance according to the schema");
1219 jMethod.addParameter(new JParameter(SGTypes.READER, "reader"));
1220 parent.addMethod(jMethod);
1221
1222 JSourceCode jsc = jMethod.getSourceCode();
1223 jsc.add("return (");
1224 jsc.append(returnType.getName());
1225 jsc.append(") org.exolab.castor.xml.Unmarshaller.unmarshal(");
1226 jsc.append(parent.getName());
1227 jsc.append(".class, reader);");
1228 }
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238 private JClass findBaseClass(final JClass jClass, final SGStateInfo sgState) {
1239 JClass returnType = jClass;
1240
1241 List<JClass> classes = new LinkedList<JClass>();
1242 classes.add(returnType);
1243
1244 while (returnType.getSuperClassQualifiedName() != null) {
1245 String superClassName = returnType.getSuperClassQualifiedName();
1246 JClass superClass = sgState.getSourceCode(superClassName);
1247 if (superClass == null) {
1248 superClass = sgState.getImportedSourceCode(superClassName);
1249 }
1250
1251
1252
1253 if (superClass == null && superClassName.indexOf('.') < 0) {
1254 String pkgName = returnType.getPackageName();
1255 if (pkgName != null && pkgName.length() > 0) {
1256 superClassName = pkgName + "." + superClassName;
1257 superClass = sgState.getSourceCode(superClassName);
1258 }
1259 }
1260
1261
1262 if (superClass == null) {
1263 break;
1264 }
1265
1266
1267 if (classes.contains(superClass)) {
1268 StringBuilder buffer = new StringBuilder(64);
1269 buffer.append("Loop found in class hierarchy: ");
1270 for (Iterator<JClass> i = classes.iterator(); i.hasNext();) {
1271 JClass element = i.next();
1272
1273
1274 buffer.append(element.getName());
1275 buffer.append(" -> ");
1276 }
1277 buffer.append(superClass.getName());
1278 sgState.getDialog().notify(buffer.toString());
1279
1280 break;
1281 }
1282
1283 classes.add(superClass);
1284 returnType = superClass;
1285 }
1286
1287 classes.clear();
1288 return returnType;
1289 }
1290
1291
1292
1293
1294
1295
1296 public void createHashCodeMethod(final JClass jclass) {
1297 if (jclass == null) {
1298 throw new IllegalArgumentException("JClass must not be null");
1299 }
1300
1301
1302 JField[] fields = jclass.getFields();
1303
1304
1305 JMethod jMethod = new JMethod("hashCode", JType.INT, "a hash code value for the object.");
1306 jMethod.setComment("Overrides the java.lang.Object.hashCode method.\n" + "<p>\n"
1307 + "The following steps came from " + "<b>Effective Java Programming Language Guide</b> "
1308 + "by Joshua Bloch, Chapter 3");
1309
1310
1311 jclass.addMethod(jMethod);
1312
1313 JSourceCode jsc = jMethod.getSourceCode();
1314 if (jclass.getSuperClassQualifiedName() == null) {
1315 jsc.add("int resultHc = 17;");
1316 } else {
1317 jsc.add("int resultHc = super.hashCode();");
1318 }
1319 jsc.add("");
1320 jsc.add("long tmp;");
1321
1322 for (JField temp : fields) {
1323
1324
1325 JType type = temp.getType();
1326 String name = temp.getName();
1327 if (type.isPrimitive()) {
1328 if (type == JType.BOOLEAN) {
1329
1330
1331 if (!name.startsWith("_has_") || jclass.getField(name.substring(5)) != null) {
1332 jsc.add("resultHc = 37 * resultHc + (" + name + "?0:1);");
1333 }
1334 } else if (type == JType.BYTE || type == JType.INT || type == JType.SHORT) {
1335 jsc.add("resultHc = 37 * resultHc + " + name + ";");
1336 } else if (type == JType.LONG) {
1337 jsc.add("resultHc = 37 * resultHc + (int)(" + name + "^(" + name + ">>>32));");
1338 } else if (type == JType.FLOAT) {
1339 jsc.add("resultHc = 37 * resultHc + java.lang.Float.floatToIntBits(" + name + ");");
1340 } else if (type == JType.DOUBLE) {
1341 jsc.add("tmp = java.lang.Double.doubleToLongBits(" + name + ");");
1342 jsc.add("resultHc = 37 * resultHc + (int)(tmp^(tmp>>>32));");
1343 }
1344 } else {
1345 if (getConfig().useCycleBreaker()) {
1346
1347 jsc.add("if (" + name + " != null");
1348 jsc.add(" && !org.castor.core.util.CycleBreaker.startingToCycle(" + name + ")) {");
1349 } else {
1350
1351 jsc.add("if (" + name + " != null) {");
1352 }
1353 jsc.add(" resultHc = 37 * resultHc + " + name + ".hashCode();");
1354
1355 if (getConfig().useCycleBreaker()) {
1356
1357 jsc.add(" org.castor.core.util.CycleBreaker.releaseCycleHandle(" + name + ");");
1358 }
1359 jsc.add("}");
1360 }
1361 }
1362 jsc.add("");
1363 jsc.add("return resultHc;");
1364 }
1365
1366
1367
1368
1369
1370
1371 public void createEqualsMethod(final JClass jclass) {
1372 if (jclass == null) {
1373 throw new IllegalArgumentException("JClass must not be null");
1374 }
1375
1376 JField[] fields = jclass.getFields();
1377 JMethod jMethod = new JMethod("equals", JType.BOOLEAN, "true if the objects are equal.");
1378 jMethod.setComment("Overrides the java.lang.Object.equals method.");
1379 jMethod.addParameter(new JParameter(SGTypes.OBJECT, "obj"));
1380
1381 if (getConfig().useJava50()) {
1382 jMethod.addAnnotation(new JAnnotation(new JAnnotationType("Override")));
1383 }
1384
1385 jclass.addMethod(jMethod);
1386 JSourceCode jsc = jMethod.getSourceCode();
1387 jsc.add("if ( this == obj )");
1388 jsc.indent();
1389 jsc.add("return true;");
1390 jsc.unindent();
1391 if (jclass.getSuperClassQualifiedName() != null) {
1392 jsc.add("");
1393 jsc.add("if (super.equals(obj)==false)");
1394 jsc.indent();
1395 jsc.add("return false;");
1396 jsc.unindent();
1397 }
1398 jsc.add("");
1399 jsc.add("if (obj instanceof ");
1400 jsc.append(jclass.getLocalName());
1401 jsc.append(") {");
1402 jsc.add("");
1403 if (fields.length > 0) {
1404 jsc.indent();
1405 jsc.add(jclass.getLocalName());
1406 jsc.append(" temp = (");
1407 jsc.append(jclass.getLocalName());
1408 jsc.append(")obj;");
1409
1410 if (getConfig().useCycleBreaker()) {
1411 jsc.add("boolean thcycle;");
1412 jsc.add("boolean tmcycle;");
1413 }
1414 }
1415 for (JField temp : fields) {
1416
1417
1418 String name = temp.getName();
1419 if (temp.getType().isPrimitive()) {
1420 jsc.add("if (this.");
1421 jsc.append(name);
1422 jsc.append(" != temp.");
1423 jsc.append(name);
1424 jsc.append(")");
1425 } else {
1426
1427
1428
1429
1430 jsc.add("if (this.");
1431 jsc.append(name);
1432 jsc.append(" != null) {");
1433 jsc.indent();
1434 jsc.add("if (temp.");
1435 jsc.append(name);
1436 jsc.append(" == null) ");
1437 jsc.indent();
1438 jsc.append("return false;");
1439 jsc.unindent();
1440
1441 if (getConfig().useCycleBreaker()) {
1442 jsc.add("if (this.");
1443 jsc.append(name);
1444 jsc.append(" != temp.");
1445 jsc.append(name);
1446 jsc.append(") {");
1447
1448
1449 jsc.indent();
1450 jsc.add("thcycle=org.castor.core.util.CycleBreaker.startingToCycle(this." + name + ");");
1451 jsc.add("tmcycle=org.castor.core.util.CycleBreaker.startingToCycle(temp." + name + ");");
1452
1453 jsc.add("if (thcycle!=tmcycle) {");
1454 jsc.indent();
1455 jsc.add("if (!thcycle) { org.castor.core.util.CycleBreaker.releaseCycleHandle(this."
1456 + name + "); };");
1457 jsc.add("if (!tmcycle) { org.castor.core.util.CycleBreaker.releaseCycleHandle(temp."
1458 + name + "); };");
1459 jsc.add("return false;");
1460 jsc.unindent();
1461 jsc.add("}");
1462 jsc.add("if (!thcycle) {");
1463 jsc.indent();
1464 }
1465 jsc.add("if (!");
1466
1467
1468 if (temp.getType().isArray()) {
1469 jsc.append("java.util.Arrays.equals(this.");
1470 jsc.append(name);
1471 jsc.append(", temp.");
1472 jsc.append(name);
1473 jsc.append(")");
1474 } else {
1475 jsc.append("this.");
1476 jsc.append(name);
1477 jsc.append(".equals(temp.");
1478 jsc.append(name);
1479 jsc.append(")");
1480 }
1481
1482 if (getConfig().useCycleBreaker()) {
1483 jsc.append(") {");
1484 } else {
1485 jsc.append(") ");
1486 }
1487 jsc.indent();
1488
1489 if (getConfig().useCycleBreaker()) {
1490 jsc.add("org.castor.core.util.CycleBreaker.releaseCycleHandle(this." + name + ");");
1491 jsc.add("org.castor.core.util.CycleBreaker.releaseCycleHandle(temp." + name + ");");
1492 }
1493 jsc.add("return false;");
1494 jsc.unindent();
1495
1496 if (getConfig().useCycleBreaker()) {
1497 jsc.add("}");
1498
1499 jsc.add("org.castor.core.util.CycleBreaker.releaseCycleHandle(this." + name + ");");
1500 jsc.add("org.castor.core.util.CycleBreaker.releaseCycleHandle(temp." + name + ");");
1501 }
1502
1503 jsc.unindent();
1504
1505 if (getConfig().useCycleBreaker()) {
1506 jsc.add("}");
1507 jsc.unindent();
1508 jsc.add("}");
1509 jsc.unindent();
1510 }
1511 jsc.add("} else if (temp.");
1512 jsc.append(name);
1513 jsc.append(" != null)");
1514 }
1515 jsc.indent();
1516 jsc.add("return false;");
1517 jsc.unindent();
1518 }
1519 jsc.add("return true;");
1520 jsc.unindent();
1521 jsc.add("}");
1522 jsc.add("return false;");
1523 }
1524
1525
1526
1527
1528
1529
1530
1531 public void createTestableMethods(final JClass jclass, final FactoryState state) {
1532 if (jclass == null) {
1533 throw new IllegalArgumentException("JClass must not be null");
1534 }
1535
1536 jclass.addInterface("org.castor.xmlctf.CastorTestable");
1537 jclass.addImport("org.castor.xmlctf.CastorTestable");
1538 jclass.addImport("org.castor.xmlctf.RandomHelper");
1539
1540 createRandomizeFields(jclass, state);
1541 createDumpFields(jclass);
1542 }
1543
1544
1545
1546
1547
1548
1549
1550
1551 private void createRandomizeFields(final JClass jclass, final FactoryState state) {
1552 JMethod jMethod = new JMethod("randomizeFields");
1553 jMethod.addException(new JClass("InstantiationException"),
1554 "if we try to instantiate an abstract class or interface");
1555 jMethod.addException(new JClass("IllegalAccessException"),
1556 "if we do not have access to the field, for example if it is private");
1557 jMethod.setComment("implementation of org.castor.xmlctf.CastorTestable");
1558 jclass.addMethod(jMethod);
1559 JSourceCode jsc = jMethod.getSourceCode();
1560 JField[] fields = jclass.getFields();
1561
1562 for (JField temp : fields) {
1563 JType type = temp.getType();
1564 String name = temp.getName();
1565
1566 if (state.getFieldInfoForChoice() != null
1567 && name.equals(state.getFieldInfoForChoice().getName())) {
1568 continue;
1569 }
1570
1571 if (name.startsWith("enumConstants")) {
1572 continue;
1573 }
1574
1575 if (name.startsWith("_")) {
1576 name = getJavaNaming().toJavaClassName(name.substring(1));
1577 } else {
1578 name = getJavaNaming().toJavaClassName(name);
1579 }
1580
1581 String setName = "set" + name;
1582 if (name.indexOf("Has") == -1) {
1583 if (type instanceof JCollectionType) {
1584
1585 int listLocat = name.lastIndexOf("List");
1586 String tempName = name;
1587 if (listLocat != -1) {
1588 tempName = tempName.substring(0, listLocat);
1589 }
1590 String methodName = getJavaNaming().toJavaClassName(tempName);
1591 methodName = "get" + methodName;
1592 JMethod method = jclass.getMethod(methodName, 0);
1593
1594 if (method == null) {
1595 continue;
1596 }
1597
1598 String componentName = method.getReturnType().getName();
1599
1600 jsc.add(temp.getName());
1601 jsc.append(" = RandomHelper.getRandom(");
1602 jsc.append(temp.getName());
1603 jsc.append(", ");
1604 jsc.append(componentName);
1605 jsc.append(".class);");
1606 } else if (type.isPrimitive()) {
1607
1608 jsc.add(setName);
1609 jsc.append("(RandomHelper.getRandom(");
1610 jsc.append(temp.getName());
1611 jsc.append("));");
1612 } else if (type.isArray()) {
1613
1614 jsc.add(setName);
1615 jsc.append("((");
1616 jsc.append(type.toString());
1617 jsc.append(")RandomHelper.getRandom(");
1618 jsc.append(temp.getName());
1619
1620 jsc.append(", java.lang.reflect.Array.class));");
1621 } else {
1622
1623 jsc.add(setName);
1624 jsc.append("((");
1625 jsc.append(type.getName());
1626 jsc.append(")RandomHelper.getRandom(");
1627 jsc.append(temp.getName());
1628 jsc.append(", ");
1629 jsc.append(type.getName());
1630 jsc.append(".class));");
1631 }
1632 jsc.add("");
1633 }
1634 }
1635 }
1636
1637
1638
1639
1640
1641
1642
1643 private void createDumpFields(final JClass jclass) {
1644 JMethod jMethod = new JMethod("dumpFields", SGTypes.STRING,
1645 "a String representation of all of the fields for " + jclass.getName());
1646 jMethod.setComment("implementation of org.castor.xmlctf.CastorTestable");
1647 jclass.addMethod(jMethod);
1648 JSourceCode jsc = jMethod.getSourceCode();
1649 jsc.add("StringBuffer stringBuffer = new StringBuffer(\"DumpFields() for element: ");
1650 jsc.append(jclass.getName());
1651 jsc.append("\\n\");");
1652
1653 for (JField temp : jclass.getFields()) {
1654 String name = temp.getName();
1655 if ((temp.getType().isPrimitive()) || temp.getType().getName().startsWith("java.lang.")) {
1656
1657
1658 jsc.add("stringBuffer.append(\"Field ");
1659 jsc.append(name);
1660 jsc.append(":\" +");
1661 jsc.append(name);
1662 jsc.append("+\"\\n\");");
1663 } else if (temp.getType().isArray()) {
1664 jsc.add("if (");
1665 jsc.append(name);
1666 jsc.append(" != null) {");
1667 jsc.indent();
1668 jsc.add("stringBuffer.append(\"[\");");
1669 jsc.add("for (int i = 0; i < ");
1670 jsc.append(name);
1671 jsc.append(".length; i++) {");
1672 jsc.indent();
1673 jsc.add("stringBuffer.append(");
1674 jsc.append(name);
1675 jsc.append("[i] + \" \");");
1676 jsc.unindent();
1677 jsc.add("}");
1678 jsc.add("stringBuffer.append(\"]\");");
1679 jsc.unindent();
1680 jsc.add("}");
1681 } else {
1682 jsc.add("if ( (");
1683 jsc.append(name);
1684 jsc.append(" != null) && (");
1685 jsc.append(name);
1686 jsc.append(".getClass().isAssignableFrom(CastorTestable.class)))");
1687 jsc.indent();
1688 jsc.add("stringBuffer.append(((CastorTestable)");
1689 jsc.append(name);
1690 jsc.append(").dumpFields());");
1691 jsc.unindent();
1692 jsc.add("else stringBuffer.append(\"Field ");
1693 jsc.append(name);
1694 jsc.append(":\" +");
1695 jsc.append(name);
1696 jsc.append("+\"\\n\");");
1697 }
1698 jsc.add("");
1699 }
1700 jsc.add("");
1701 jsc.add("return stringBuffer.toString();");
1702 }
1703
1704
1705
1706
1707
1708
1709 private void createValidateMethods(final JClass jClass) {
1710 JMethod jMethod = null;
1711 JSourceCode jsc = null;
1712
1713
1714 jMethod = new JMethod("validate");
1715 jMethod.addException(SGTypes.VALIDATION_EXCEPTION,
1716 "if this object is an invalid instance according to the schema");
1717
1718 jClass.addMethod(jMethod);
1719 jsc = jMethod.getSourceCode();
1720 jsc.add("org.exolab.castor.xml.Validator validator = new ");
1721 jsc.append("org.exolab.castor.xml.Validator();");
1722 jsc.add("validator.validate(this);");
1723
1724
1725 jMethod = new JMethod("isValid", JType.BOOLEAN,
1726 "true if this object is valid according to the schema");
1727 jsc = jMethod.getSourceCode();
1728 jsc.add("try {");
1729 jsc.indent();
1730 jsc.add("validate();");
1731 jsc.unindent();
1732 jsc.add("} catch (org.exolab.castor.xml.ValidationException vex) {");
1733 jsc.indent();
1734 jsc.add("return false;");
1735 jsc.unindent();
1736 jsc.add("}");
1737 jsc.add("return true;");
1738 jClass.addMethod(jMethod);
1739 }
1740
1741
1742
1743
1744
1745
1746
1747
1748
1749
1750
1751
1752 private String resolveClassName(final String name, final String packageName) {
1753 if ((packageName != null) && (packageName.length() > 0)) {
1754 return packageName + "." + name;
1755 }
1756 return name;
1757 }
1758
1759
1760
1761
1762
1763
1764
1765
1766
1767
1768
1769
1770
1771
1772
1773
1774
1775
1776 private void processAppInfo(final Annotated annotated, final ClassInfo cInfo) {
1777 Enumeration<Annotation> annotations = annotated.getAnnotations();
1778 while (annotations.hasMoreElements()) {
1779 Annotation ann = annotations.nextElement();
1780 Enumeration<AppInfo> appInfos = ann.getAppInfo();
1781 while (appInfos.hasMoreElements()) {
1782 AppInfo appInfo = appInfos.nextElement();
1783 if (appInfo.hasNature(AppInfoJpaNature.class.getName())) {
1784 AppInfoJpaNature nature = new AppInfoJpaNature(appInfo);
1785 List<?> content = nature.getContent();
1786 if (content != null && !content.isEmpty()) {
1787 Iterator<?> it = content.iterator();
1788 if (it.hasNext()) {
1789 cInfo.addNature(JDOClassInfoNature.class.getName());
1790 JDOClassInfoNature cNature = new JDOClassInfoNature(cInfo);
1791 while (it.hasNext()) {
1792 Object tmpObject = it.next();
1793 if (tmpObject instanceof Table) {
1794 Table table = (Table) tmpObject;
1795 cNature.setTableName(table.getName());
1796 cNature.setAccessMode(AccessMode.valueOf("shared"));
1797 cNature.setDetachable(table.isDetachable());
1798
1799
1800 PrimaryKey pk = table.getPrimaryKey();
1801 Iterator<? extends String> pIt = pk.iterateKey();
1802 while (pIt.hasNext()) {
1803 cNature.addPrimaryKey(pIt.next());
1804 }
1805 }
1806 }
1807 }
1808 }
1809 }
1810 }
1811 }
1812 }
1813
1814
1815
1816
1817
1818
1819
1820
1821
1822
1823
1824
1825 private void processAppInfo(final Annotated annotated, final FieldInfo fInfo) {
1826 Enumeration<Annotation> annotations = annotated.getAnnotations();
1827
1828 while (annotations.hasMoreElements()) {
1829 Annotation ann = annotations.nextElement();
1830 Enumeration<AppInfo> appInfos = ann.getAppInfo();
1831 while (appInfos.hasMoreElements()) {
1832 AppInfo appInfo = appInfos.nextElement();
1833
1834 if (appInfo.hasNature(AppInfoSolrjNature.class.getName())) {
1835 AppInfoSolrjNature nature = new AppInfoSolrjNature(appInfo);
1836 Object solrjRawContent = nature.getContent();
1837 if (solrjRawContent != null) {
1838 fInfo.addNature(SolrjFieldInfoNature.class.getName());
1839 SolrjFieldInfoNature solrjNature = new SolrjFieldInfoNature(fInfo);
1840 if (solrjRawContent instanceof Field) {
1841 Field solrjField = (Field) solrjRawContent;
1842 if (StringUtils.isNotBlank(solrjField.getName())) {
1843 solrjNature.setFieldName(solrjField.getName());
1844 }
1845 }
1846 }
1847 }
1848
1849 if (appInfo.hasNature(AppInfoJpaNature.class.getName())) {
1850 AppInfoJpaNature nature = new AppInfoJpaNature(appInfo);
1851 List<?> content = nature.getContent();
1852 if (content != null && !content.isEmpty()) {
1853 Iterator<?> it = content.iterator();
1854 if (it.hasNext()) {
1855 while (it.hasNext()) {
1856 Object tmpObject = it.next();
1857 if (tmpObject instanceof Column) {
1858 fInfo.addNature(JDOFieldInfoNature.class.getName());
1859 JDOFieldInfoNature fNature = new JDOFieldInfoNature(fInfo);
1860 Column column = (Column) tmpObject;
1861 fNature.setColumnName(column.getName());
1862 fNature.setColumnType(column.getType());
1863 fNature.setReadOnly(column.isReadOnly());
1864 fNature.setDirty(false);
1865 fNature.setDirty(column.getDirty());
1866 } else if (tmpObject instanceof OneToOne) {
1867 OneToOne relation = (OneToOne) tmpObject;
1868 fInfo.addNature(JDOOneToOneNature.class.getName());
1869 JDOOneToOneNature oneNature = new JDOOneToOneNature(fInfo);
1870 oneNature.addForeignKey(relation.getName());
1871 oneNature.setDirty(relation.isDirty());
1872 oneNature.setReadOnly(relation.isReadOnly());
1873 } else if (tmpObject instanceof OneToMany) {
1874 OneToMany relation = (OneToMany) tmpObject;
1875 fInfo.addNature(JDOOneToManyNature.class.getName());
1876 JDOOneToManyNature manyNature = new JDOOneToManyNature(fInfo);
1877 manyNature.addForeignKey(relation.getName());
1878 manyNature.setDirty(relation.isDirty());
1879 manyNature.setReadOnly(relation.isReadOnly());
1880 }
1881 }
1882 }
1883 }
1884 }
1885 }
1886 }
1887 }
1888
1889
1890
1891
1892
1893
1894
1895
1896 private void processAttributes(final ExtendedBinding binding, final ComplexType complexType,
1897 final FactoryState state) {
1898 if (complexType == null) {
1899 return;
1900 }
1901
1902 Enumeration<AttributeDecl> enumeration = complexType.getAttributeDecls();
1903 XMLBindingComponent component = new XMLBindingComponent(getConfig(), getGroupNaming());
1904 if (_binding != null) {
1905 component.setBinding(_binding);
1906 }
1907
1908 while (enumeration.hasMoreElements()) {
1909 AttributeDecl attr = enumeration.nextElement();
1910
1911 component.setView(attr);
1912
1913
1914 SimpleType sType = attr.getSimpleType();
1915
1916
1917 XMLType baseXMLType = complexType.getBaseType();
1918 while (sType == null) {
1919
1920
1921 if (baseXMLType == null || !(baseXMLType instanceof ComplexType)) {
1922 break;
1923 }
1924
1925
1926
1927 final ComplexType baseComplexType = (ComplexType) baseXMLType;
1928 AttributeDecl baseAttribute = baseComplexType.getAttributeDecl(attr.getName());
1929
1930 if (baseAttribute != null) {
1931
1932 sType = baseAttribute.getSimpleType();
1933 if (sType != null) {
1934 attr.setSimpleType(sType);
1935 break;
1936 }
1937 }
1938
1939
1940 baseXMLType = baseXMLType.getBaseType();
1941 }
1942
1943
1944
1945 if (sType == null && attr.getReference() != null) {
1946 SimpleType referencedSimpleType = attr.getReference().getSimpleType();
1947 attr.setSimpleType(referencedSimpleType);
1948 sType = referencedSimpleType;
1949 }
1950
1951 if (sType != null && !(SimpleTypesFactory.isBuiltInType(sType.getTypeCode()))) {
1952 if (sType.getSchema() == component.getSchema() && state.resolve(sType) == null) {
1953 if (sType.hasFacet(Facet.ENUMERATION)) {
1954 createSourceCode(component.getBinding(), sType, state.getSGStateInfo());
1955 }
1956 }
1957 }
1958
1959 FieldInfo fieldInfo =
1960 _memberFactory.createFieldInfo(component, state, getConfig().useJava50());
1961 handleField(fieldInfo, state, component);
1962 }
1963 }
1964
1965
1966
1967
1968
1969 private void processComplexType(final ComplexType complexType, final FactoryState state) {
1970 XMLBindingComponent component = new XMLBindingComponent(getConfig(), getGroupNaming());
1971 if (_binding != null) {
1972 component.setBinding(_binding);
1973 }
1974 component.setView(complexType);
1975
1976 String typeName = component.getXMLName();
1977
1978 ClassInfo classInfo = state.getClassInfo();
1979 XMLInfoNature xmlNature = new XMLInfoNature(classInfo);
1980 xmlNature.setSchemaType(new XSClass(state.getJClass(), typeName));
1981
1982
1983
1984
1985
1986 XMLType base = complexType.getBaseType();
1987
1988
1989 if (base != null) {
1990 if (base.isComplexType()) {
1991 String baseClassName = null;
1992
1993 component.setView(base);
1994
1995
1996
1997
1998
1999 if (base.getSchema() == complexType.getSchema()) {
2000 ClassInfo cInfo = state.resolve(base);
2001
2002
2003 if (cInfo == null) {
2004 JClass[] classes = createSourceCode(component, state.getSGStateInfo());
2005 cInfo = state.resolve(base);
2006 baseClassName = classes[0].getName();
2007 } else {
2008 baseClassName = cInfo.getJClass().getName();
2009 }
2010
2011 classInfo.setBaseClass(cInfo);
2012 } else {
2013
2014
2015 baseClassName = component.getQualifiedName();
2016 }
2017
2018
2019 component.setView(complexType);
2020
2021
2022
2023
2024
2025
2026
2027
2028
2029 state.getJClass().setSuperClass(baseClassName);
2030 }
2031
2032
2033 if (complexType.getContentType().getType() == ContentType.SIMPLE) {
2034 SimpleContent simpleContent = (SimpleContent) complexType.getContentType();
2035 SimpleType temp = simpleContent.getSimpleType();
2036 SimpleType baseType = (SimpleType) temp.getBaseType();
2037 XSType xsType =
2038 _typeConversion.convertType(temp, state.getPackageName(), getConfig().useJava50());
2039
2040 FieldInfo fieldInfo = null;
2041 if ((baseType != null) && extendsSimpleType(state.getJClass(), baseType, state)) {
2042 if (xsType.isEnumerated()) {
2043 fieldInfo = _memberFactory.createFieldInfoForContent(component, xsType,
2044 getConfig().useJava50());
2045 fieldInfo.setBound(false);
2046
2047 handleField(fieldInfo, state, component);
2048
2049
2050 String mname = fieldInfo.getReadMethodName();
2051 JClass jClass = state.getJClass();
2052 JMethod method = jClass.getMethod(mname, 0);
2053 jClass.removeMethod(method);
2054
2055
2056 mname = fieldInfo.getWriteMethodName();
2057 method = jClass.getMethod(mname, 0);
2058 JSourceCode jsc = method.getSourceCode();
2059 jsc.add("super.");
2060 jsc.append(mname);
2061 jsc.append("(this.");
2062 jsc.append(fieldInfo.getName());
2063 jsc.append(".toString());");
2064 }
2065
2066
2067 } else {
2068
2069 while (temp.getBaseType() != null && !temp.isBuiltInType()) {
2070 temp = (SimpleType) temp.getBaseType();
2071 }
2072
2073 xsType =
2074 _typeConversion.convertType(temp, state.getPackageName(), getConfig().useJava50());
2075 fieldInfo =
2076 _memberFactory.createFieldInfoForContent(component, xsType, getConfig().useJava50());
2077 handleField(fieldInfo, state, component);
2078 }
2079 }
2080 }
2081
2082
2083
2084
2085
2086
2087 if (!state.isCreateGroupItem()) {
2088 processAttributes(component.getBinding(), complexType, state);
2089
2090 component.setView(complexType);
2091 if (complexType.getContentType() == ContentType.mixed) {
2092 FieldInfo fieldInfo = _memberFactory.createFieldInfoForContent(component, new XSString(),
2093 getConfig().useJava50());
2094 handleField(fieldInfo, state, component);
2095 }
2096 }
2097
2098 processContentModel(complexType, state);
2099 }
2100
2101
2102
2103
2104
2105
2106
2107
2108 private void processContentModel(final ContentModelGroup model, final FactoryState state) {
2109
2110
2111
2112
2113 ContentModelGroup contentModel = model;
2114 Enumeration<Particle> enumeration = contentModel.enumerate();
2115
2116
2117 if (new XMLInfoNature(state.getClassInfo()).isChoice()
2118 && state.getFieldInfoForChoice() == null) {
2119 state.setFieldInfoForChoice(_memberFactory.createFieldInfoForChoiceValue());
2120 state.getFieldInfoForChoice().getMemberAndAccessorFactory()
2121 .createJavaField(state.getFieldInfoForChoice(), state.getJClass());
2122 state.getFieldInfoForChoice().getMemberAndAccessorFactory().createAccessMethods(
2123 state.getFieldInfoForChoice(), state.getJClass(), getConfig().useJava50(),
2124 getConfig().getAnnotationBuilders());
2125 }
2126
2127 FieldInfo fieldInfo = null;
2128 XMLBindingComponent component = new XMLBindingComponent(getConfig(), getGroupNaming());
2129 if (_binding != null) {
2130 component.setBinding(_binding);
2131 }
2132
2133 while (enumeration.hasMoreElements()) {
2134 Annotated annotated = enumeration.nextElement();
2135 component.setView(annotated);
2136
2137 switch (annotated.getStructureType()) {
2138 case Structure.ELEMENT:
2139 fieldInfo = _memberFactory.createFieldInfo(component, state, getConfig().useJava50());
2140
2141
2142
2143 if (contentModel.getMinOccurs() == 0) {
2144 XMLInfoNature xmlNature = new XMLInfoNature(fieldInfo);
2145 xmlNature.setRequired(false);
2146 }
2147
2148 handleField(fieldInfo, state, component);
2149 break;
2150 case Structure.GROUP:
2151 Group group = (Group) annotated;
2152
2153 if ((contentModel instanceof ComplexType) || (contentModel instanceof ModelGroup)) {
2154 if (group.getOrder() == Order.choice) {
2155 new XMLInfoNature(state.getClassInfo()).getGroupInfo().setAsChoice();
2156 } else if (group.getOrder() == Order.all) {
2157 new XMLInfoNature(state.getClassInfo()).getGroupInfo().setAsAll();
2158 } else if (group.getOrder() == Order.sequence) {
2159 new XMLInfoNature(state.getClassInfo()).getGroupInfo().setAsSequence();
2160 }
2161 }
2162
2163
2164 if (!((contentModel instanceof ComplexType) || (contentModel instanceof ModelGroup))) {
2165 if (contentModel instanceof ModelGroup) {
2166 ModelGroup mg = (ModelGroup) contentModel;
2167 if (mg.isReference()) {
2168 contentModel = mg.getReference();
2169 }
2170 }
2171
2172 if (contentModel.getParticleCount() > 0) {
2173 fieldInfo = _memberFactory.createFieldInfo(component, state.getSGStateInfo(),
2174 getConfig().useJava50());
2175 handleField(fieldInfo, state, component);
2176 }
2177 } else {
2178
2179 processContentModel(group, state);
2180 }
2181 break;
2182
2183 case Structure.MODELGROUP:
2184 ModelGroup modelgroup = (ModelGroup) annotated;
2185
2186
2187
2188 if (modelgroup.getName() != null) {
2189
2190
2191
2192 if (modelgroup.isReference()) {
2193 modelgroup = modelgroup.getReference();
2194 }
2195
2196 if (modelgroup.getParticleCount() > 0) {
2197 fieldInfo = _memberFactory.createFieldInfo(component, state.getSGStateInfo(),
2198 getConfig().useJava50());
2199 handleField(fieldInfo, state, component);
2200 }
2201 break;
2202 }
2203
2204 processContentModel(modelgroup.getContentModelGroup(), state);
2205 break;
2206
2207 case Structure.WILDCARD:
2208 Wildcard wildcard = (Wildcard) annotated;
2209 FieldInfo fieldForAny =
2210 _memberFactory.createFieldInfoForAny(wildcard, getConfig().useJava50());
2211 handleField(fieldForAny, state, component);
2212 break;
2213
2214 default:
2215 break;
2216 }
2217 }
2218
2219 }
2220
2221
2222
2223
2224
2225
2226
2227
2228
2229
2230 private void processEnumeration(final ExtendedBinding binding, final SimpleType simpleType,
2231 final FactoryState state) {
2232
2233 if (getConfig().useEnumeratedTypeInterface()) {
2234 state.getJClass().addInterface(ENUM_ACCESS_INTERFACE);
2235 }
2236
2237 switch (_enumerationType) {
2238 case BASE_TYPE_ENUMERATION:
2239 processEnumerationAsBaseType(binding, simpleType, state);
2240 break;
2241 default:
2242 processEnumerationAsNewObject(binding, simpleType, state);
2243 break;
2244 }
2245 }
2246
2247
2248
2249
2250
2251
2252
2253
2254
2255
2256 private void processEnumerationAsNewObject(final ExtendedBinding binding,
2257 final SimpleType simpleType, final FactoryState state) {
2258 _enumerationFactory.processEnumerationAsNewObject(binding, simpleType, state);
2259 if (_testable && state.getJClass() instanceof JEnum) {
2260 createTestableMethods(state.getJClass(), state);
2261 }
2262 }
2263
2264
2265
2266
2267
2268
2269
2270
2271 private void processEnumerationAsBaseType(final ExtendedBinding binding,
2272 final SimpleType simpleType, final FactoryState state) {
2273 _enumerationFactory.processEnumerationAsBaseType(binding, simpleType, state);
2274 }
2275
2276
2277
2278
2279
2280
2281
2282
2283 private void handleField(final FieldInfo fieldInfo, final FactoryState state,
2284 final XMLBindingComponent component) {
2285 if (fieldInfo == null) {
2286 return;
2287 }
2288
2289 XMLInfoNature xmlNature = new XMLInfoNature(fieldInfo);
2290
2291 if (CLASS_METHOD_SUFFIX.equals(fieldInfo.getMethodSuffix())) {
2292 SGStateInfo sInfo = state.getSGStateInfo();
2293 if (!sInfo.getSuppressNonFatalWarnings()) {
2294 String warn = "warning a field name conflicts with \"" + CLASS_KEYWORD
2295 + "\", please use a binding file to specify " + "a different name for the "
2296 + xmlNature.getNodeTypeName() + " '" + xmlNature.getNodeName() + "'.";
2297 sInfo.getDialog().notify(warn);
2298 }
2299 } else if (CLASS_KEYWORD.equals(xmlNature.getNodeName())) {
2300 SGStateInfo sInfo = state.getSGStateInfo();
2301 if (!sInfo.getSuppressNonFatalWarnings()) {
2302 String warn = "warning a field name conflicts with \"" + CLASS_KEYWORD
2303 + "\" and is being replaced by \"clazz\". "
2304 + "You may use a binding file to specify a different " + "name for the "
2305 + xmlNature.getNodeTypeName() + " '" + xmlNature.getNodeName() + "'.";
2306 sInfo.getDialog().notify(warn);
2307 }
2308 }
2309
2310 processAppInfo(component.getAnnotated(), fieldInfo);
2311
2312 JSourceCode scInitializer = state.getJClass().getConstructor(0).getSourceCode();
2313
2314 ClassInfo base = state.getClassInfo().getBaseClass();
2315 boolean present = false;
2316 if (base != null) {
2317 switch (new XMLInfoNature(fieldInfo).getNodeType()) {
2318 case ATTRIBUTE:
2319 present = (base.getAttributeField(xmlNature.getNodeName()) != null);
2320 break;
2321 case ELEMENT:
2322 String baseNodeName = xmlNature.getNodeName();
2323
2324 if (baseNodeName != null
2325 && !(baseNodeName.equals(XMLInfo.CHOICE_NODE_NAME_ERROR_INDICATION))) {
2326
2327
2328
2329 FieldInfo inheritedFieldInfo = base.getElementField(baseNodeName);
2330
2331 if (inheritedFieldInfo != null) {
2332 String namespaceURI = xmlNature.getNamespaceURI();
2333 if (namespaceURI != null
2334 && namespaceURI.equals(new XMLInfoNature(inheritedFieldInfo).getNamespaceURI())) {
2335 present = true;
2336 }
2337 }
2338 }
2339 break;
2340 default:
2341 break;
2342 }
2343 }
2344
2345 state.getClassInfo().addFieldInfo(fieldInfo);
2346 present = present && !xmlNature.isMultivalued();
2347
2348
2349 if (!present) {
2350 if (state.getFieldInfoForChoice() != null) {
2351 if (fieldInfo != state.getFieldInfoForChoice()) {
2352 fieldInfo.setFieldInfoReference(state.getFieldInfoForChoice());
2353 }
2354 }
2355
2356 fieldInfo.getMemberAndAccessorFactory().createJavaField(fieldInfo, state.getJClass());
2357
2358 if (!fieldInfo.isTransient()) {
2359 fieldInfo.getMemberAndAccessorFactory().createAccessMethods(fieldInfo, state.getJClass(),
2360 getConfig().useJava50(), getConfig().getAnnotationBuilders());
2361 if (fieldInfo.isBound()) {
2362 state.setBoundProperties(true);
2363 }
2364 }
2365 }
2366
2367
2368 fieldInfo.getMemberAndAccessorFactory().generateInitializerCode(fieldInfo, scInitializer);
2369 }
2370
2371
2372
2373
2374
2375
2376
2377
2378
2379
2380
2381 private boolean extendsSimpleType(final JClass jClass, final SimpleType type,
2382 final FactoryState state) {
2383 String superClassName = jClass.getSuperClassQualifiedName();
2384 if (superClassName != null) {
2385 ClassInfo cInfo = state.resolve(type);
2386 if (cInfo != null) {
2387 return superClassName.equals(cInfo.getJClass().getName());
2388 }
2389 }
2390 return false;
2391 }
2392
2393 }