X-Git-Url: https://git.opendaylight.org/gerrit/gitweb?a=blobdiff_plain;f=opendaylight%2Fmd-sal%2Fsal-rest-connector%2Fsrc%2Fmain%2Fjava%2Forg%2Fopendaylight%2Fcontroller%2Fsal%2Frest%2Fimpl%2FXmlNormalizedNodeBodyReader.java;h=4257e172b4a5c22847b1f0469e810ab86dca828b;hb=0f026fdca9317d6b5bb59b1500205652ef781f6e;hp=905cb50c3a8bbcc2f916fb62cdb2ec017903b45e;hpb=7f44a5812395762479de68d339c3d017db6c0e9d;p=controller.git diff --git a/opendaylight/md-sal/sal-rest-connector/src/main/java/org/opendaylight/controller/sal/rest/impl/XmlNormalizedNodeBodyReader.java b/opendaylight/md-sal/sal-rest-connector/src/main/java/org/opendaylight/controller/sal/rest/impl/XmlNormalizedNodeBodyReader.java index 905cb50c3a..4257e172b4 100644 --- a/opendaylight/md-sal/sal-rest-connector/src/main/java/org/opendaylight/controller/sal/rest/impl/XmlNormalizedNodeBodyReader.java +++ b/opendaylight/md-sal/sal-rest-connector/src/main/java/org/opendaylight/controller/sal/rest/impl/XmlNormalizedNodeBodyReader.java @@ -7,11 +7,11 @@ */ package org.opendaylight.controller.sal.rest.impl; -import com.google.common.base.Optional; import java.io.IOException; import java.io.InputStream; import java.lang.annotation.Annotation; import java.lang.reflect.Type; +import java.util.ArrayList; import java.util.Collection; import java.util.Collections; import java.util.List; @@ -34,10 +34,14 @@ import org.opendaylight.controller.sal.restconf.impl.RestconfError.ErrorType; import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode; import org.opendaylight.yangtools.yang.data.impl.codec.xml.XmlUtils; import org.opendaylight.yangtools.yang.data.impl.schema.transform.dom.parser.DomToNormalizedNodeParserFactory; +import org.opendaylight.yangtools.yang.model.api.ChoiceCaseNode; +import org.opendaylight.yangtools.yang.model.api.ChoiceSchemaNode; import org.opendaylight.yangtools.yang.model.api.ContainerSchemaNode; import org.opendaylight.yangtools.yang.model.api.DataNodeContainer; import org.opendaylight.yangtools.yang.model.api.DataSchemaNode; import org.opendaylight.yangtools.yang.model.api.ListSchemaNode; +import org.opendaylight.yangtools.yang.model.api.RpcDefinition; +import org.opendaylight.yangtools.yang.model.api.SchemaNode; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.w3c.dom.Document; @@ -81,7 +85,12 @@ public class XmlNormalizedNodeBodyReader extends AbstractIdentifierAwareJaxRsPro final MultivaluedMap httpHeaders, final InputStream entityStream) throws IOException, WebApplicationException { try { - final Optional path = getIdentifierWithSchema(); + final InstanceIdentifierContext path = getInstanceIdentifierContext(); + + if (entityStream.available() < 1) { + // represent empty nopayload input + return new NormalizedNodeContext(path, null); + } final DocumentBuilder dBuilder; try { @@ -91,32 +100,36 @@ public class XmlNormalizedNodeBodyReader extends AbstractIdentifierAwareJaxRsPro } final Document doc = dBuilder.parse(entityStream); - final NormalizedNode result = parse(path.get(),doc); - return new NormalizedNodeContext(path.get(),result); + final NormalizedNode result = parse(path,doc); + return new NormalizedNodeContext(path,result); } catch (final Exception e) { - LOG.debug("Error parsing json input", e); + LOG.debug("Error parsing xml input", e); throw new RestconfDocumentedException("Error parsing input: " + e.getMessage(), ErrorType.PROTOCOL, ErrorTag.MALFORMED_MESSAGE); } } - private static NormalizedNode parse(final InstanceIdentifierContext pathContext,final Document doc) { + private static NormalizedNode parse(final InstanceIdentifierContext pathContext,final Document doc) { final List elements = Collections.singletonList(doc.getDocumentElement()); - DataSchemaNode schemaNode = pathContext.getSchemaNode(); + final SchemaNode schemaNodeContext = pathContext.getSchemaNode(); + DataSchemaNode schemaNode; + if (schemaNodeContext instanceof RpcDefinition) { + schemaNode = ((RpcDefinition) schemaNodeContext).getInput(); + } else if (schemaNodeContext instanceof DataSchemaNode) { + schemaNode = (DataSchemaNode) schemaNodeContext; + } else { + throw new IllegalStateException("Unknow SchemaNode"); + } final String docRootElm = doc.getDocumentElement().getLocalName(); final String schemaNodeName = pathContext.getSchemaNode().getQName().getLocalName(); - // TODO : do we want to really follow netconf-restconf specification ? if (!schemaNodeName.equalsIgnoreCase(docRootElm)) { - final Collection children = ((DataNodeContainer) schemaNode).getChildNodes(); - for (final DataSchemaNode child : children) { - if (child.getQName().getLocalName().equalsIgnoreCase(docRootElm)) { - schemaNode = child; - break; - } + final DataSchemaNode foundSchemaNode = findSchemaNodeOrParentChoiceByName(schemaNode, docRootElm); + if (foundSchemaNode != null) { + schemaNode = foundSchemaNode; } } @@ -124,11 +137,41 @@ public class XmlNormalizedNodeBodyReader extends AbstractIdentifierAwareJaxRsPro final DomToNormalizedNodeParserFactory parserFactory = DomToNormalizedNodeParserFactory.getInstance(XmlUtils.DEFAULT_XML_CODEC_PROVIDER, pathContext.getSchemaContext()); + NormalizedNode parsed = null; if(schemaNode instanceof ContainerSchemaNode) { return parserFactory.getContainerNodeParser().parse(Collections.singletonList(doc.getDocumentElement()), (ContainerSchemaNode) schemaNode); } else if(schemaNode instanceof ListSchemaNode) { final ListSchemaNode casted = (ListSchemaNode) schemaNode; return parserFactory.getMapEntryNodeParser().parse(elements, casted); + } else if (schemaNode instanceof ChoiceSchemaNode) { + final ChoiceSchemaNode casted = (ChoiceSchemaNode) schemaNode; + return parserFactory.getChoiceNodeParser().parse(elements, casted); + } + + // FIXME : add another DataSchemaNode extensions e.g. LeafSchemaNode + + return parsed; + } + + private static DataSchemaNode findSchemaNodeOrParentChoiceByName(DataSchemaNode schemaNode, String elementName) { + final ArrayList choiceSchemaNodes = new ArrayList<>(); + final Collection children = ((DataNodeContainer) schemaNode).getChildNodes(); + for (final DataSchemaNode child : children) { + if (child instanceof ChoiceSchemaNode) { + choiceSchemaNodes.add((ChoiceSchemaNode) child); + } else if (child.getQName().getLocalName().equalsIgnoreCase(elementName)) { + return child; + } + } + + for (final ChoiceSchemaNode choiceNode : choiceSchemaNodes) { + for (final ChoiceCaseNode caseNode : choiceNode.getCases()) { + final DataSchemaNode resultFromRecursion = findSchemaNodeOrParentChoiceByName(caseNode, elementName); + if (resultFromRecursion != null) { + // this returns top choice node in which child element is found + return choiceNode; + } + } } return null; }