1515 */
1616package org .raml .v2 .internal .impl .v10 .phase ;
1717
18+ import com .fasterxml .jackson .core .JsonParser ;
19+ import com .fasterxml .jackson .databind .JsonNode ;
20+ import com .fasterxml .jackson .databind .ObjectMapper ;
21+ import com .google .common .base .Predicate ;
22+ import com .google .common .collect .FluentIterable ;
1823import org .apache .ws .commons .schema .XmlSchema ;
1924import org .raml .v2 .api .loader .ResourceLoader ;
2025import org .raml .v2 .internal .impl .commons .model .factory .TypeDeclarationModelFactory ;
26+ import org .raml .v2 .internal .impl .commons .model .type .TypeDeclaration ;
27+ import org .raml .v2 .internal .impl .commons .model .type .UnionTypeDeclaration ;
2128import org .raml .v2 .internal .impl .commons .nodes .ExampleDeclarationNode ;
2229import org .raml .v2 .internal .impl .commons .nodes .TypeDeclarationNode ;
30+ import org .raml .v2 .internal .impl .commons .nodes .TypeExpressionNode ;
2331import org .raml .v2 .internal .impl .commons .type .JsonSchemaExternalType ;
2432import org .raml .v2 .internal .impl .commons .type .ResolvedType ;
2533import org .raml .v2 .internal .impl .commons .type .XmlSchemaExternalType ;
26- import org .raml .v2 .internal .impl .v10 .type .AnyResolvedType ;
27- import org .raml .v2 .internal .impl .v10 .type .FileResolvedType ;
28- import org .raml .v2 .internal .impl .v10 .type .StringResolvedType ;
29- import org .raml .v2 .internal .impl .v10 .type .TypeToRuleVisitor ;
30- import org .raml .v2 .internal .impl .v10 .type .TypeToXmlSchemaVisitor ;
34+ import org .raml .v2 .internal .impl .v10 .nodes .NamedTypeExpressionNode ;
35+ import org .raml .v2 .internal .impl .v10 .nodes .UnionTypeExpressionNode ;
36+ import org .raml .v2 .internal .impl .v10 .type .*;
3137import org .raml .yagi .framework .grammar .rule .ErrorNodeFactory ;
3238import org .raml .yagi .framework .grammar .rule .Rule ;
33- import org .raml .yagi .framework .nodes .ErrorNode ;
34- import org .raml .yagi .framework .nodes .Node ;
35- import org .raml .yagi .framework .nodes .NodeType ;
36- import org .raml .yagi .framework .nodes .NullNodeImpl ;
37- import org .raml .yagi .framework .nodes .StringNode ;
38- import org .raml .yagi .framework .nodes .StringNodeImpl ;
39+ import org .raml .yagi .framework .nodes .*;
3940import org .raml .yagi .framework .nodes .jackson .JNodeParser ;
41+ import org .raml .yagi .framework .nodes .jackson .JsonUtils ;
4042import org .raml .yagi .framework .nodes .snakeyaml .NodeParser ;
4143import org .raml .yagi .framework .phase .Phase ;
4244import org .xml .sax .Attributes ;
4648import org .xml .sax .helpers .XMLFilterImpl ;
4749import org .xml .sax .helpers .XMLReaderFactory ;
4850
51+ import javax .annotation .Nonnull ;
4952import javax .annotation .Nullable ;
5053import javax .xml .XMLConstants ;
5154import javax .xml .transform .sax .SAXSource ;
5457import javax .xml .validation .SchemaFactory ;
5558import javax .xml .validation .Validator ;
5659import java .io .IOException ;
60+ import java .io .Reader ;
5761import java .io .StringReader ;
5862import java .io .StringWriter ;
63+ import java .util .ArrayList ;
64+ import java .util .Collection ;
65+ import java .util .HashSet ;
5966import java .util .List ;
6067
6168import static org .apache .commons .lang .StringUtils .isBlank ;
@@ -108,7 +115,10 @@ public Node validate(TypeDeclarationNode type, String exampleValue)
108115 {
109116 exampleValueNode = new NullNodeImpl ();
110117 }
111- else if (!(type .getResolvedType () instanceof StringResolvedType ) && !(type .getResolvedType () instanceof FileResolvedType ) && !isJsonValue (exampleValue ) && !isXmlValue (exampleValue ))
118+ else if (!(type .getResolvedType () instanceof StringResolvedType ) &&
119+ !(type .getResolvedType () instanceof FileResolvedType ) &&
120+ !isJsonValue (exampleValue ) &&
121+ !isXmlValue (exampleValue ))
112122 {
113123 // parse as yaml except for string, file, json and xml types
114124 exampleValueNode = NodeParser .parse (resourceLoader , "" , exampleValue );
@@ -124,14 +134,14 @@ public Node validate(TypeDeclarationNode type, Node exampleValue)
124134 {
125135 return null ;
126136 }
127- if (exampleValue instanceof StringNode && !( resolvedType instanceof StringResolvedType ) && ! isExternalSchemaType (resolvedType ))
137+ if (exampleValue instanceof StringNode && !isExternalSchemaType (resolvedType ))
128138 {
129139 final String value = ((StringNode ) exampleValue ).getValue ();
130- if (isXmlValue (value ))
140+ if (( mightBeAnObjectType ( resolvedType )) && isXmlValue (value ))
131141 {
132142 return validateXml (type , resolvedType , value );
133143 }
134- else if (isJsonValue (value ))
144+ else if (( mightBeAnObjectType ( resolvedType ) || ( resolvedType instanceof ArrayResolvedType )) && isJsonValue (value ))
135145 {
136146 return validateJson (exampleValue , resolvedType , value );
137147 }
@@ -144,6 +154,35 @@ else if (isJsonValue(value))
144154 return null ;
145155 }
146156
157+ private boolean mightBeAnObjectType (ResolvedType resolvedType )
158+ {
159+ if (resolvedType instanceof ObjectResolvedType )
160+ {
161+ return true ;
162+ }
163+
164+ return unionMightBeAnObject (resolvedType , new HashSet <String >());
165+ }
166+
167+ private boolean unionMightBeAnObject (ResolvedType resolvedType , HashSet <String > seenTypes )
168+ {
169+
170+ seenTypes .add (resolvedType .getTypeName ());
171+ if (resolvedType instanceof UnionResolvedType )
172+ {
173+ UnionResolvedType urt = (UnionResolvedType ) resolvedType ;
174+ for (ResolvedType type : urt .of ())
175+ {
176+ if (!seenTypes .contains (type .getTypeName ()))
177+ {
178+ return unionMightBeAnObject (type , seenTypes );
179+ }
180+ }
181+ }
182+
183+ return resolvedType instanceof ObjectResolvedType ;
184+ }
185+
147186 protected Node validateJson (Node exampleValue , ResolvedType resolvedType , String value )
148187 {
149188 final Rule rule = resolvedType .visit (new TypeToRuleVisitor (resourceLoader ));
0 commit comments