50
50
import static io .ballerina .xsd .core .visitor .VisitorUtils .handleMinOccurrences ;
51
51
import static io .ballerina .xsd .core .visitor .VisitorUtils .isSimpleType ;
52
52
import static io .ballerina .xsd .core .visitor .VisitorUtils .convertToCamelCase ;
53
+ import static io .ballerina .xsd .core .visitor .VisitorUtils .resolveNames ;
53
54
import static io .ballerina .xsd .core .visitor .VisitorUtils .sanitizeString ;
54
55
import static io .ballerina .xsd .core .visitor .VisitorUtils .typeGenerator ;
55
56
@@ -99,6 +100,8 @@ public class XSDVisitorImpl implements XSDVisitor {
99
100
public static final String EMPTY_STRING = "" ;
100
101
public static final String RECORD_WITH_OPEN_BRACE = "record {|" ;
101
102
public static final String REQUIRED_FIELD_NOT_FOUND_ERROR = "Required field is not found in <complexType>: '%s'" ;
103
+ public static final String ELEMENT_NAME_NOT_FOUND_ERROR = "Missing name attribute for the root element of '%s'" ;
104
+ public static final String ATTRIBUTE_NOT_FOUND_ERROR = "Required attribute is not found: '%s'" ;
102
105
public static final String ONE = "1" ;
103
106
public static final String XMLDATA_CHOICE = "@xmldata:Choice" ;
104
107
public static final String CHOICE_NAME = "ChoiceOption" ;
@@ -115,12 +118,12 @@ public class XSDVisitorImpl implements XSDVisitor {
115
118
public static final String REF = "ref" ;
116
119
117
120
private final ArrayList <String > imports = new ArrayList <>();
118
- private Map <String , String > extensions = new LinkedHashMap <>();
119
- private Map <String , String > rootElements = new LinkedHashMap <>();
121
+ private final Map <String , String > extensions = new LinkedHashMap <>();
122
+ private final Map <String , String > rootElements = new LinkedHashMap <>();
120
123
private final Map <String , String > nameResolvers = new LinkedHashMap <>();
121
- private ArrayList <String > simpleTypeNames = new ArrayList <>();
122
- private Map <String , String > nestedElements = new LinkedHashMap <>();
123
- private Map <String , ArrayList <String >> enumerationElements = new LinkedHashMap <>();
124
+ private final ArrayList <String > simpleTypeNames = new ArrayList <>();
125
+ private final Map <String , String > nestedElements = new LinkedHashMap <>();
126
+ private final Map <String , ArrayList <String >> enumerationElements = new LinkedHashMap <>();
124
127
private final List <XsdDiagnostic > diagnostics = new ArrayList <>();
125
128
private String targetNamespace ;
126
129
@@ -151,7 +154,11 @@ public String visit(Element element, boolean subElement) {
151
154
if (component .isEmpty ()) {
152
155
continue ;
153
156
}
154
- if (component .get () instanceof SimpleType ) {
157
+ if (component .get () instanceof SimpleType simpleType ) {
158
+ if (nameNode == null ) {
159
+ throw new Exception (String .format (ELEMENT_NAME_NOT_FOUND_ERROR ,
160
+ simpleType .getNode ().getNodeName ()));
161
+ }
155
162
return handleNestedSimpleTypes (builder , nameNode , component .get ());
156
163
}
157
164
}
@@ -170,7 +177,7 @@ public String visit(Element element, boolean subElement) {
170
177
} else if (typeNode != null && node .hasAttributes ()) {
171
178
handleFixedValues (node , builder , typeNode );
172
179
handleMaxOccurrences (node , builder );
173
- builder .append (nameNode .getNodeValue ());
180
+ builder .append (resolveNames ( nameNode .getNodeValue () ));
174
181
handleMinOccurrences (element , builder );
175
182
handleDefaultValues (node , builder , typeNode );
176
183
}
@@ -333,21 +340,22 @@ private Node visitNestedElements(Node node, Node nameNode, Node typeNode) throws
333
340
typeNode = nameNode ;
334
341
for (int i = 0 ; i < node .getAttributes ().getLength (); i ++) {
335
342
Node attribute = node .getAttributes ().item (i );
336
- if (attribute .getNodeName ().equals (TYPE )) {
343
+ if (attribute .getNodeName ().equals (TYPE ) || attribute . getNodeName (). equals ( REF ) ) {
337
344
typeNode = attribute ;
338
- } else if (attribute .getNodeName ().equals (REF )) {
339
- typeNode = attribute ;
340
345
}
341
346
}
342
347
}
343
348
return typeNode ;
344
349
}
345
350
346
- public String visitAttribute (Node attribute ) {
351
+ public String visitAttribute (Node attribute ) throws Exception {
347
352
StringBuilder builder = new StringBuilder ();
348
353
this .addImports (BALLERINA_XML_DATA_MODULE );
349
354
Node nameNode = attribute .getAttributes ().getNamedItem (NAME );
350
355
Node typeNode = attribute .getAttributes ().getNamedItem (TYPE );
356
+ if (nameNode == null ) {
357
+ throw new Exception (String .format (ATTRIBUTE_NOT_FOUND_ERROR , NAME ));
358
+ }
351
359
builder .append (ATTRIBUTE_ANNOTATION ).append (WHITESPACE );
352
360
Node fixedNode = attribute .getAttributes ().getNamedItem (FIXED );
353
361
Node defaultNode = attribute .getAttributes ().getNamedItem (DEFAULT );
@@ -372,11 +380,11 @@ public String visitAttribute(Node attribute) {
372
380
}
373
381
374
382
public String visitAttributeChildNodes (NodeList childNodes ) {
375
- for (int i = 0 ; i < childNodes .getLength (); i ++) {
376
- if (childNodes .item (i ).getNodeType () != Node .ELEMENT_NODE ) {
383
+
384
+ for (Node childNode : asIterable (childNodes )) {
385
+ if (childNode .getNodeType () != Node .ELEMENT_NODE ) {
377
386
continue ;
378
387
}
379
- Node childNode = childNodes .item (i );
380
388
if (childNode .getLocalName ().equals (SIMPLE_TYPE )) {
381
389
for (Node simpleTypeNode : asIterable (childNode .getChildNodes ())) {
382
390
if (simpleTypeNode .getNodeType () != Node .ELEMENT_NODE ) {
@@ -477,6 +485,9 @@ public String visitAllContent(Node node, boolean isOptional) throws Exception {
477
485
private String handleElementsWithChildNodes (Node node , StringBuilder builder ) throws Exception {
478
486
Node nameNode = node .getAttributes ().getNamedItem (NAME );
479
487
Node typeNode = node .getAttributes ().getNamedItem (TYPE );
488
+ if (nameNode == null ) {
489
+ throw new Exception (String .format (ATTRIBUTE_NOT_FOUND_ERROR , NAME ));
490
+ }
480
491
if (typeNode != null && typeNode .getNodeValue ().equals (nameNode .getNodeValue ())) {
481
492
String resolvedName = resolveTypeNameConflicts (nameNode .getNodeValue (), typeNode .getNodeValue ());
482
493
nameResolvers .put (resolvedName , nameNode .getNodeValue ());
@@ -558,25 +569,23 @@ private void processChildNodeByType(Node childNode, StringBuilder builder) throw
558
569
559
570
private void processChildChoiceNodes (NodeList childNodes , StringBuilder stringBuilder ) throws Exception {
560
571
for (Node childNode : asIterable (childNodes )) {
561
- if (childNode .getNodeType () != Node .ELEMENT_NODE ) {
562
- continue ;
563
- }
564
- if (childNode .getLocalName ().equals (ANNOTATION )) {
572
+ if (childNode .getNodeType () != Node .ELEMENT_NODE || childNode .getLocalName ().equals (ANNOTATION )) {
565
573
continue ;
566
574
}
567
575
if (childNode .getLocalName ().equals (SEQUENCE )) {
568
576
stringBuilder .append (visitSequence (childNode , true ));
569
577
} else {
570
578
stringBuilder .append (addNamespace (this , getTargetNamespace ()));
571
- Node nameNode = childNode .getAttributes ().getNamedItem (NAME );
572
- Node typeNode = childNode .getAttributes ().getNamedItem (TYPE );
573
579
if (childNode .hasChildNodes ()) {
574
580
StringBuilder childNodeBuilder = new StringBuilder ();
575
- processChildNode (false , childNode , childNodeBuilder );
581
+ processChildNode (childNode , childNodeBuilder );
576
582
}
577
- if (typeNode == null ) {
578
- typeNode = nameNode ;
583
+ Node nameNode = childNode .getAttributes ().getNamedItem (NAME );
584
+ if (nameNode == null ) {
585
+ throw new Exception (String .format (ATTRIBUTE_NOT_FOUND_ERROR , NAME ));
579
586
}
587
+ Node typeNode = childNode .getAttributes ().getNamedItem (TYPE );
588
+ typeNode = typeNode == null ? nameNode : typeNode ;
580
589
if (childNode .hasAttributes () && childNode .getAttributes ().getNamedItem (REF ) != null ) {
581
590
Node refNode = childNode .getAttributes ().getNamedItem (REF );
582
591
String derivedType = refNode .getNodeValue ().contains (COLON )
@@ -586,7 +595,7 @@ private void processChildChoiceNodes(NodeList childNodes, StringBuilder stringBu
586
595
stringBuilder .append (derivedType );
587
596
} else {
588
597
stringBuilder .append (deriveType (typeNode )).append (WHITESPACE );
589
- stringBuilder .append (nameNode == null ? deriveType ( typeNode ) : nameNode .getNodeValue ());
598
+ stringBuilder .append (nameNode .getNodeValue ());
590
599
}
591
600
stringBuilder .append (QUESTION_MARK ).append (SEMICOLON );
592
601
}
@@ -657,12 +666,12 @@ private void processAllChildNodes(boolean isOptional, NodeList childNodes,
657
666
}
658
667
}
659
668
660
- private void processChildNode (boolean isOptional , Node childNode ,
669
+ private void processChildNode (Node childNode ,
661
670
StringBuilder stringBuilder ) throws Exception {
662
671
Optional <XSDComponent > component = XSDFactory .generateComponents (childNode );
663
672
if (component .isPresent ()) {
664
673
component .get ().setSubType (true );
665
- component .get ().setOptional (isOptional );
674
+ component .get ().setOptional (false );
666
675
stringBuilder .append (addNamespace (this , getTargetNamespace ()));
667
676
stringBuilder .append (component .get ().accept (this ));
668
677
}
@@ -698,9 +707,17 @@ private void processUnionOfSimpleTypes(String nameValue, StringBuilder builder,
698
707
if (simpleTypeNode .hasAttributes () && simpleTypeNode .getAttributes ().getNamedItem (MEMBER_TYPES ) != null ) {
699
708
builder .append (addNamespace (xsdVisitor , targetNamespace ));
700
709
builder .append (PUBLIC ).append (WHITESPACE ).append (TYPE ).append (WHITESPACE );
701
- builder .append (simpleTypeNode .getParentNode ().getAttributes ().getNamedItem (NAME ).getNodeValue ());
710
+ Node nameNode = simpleTypeNode .getParentNode ().getAttributes ().getNamedItem (NAME );
711
+ if (nameNode == null ) {
712
+ throw new Exception (String .format (ATTRIBUTE_NOT_FOUND_ERROR , NAME ));
713
+ }
714
+ builder .append (nameNode .getNodeValue ());
702
715
builder .append (WHITESPACE );
703
- String unionTypes = simpleTypeNode .getAttributes ().getNamedItem (MEMBER_TYPES ).getNodeValue ();
716
+ Node memberTypesNode = simpleTypeNode .getAttributes ().getNamedItem (MEMBER_TYPES );
717
+ if (memberTypesNode == null ) {
718
+ throw new Exception (String .format (ATTRIBUTE_NOT_FOUND_ERROR , MEMBER_TYPES ));
719
+ }
720
+ String unionTypes = memberTypesNode .getNodeValue ();
704
721
String [] typesArray = unionTypes .split (WHITESPACE );
705
722
ArrayList <String > existingTypes = new ArrayList <>();
706
723
for (String type : typesArray ) {
@@ -744,14 +761,18 @@ private void processUnionOfSimpleTypes(String nameValue, StringBuilder builder,
744
761
}
745
762
}
746
763
747
- private static boolean hasEnumerations (Node simpleTypeNode , ArrayList <String > enumValues ) {
764
+ private static boolean hasEnumerations (Node simpleTypeNode , ArrayList <String > enumValues ) throws Exception {
748
765
boolean enumeration = false ;
749
766
if (simpleTypeNode .hasChildNodes ()) {
750
767
NodeList nodes = simpleTypeNode .getChildNodes ();
751
768
for (Node node : asIterable (nodes )) {
752
769
if (node .getNodeType () == Node .ELEMENT_NODE && ENUMERATION .equals (node .getLocalName ())) {
753
770
enumeration = true ;
754
- String enumValue = sanitizeString (node .getAttributes ().getNamedItem (VALUE ).getNodeValue ());
771
+ Node valueNode = node .getAttributes ().getNamedItem (VALUE );
772
+ if (valueNode == null ) {
773
+ throw new Exception (String .format (ATTRIBUTE_NOT_FOUND_ERROR , VALUE ));
774
+ }
775
+ String enumValue = sanitizeString (valueNode .getNodeValue ());
755
776
if (enumValue .equals (EMPTY_STRING )) {
756
777
continue ;
757
778
}
0 commit comments