--- /dev/null
+/*
+ * Copyright (c) 2018 Cisco Systems, Inc. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * 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.yangtools.yang.data.codec.xml;
+
+import java.io.InputStream;
+import javax.xml.stream.XMLStreamReader;
+import org.junit.Before;
+import org.junit.Test;
+import org.opendaylight.yangtools.util.xml.UntrustedXML;
+import org.opendaylight.yangtools.yang.common.QName;
+import org.opendaylight.yangtools.yang.common.Revision;
+import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
+import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
+import org.opendaylight.yangtools.yang.data.api.schema.stream.NormalizedNodeStreamWriter;
+import org.opendaylight.yangtools.yang.data.api.schema.tree.DataTree;
+import org.opendaylight.yangtools.yang.data.api.schema.tree.DataTreeCandidate;
+import org.opendaylight.yangtools.yang.data.api.schema.tree.DataTreeConfiguration;
+import org.opendaylight.yangtools.yang.data.api.schema.tree.DataTreeModification;
+import org.opendaylight.yangtools.yang.data.impl.leafref.LeafRefContext;
+import org.opendaylight.yangtools.yang.data.impl.leafref.LeafRefDataValidationFailedException;
+import org.opendaylight.yangtools.yang.data.impl.leafref.LeafRefValidatation;
+import org.opendaylight.yangtools.yang.data.impl.schema.ImmutableNormalizedNodeStreamWriter;
+import org.opendaylight.yangtools.yang.data.impl.schema.NormalizedNodeResult;
+import org.opendaylight.yangtools.yang.data.impl.schema.tree.InMemoryDataTreeFactory;
+import org.opendaylight.yangtools.yang.model.api.ContainerSchemaNode;
+import org.opendaylight.yangtools.yang.model.api.Module;
+import org.opendaylight.yangtools.yang.model.api.SchemaContext;
+import org.opendaylight.yangtools.yang.test.util.YangParserTestUtils;
+
+public class Yangtools891Test {
+ private static final String FOO = "foo";
+ private static final String FOO_NS = "urn:opendaylight:params:xml:ns:yang:foo";
+ private static final String FOO_REV = "2018-07-27";
+ private static final QName FOO_TOP = QName.create(FOO_NS, FOO_REV, "foo-top");
+ private static final YangInstanceIdentifier FOO_TOP_ID = YangInstanceIdentifier.of(FOO_TOP);
+ private static final String BAZ = "baz";
+ private static final String BAZ_NS = "urn:opendaylight:params:xml:ns:yang:baz";
+ private static final String BAZ_REV = "2018-07-27";
+ private static final QName BAZ_TOP = QName.create(BAZ_NS, BAZ_REV, "baz-top");
+ private static final YangInstanceIdentifier BAZ_TOP_ID = YangInstanceIdentifier.of(BAZ_TOP);
+
+ private SchemaContext schemaContext;
+ private LeafRefContext leafRefContext;
+ private DataTree dataTree;
+ private ContainerSchemaNode fooTopNode;
+ private ContainerSchemaNode bazTopNode;
+
+ @Before
+ public void setup() {
+ schemaContext = YangParserTestUtils.parseYangResourceDirectory("/yangtools891");
+ leafRefContext = LeafRefContext.create(schemaContext);
+ dataTree = new InMemoryDataTreeFactory().create(DataTreeConfiguration.DEFAULT_CONFIGURATION, schemaContext);
+ final Module fooModule = schemaContext.findModule(FOO, Revision.of(FOO_REV)).get();
+ fooTopNode = (ContainerSchemaNode) fooModule.findDataChildByName(FOO_TOP).get();
+ final Module bazModule = schemaContext.findModule(BAZ, Revision.of(BAZ_REV)).get();
+ bazTopNode = (ContainerSchemaNode) bazModule.findDataChildByName(BAZ_TOP).get();
+ }
+
+ @Test
+ public void testValid() throws Exception {
+ final NormalizedNode<?, ?> fooTop = readNode("/yangtools891/grouping-with-list-valid.xml", fooTopNode);
+ final DataTreeModification writeModification = dataTree.takeSnapshot().newModification();
+ writeModification.write(FOO_TOP_ID, fooTop);
+ writeModification.ready();
+ final DataTreeCandidate writeContributorsCandidate = dataTree.prepare(writeModification);
+
+ LeafRefValidatation.validate(writeContributorsCandidate, leafRefContext);
+ dataTree.commit(writeContributorsCandidate);
+ }
+
+ @Test(expected = LeafRefDataValidationFailedException.class)
+ public void testInvalid() throws Exception {
+ final NormalizedNode<?, ?> fooTop = readNode("/yangtools891/grouping-with-list-invalid.xml", fooTopNode);
+ final DataTreeModification writeModification = dataTree.takeSnapshot().newModification();
+ writeModification.write(FOO_TOP_ID, fooTop);
+ writeModification.ready();
+ final DataTreeCandidate writeContributorsCandidate = dataTree.prepare(writeModification);
+
+ LeafRefValidatation.validate(writeContributorsCandidate, leafRefContext);
+ }
+
+ @Test
+ public void testGroupingWithLeafrefValid() throws Exception {
+ final NormalizedNode<?, ?> bazTop = readNode("/yangtools891/baz-top.xml", bazTopNode);
+ final NormalizedNode<?, ?> fooTop = readNode("/yangtools891/grouping-with-leafref-valid.xml", fooTopNode);
+ final DataTreeModification writeModification = dataTree.takeSnapshot().newModification();
+ writeModification.write(BAZ_TOP_ID, bazTop);
+ writeModification.write(FOO_TOP_ID, fooTop);
+ writeModification.ready();
+ final DataTreeCandidate writeContributorsCandidate = dataTree.prepare(writeModification);
+
+ LeafRefValidatation.validate(writeContributorsCandidate, leafRefContext);
+ }
+
+ @Test(expected = LeafRefDataValidationFailedException.class)
+ public void testGroupingWithLeafrefInvalid() throws Exception {
+ final NormalizedNode<?, ?> bazTop = readNode("/yangtools891/baz-top.xml", bazTopNode);
+ final NormalizedNode<?, ?> fooTop = readNode("/yangtools891/grouping-with-leafref-invalid.xml", fooTopNode);
+ final DataTreeModification writeModification = dataTree.takeSnapshot().newModification();
+ writeModification.write(BAZ_TOP_ID, bazTop);
+ writeModification.write(FOO_TOP_ID, fooTop);
+ writeModification.ready();
+ final DataTreeCandidate writeContributorsCandidate = dataTree.prepare(writeModification);
+
+ LeafRefValidatation.validate(writeContributorsCandidate, leafRefContext);
+ }
+
+ private NormalizedNode<?, ?> readNode(final String filename, final ContainerSchemaNode node) throws Exception {
+ final InputStream resourceAsStream = Yangtools891Test.class.getResourceAsStream(filename);
+ final XMLStreamReader reader = UntrustedXML.createXMLStreamReader(resourceAsStream);
+ final NormalizedNodeResult result = new NormalizedNodeResult();
+ final NormalizedNodeStreamWriter streamWriter = ImmutableNormalizedNodeStreamWriter.from(result);
+ final XmlParserStream xmlParser = XmlParserStream.create(streamWriter, schemaContext, node);
+ xmlParser.parse(reader);
+ return result.getResult();
+ }
+}
\ No newline at end of file
import static com.google.common.base.Preconditions.checkArgument;
import com.google.common.collect.Lists;
-import java.net.URI;
import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
private final List<QNameWithPredicateBuilder> leafRefPathQnameList = new ArrayList<>();
private final SchemaContext schemaContext;
private final Module module;
+ private final Module leafrefModule;
// FIXME: use for identifier path completion
private final SchemaNode node;
LEAF_REF_PATH, PATH_PREDICATE, PREDICATE_PATH_EQUALITY_EXPR, PATH_KEY_EXPR
}
- LeafRefPathParserListenerImpl(final SchemaContext schemaContext, final Module currentModule,
+ LeafRefPathParserListenerImpl(final SchemaContext schemaContext, final Module leafrefModule,
final SchemaNode currentNode) {
this.schemaContext = schemaContext;
- this.module = currentModule;
+ this.module = schemaContext.findModule(currentNode.getQName().getModule()).get();
+ this.leafrefModule = leafrefModule;
this.node = currentNode;
}
@Override
public void enterPrefix(final PrefixContext ctx) {
final String prefix = ctx.getText();
- if (!module.getPrefix().equals(prefix)) {
- final Optional<QNameModule> qnameModuleOpt = getQNameModuleForImportPrefix(prefix);
+ if (!leafrefModule.getPrefix().equals(prefix)) {
+ final Optional<QNameModule> qnameModuleOpt = getQNameModuleForImportPrefix(leafrefModule, prefix);
checkArgument(qnameModuleOpt.isPresent(), "No module import for prefix: %s in module: %s", prefix,
- module.getName());
+ leafrefModule.getName());
currentQnameModule = qnameModuleOpt.get();
} else {
- currentQnameModule = module.getQNameModule();
+ currentQnameModule = leafrefModule.getQNameModule();
}
}
@Override
public void exitNode_identifier(final Node_identifierContext ctx) {
if (currentQnameModule == null) {
- currentQnameModule = module.getQNameModule();
+ if (relativePath) {
+ currentQnameModule = module.getQNameModule();
+ } else {
+ currentQnameModule = leafrefModule.getQNameModule();
+ }
}
if (currentParsingState == ParsingState.PREDICATE_PATH_EQUALITY_EXPR) {
return leafRefPath;
}
- private URI getNamespaceForImportPrefix(final String prefix) {
- final ModuleImport moduleImport = getModuleImport(prefix);
- return schemaContext.findModule(moduleImport.getModuleName(), moduleImport.getRevision()).get().getNamespace();
- }
-
- private Optional<QNameModule> getQNameModuleForImportPrefix(final String prefix) {
- final ModuleImport moduleImport = getModuleImport(prefix);
+ private Optional<QNameModule> getQNameModuleForImportPrefix(final Module targetModule, final String prefix) {
+ final ModuleImport moduleImport = getModuleImport(targetModule, prefix);
if (moduleImport == null) {
return Optional.empty();
}
return schemaContext.findModule(moduleName, revision).map(Module::getQNameModule);
}
- private ModuleImport getModuleImport(final String prefix) {
- return module.getImports().stream().filter(imp -> prefix.equals(imp.getPrefix())).findFirst().orElse(null);
+ private ModuleImport getModuleImport(final Module targetModule, final String prefix) {
+ return targetModule.getImports().stream()
+ .filter(imp -> prefix.equals(imp.getPrefix())).findFirst().orElse(null);
}
}