X-Git-Url: https://git.opendaylight.org/gerrit/gitweb?a=blobdiff_plain;f=restconf%2Frestconf-nb-bierman02%2Fsrc%2Fmain%2Fjava%2Forg%2Fopendaylight%2Fnetconf%2Fsal%2Frest%2Fimpl%2FXmlToPatchBodyReader.java;h=af353d67a4ff837aaa46902824b03c6359909f3f;hb=cc3aeff1491b7978cff76b5efc3fb76f512ff0de;hp=4f88e14d5c28d1b43a15fc6a0aab677fbf676e8c;hpb=676b7818fd81f1322b7e8aa977271f3a3af397a6;p=netconf.git diff --git a/restconf/restconf-nb-bierman02/src/main/java/org/opendaylight/netconf/sal/rest/impl/XmlToPatchBodyReader.java b/restconf/restconf-nb-bierman02/src/main/java/org/opendaylight/netconf/sal/rest/impl/XmlToPatchBodyReader.java index 4f88e14d5c..af353d67a4 100644 --- a/restconf/restconf-nb-bierman02/src/main/java/org/opendaylight/netconf/sal/rest/impl/XmlToPatchBodyReader.java +++ b/restconf/restconf-nb-bierman02/src/main/java/org/opendaylight/netconf/sal/rest/impl/XmlToPatchBodyReader.java @@ -5,23 +5,23 @@ * terms of the Eclipse Public License v1.0 which accompanies this distribution, * and is available at http://www.eclipse.org/legal/epl-v10.html */ - package org.opendaylight.netconf.sal.rest.impl; +import static com.google.common.base.Verify.verify; +import static com.google.common.base.Verify.verifyNotNull; + import com.google.common.base.Splitter; import com.google.common.collect.ImmutableList; import java.io.IOException; import java.io.InputStream; import java.lang.annotation.Annotation; import java.lang.reflect.Type; -import java.net.URI; import java.net.URISyntaxException; import java.util.ArrayList; import java.util.Iterator; import java.util.List; import java.util.Locale; import java.util.Optional; -import javax.annotation.Nonnull; import javax.ws.rs.Consumes; import javax.ws.rs.WebApplicationException; import javax.ws.rs.core.MediaType; @@ -31,20 +31,22 @@ import javax.ws.rs.ext.Provider; import javax.xml.parsers.ParserConfigurationException; import javax.xml.stream.XMLStreamException; import javax.xml.transform.dom.DOMSource; +import org.eclipse.jdt.annotation.NonNull; import org.opendaylight.netconf.sal.rest.api.Draft02; import org.opendaylight.netconf.sal.rest.api.RestconfService; import org.opendaylight.netconf.sal.restconf.impl.ControllerContext; import org.opendaylight.restconf.common.context.InstanceIdentifierContext; import org.opendaylight.restconf.common.errors.RestconfDocumentedException; -import org.opendaylight.restconf.common.errors.RestconfError.ErrorTag; -import org.opendaylight.restconf.common.errors.RestconfError.ErrorType; import org.opendaylight.restconf.common.patch.PatchContext; import org.opendaylight.restconf.common.patch.PatchEditOperation; import org.opendaylight.restconf.common.patch.PatchEntity; import org.opendaylight.restconf.common.util.RestUtil; import org.opendaylight.yangtools.util.xml.UntrustedXML; +import org.opendaylight.yangtools.yang.common.ErrorTag; +import org.opendaylight.yangtools.yang.common.ErrorType; import org.opendaylight.yangtools.yang.common.QName; import org.opendaylight.yangtools.yang.common.Revision; +import org.opendaylight.yangtools.yang.common.XMLNamespace; import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier; import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifierWithPredicates; import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode; @@ -58,7 +60,9 @@ import org.opendaylight.yangtools.yang.model.api.DataSchemaNode; import org.opendaylight.yangtools.yang.model.api.ListSchemaNode; import org.opendaylight.yangtools.yang.model.api.Module; import org.opendaylight.yangtools.yang.model.api.SchemaNode; -import org.opendaylight.yangtools.yang.model.util.SchemaContextUtil; +import org.opendaylight.yangtools.yang.model.api.meta.EffectiveStatement; +import org.opendaylight.yangtools.yang.model.util.SchemaInferenceStack; +import org.opendaylight.yangtools.yang.model.util.SchemaInferenceStack.Inference; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.w3c.dom.Document; @@ -80,7 +84,7 @@ public class XmlToPatchBodyReader extends AbstractIdentifierAwareJaxRsProvider i private static final Logger LOG = LoggerFactory.getLogger(XmlToPatchBodyReader.class); - public XmlToPatchBodyReader(ControllerContext controllerContext) { + public XmlToPatchBodyReader(final ControllerContext controllerContext) { super(controllerContext); } @@ -100,7 +104,7 @@ public class XmlToPatchBodyReader extends AbstractIdentifierAwareJaxRsProvider i try { final InstanceIdentifierContext path = getInstanceIdentifierContext(); final Optional nonEmptyInputStreamOptional = RestUtil.isInputStreamEmpty(entityStream); - if (!nonEmptyInputStreamOptional.isPresent()) { + if (nonEmptyInputStreamOptional.isEmpty()) { // represent empty nopayload input return new PatchContext(path, null, null); } @@ -111,7 +115,7 @@ public class XmlToPatchBodyReader extends AbstractIdentifierAwareJaxRsProvider i throw e; } catch (final Exception e) { LOG.debug("Error parsing xml input", e); - + RestconfDocumentedException.throwIfYangError(e); throw new RestconfDocumentedException("Error parsing input: " + e.getMessage(), ErrorType.PROTOCOL, ErrorTag.MALFORMED_MESSAGE, e); } @@ -139,7 +143,8 @@ public class XmlToPatchBodyReader extends AbstractIdentifierAwareJaxRsProvider i ? schemaNode.getQName().getNamespace().toString() : firstValueElement.getNamespaceURI(); // find module according to namespace - final Module module = pathContext.getSchemaContext().findModules(URI.create(namespace)).iterator().next(); + final Module module = pathContext.getSchemaContext().findModules(XMLNamespace.of(namespace)).iterator() + .next(); // initialize codec + set default prefix derived from module name final StringModuleInstanceIdentifierCodec codec = new StringModuleInstanceIdentifierCodec( @@ -149,21 +154,29 @@ public class XmlToPatchBodyReader extends AbstractIdentifierAwareJaxRsProvider i // target can be also empty (only slash) YangInstanceIdentifier targetII; final SchemaNode targetNode; + final Inference inference; if (target.equals("/")) { targetII = pathContext.getInstanceIdentifier(); targetNode = pathContext.getSchemaContext(); + inference = Inference.ofDataTreePath(pathContext.getSchemaContext(), schemaNode.getQName()); } else { targetII = codec.deserialize(codec.serialize(pathContext.getInstanceIdentifier()) .concat(prepareNonCondXpath(schemaNode, target.replaceFirst("/", ""), firstValueElement, namespace, module.getQNameModule().getRevision().map(Revision::toString).orElse(null)))); - - targetNode = SchemaContextUtil.findDataSchemaNode(pathContext.getSchemaContext(), - codec.getDataContextTree().getChild(targetII).getDataSchemaNode().getPath().getParent()); - // move schema node - schemaNode = (DataSchemaNode) SchemaContextUtil.findDataSchemaNode(pathContext.getSchemaContext(), - codec.getDataContextTree().getChild(targetII).getDataSchemaNode().getPath()); + schemaNode = verifyNotNull(codec.getDataContextTree().findChild(targetII).orElseThrow() + .getDataSchemaNode()); + + final SchemaInferenceStack stack = SchemaInferenceStack.of(pathContext.getSchemaContext()); + targetII.getPathArguments().stream() + .filter(arg -> !(arg instanceof YangInstanceIdentifier.NodeIdentifierWithPredicates)) + .filter(arg -> !(arg instanceof YangInstanceIdentifier.AugmentationIdentifier)) + .forEach(p -> stack.enterSchemaTree(p.getNodeType())); + final EffectiveStatement parentStmt = stack.exit(); + verify(parentStmt instanceof SchemaNode, "Unexpected parent %s", parentStmt); + targetNode = (SchemaNode) parentStmt; + inference = stack.toInference(); } if (targetNode == null) { @@ -173,12 +186,11 @@ public class XmlToPatchBodyReader extends AbstractIdentifierAwareJaxRsProvider i } if (oper.isWithValue()) { - final NormalizedNode parsed; + final NormalizedNode parsed; if (schemaNode instanceof ContainerSchemaNode || schemaNode instanceof ListSchemaNode) { final NormalizedNodeResult resultHolder = new NormalizedNodeResult(); final NormalizedNodeStreamWriter writer = ImmutableNormalizedNodeStreamWriter.from(resultHolder); - final XmlParserStream xmlParser = XmlParserStream.create(writer, pathContext.getSchemaContext(), - schemaNode); + final XmlParserStream xmlParser = XmlParserStream.create(writer, inference); xmlParser.traverse(new DOMSource(firstValueElement)); parsed = resultHolder.getResult(); } else { @@ -206,8 +218,8 @@ public class XmlToPatchBodyReader extends AbstractIdentifierAwareJaxRsProvider i * @param operation Name of current operation * @return List of value elements */ - private static List readValueNodes(@Nonnull final Element element, - @Nonnull final PatchEditOperation operation) { + private static List readValueNodes(final @NonNull Element element, + final @NonNull PatchEditOperation operation) { final Node valueNode = element.getElementsByTagName("value").item(0); if (operation.isWithValue() && valueNode == null) { @@ -245,8 +257,8 @@ public class XmlToPatchBodyReader extends AbstractIdentifierAwareJaxRsProvider i * @param revision Module revision * @return Non-conditional XPath */ - private static String prepareNonCondXpath(@Nonnull final DataSchemaNode schemaNode, @Nonnull final String target, - @Nonnull final Element value, @Nonnull final String namespace, @Nonnull final String revision) { + private static String prepareNonCondXpath(final @NonNull DataSchemaNode schemaNode, final @NonNull String target, + final @NonNull Element value, final @NonNull String namespace, final @NonNull String revision) { final Iterator args = Splitter.on("/").split(target.substring(target.indexOf(':') + 1)).iterator(); final StringBuilder nonCondXpath = new StringBuilder(); @@ -254,8 +266,7 @@ public class XmlToPatchBodyReader extends AbstractIdentifierAwareJaxRsProvider i while (args.hasNext()) { final String s = args.next(); - nonCondXpath.append("/"); - nonCondXpath.append(s); + nonCondXpath.append('/').append(s); childNode = ((DataNodeContainer) childNode).getDataChildByName(QName.create(namespace, revision, s)); if (childNode instanceof ListSchemaNode && args.hasNext()) { @@ -279,7 +290,7 @@ public class XmlToPatchBodyReader extends AbstractIdentifierAwareJaxRsProvider i * @param keys Iterator of list keys names * @return Iterator of list keys values */ - private static Iterator readKeyValues(@Nonnull final Element value, @Nonnull final Iterator keys) { + private static Iterator readKeyValues(final @NonNull Element value, final @NonNull Iterator keys) { final List result = new ArrayList<>(); while (keys.hasNext()) { @@ -296,16 +307,11 @@ public class XmlToPatchBodyReader extends AbstractIdentifierAwareJaxRsProvider i * @param keyNames Iterator of list keys names * @param keyValues Iterator of list keys values */ - private static void appendKeys(@Nonnull final StringBuilder nonCondXpath, @Nonnull final Iterator keyNames, - @Nonnull final Iterator keyValues) { + private static void appendKeys(final @NonNull StringBuilder nonCondXpath, final @NonNull Iterator keyNames, + final @NonNull Iterator keyValues) { while (keyNames.hasNext()) { - nonCondXpath.append("["); - nonCondXpath.append(keyNames.next().getLocalName()); - nonCondXpath.append("="); - nonCondXpath.append("'"); - nonCondXpath.append(keyValues.next()); - nonCondXpath.append("'"); - nonCondXpath.append("]"); + nonCondXpath.append("[").append(keyNames.next().getLocalName()).append("='").append(keyValues.next()) + .append("']"); } } }