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=d2c75f7e0ccfb6b8f4d82d78e7ea0b0a1e0c7971;hb=d7b5e0619787f99844e19b9ef36f0a1793044f33;hp=2a9c5bf190cbed62c4756940942436ac8f88682e;hpb=6ed2706cc745f794f302d3919b4c5b9e6791f311;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 2a9c5bf190..d2c75f7e0c 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,13 +7,16 @@ */ package org.opendaylight.controller.sal.rest.impl; +import com.google.common.collect.Iterables; import java.io.IOException; import java.io.InputStream; import java.lang.annotation.Annotation; import java.lang.reflect.Type; +import java.util.ArrayDeque; import java.util.ArrayList; import java.util.Collection; import java.util.Collections; +import java.util.Deque; import java.util.List; import javax.ws.rs.Consumes; import javax.ws.rs.WebApplicationException; @@ -31,8 +34,10 @@ import org.opendaylight.controller.sal.restconf.impl.NormalizedNodeContext; import org.opendaylight.controller.sal.restconf.impl.RestconfDocumentedException; import org.opendaylight.controller.sal.restconf.impl.RestconfError.ErrorTag; import org.opendaylight.controller.sal.restconf.impl.RestconfError.ErrorType; +import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier; 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.SchemaUtils; import org.opendaylight.yangtools.yang.data.impl.schema.transform.dom.parser.DomToNormalizedNodeParserFactory; import org.opendaylight.yangtools.yang.model.api.AugmentationSchema; import org.opendaylight.yangtools.yang.model.api.AugmentationTarget; @@ -102,8 +107,7 @@ public class XmlNormalizedNodeBodyReader extends AbstractIdentifierAwareJaxRsPro } final Document doc = dBuilder.parse(entityStream); - final NormalizedNode result = parse(path,doc); - return new NormalizedNodeContext(path,result); + return parse(path,doc); } catch (final RestconfDocumentedException e){ throw e; } catch (final Exception e) { @@ -114,7 +118,7 @@ public class XmlNormalizedNodeBodyReader extends AbstractIdentifierAwareJaxRsPro } } - private static NormalizedNode parse(final InstanceIdentifierContext pathContext,final Document doc) { + private NormalizedNodeContext parse(final InstanceIdentifierContext pathContext,final Document doc) { final List elements = Collections.singletonList(doc.getDocumentElement()); final SchemaNode schemaNodeContext = pathContext.getSchemaNode(); @@ -128,68 +132,91 @@ public class XmlNormalizedNodeBodyReader extends AbstractIdentifierAwareJaxRsPro } final String docRootElm = doc.getDocumentElement().getLocalName(); - final String schemaNodeName = pathContext.getSchemaNode().getQName().getLocalName(); + final List iiToDataList = new ArrayList<>(); + InstanceIdentifierContext outIIContext; + // FIXME the factory instance should be cached if the schema context is the same final DomToNormalizedNodeParserFactory parserFactory = DomToNormalizedNodeParserFactory.getInstance(XmlUtils.DEFAULT_XML_CODEC_PROVIDER, pathContext.getSchemaContext()); - if (!schemaNodeName.equalsIgnoreCase(docRootElm)) { - final DataSchemaNode foundSchemaNode = findSchemaNodeOrParentChoiceByName(schemaNode, docRootElm); - if (foundSchemaNode != null) { - if (schemaNode instanceof AugmentationTarget) { - final AugmentationSchema augmentSchemaNode = findCorrespondingAugment(schemaNode, foundSchemaNode); - if (augmentSchemaNode != null) { - return parserFactory.getAugmentationNodeParser().parse(elements, augmentSchemaNode); - } + if (isPost()) { + final Deque foundSchemaNodes = findPathToSchemaNodeByName(schemaNode, docRootElm); + while (!foundSchemaNodes.isEmpty()) { + final Object child = foundSchemaNodes.pop(); + if (child instanceof AugmentationSchema) { + final AugmentationSchema augmentSchemaNode = (AugmentationSchema) child; + iiToDataList.add(SchemaUtils.getNodeIdentifierForAugmentation(augmentSchemaNode)); + } else if (child instanceof DataSchemaNode) { + schemaNode = (DataSchemaNode) child; + iiToDataList.add(new YangInstanceIdentifier.NodeIdentifier(schemaNode.getQName())); } - schemaNode = foundSchemaNode; } } NormalizedNode parsed = null; if(schemaNode instanceof ContainerSchemaNode) { - return parserFactory.getContainerNodeParser().parse(Collections.singletonList(doc.getDocumentElement()), (ContainerSchemaNode) schemaNode); + parsed = 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); + parsed = parserFactory.getMapEntryNodeParser().parse(elements, casted); + if (isPost()) { + iiToDataList.add(parsed.getIdentifier()); + } } // FIXME : add another DataSchemaNode extensions e.g. LeafSchemaNode - return parsed; + final YangInstanceIdentifier fullIIToData = YangInstanceIdentifier.create(Iterables.concat( + pathContext.getInstanceIdentifier().getPathArguments(), iiToDataList)); + + outIIContext = new InstanceIdentifierContext<>(fullIIToData, pathContext.getSchemaNode(), pathContext.getMountPoint(), + pathContext.getSchemaContext()); + + return new NormalizedNodeContext(outIIContext, parsed); } - private static DataSchemaNode findSchemaNodeOrParentChoiceByName(DataSchemaNode schemaNode, String elementName) { + private static Deque findPathToSchemaNodeByName(final DataSchemaNode schemaNode, final String elementName) { + final Deque result = new ArrayDeque<>(); 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; + result.push(child); + if (child.isAugmenting()) { + final AugmentationSchema augment = findCorrespondingAugment(schemaNode, child); + if (augment != null) { + result.push(augment); + } + } + return result; } } 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; + final Deque resultFromRecursion = findPathToSchemaNodeByName(caseNode, elementName); + if (!resultFromRecursion.isEmpty()) { + resultFromRecursion.push(choiceNode); + if (choiceNode.isAugmenting()) { + final AugmentationSchema augment = findCorrespondingAugment(schemaNode, choiceNode); + if (augment != null) { + resultFromRecursion.push(augment); + } + } + return resultFromRecursion; } } } - return null; + return result; } private static AugmentationSchema findCorrespondingAugment(final DataSchemaNode parent, final DataSchemaNode child) { - if (parent instanceof AugmentationTarget && !((parent instanceof ChoiceCaseNode) || (parent instanceof ChoiceSchemaNode))) { - for (AugmentationSchema augmentation : ((AugmentationTarget) parent).getAvailableAugmentations()) { - DataSchemaNode childInAugmentation = augmentation.getDataChildByName(child.getQName()); + if (parent instanceof AugmentationTarget && !(parent instanceof ChoiceSchemaNode)) { + for (final AugmentationSchema augmentation : ((AugmentationTarget) parent).getAvailableAugmentations()) { + final DataSchemaNode childInAugmentation = augmentation.getDataChildByName(child.getQName()); if (childInAugmentation != null) { return augmentation; }