X-Git-Url: https://git.opendaylight.org/gerrit/gitweb?a=blobdiff_plain;f=yang%2Fyang-data-codec-gson%2Fsrc%2Fmain%2Fjava%2Forg%2Fopendaylight%2Fyangtools%2Fyang%2Fdata%2Fcodec%2Fgson%2FJsonParserStream.java;h=9a93146e21fb4a5886cdf954e70c2bf6559045bb;hb=b52c1ffb0df2b84665b4d222166a3e4cdb8427bb;hp=7922b95197b63badb9676c4e95286677017ad9ab;hpb=8010ad16c8145165ba7567556ba75664e46946cf;p=yangtools.git diff --git a/yang/yang-data-codec-gson/src/main/java/org/opendaylight/yangtools/yang/data/codec/gson/JsonParserStream.java b/yang/yang-data-codec-gson/src/main/java/org/opendaylight/yangtools/yang/data/codec/gson/JsonParserStream.java index 7922b95197..9a93146e21 100644 --- a/yang/yang-data-codec-gson/src/main/java/org/opendaylight/yangtools/yang/data/codec/gson/JsonParserStream.java +++ b/yang/yang-data-codec-gson/src/main/java/org/opendaylight/yangtools/yang/data/codec/gson/JsonParserStream.java @@ -27,7 +27,9 @@ import java.util.HashSet; import java.util.List; import java.util.Set; import org.opendaylight.yangtools.yang.common.QName; +import org.opendaylight.yangtools.yang.data.api.schema.stream.DataSchemaNodeAwareAdaptor; import org.opendaylight.yangtools.yang.data.api.schema.stream.NormalizedNodeStreamWriter; +import org.opendaylight.yangtools.yang.data.api.schema.stream.SchemaAwareNormalizedNodeStreamWriter; import org.opendaylight.yangtools.yang.model.api.AnyXmlSchemaNode; import org.opendaylight.yangtools.yang.model.api.ChoiceCaseNode; import org.opendaylight.yangtools.yang.model.api.ChoiceSchemaNode; @@ -37,6 +39,7 @@ import org.opendaylight.yangtools.yang.model.api.Module; import org.opendaylight.yangtools.yang.model.api.RpcDefinition; import org.opendaylight.yangtools.yang.model.api.SchemaContext; import org.opendaylight.yangtools.yang.model.api.SchemaNode; +import org.opendaylight.yangtools.yang.model.api.YangModeledAnyXmlSchemaNode; /** * This class parses JSON elements from a GSON JsonReader. It disallows multiple elements of the same name unlike the @@ -45,20 +48,22 @@ import org.opendaylight.yangtools.yang.model.api.SchemaNode; @Beta public final class JsonParserStream implements Closeable, Flushable { private final Deque namespaces = new ArrayDeque<>(); - private final NormalizedNodeStreamWriter writer; + private final SchemaAwareNormalizedNodeStreamWriter writer; private final JSONCodecFactory codecs; private final SchemaContext schema; private final DataSchemaNode parentNode; - private JsonParserStream(final NormalizedNodeStreamWriter writer, final SchemaContext schemaContext, final DataSchemaNode parentNode) { + private JsonParserStream(final NormalizedNodeStreamWriter writer, final SchemaContext schemaContext, + final DataSchemaNode parentNode) { this.schema = Preconditions.checkNotNull(schemaContext); - this.writer = Preconditions.checkNotNull(writer); + this.writer = DataSchemaNodeAwareAdaptor.forWriter(writer); this.codecs = JSONCodecFactory.create(schemaContext); this.parentNode = parentNode; } - public static JsonParserStream create(final NormalizedNodeStreamWriter writer, final SchemaContext schemaContext, final SchemaNode parentNode ) { - if(parentNode instanceof RpcDefinition) { + public static JsonParserStream create(final NormalizedNodeStreamWriter writer, final SchemaContext schemaContext, + final SchemaNode parentNode ) { + if (parentNode instanceof RpcDefinition) { return new JsonParserStream(writer, schemaContext, new RpcAsContainer((RpcDefinition) parentNode)); } Preconditions.checkArgument(parentNode instanceof DataSchemaNode, "Instance of DataSchemaNode class awaited."); @@ -69,7 +74,7 @@ public final class JsonParserStream implements Closeable, Flushable { return new JsonParserStream(writer, schemaContext, schemaContext); } - public JsonParserStream parse(final JsonReader reader) throws JsonIOException, JsonSyntaxException { + public JsonParserStream parse(final JsonReader reader) { // code copied from gson's JsonParser and Stream classes final boolean lenient = reader.isLenient(); @@ -83,11 +88,9 @@ public final class JsonParserStream implements Closeable, Flushable { compositeNodeDataWithSchema.write(writer); return this; - // return read(reader); } catch (final EOFException e) { if (isEmpty) { return this; - // return JsonNull.INSTANCE; } // The stream ended prematurely so it is likely a syntax error. throw new JsonSyntaxException(e); @@ -104,11 +107,15 @@ public final class JsonParserStream implements Closeable, Flushable { } } - private final void setValue(final AbstractNodeDataWithSchema parent, final String value) { - Preconditions.checkArgument(parent instanceof SimpleNodeDataWithSchema, "Node %s is not a simple type", parent); + private void setValue(final AbstractNodeDataWithSchema parent, final String value) { + Preconditions.checkArgument(parent instanceof SimpleNodeDataWithSchema, "Node %s is not a simple type", + parent.getSchema().getQName()); + final SimpleNodeDataWithSchema parentSimpleNode = (SimpleNodeDataWithSchema) parent; + Preconditions.checkArgument(parentSimpleNode.getValue() == null, "Node '%s' has already set its value to '%s'", + parentSimpleNode.getSchema().getQName(), parentSimpleNode.getValue()); - final Object translatedValue = translateValueByType(value, parent.getSchema()); - ((SimpleNodeDataWithSchema) parent).setValue(translatedValue); + final Object translatedValue = translateValueByType(value, parentSimpleNode.getSchema()); + parentSimpleNode.setValue(translatedValue); } public void read(final JsonReader in, AbstractNodeDataWithSchema parent) throws IOException { @@ -127,8 +134,12 @@ public final class JsonParserStream implements Closeable, Flushable { case BEGIN_ARRAY: in.beginArray(); while (in.hasNext()) { - final AbstractNodeDataWithSchema newChild = newArrayEntry(parent); - read(in, newChild); + if (parent instanceof LeafNodeDataWithSchema) { + read(in, parent); + } else { + final AbstractNodeDataWithSchema newChild = newArrayEntry(parent); + read(in, newChild); + } } in.endArray(); return; @@ -147,14 +158,19 @@ public final class JsonParserStream implements Closeable, Flushable { } while (in.hasNext()) { final String jsonElementName = in.nextName(); - final NamespaceAndName namespaceAndName = resolveNamespace(jsonElementName, parent.getSchema()); + DataSchemaNode parentSchema = parent.getSchema(); + if (parentSchema instanceof YangModeledAnyXmlSchemaNode) { + parentSchema = ((YangModeledAnyXmlSchemaNode) parentSchema).getSchemaOfAnyXmlData(); + } + final NamespaceAndName namespaceAndName = resolveNamespace(jsonElementName, parentSchema); final String localName = namespaceAndName.getName(); addNamespace(namespaceAndName.getUri()); if (namesakes.contains(jsonElementName)) { throw new JsonSyntaxException("Duplicate name " + jsonElementName + " in JSON input."); } namesakes.add(jsonElementName); - final Deque childDataSchemaNodes = findSchemaNodeByNameAndNamespace(parent.getSchema(), + + final Deque childDataSchemaNodes = findSchemaNodeByNameAndNamespace(parentSchema, localName, getCurrentNamespace()); if (childDataSchemaNodes.isEmpty()) { throw new IllegalStateException("Schema for node with name " + localName + " and namespace " @@ -184,18 +200,18 @@ public final class JsonParserStream implements Closeable, Flushable { } } - private boolean isArray(final AbstractNodeDataWithSchema parent) { - return parent instanceof ListNodeDataWithSchema || parent instanceof ListNodeDataWithSchema; + private static boolean isArray(final AbstractNodeDataWithSchema parent) { + return parent instanceof ListNodeDataWithSchema || parent instanceof LeafListNodeDataWithSchema; } - private AbstractNodeDataWithSchema newArrayEntry(final AbstractNodeDataWithSchema parent) { + private static AbstractNodeDataWithSchema newArrayEntry(final AbstractNodeDataWithSchema parent) { AbstractNodeDataWithSchema newChild; if (parent instanceof ListNodeDataWithSchema) { newChild = new ListEntryNodeDataWithSchema(parent.getSchema()); } else if (parent instanceof LeafListNodeDataWithSchema) { newChild = new LeafListEntryNodeDataWithSchema(parent.getSchema()); } else { - throw new IllegalStateException("Incorrec nesting caused by parser."); + throw new IllegalStateException("Found an unexpected array nested under "+ parent.getSchema().getQName()); } ((CompositeNodeDataWithSchema) parent).addChild(newChild); return newChild; @@ -246,7 +262,7 @@ public final class JsonParserStream implements Closeable, Flushable { } else if (potentialUris.size() > 1) { throw new IllegalStateException("Choose suitable module name for element "+nodeNamePart+":"+toModuleNames(potentialUris)); } else if (potentialUris.isEmpty()) { - throw new IllegalStateException("Schema node with name "+nodeNamePart+" wasn't found."); + throw new IllegalStateException("Schema node with name "+nodeNamePart+" wasn't found under "+dataSchemaNode.getQName()+"."); } }