1
2
3
4
5
6
7
8
9
10
11 package com.legstar.xsdc.gen;
12
13 import java.io.File;
14 import java.io.FileNotFoundException;
15 import java.io.FileOutputStream;
16 import java.io.IOException;
17 import java.io.OutputStream;
18 import java.io.StringWriter;
19 import java.net.URI;
20 import java.util.HashMap;
21 import java.util.Iterator;
22 import java.util.Map;
23 import java.util.Properties;
24
25 import javax.xml.namespace.QName;
26 import javax.xml.parsers.DocumentBuilder;
27 import javax.xml.parsers.DocumentBuilderFactory;
28 import javax.xml.parsers.ParserConfigurationException;
29 import javax.xml.transform.OutputKeys;
30
31 import org.apache.commons.logging.Log;
32 import org.apache.commons.logging.LogFactory;
33 import org.apache.tools.ant.BuildException;
34 import org.apache.ws.commons.schema.XmlSchema;
35 import org.apache.ws.commons.schema.XmlSchemaAll;
36 import org.apache.ws.commons.schema.XmlSchemaAnnotation;
37 import org.apache.ws.commons.schema.XmlSchemaAppInfo;
38 import org.apache.ws.commons.schema.XmlSchemaCollection;
39 import org.apache.ws.commons.schema.XmlSchemaComplexType;
40 import org.apache.ws.commons.schema.XmlSchemaElement;
41 import org.apache.ws.commons.schema.XmlSchemaFractionDigitsFacet;
42 import org.apache.ws.commons.schema.XmlSchemaImport;
43 import org.apache.ws.commons.schema.XmlSchemaLengthFacet;
44 import org.apache.ws.commons.schema.XmlSchemaObject;
45 import org.apache.ws.commons.schema.XmlSchemaObjectCollection;
46 import org.apache.ws.commons.schema.XmlSchemaPatternFacet;
47 import org.apache.ws.commons.schema.XmlSchemaSequence;
48 import org.apache.ws.commons.schema.XmlSchemaSimpleType;
49 import org.apache.ws.commons.schema.XmlSchemaSimpleTypeList;
50 import org.apache.ws.commons.schema.XmlSchemaSimpleTypeRestriction;
51 import org.apache.ws.commons.schema.XmlSchemaSimpleTypeUnion;
52 import org.apache.ws.commons.schema.XmlSchemaTotalDigitsFacet;
53 import org.apache.ws.commons.schema.XmlSchemaType;
54 import org.apache.ws.commons.schema.utils.NamespaceMap;
55 import org.apache.ws.commons.schema.utils.NamespacePrefixList;
56 import org.w3c.dom.Attr;
57 import org.w3c.dom.Comment;
58 import org.w3c.dom.Document;
59 import org.w3c.dom.Element;
60 import org.w3c.dom.Node;
61 import org.w3c.dom.NodeList;
62 import org.xml.sax.SAXException;
63
64 import com.legstar.codegen.tasks.SourceToXsdCobolTask;
65 import com.legstar.coxb.CobolMarkup;
66 import com.legstar.coxb.CobolType;
67
68
69
70
71
72
73
74
75
76 public class XsdCobolAnnotator extends SourceToXsdCobolTask {
77
78
79 private final Log _log = LogFactory.getLog(getClass());
80
81
82
83
84
85
86 private final DocumentBuilder mDb;
87
88
89 private XsdCobolTypeMap mTypeMap = new XsdCobolTypeMap();
90
91
92 private CobolNameResolver mNameResolver;
93
94
95 private Properties mOptions;
96
97
98
99
100
101 private Map < QName, QName > mRootElements;
102
103
104 private Map < String, String > mComplexTypeToJavaClassMap;
105
106
107
108
109
110 private static final String XSD_NS = "http://www.w3.org/2001/XMLSchema";
111
112
113 private static final String SOAP_NS =
114 "http://schemas.xmlsoap.org/wsdl/soap/";
115
116
117 private static final String WSDL_NS = "http://schemas.xmlsoap.org/wsdl/";
118
119
120 private static final String ADDRESSING_NS =
121 "http://schemas.xmlsoap.org/ws/2004/08/addressing";
122
123
124 private static final String NS_NS = "http://www.w3.org/2000/xmlns/";
125
126
127 private static final String COBOL_NS = "http://www.legsem.com/legstar/xml/cobol-binding-1.0.1.xsd";
128
129
130 private static final String COBOL_PFX = "cb";
131
132
133 private static final String COBOL_PARENT_ELN = "cb:cobolElements";
134
135
136 private static final String COBOL_ELN = "cb:cobolElement";
137
138
139 private static final String COBOL_PARENT_CTN = "cb:cobolComplexTypes";
140
141
142 private static final String COBOL_CTN = "cb:cobolComplexType";
143
144
145 public static final int MAX_COBOLNAME_LEN = 30;
146
147
148 private static final String OPTIONS_FILE_NAME = "xsdcoptions.properties";
149
150
151 private String mOriginalTargetNamespace;
152
153
154 private boolean mNeedNamespaceSwitch = false;
155
156
157
158
159
160
161
162 public XsdCobolAnnotator() {
163 setModel(new XsdToXsdCobolModel());
164 try {
165 DocumentBuilderFactory docFac =
166 DocumentBuilderFactory.newInstance();
167 docFac.setNamespaceAware(true);
168 mDb = docFac.newDocumentBuilder();
169 mNameResolver = new CobolNameResolver();
170 mOptions = XsdcUtil.loadFromPropFile(this.getClass(),
171 OPTIONS_FILE_NAME);
172 } catch (ParserConfigurationException e) {
173 throw (new BuildException(e));
174 } catch (CobolNameResolverException e) {
175 throw (new BuildException(e));
176 } catch (IOException e) {
177 throw (new BuildException(e));
178 }
179 }
180
181
182
183
184 public void execute() {
185 if (_log.isDebugEnabled()) {
186 _log.debug("XML Schema Cobol annotation started");
187 }
188 checkInputXsd();
189 XmlSchema schema = getSchema();
190
191 checkAllParameters(schema);
192
193 annotateSchema(schema);
194 addRootElements(schema);
195
196 OutputStream out = getOutputStream();
197
198 XmlSchemaObjectCollection items = schema.getItems();
199
200
201
202
203
204
205
206 try {
207 for (int i = 0; i < items.getCount(); i++) {
208 XmlSchemaObject obj = items.getItem(i);
209 if (obj instanceof XmlSchemaElement) {
210 annotateElement(schema, (XmlSchemaElement) obj, 1);
211 }
212 }
213 } catch (XsdCobolAnnotatorException e) {
214 throw (new BuildException(e));
215 }
216
217
218 schema.setInputEncoding("UTF-8");
219 Map < String, String > options = new HashMap < String, String >();
220 options.put(OutputKeys.INDENT, "yes");
221 options.put(OutputKeys.OMIT_XML_DECLARATION, "no");
222 schema.write(out, options);
223 if (_log.isDebugEnabled()) {
224 _log.debug("XML Schema Cobol annotation ended. Result:");
225 logSchema(schema);
226 }
227 }
228
229
230
231
232 protected void checkInputXsd() {
233
234 if (_log.isDebugEnabled()) {
235 _log.debug(" Source Xsd URI = "
236 + ((getInputXsdUri() == null) ? null
237 : getInputXsdUri().toString()));
238 }
239
240 if (getInputXsdUri() == null) {
241 throw (new BuildException(
242 "Invalid input XML schema"));
243 }
244
245
246 if (getTargetXsdFileName() == null
247 || getTargetXsdFileName().length() == 0) {
248 String targetXsdFileName = getLastSegment(getInputXsdUri());
249
250
251
252
253 int p = targetXsdFileName.lastIndexOf('.');
254 if (p > 0) {
255 String ext = targetXsdFileName.substring(
256 p, targetXsdFileName.length());
257 if (ext.compareToIgnoreCase(".xsd") != 0) {
258 targetXsdFileName += ".xsd";
259 }
260 } else {
261 targetXsdFileName += ".xsd";
262 }
263 setTargetXsdFileName(targetXsdFileName);
264 }
265 }
266
267
268
269
270
271
272
273 private String getLastSegment(final URI uri) {
274 String path = uri.getPath();
275 if (path == null || path.length() < 2) {
276 return null;
277 }
278 if ((path.charAt(path.length() - 1)) == '/') {
279 path = path.substring(0, path.length() - 1);
280 }
281 int pos = path.lastIndexOf('/');
282 if (pos < 0) {
283 return null;
284 }
285 return path.substring(++pos, path.length());
286 }
287
288
289
290
291
292
293 @SuppressWarnings("unchecked")
294 private XmlSchema getSchema() {
295
296 if (_log.isDebugEnabled()) {
297 _log.debug("getSchema started");
298 }
299
300 XmlSchemaCollection schemaCol = new XmlSchemaCollection();
301 XmlSchema schema;
302 try {
303 Document doc = mDb.parse(getInputXsdUri().toString());
304
305
306 Node root = doc.getFirstChild();
307 while (root != null && root instanceof Comment) {
308 root = root.getNextSibling();
309 }
310 if (root == null) {
311 throw new BuildException("File " + getInputXsdUri().toString()
312 + " does not contain an XML schema");
313 }
314
315
316 NodeList nodes = doc.getElementsByTagNameNS(XSD_NS, "schema");
317 if (nodes == null || nodes.getLength() == 0) {
318 throw new BuildException("File " + getInputXsdUri().toString()
319 + " does not contain an XML schema");
320 }
321 if (nodes.getLength() > 1) {
322 _log.warn("Only the first XML schema in "
323 + getInputXsdUri().toString()
324 + " will be processed");
325 }
326
327
328 schema = schemaCol.read((Element) nodes.item(0));
329
330
331
332
333
334
335
336
337
338
339 XmlSchemaObjectCollection includes = schema.getIncludes();
340 for (Iterator includedItems = includes.getIterator(); includedItems
341 .hasNext();) {
342 Object include = includedItems.next();
343 if (include instanceof XmlSchemaImport) {
344 schema = ((XmlSchemaImport) include).getSchema();
345 break;
346 }
347 }
348
349
350
351
352
353
354
355
356
357
358
359 if (root.getLocalName().compareTo("definitions") == 0
360 && root.getNamespaceURI().compareTo(WSDL_NS) == 0) {
361
362 NamespaceMap prefixmap = new NamespaceMap();
363 NamespacePrefixList npl = schema.getNamespaceContext();
364 for (int i = 0; i < npl.getDeclaredPrefixes().length; i++) {
365 prefixmap.add(npl.getDeclaredPrefixes()[i], npl
366 .getNamespaceURI(
367 npl.getDeclaredPrefixes()[i]));
368 }
369 for (int i = 0; i < root.getAttributes().getLength(); i++) {
370 Attr attribute = (Attr) root.getAttributes().item(i);
371 String namespaceURI = attribute.getNamespaceURI();
372 String value = attribute.getValue();
373 String name = attribute.getName();
374 if (name.equals("targetNamespace")
375 && schema.getTargetNamespace() == null) {
376 schema.setTargetNamespace(value);
377 } else if (namespaceURI != null
378 && namespaceURI.compareTo(NS_NS) == 0
379 && value.compareTo(SOAP_NS) != 0
380 && value.compareTo(WSDL_NS) != 0
381 && value.compareTo(ADDRESSING_NS) != 0) {
382 prefixmap.add(attribute.getLocalName(), value);
383 }
384 }
385 schema.setNamespaceContext(prefixmap);
386
387 addWsdlPartsAsRootElements(doc, schema.getTargetNamespace());
388
389 }
390
391 } catch (FileNotFoundException e) {
392 throw (new BuildException(e));
393 } catch (SAXException e) {
394 throw (new BuildException(e));
395 } catch (IOException e) {
396 throw (new BuildException(e));
397 }
398
399 if (_log.isDebugEnabled()) {
400 _log.debug("getSchema ended. Target namespace = "
401 + schema.getTargetNamespace());
402 _log.debug("XML Schema before annotations:");
403 logSchema(schema);
404 }
405 return schema;
406 }
407
408
409
410
411
412
413
414
415
416
417
418
419 protected void addWsdlPartsAsRootElements(final Document doc,
420 final String targetNamespace) {
421 NodeList nodes = doc.getElementsByTagNameNS(WSDL_NS, "part");
422 if (nodes != null) {
423 for (int i = 0; i < nodes.getLength(); i++) {
424 Element partElement = (Element) nodes.item(i);
425 String name = partElement.getAttribute("name");
426 String type = partElement.getAttribute("type");
427 if (type != null && type.length() > 0) {
428 if (type.indexOf(':') > 0) {
429 type = type.substring(type.indexOf(':') + 1);
430 }
431 if (mRootElements == null) {
432 mRootElements = new HashMap < QName, QName >();
433 }
434 mRootElements.put(
435 new QName(targetNamespace, type),
436 new QName(targetNamespace, name));
437 }
438 }
439 }
440 }
441
442
443
444
445
446
447 private void checkAllParameters(final XmlSchema schema) {
448
449
450 if (getNamespace() == null || getNamespace().length() == 0) {
451 setNamespace(schema.getTargetNamespace());
452 } else {
453
454 switchTargetNamespace(schema, getNamespace());
455 }
456
457
458
459
460
461 super.checkInput(false, false);
462
463 }
464
465
466
467
468
469
470
471
472
473
474 private void switchTargetNamespace(
475 final XmlSchema schema, final String newTargetNamespace) {
476 mOriginalTargetNamespace = schema.getTargetNamespace();
477 if (mOriginalTargetNamespace.equals(newTargetNamespace)) {
478 return;
479 }
480 mNeedNamespaceSwitch = true;
481 schema.setTargetNamespace(newTargetNamespace);
482 NamespaceMap prefixmap = new NamespaceMap();
483 NamespacePrefixList npl = schema.getNamespaceContext();
484 for (int i = 0; i < npl.getDeclaredPrefixes().length; i++) {
485 String ns = npl.getNamespaceURI(npl.getDeclaredPrefixes()[i]);
486 if (ns.equals(mOriginalTargetNamespace)) {
487 prefixmap.add(npl.getDeclaredPrefixes()[i], newTargetNamespace);
488 } else {
489 prefixmap.add(npl.getDeclaredPrefixes()[i], ns);
490 }
491 }
492 schema.setNamespaceContext(prefixmap);
493 }
494
495
496
497
498
499
500
501 private void switchNamespace(
502 final XmlSchema schema,
503 final XmlSchemaElement obj) {
504 if (obj.getQName().getNamespaceURI().equals(mOriginalTargetNamespace)) {
505 QName newQName = new QName(
506 schema.getTargetNamespace(),
507 obj.getQName().getLocalPart(),
508 obj.getQName().getPrefix());
509 obj.setQName(newQName);
510 }
511 QName typeQName = obj.getSchemaTypeName();
512 if (typeQName.getNamespaceURI().equals(mOriginalTargetNamespace)) {
513 QName newTypeQName = new QName(
514 schema.getTargetNamespace(),
515 typeQName.getLocalPart(),
516 typeQName.getPrefix());
517 obj.setSchemaTypeName(newTypeQName);
518 }
519 }
520
521
522
523
524
525
526 private void annotateSchema(final XmlSchema schema) {
527 if (_log.isDebugEnabled()) {
528 _log.debug("AnnotateSchema started");
529 }
530
531 NamespaceMap prefixmap = new NamespaceMap();
532 NamespacePrefixList npl = schema.getNamespaceContext();
533 for (int i = 0; i < npl.getDeclaredPrefixes().length; i++) {
534 prefixmap.add(npl.getDeclaredPrefixes()[i], npl.getNamespaceURI(
535 npl.getDeclaredPrefixes()[i]));
536 }
537
538
539
540
541
542
543
544
545 prefixmap.add(COBOL_PFX, COBOL_NS);
546 schema.setNamespaceContext(prefixmap);
547
548 if (_log.isDebugEnabled()) {
549 _log.debug("AnnotateSchema ended");
550 }
551
552 }
553
554
555
556
557
558
559
560
561
562 private void addRootElements(final XmlSchema schema) {
563 if (mRootElements == null) {
564 return;
565 }
566 for (QName typeName : mRootElements.keySet()) {
567 XmlSchemaType schemaType = schema.getTypeByName(typeName);
568 QName eln = mRootElements.get(typeName);
569 if (schema.getTypeByName(typeName) == null) {
570 throw (new BuildException("Root element " + eln
571 + " has unknown type " + typeName));
572 }
573
574 QName elementName = mRootElements.get(typeName);
575 XmlSchemaElement el = schema.getElementByName(elementName);
576 if (el == null) {
577 el = new XmlSchemaElement();
578 el.setQName(elementName);
579 el.setName(elementName.getLocalPart());
580 el.setSchemaTypeName(typeName);
581 el.setSchemaType(schemaType);
582 schema.getElements().add(eln, el);
583 schema.getItems().add(el);
584 }
585 }
586 }
587
588
589
590
591
592
593 private OutputStream getOutputStream() {
594 OutputStream out;
595 String outPath = getTargetDir().getPath() + File.separator
596 + getTargetXsdFileName();
597 try {
598 out = new FileOutputStream(new File(outPath));
599 return out;
600 } catch (FileNotFoundException e) {
601 throw (new BuildException(e));
602 }
603 }
604
605
606
607
608
609
610
611
612
613
614
615 public void annotateElement(
616 final XmlSchema schema,
617 final XmlSchemaElement obj,
618 final int level) throws XsdCobolAnnotatorException {
619
620
621
622
623 if (obj.getRefName() != null) {
624 return;
625 }
626 if (_log.isDebugEnabled()) {
627 _log.debug("annotate started for element = " + obj.getName());
628 }
629
630
631 Document doc = mDb.newDocument();
632 Element el = doc.createElementNS(COBOL_NS, COBOL_PARENT_ELN);
633 Element elc = doc.createElementNS(COBOL_NS, COBOL_ELN);
634 setAttributes(schema, obj, elc, level);
635 el.appendChild(elc);
636
637
638 obj.setAnnotation(createAnnotation(el));
639
640
641
642
643
644 if (obj.getSchemaType() instanceof XmlSchemaComplexType) {
645 XmlSchemaComplexType type = (XmlSchemaComplexType) obj
646 .getSchemaType();
647 annotateComplexType(schema, type, level);
648 }
649
650 if (mNeedNamespaceSwitch) {
651 switchNamespace(schema, obj);
652 }
653
654 if (_log.isDebugEnabled()) {
655 _log.debug("annotate ended for element = " + obj.getName());
656 }
657 }
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673 public void annotateComplexType(
674 final XmlSchema schema,
675 final XmlSchemaComplexType type,
676 final int level) throws XsdCobolAnnotatorException {
677 if (_log.isDebugEnabled()) {
678 _log.debug("annotate started for complex type = " + type.getName());
679 }
680
681
682
683
684
685 if (mComplexTypeToJavaClassMap != null) {
686 String javaClassName =
687 mComplexTypeToJavaClassMap.get(type.getName());
688 if (javaClassName != null) {
689 if (_log.isDebugEnabled()) {
690 _log.debug(" java class name = " + javaClassName);
691 }
692
693 Document doc = mDb.newDocument();
694 Element el = doc.createElementNS(COBOL_NS, COBOL_PARENT_CTN);
695 Element elc = doc.createElementNS(COBOL_NS, COBOL_CTN);
696 elc.setAttribute(CobolMarkup.JAVA_CLASS_NAME, javaClassName);
697 el.appendChild(elc);
698
699
700 type.setAnnotation(createAnnotation(el));
701 }
702 }
703
704 annotateComplexTypeElements(schema, type, level);
705
706 if (_log.isDebugEnabled()) {
707 _log.debug("annotate ended for complex type = " + type.getName());
708 }
709 }
710
711
712
713
714
715
716
717
718
719
720
721 protected void annotateComplexTypeElements(
722 final XmlSchema schema,
723 final XmlSchemaComplexType type,
724 final int level) throws XsdCobolAnnotatorException {
725
726
727 if (type.getParticle() != null) {
728
729 if (type.getParticle().getMaxOccurs() > 1) {
730
731 _log
732 .warn("Complex type "
733 + type.getName()
734 + " contains a multi-occurence particle that is ignored");
735 }
736
737 if (type.getParticle() instanceof XmlSchemaSequence) {
738 XmlSchemaSequence sequence = (XmlSchemaSequence) type
739 .getParticle();
740 annotateCollectionElements(schema, sequence.getItems(), level);
741 return;
742
743 } else if (type.getParticle() instanceof XmlSchemaAll) {
744 XmlSchemaAll all = (XmlSchemaAll) type.getParticle();
745 annotateCollectionElements(schema, all.getItems(), level);
746 return;
747 }
748 }
749
750
751
752 _log.warn("Complex type " + type.getName()
753 + " does not contain a sequence or all element");
754 }
755
756
757
758
759
760
761
762
763
764
765
766 protected void annotateCollectionElements(
767 final XmlSchema schema,
768 final XmlSchemaObjectCollection items,
769 final int level) throws XsdCobolAnnotatorException {
770
771
772 for (int i = 0; i < items.getCount(); i++) {
773 XmlSchemaObject element = items.getItem(i);
774 if (element instanceof XmlSchemaElement) {
775 annotateElement(schema, (XmlSchemaElement) element,
776 level + 2);
777 }
778 }
779 }
780
781
782
783
784
785
786
787
788 private XmlSchemaAnnotation createAnnotation(final Element el) {
789 XmlSchemaAnnotation annotation = new XmlSchemaAnnotation();
790 XmlSchemaAppInfo appInfo = new XmlSchemaAppInfo();
791 NodeList markup = el.getChildNodes();
792 appInfo.setMarkup(markup);
793 annotation.getItems().add(appInfo);
794 return annotation;
795 }
796
797
798
799
800
801
802
803
804
805
806
807
808
809 private void setAttributes(
810 final XmlSchema schema,
811 final XmlSchemaElement obj,
812 final Element elc,
813 final int level) throws XsdCobolAnnotatorException {
814
815 if (_log.isDebugEnabled()) {
816 _log.debug("setAttributes started for element = "
817 + obj.getName());
818 _log.debug(" XmlSchemaElement QName = "
819 + obj.getQName());
820 _log.debug(" XmlSchemaElement SchemaType = "
821 + obj.getSchemaType());
822 _log.debug(" XmlSchemaElement SchemaTypeName = "
823 + obj.getSchemaTypeName());
824 _log.debug(" XmlSchemaElement MaxOccurs = "
825 + obj.getMaxOccurs());
826 _log.debug(" XmlSchemaElement MinOccurs = "
827 + obj.getMinOccurs());
828 _log.debug(" XmlSchemaElement RefName = "
829 + obj.getRefName());
830 _log.debug(" XmlSchemaElement DefaultValue = "
831 + obj.getDefaultValue());
832 _log.debug(" XmlSchemaElement FixedValue = "
833 + obj.getFixedValue());
834 }
835
836
837 elc.setAttribute(CobolMarkup.LEVEL_NUMBER, Integer.toString(level));
838 elc.setAttribute(CobolMarkup.COBOL_NAME, getCobolName(obj.getName()));
839
840 if (_log.isDebugEnabled()) {
841 _log.debug(" Cobol level = "
842 + level);
843 _log.debug(" Cobol name = "
844 + elc.getAttribute(CobolMarkup.COBOL_NAME));
845 }
846
847
848
849
850
851
852
853
854
855
856
857
858 if (obj.getMaxOccurs() > 1) {
859 if (obj.getMaxOccurs() > Short.MAX_VALUE) {
860 String defaultMaxOccurs = XsdcUtil.getStringOption(mOptions,
861 "default.max.occurs");
862 elc.setAttribute(CobolMarkup.MAX_OCCURS, defaultMaxOccurs);
863 _log.warn("Max occurs for element " + obj.getName()
864 + " has been set to default value " + defaultMaxOccurs);
865 } else {
866 elc.setAttribute(CobolMarkup.MAX_OCCURS,
867 Long.toString(obj.getMaxOccurs()));
868 }
869
870 elc.setAttribute(CobolMarkup.MIN_OCCURS,
871 Long.toString(obj.getMinOccurs()));
872
873 if (_log.isDebugEnabled()) {
874 _log.debug(" Cobol minOccurs = "
875 + elc.getAttribute(CobolMarkup.MIN_OCCURS));
876 _log.debug(" Cobol maxOccurs = "
877 + elc.getAttribute(CobolMarkup.MAX_OCCURS));
878 }
879 }
880
881
882 if (obj.getSchemaType() instanceof XmlSchemaSimpleType) {
883
884 setSimpleTypeAttributes(schema,
885 (XmlSchemaSimpleType) obj.getSchemaType(), elc);
886
887 } else if (obj.getSchemaType() instanceof XmlSchemaComplexType) {
888
889 setComplexTypeAttributes(
890 schema, (XmlSchemaComplexType) obj.getSchemaType(), elc,
891 level);
892 }
893 if (_log.isDebugEnabled()) {
894 _log.debug("setAttributes ended for element = " + obj.getName());
895 }
896 }
897
898
899
900
901
902
903
904
905
906 private void setSimpleTypeAttributes(
907 final XmlSchema schema,
908 final XmlSchemaSimpleType type,
909 final Element elc) throws XsdCobolAnnotatorException {
910
911 if (_log.isDebugEnabled()) {
912 _log.debug("setSimpleTypeAttributes started for type = "
913 + type.getName());
914 _log.debug(" XmlSchemaType QName = "
915 + type.getQName());
916 _log.debug(" XmlSchemaType BaseSchemaType = "
917 + type.getBaseSchemaType());
918 _log.debug(" XmlSchemaType DataType = "
919 + type.getDataType());
920 _log.debug(" XmlSchemaType DeriveBy = "
921 + type.getDeriveBy());
922 }
923
924
925
926
927 QName primitiveType = getPrimitiveType(schema, type);
928
929
930 CobolType cobolType = mTypeMap.get(primitiveType);
931 if (cobolType == null) {
932 throw new XsdCobolAnnotatorException(
933 "Unsupported XML Schema type " + type.getQName());
934 }
935 elc.setAttribute(CobolMarkup.TYPE, cobolType.name());
936 if (_log.isDebugEnabled()) {
937 _log.debug(" Cobol type = "
938 + elc.getAttribute(CobolMarkup.TYPE));
939 }
940
941
942
943
944
945
946 if (type.getContent() instanceof XmlSchemaSimpleTypeList) {
947 elc.setAttribute(CobolMarkup.MIN_OCCURS, "1");
948 elc.setAttribute(CobolMarkup.MAX_OCCURS,
949 XsdcUtil.getStringOption(mOptions, "default.max.occurs"));
950 if (_log.isDebugEnabled()) {
951 _log.debug(" Cobol minOccurs = "
952 + elc.getAttribute(CobolMarkup.MIN_OCCURS));
953 _log.debug(" Cobol maxOccurs = "
954 + elc.getAttribute(CobolMarkup.MAX_OCCURS));
955 }
956 }
957
958
959 XsdFacets facets = new XsdFacets();
960 getFacets(schema, type, facets);
961
962
963 switch (cobolType) {
964 case ALPHANUMERIC_ITEM:
965 setAlphaNumericAttributes(primitiveType, facets, elc);
966 break;
967 case BINARY_ITEM:
968 setBinaryAttributes(primitiveType, facets, elc);
969 break;
970 case PACKED_DECIMAL_ITEM:
971 setDecimalAttributes(primitiveType, facets, elc);
972 break;
973 case SINGLE_FLOAT_ITEM:
974 setSingleFloatAttributes(primitiveType, elc);
975 break;
976 case DOUBLE_FLOAT_ITEM:
977 setDoubleFloatAttributes(primitiveType, elc);
978 break;
979 case OCTET_STREAM_ITEM:
980 setOctetStreamAttributes(primitiveType, facets, elc);
981 break;
982 default:
983 throw new XsdCobolAnnotatorException(
984 "Cobol type inferred is invalid");
985 }
986 if (_log.isDebugEnabled()) {
987 _log.debug("setSimpleTypeAttributes ended for type = "
988 + type.getName());
989 }
990 }
991
992
993
994
995
996
997
998
999
1000
1001 private void setComplexTypeAttributes(
1002 final XmlSchema schema,
1003 final XmlSchemaComplexType type,
1004 final Element elc,
1005 final int level) throws XsdCobolAnnotatorException {
1006
1007 if (_log.isDebugEnabled()) {
1008 _log.debug("setComplexTypeAttributes started for type = "
1009 + type.getName());
1010 _log.debug(" XmlSchemaType QName = "
1011 + type.getQName());
1012 }
1013
1014 elc.setAttribute(CobolMarkup.TYPE, CobolType.GROUP_ITEM.name());
1015 if (_log.isDebugEnabled()) {
1016 _log.debug(" Cobol type = "
1017 + elc.getAttribute(CobolMarkup.TYPE));
1018 }
1019
1020 if (_log.isDebugEnabled()) {
1021 _log.debug("setComplexTypeAttributes ended for type = "
1022 + type.getQName());
1023 }
1024 }
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035 private void setAlphaNumericAttributes(
1036 final QName primitiveType,
1037 final XsdFacets facets,
1038 final Element elc) throws XsdCobolAnnotatorException {
1039
1040 if (_log.isDebugEnabled()) {
1041 _log.debug("setAlphaNumericAttributes started for type = "
1042 + primitiveType.getLocalPart());
1043 }
1044
1045
1046
1047
1048
1049 int byteLength = facets.getLength();
1050 if (byteLength < 0) {
1051 byteLength = XsdcUtil.getIntOption(mOptions,
1052 "default.alphanumeric.len");
1053 _log.warn("Byte length for element "
1054 + elc.getAttribute(CobolMarkup.COBOL_NAME)
1055 + " has been set to default value " + byteLength);
1056 }
1057
1058
1059
1060
1061
1062
1063 elc.setAttribute(CobolMarkup.PICTURE, "X("
1064 + Integer.toString(byteLength) + ")");
1065 elc.setAttribute(CobolMarkup.USAGE, "DISPLAY");
1066
1067 if (_log.isDebugEnabled()) {
1068 _log.debug("setAlphaNumericAttributes ended for type = "
1069 + primitiveType.getLocalPart());
1070 _log.debug(" Cobol picture = "
1071 + elc.getAttribute(CobolMarkup.PICTURE));
1072 _log.debug(" Cobol usage = "
1073 + elc.getAttribute(CobolMarkup.USAGE));
1074 }
1075 }
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085 private void setOctetStreamAttributes(
1086 final QName primitiveType,
1087 final XsdFacets facets,
1088 final Element elc) throws XsdCobolAnnotatorException {
1089
1090 if (_log.isDebugEnabled()) {
1091 _log.debug("setOctetStreamAttributes started for type = "
1092 + primitiveType.getLocalPart());
1093 }
1094
1095
1096
1097
1098 int byteLength = facets.getLength();
1099 if (byteLength < 0) {
1100 byteLength = XsdcUtil.getIntOption(mOptions,
1101 "default.octet.stream.len");
1102 }
1103
1104 elc.setAttribute(CobolMarkup.PICTURE, "X("
1105 + Integer.toString(byteLength) + ")");
1106 elc.setAttribute(CobolMarkup.USAGE, "DISPLAY");
1107
1108 if (_log.isDebugEnabled()) {
1109 _log.debug("setOctetStreamAttributes ended for type = "
1110 + primitiveType.getLocalPart());
1111 _log.debug(" Cobol picture = "
1112 + elc.getAttribute(CobolMarkup.PICTURE));
1113 _log.debug(" Cobol usage = "
1114 + elc.getAttribute(CobolMarkup.USAGE));
1115 }
1116 }
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127 private void setBinaryAttributes(
1128 final QName primitiveType,
1129 final XsdFacets facets,
1130 final Element elc) throws XsdCobolAnnotatorException {
1131
1132 if (_log.isDebugEnabled()) {
1133 _log.debug("setBinaryAttributes started for type = "
1134 + primitiveType.getLocalPart());
1135 }
1136
1137
1138
1139
1140 int totalDigits = facets.getTotalDigits();
1141 if (totalDigits < 0) {
1142 totalDigits = XsdcUtil.getIntOption(mOptions,
1143 "default.int.total.digits");
1144 if (primitiveType.getLocalPart().equals("boolean")) {
1145 totalDigits = XsdcUtil.getIntOption(mOptions,
1146 "default.bool.total.digits");
1147 } else if (primitiveType.getLocalPart().equals("unsignedShort")) {
1148 totalDigits = XsdcUtil.getIntOption(mOptions,
1149 "default.short.total.digits");
1150 } else if (primitiveType.getLocalPart().equals("unsignedLong")) {
1151 totalDigits = XsdcUtil.getIntOption(mOptions,
1152 "default.long.total.digits");
1153 } else if (primitiveType.getLocalPart().equals("long")) {
1154 totalDigits = XsdcUtil.getIntOption(mOptions,
1155 "default.long.total.digits");
1156 } else if (primitiveType.getLocalPart().equals("short")) {
1157 totalDigits = XsdcUtil.getIntOption(mOptions,
1158 "default.short.total.digits");
1159 }
1160
1161
1162
1163
1164 elc.setAttribute(CobolMarkup.USAGE, "COMP-5");
1165 } else {
1166 elc.setAttribute(CobolMarkup.USAGE, "BINARY");
1167 }
1168
1169
1170 boolean signed = true;
1171 if (primitiveType.getLocalPart().equals("boolean")
1172 || primitiveType.getLocalPart().equals("positiveInteger")
1173 || primitiveType.getLocalPart().equals("nonNegativeInteger")
1174 || primitiveType.getLocalPart().equals("unsignedShort")
1175 || primitiveType.getLocalPart().equals("unsignedLong")
1176 || primitiveType.getLocalPart().equals("unsignedInt")) {
1177 signed = false;
1178 }
1179
1180
1181
1182
1183
1184 elc.setAttribute(CobolMarkup.PICTURE, "9("
1185 + Integer.toString(totalDigits) + ")");
1186 elc.setAttribute(CobolMarkup.TOTAL_DIGITS,
1187 Integer.toString(totalDigits));
1188 elc.setAttribute(CobolMarkup.IS_SIGNED, Boolean.toString(signed));
1189
1190 if (_log.isDebugEnabled()) {
1191 _log.debug("setBinaryAttributes ended for type = "
1192 + primitiveType.getLocalPart());
1193 _log.debug(" Cobol picture = "
1194 + elc.getAttribute(CobolMarkup.PICTURE));
1195 _log.debug(" Cobol usage = "
1196 + elc.getAttribute(CobolMarkup.USAGE));
1197 _log.debug(" Cobol totalDigits = "
1198 + elc.getAttribute(CobolMarkup.TOTAL_DIGITS));
1199 _log.debug(" Cobol isSigned = "
1200 + elc.getAttribute(CobolMarkup.IS_SIGNED));
1201 }
1202 }
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214 private void setDecimalAttributes(
1215 final QName primitiveType,
1216 final XsdFacets facets,
1217 final Element elc) throws XsdCobolAnnotatorException {
1218
1219 if (_log.isDebugEnabled()) {
1220 _log.debug("setDecimalAttributes started for type = "
1221 + primitiveType.getLocalPart());
1222 }
1223
1224
1225
1226
1227
1228 int totalDigits = facets.getTotalDigits();
1229 if (totalDigits < 0) {
1230 totalDigits = XsdcUtil.getIntOption(mOptions,
1231 "default.dec.total.digits");
1232 }
1233 int fractionDigits = facets.getFractionDigits();
1234 if (fractionDigits < 0) {
1235 fractionDigits = XsdcUtil.getIntOption(mOptions,
1236 "default.dec.frac.digits");
1237 }
1238
1239
1240 boolean signed = true;
1241
1242 elc.setAttribute(CobolMarkup.PICTURE, "9("
1243 + Integer.toString(totalDigits - fractionDigits)
1244 + ((fractionDigits > 0)
1245 ? ")V9(" + Integer.toString(fractionDigits) : "")
1246 + ")");
1247 elc.setAttribute(CobolMarkup.TOTAL_DIGITS,
1248 Integer.toString(totalDigits));
1249 elc.setAttribute(CobolMarkup.FRACTION_DIGITS,
1250 Integer.toString(fractionDigits));
1251 elc.setAttribute(CobolMarkup.USAGE, "COMP-3");
1252 elc.setAttribute(CobolMarkup.IS_SIGNED, Boolean.toString(signed));
1253
1254 if (_log.isDebugEnabled()) {
1255 _log.debug("setDecimalAttributes ended for type = "
1256 + primitiveType.getLocalPart());
1257 _log.debug(" Cobol picture = "
1258 + elc.getAttribute(CobolMarkup.PICTURE));
1259 _log.debug(" Cobol usage = "
1260 + elc.getAttribute(CobolMarkup.USAGE));
1261 _log.debug(" Cobol totalDigits = "
1262 + elc.getAttribute(CobolMarkup.TOTAL_DIGITS));
1263 _log.debug(" Cobol fractionDigits = "
1264 + elc.getAttribute(CobolMarkup.FRACTION_DIGITS));
1265 _log.debug(" Cobol isSigned = "
1266 + elc.getAttribute(CobolMarkup.IS_SIGNED));
1267 }
1268 }
1269
1270
1271
1272
1273
1274
1275
1276
1277 private void setSingleFloatAttributes(
1278 final QName primitiveType,
1279 final Element elc) throws XsdCobolAnnotatorException {
1280
1281 if (_log.isDebugEnabled()) {
1282 _log.debug("setSingleFloatAttributes started for type = "
1283 + primitiveType.getLocalPart());
1284 }
1285
1286 elc.setAttribute(CobolMarkup.USAGE, "COMP-1");
1287
1288 if (_log.isDebugEnabled()) {
1289 _log.debug("setSingleFloatAttributes ended for type = "
1290 + primitiveType.getLocalPart());
1291 _log.debug(" Cobol usage = "
1292 + elc.getAttribute(CobolMarkup.USAGE));
1293 }
1294 }
1295
1296
1297
1298
1299
1300
1301
1302
1303 private void setDoubleFloatAttributes(
1304 final QName primitiveType,
1305 final Element elc) throws XsdCobolAnnotatorException {
1306
1307 if (_log.isDebugEnabled()) {
1308 _log.debug("setDoubleFloatAttributes started for type = "
1309 + primitiveType.getLocalPart());
1310 }
1311
1312 elc.setAttribute(CobolMarkup.USAGE, "COMP-2");
1313
1314 if (_log.isDebugEnabled()) {
1315 _log.debug("setDoubleFloatAttributes ended for type = "
1316 + primitiveType.getLocalPart());
1317 _log.debug(" Cobol usage = "
1318 + elc.getAttribute(CobolMarkup.USAGE));
1319 }
1320 }
1321
1322
1323
1324
1325
1326
1327
1328
1329
1330
1331 private QName getPrimitiveType(
1332 final XmlSchema schema,
1333 final XmlSchemaSimpleType type) throws XsdCobolAnnotatorException {
1334
1335 if (_log.isDebugEnabled()) {
1336 _log.debug("getPrimitiveType started for type = " + type.getName());
1337 }
1338
1339 QName typeName = type.getQName();
1340 if (typeName != null && XSD_NS.equals(typeName.getNamespaceURI())) {
1341 if (_log.isDebugEnabled()) {
1342 _log.debug("getPrimitiveType ended for type = "
1343 + type.getName());
1344 _log.debug(" PrimitiveType = " + typeName);
1345 }
1346 return typeName;
1347 }
1348 if (type.getContent() != null) {
1349 if (type.getContent() instanceof XmlSchemaSimpleTypeRestriction) {
1350 XmlSchemaSimpleTypeRestriction restriction =
1351 (XmlSchemaSimpleTypeRestriction) type.getContent();
1352
1353
1354
1355
1356
1357 if (restriction.getBaseType() == null) {
1358 typeName = restriction.getBaseTypeName();
1359 if (typeName != null) {
1360 if (XSD_NS.equals(typeName.getNamespaceURI())) {
1361 if (_log.isDebugEnabled()) {
1362 _log.debug("getPrimitiveType ended for type = "
1363 + type.getName());
1364 _log.debug(" PrimitiveType = " + typeName);
1365 }
1366 return typeName;
1367 }
1368
1369
1370
1371
1372
1373
1374 XmlSchemaType restrictionBaseType =
1375 schema.getTypeByName(typeName);
1376 if (restrictionBaseType != null
1377 && restrictionBaseType
1378 instanceof XmlSchemaSimpleType) {
1379 return getPrimitiveType(schema,
1380 (XmlSchemaSimpleType) restrictionBaseType);
1381 }
1382 }
1383 } else {
1384 return getPrimitiveType(schema, restriction.getBaseType());
1385 }
1386
1387 } else if (type.getContent() instanceof XmlSchemaSimpleTypeList) {
1388
1389 XmlSchemaSimpleTypeList listType =
1390 (XmlSchemaSimpleTypeList) type.getContent();
1391 return getPrimitiveType(schema, listType.getItemType());
1392
1393 } else if (type.getContent() instanceof XmlSchemaSimpleTypeUnion) {
1394 _log.warn(type.getName()
1395 + " is a union. Processing first type in the union.");
1396 XmlSchemaSimpleTypeUnion simpleUnion = (XmlSchemaSimpleTypeUnion) type
1397 .getContent();
1398 return getPrimitiveType(schema,
1399 (XmlSchemaSimpleType) simpleUnion.getBaseTypes()
1400 .getItem(0));
1401 }
1402 }
1403 throw new XsdCobolAnnotatorException(
1404 "Cannot infer primitive type for " + typeName);
1405 }
1406
1407
1408
1409
1410
1411
1412
1413
1414
1415
1416
1417 @SuppressWarnings("unchecked")
1418 private void getFacets(
1419 final XmlSchema schema,
1420 final XmlSchemaSimpleType type,
1421 final XsdFacets facets) throws XsdCobolAnnotatorException {
1422
1423
1424 if (type.getContent() == null) {
1425 return;
1426 }
1427 if (_log.isDebugEnabled()) {
1428 _log.debug("getFacets started for type = " + type.getName());
1429 }
1430
1431 if (type.getContent() instanceof XmlSchemaSimpleTypeRestriction) {
1432 XmlSchemaSimpleTypeRestriction restriction =
1433 (XmlSchemaSimpleTypeRestriction) type.getContent();
1434 if (restriction.getFacets() != null) {
1435 XmlSchemaObjectCollection collection = restriction.getFacets();
1436 for (Iterator < XmlSchemaObject > i =
1437 collection.getIterator(); i.hasNext();) {
1438 XmlSchemaObject facet = i.next();
1439
1440
1441
1442
1443 if (facet instanceof XmlSchemaLengthFacet) {
1444 XmlSchemaLengthFacet xsef =
1445 (XmlSchemaLengthFacet) facet;
1446 if (facets.getLength() == -1) {
1447 facets.setLength(
1448 new Integer((String) xsef.getValue()));
1449 }
1450 }
1451 if (facet instanceof XmlSchemaPatternFacet) {
1452 XmlSchemaPatternFacet xsef =
1453 (XmlSchemaPatternFacet) facet;
1454 if (facets.getPattern() == null) {
1455 facets.setPattern((String) xsef.getValue());
1456 }
1457 }
1458 if (facet instanceof XmlSchemaTotalDigitsFacet) {
1459 XmlSchemaTotalDigitsFacet xsef =
1460 (XmlSchemaTotalDigitsFacet) facet;
1461 if (facets.getTotalDigits() == -1) {
1462 facets.setTotalDigits(
1463 new Integer((String) xsef.getValue()));
1464 }
1465 }
1466 if (facet instanceof XmlSchemaFractionDigitsFacet) {
1467 XmlSchemaFractionDigitsFacet xsef =
1468 (XmlSchemaFractionDigitsFacet) facet;
1469 if (facets.getFractionDigits() == -1) {
1470 facets.setFractionDigits(
1471 new Integer((String) xsef.getValue()));
1472 }
1473 }
1474 }
1475 }
1476
1477
1478
1479
1480
1481 if (restriction.getBaseType() == null) {
1482 QName typeName = restriction.getBaseTypeName();
1483 if (typeName != null) {
1484 if (XSD_NS.equals(typeName.getNamespaceURI())) {
1485 return;
1486 }
1487 getFacets(schema,
1488 (XmlSchemaSimpleType) schema.getTypeByName(
1489 typeName), facets);
1490 }
1491 } else {
1492 getFacets(schema, restriction.getBaseType(), facets);
1493 }
1494 }
1495
1496 if (_log.isDebugEnabled()) {
1497 _log.debug("getFacets ended for type = " + type.getName());
1498 _log.debug(" Length facet = " + facets.getLength());
1499 _log.debug(" TotalDigits facet = " + facets.getTotalDigits());
1500 _log.debug(" FractionDigits facet = "
1501 + facets.getFractionDigits());
1502 _log.debug(" Pattern facet = " + facets.getPattern());
1503 }
1504 }
1505
1506
1507
1508
1509
1510
1511
1512
1513 public String getCobolName(
1514 final String xsdName) throws XsdCobolAnnotatorException {
1515 try {
1516 return mNameResolver.getName(xsdName);
1517 } catch (CobolNameResolverException e) {
1518 throw new XsdCobolAnnotatorException(e);
1519 }
1520 }
1521
1522
1523
1524
1525 public URI getInputXsdUri() {
1526 return getModel().getInputXsdUri();
1527 }
1528
1529
1530
1531
1532 public void setInputXsdUri(
1533 final URI xsdUri) {
1534 getModel().setInputXsdUri(xsdUri);
1535 }
1536
1537
1538
1539
1540
1541 public Map < QName, QName > getRootElements() {
1542 return mRootElements;
1543 }
1544
1545
1546
1547
1548
1549 public void setRootElements(final Map < QName, QName > rootElements) {
1550 mRootElements = rootElements;
1551 }
1552
1553
1554
1555
1556 public Map < String, String > getComplexTypeToJavaClassMap() {
1557 return mComplexTypeToJavaClassMap;
1558 }
1559
1560
1561
1562
1563
1564 public void setComplexTypeToJavaClassMap(
1565 final Map < String, String > complexTypeToJavaClassMap) {
1566 mComplexTypeToJavaClassMap = complexTypeToJavaClassMap;
1567 }
1568
1569
1570
1571
1572 public XsdToXsdCobolModel getModel() {
1573 return (XsdToXsdCobolModel) super.getModel();
1574 }
1575
1576
1577
1578
1579
1580
1581 protected void logSchema(final XmlSchema schema) {
1582 StringWriter sw = new StringWriter();
1583 schema.write(sw);
1584 _log.debug(sw.toString());
1585
1586 }
1587
1588 }