Fixed implementation in TypeProviderImpl - if leafref references the leaf through the conditional XPath the method will no more returns null but wrapped Type as java.lang.Object.
Added test into GeneratedTypesTest for conditional XPath.
Fixed controller-network-ne.yang - changed name of flow-tables to flow-tables2 - the build should no more fail.
Fixed wrong transformation of yang namespace to java package in case that yang namespace contains numbers right after the "."
Added check into BindingGeneratorUtil - validateJavaPackage.
Refactored and commented SchemaContextUtil.java
Signed-off-by: Lukas Sedlak <lsedlak@cisco.com>
final String strXPath = xpath.toString();
if (strXPath != null) {
- if (strXPath.matches(".*//[.* | .*//].*")) {
+ if (strXPath.contains("[")) {
returnType = Types.typeForClass(Object.class);
} else {
final Module module = findParentModuleForTypeDefinition(schemaContext, leafrefType);
package org.opendaylight.controller.sal.binding.generator.impl;
import static org.junit.Assert.*;
+import static org.junit.Assert.assertEquals;
import java.io.File;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;
+import org.junit.Ignore;
import org.junit.Test;
import org.opendaylight.controller.sal.binding.generator.api.BindingGenerator;
import org.opendaylight.controller.sal.binding.model.api.GeneratedProperty;
assertNotNull(inetTypesPath);
assertNotNull(yangTypesPath);
- // final SchemaContext context = resolveSchemaContextFromFiles(
- // topologyPath, interfacesPath, ifTypePath, inetTypesPath,
- // yangTypesPath);
+ // final SchemaContext context = resolveSchemaContextFromFiles(topologyPath, interfacesPath, ifTypePath,
+ // inetTypesPath, yangTypesPath);
final SchemaContext context = resolveSchemaContextFromFiles(topologyPath, interfacesPath, inetTypesPath,
yangTypesPath);
assertNotNull(context);
GeneratedType gtDest = null;
GeneratedType gtTunnel = null;
GeneratedTransferObject gtTunnelKey = null;
+ GeneratedType gtTopology = null;
for (final Type type : genTypes) {
String name = type.getName();
if ("InterfaceKey".equals(name)) {
gtTunnel = (GeneratedType) type;
} else if ("TunnelKey".equals(name)) {
gtTunnelKey = (GeneratedTransferObject) type;
+ } else if ("Topology".equals(name)) {
+ gtTopology = (GeneratedType) type;
}
}
assertNotNull(gtDest);
assertNotNull(gtTunnel);
assertNotNull(gtTunnelKey);
+ assertNotNull(gtTopology);
+
+ // Topology
+ final List<MethodSignature> gtTopoMethods = gtTopology.getMethodDefinitions();
+ assertNotNull(gtTopoMethods);
+ MethodSignature condLeafref = null;
+ for (final MethodSignature method : gtTopoMethods) {
+ if (method.getName().equals("getCondLeafref")) {
+ condLeafref = method;
+ }
+ }
+ assertNotNull(condLeafref);
+ Type condLeafRT = condLeafref.getReturnType();
+ assertNotNull(condLeafRT);
+ assertEquals("java.lang.Object", condLeafRT.getFullyQualifiedName());
// InterfaceId
final List<GeneratedProperty> gtIfcKeyProps = gtIfcKey.getProperties();
assertNotNull(ifcIdProp);
Type ifcIdPropType = ifcIdProp.getReturnType();
assertNotNull(ifcIdPropType);
- assertFalse(ifcIdPropType.equals("java.lang.Void"));
- assertEquals(ifcIdPropType.getName(), "String");
+ assertEquals("java.lang.String", ifcIdPropType.getFullyQualifiedName());
// Interface
final List<MethodSignature> gtIfcMethods = gtIfc.getMethodDefinitions();
assertNotNull(getIfcKey);
Type getIfcKeyType = getIfcKey.getReturnType();
assertNotNull(getIfcKeyType);
- assertFalse(getIfcKeyType.equals("java.lang.Void"));
- assertEquals(getIfcKeyType.getName(), "InterfaceKey");
+ assertNotSame("java.lang.Void", getIfcKeyType);
+ assertEquals("InterfaceKey", getIfcKeyType.getName());
assertNotNull(getHigherLayerIf);
Type getHigherLayerIfType = getHigherLayerIf.getReturnType();
assertNotNull(getHigherLayerIfType);
- assertFalse(getHigherLayerIfType.equals("java.lang.Void"));
- assertEquals(getHigherLayerIfType.getName(), "List");
+ assertNotSame("java.lang.Void", getHigherLayerIfType);
+ assertEquals("List", getHigherLayerIfType.getName());
// NetworkLink
final List<MethodSignature> gtNetworkLinkMethods = gtNetworkLink.getMethodDefinitions();
assertNotNull(getIfc);
Type getIfcType = getIfc.getReturnType();
assertNotNull(getIfcType);
- assertFalse(getIfcType.equals("java.lang.Void"));
- assertEquals(getIfcType.getName(), "String");
+ assertNotSame("java.lang.Void", getIfcType);
+ assertEquals("String", getIfcType.getName());
// SourceNode
final List<MethodSignature> gtSourceMethods = gtSource.getMethodDefinitions();
assertNotNull(getIdSource);
Type getIdType = getIdSource.getReturnType();
assertNotNull(getIdType);
- assertFalse(getIdType.equals("java.lang.Void"));
- assertEquals(getIdType.getName(), "Uri");
+ assertNotSame("java.lang.Void", getIdType);
+ assertEquals("Uri", getIdType.getName());
// DestinationNode
final List<MethodSignature> gtDestMethods = gtDest.getMethodDefinitions();
assertNotNull(getIdDest);
Type getIdDestType = getIdDest.getReturnType();
assertNotNull(getIdDestType);
- assertFalse(getIdDestType.equals("java.lang.Void"));
- assertEquals(getIdDestType.getName(), "Uri");
+ assertNotSame("java.lang.Void", getIdDestType);
+ assertEquals("Uri", getIdDestType.getName());
// Tunnel
final List<MethodSignature> gtTunnelMethods = gtTunnel.getMethodDefinitions();
assertNotNull(getTunnelKey);
Type getTunnelKeyType = getTunnelKey.getReturnType();
assertNotNull(getTunnelKeyType);
- assertFalse(getTunnelKeyType.equals("java.lang.Void"));
- assertEquals(getTunnelKeyType.getName(), "TunnelKey");
+ assertNotSame("java.lang.Void", getTunnelKeyType);
+ assertEquals("TunnelKey", getTunnelKeyType.getName());
// TunnelKey
final List<GeneratedProperty> gtTunnelKeyProps = gtTunnelKey.getProperties();
assertNotNull(tunnelId);
Type tunnelIdType = tunnelId.getReturnType();
assertNotNull(tunnelIdType);
- assertFalse(tunnelIdType.equals("java.lang.Void"));
- assertEquals(tunnelIdType.getName(), "Uri");
+ assertNotSame("java.lang.Void", tunnelIdType);
+ assertEquals("Uri", tunnelIdType.getName());
}
@Test
assertEquals(3, simpleContainer.getMethodDefinitions().size());
assertEquals(2, nestedContainer.getMethodDefinitions().size());
- int setFooMethodCounter = 0;
int getFooMethodCounter = 0;
int getBarMethodCounter = 0;
int getNestedContainerCounter = 0;
String getFooMethodReturnTypeName = "";
- String setFooMethodInputParamName = "";
- String setFooMethodInputParamTypeName = "";
String getBarMethodReturnTypeName = "";
String getNestedContainerReturnTypeName = "";
for (final MethodSignature method : simpleContainer.getMethodDefinitions()) {
getFooMethodReturnTypeName = method.getReturnType().getName();
}
- if (method.getName().equals("setFoo")) {
- setFooMethodCounter++;
- final MethodSignature.Parameter param = method.getParameters().get(0);
- setFooMethodInputParamName = param.getName();
- setFooMethodInputParamTypeName = param.getType().getName();
- }
-
if (method.getName().equals("getBar")) {
getBarMethodCounter++;
getBarMethodReturnTypeName = method.getReturnType().getName();
}
}
- assertEquals(getFooMethodCounter, 1);
- assertEquals(getFooMethodReturnTypeName, "Integer");
-
- // TODO no setter methods, because 'config' is default true
- // assertEquals(setFooMethodCounter, 1);
- // assertEquals(setFooMethodInputParamName, "foo");
- // assertEquals(setFooMethodInputParamTypeName, "Integer");
+ assertEquals(1, getFooMethodCounter);
+ assertEquals("Integer", getFooMethodReturnTypeName);
- assertEquals(getBarMethodCounter, 1);
- assertEquals(getBarMethodReturnTypeName, "String");
+ assertEquals(1, getBarMethodCounter);
+ assertEquals("String", getBarMethodReturnTypeName);
- assertEquals(getNestedContainerCounter, 1);
- assertEquals(getNestedContainerReturnTypeName, "NestedContainer");
+ assertEquals(1, getNestedContainerCounter);
+ assertEquals("NestedContainer", getNestedContainerReturnTypeName);
- setFooMethodCounter = 0;
getFooMethodCounter = 0;
getBarMethodCounter = 0;
- int setBarMethodCounter = 0;
getFooMethodReturnTypeName = "";
- setFooMethodInputParamName = "";
- setFooMethodInputParamTypeName = "";
getBarMethodReturnTypeName = "";
- String setBarMethodInputParamName = "";
- String setBarMethodInputParamTypeName = "";
for (final MethodSignature method : nestedContainer.getMethodDefinitions()) {
getFooMethodReturnTypeName = method.getReturnType().getName();
}
- if (method.getName().equals("setFoo")) {
- setFooMethodCounter++;
- final MethodSignature.Parameter param = method.getParameters().get(0);
- setFooMethodInputParamName = param.getName();
- setFooMethodInputParamTypeName = param.getType().getName();
- }
-
if (method.getName().equals("getBar")) {
getBarMethodCounter++;
getBarMethodReturnTypeName = method.getReturnType().getName();
}
-
- if (method.getName().equals("setBar")) {
- setBarMethodCounter++;
- final MethodSignature.Parameter param = method.getParameters().get(0);
- setBarMethodInputParamName = param.getName();
- setBarMethodInputParamTypeName = param.getType().getName();
- }
}
assertEquals(1, getFooMethodCounter);
- assertEquals(getFooMethodReturnTypeName, "Short");
-
- // TODO no setter methods, because 'config' is default true
- // assertEquals(1, setFooMethodCounter);
- // assertEquals(setFooMethodInputParamName, "foo");
- // assertEquals(setFooMethodInputParamTypeName, "Short");
+ assertEquals("Short", getFooMethodReturnTypeName);
assertEquals(1, getBarMethodCounter);
- assertEquals(getBarMethodReturnTypeName, "String");
-
- // TODO no setter methods, because 'config' is default true
- // assertEquals(1, setBarMethodCounter);
- // assertEquals(setBarMethodInputParamName, "bar");
- // assertEquals(setBarMethodInputParamTypeName, "String");
+ assertEquals("String", getBarMethodReturnTypeName);
}
@Test
assertEquals(3, simpleContainer.getMethodDefinitions().size());
assertEquals(2, nestedContainer.getMethodDefinitions().size());
- int setFooMethodCounter = 0;
int getFooMethodCounter = 0;
int getBarMethodCounter = 0;
int getNestedContainerCounter = 0;
String getFooMethodReturnTypeName = "";
- String setFooMethodInputParamName = "";
- String setFooMethodInputParamTypeName = "";
String getBarMethodReturnTypeName = "";
String getNestedContainerReturnTypeName = "";
for (final MethodSignature method : simpleContainer.getMethodDefinitions()) {
getFooMethodReturnTypeName = method.getReturnType().getName();
}
- if (method.getName().equals("setFoo")) {
- setFooMethodCounter++;
- final MethodSignature.Parameter param = method.getParameters().get(0);
- setFooMethodInputParamName = param.getName();
- setFooMethodInputParamTypeName = param.getType().getName();
- }
-
if (method.getName().equals("getBar")) {
getBarMethodCounter++;
getBarMethodReturnTypeName = method.getReturnType().getName();
}
assertEquals(1, getFooMethodCounter);
- assertEquals(getFooMethodReturnTypeName, "List");
-
- // TODO no setter methods, because 'config' is default true
- // assertEquals(1, setFooMethodCounter);
- // assertEquals(setFooMethodInputParamName, "foo");
- // assertEquals(setFooMethodInputParamTypeName, "List");
+ assertEquals("List", getFooMethodReturnTypeName);
assertEquals(1, getBarMethodCounter);
- assertEquals(getBarMethodReturnTypeName, "String");
+ assertEquals("String", getBarMethodReturnTypeName);
assertEquals(1, getNestedContainerCounter);
- assertEquals(getNestedContainerReturnTypeName, "NestedContainer");
+ assertEquals("NestedContainer", getNestedContainerReturnTypeName);
- setFooMethodCounter = 0;
getFooMethodCounter = 0;
getBarMethodCounter = 0;
getFooMethodReturnTypeName = "";
- setFooMethodInputParamName = "";
- setFooMethodInputParamTypeName = "";
getBarMethodReturnTypeName = "";
for (final MethodSignature method : nestedContainer.getMethodDefinitions()) {
getFooMethodReturnTypeName = method.getReturnType().getName();
}
- if (method.getName().equals("setFoo")) {
- setFooMethodCounter++;
- final MethodSignature.Parameter param = method.getParameters().get(0);
- setFooMethodInputParamName = param.getName();
- setFooMethodInputParamTypeName = param.getType().getName();
- }
-
if (method.getName().equals("getBar")) {
getBarMethodCounter++;
getBarMethodReturnTypeName = method.getReturnType().getName();
}
assertEquals(1, getFooMethodCounter);
- assertEquals(getFooMethodReturnTypeName, "Short");
-
- // TODO no setter methods, because 'config' is default true
- // assertEquals(1, setFooMethodCounter);
- // assertEquals(setFooMethodInputParamName, "foo");
- // assertEquals(setFooMethodInputParamTypeName, "Short");
+ assertEquals("Short", getFooMethodReturnTypeName);
assertEquals(1, getBarMethodCounter);
- assertEquals(getBarMethodReturnTypeName, "List");
+ assertEquals("List", getBarMethodReturnTypeName);
}
@Test
assertNotNull(genTypes);
assertEquals(6, genTypes.size());
- int genTypesCount = 0;
- int genTOsCount = 0;
-
int listParentContainerMethodsCount = 0;
int simpleListMethodsCount = 0;
int listChildContainerMethodsCount = 0;
final GeneratedType genType = (GeneratedType) type;
if (genType.getName().equals("ListParentContainer")) {
listParentContainerMethodsCount = genType.getMethodDefinitions().size();
- genTypesCount++;
} else if (genType.getName().equals("SimpleList")) {
simpleListMethodsCount = genType.getMethodDefinitions().size();
final List<MethodSignature> methods = genType.getMethodDefinitions();
getBarMethodCount++;
}
}
- genTypesCount++;
} else if (genType.getName().equals("ListChildContainer")) {
listChildContainerMethodsCount = genType.getMethodDefinitions().size();
- genTypesCount++;
}
} else if (type instanceof GeneratedTransferObject) {
- genTOsCount++;
final GeneratedTransferObject genTO = (GeneratedTransferObject) type;
final List<GeneratedProperty> properties = genTO.getProperties();
final List<GeneratedProperty> hashProps = genTO.getHashCodeIdentifiers();
module demo-topology {
yang-version 1;
- namespace "";
+ namespace "urn:model.1demo-275topology.4.5.my";
prefix "tp";
organization "OPEN DAYLIGHT";
UNIQUE topology identifier.";
}
+ leaf cond-leafref {
+ type leafref {
+ path "/tp:topology/tp:network-nodes/tp:network-node[node-id = 'super-node']";
+ }
+ }
+
container network-nodes {
list network-node {
key "node-id";
if (packNameParts != null) {
final StringBuilder builder = new StringBuilder();
for (int i = 0; i < packNameParts.length; ++i) {
- if (JAVA_RESERVED_WORDS.contains(packNameParts[i])) {
- packNameParts[i] = "_" + packNameParts[i];
+ final String packNamePart = packNameParts[i];
+ if (Character.isDigit(packNamePart.charAt(0))) {
+ packNameParts[i] = "_" + packNamePart;
+ } else if (JAVA_RESERVED_WORDS.contains(packNamePart)) {
+ packNameParts[i] = "_" + packNamePart;
}
if (i > 0) {
builder.append(".");
+++ /dev/null
-<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"\r
- xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">\r
- <modelVersion>4.0.0</modelVersion>\r
- <groupId>org.opendaylight.controller</groupId>\r
- <artifactId>code-generator-demo</artifactId>\r
- <version>1.0</version>\r
- <packaging>jar</packaging>\r
-\r
- <dependencies>\r
- <dependency>\r
- <groupId>org.antlr</groupId>\r
- <artifactId>antlr4</artifactId>\r
- <version>4.0</version>\r
- </dependency>\r
- <dependency>\r
- <groupId>org.opendaylight.controller</groupId>\r
- <artifactId>binding-generator-impl</artifactId>\r
- </dependency>\r
- <dependency>\r
- <groupId>org.opendaylight.controller</groupId>\r
- <artifactId>binding-java-api-generator</artifactId>\r
- </dependency>\r
- </dependencies>\r
-\r
- <build>\r
- <plugins>\r
- <plugin>\r
- <artifactId>maven-assembly-plugin</artifactId>\r
- <version>2.4</version>\r
- <configuration>\r
- <descriptorRefs>\r
- <descriptorRef>jar-with-dependencies</descriptorRef>\r
- </descriptorRefs>\r
- <archive>\r
- <manifest>\r
- <mainClass>org.opendaylight.controller.yang.Demo</mainClass>\r
- </manifest>\r
- </archive>\r
- </configuration>\r
- <executions>\r
- <execution>\r
- <id>make-assembly</id>\r
- <phase>package</phase>\r
- <goals>\r
- <goal>single</goal>\r
- </goals>\r
- </execution>\r
- </executions>\r
- </plugin>\r
- </plugins>\r
- </build>\r
-</project>\r
-\r
+++ /dev/null
-/*
- * Copyright (c) 2013 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.controller.yang;
-
-import java.io.File;
-import java.util.ArrayList;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Set;
-
-import org.opendaylight.controller.sal.binding.generator.api.BindingGenerator;
-import org.opendaylight.controller.sal.binding.generator.impl.BindingGeneratorImpl;
-import org.opendaylight.controller.sal.binding.model.api.GeneratedTransferObject;
-import org.opendaylight.controller.sal.binding.model.api.GeneratedType;
-import org.opendaylight.controller.sal.binding.model.api.Type;
-import org.opendaylight.controller.sal.java.api.generator.GeneratorJavaFile;
-import org.opendaylight.controller.yang.model.api.Module;
-import org.opendaylight.controller.yang.model.api.SchemaContext;
-import org.opendaylight.controller.yang.parser.impl.YangParserImpl;
-
-public class Demo {
- private static final String ERR_MSG = "2 parameters expected: 1. -f=<path-to-input-folder>, 2. -o=<output-folder>";
-
- public static void main(String[] args) throws Exception {
- if (args.length != 2) {
- System.err.println(ERR_MSG);
- return;
- }
-
- String inputFilesDir = null;
- String outputFilesDir = null;
- if (args[0].startsWith("-f=")) {
- inputFilesDir = args[0].substring(3);
- } else {
- System.err.println("Missing input-folder declaration (-f=)");
- }
-
- if (args[1].startsWith("-o=")) {
- outputFilesDir = args[1].substring(3);
- } else {
- System.err.println("Missing output-folder declaration (-o=)");
- }
-
- File resourceDir = new File(inputFilesDir);
- if (!resourceDir.exists()) {
- throw new IllegalArgumentException(
- "Specified input-folder does not exists: "
- + resourceDir.getAbsolutePath());
- }
-
- final File outputFolder = new File(outputFilesDir);
- if (!outputFolder.exists()) {
- outputFolder.mkdirs();
- }
-
- String[] dirList = resourceDir.list();
- List<File> inputFiles = new ArrayList<File>();
- for (String fileName : dirList) {
- inputFiles.add(new File(resourceDir, fileName));
- }
-
- final YangParserImpl parser = new YangParserImpl();
- final BindingGenerator bindingGenerator = new BindingGeneratorImpl();
- final Set<Module> modulesToBuild = parser.parseYangModels(inputFiles);
-
- final SchemaContext context = parser
- .resolveSchemaContext(modulesToBuild);
- final List<Type> types = bindingGenerator.generateTypes(context);
- final Set<GeneratedType> typesToGenerate = new HashSet<GeneratedType>();
- final Set<GeneratedTransferObject> tosToGenerate = new HashSet<GeneratedTransferObject>();
- for (Type type : types) {
- if (type instanceof GeneratedType && !(type instanceof GeneratedTransferObject)) {
- typesToGenerate.add((GeneratedType) type);
- }
-
- if (type instanceof GeneratedTransferObject) {
- tosToGenerate.add((GeneratedTransferObject) type);
- } else if (type instanceof GeneratedType) {
- typesToGenerate.add((GeneratedType) type);
- }
- }
-
- final GeneratorJavaFile generator = new GeneratorJavaFile(typesToGenerate, tosToGenerate);
-
- generator.generateToFile(outputFolder);
- System.out.println("Modules built: " + modulesToBuild.size());
- }
-}
+++ /dev/null
-module demo-topology {
- yang-version 1;
- namespace "urn:demo.simple-topology";
- prefix "tp";
- import simple-list-demo { prefix "simple"; revision-date 2008-01-01; }
- import controller-network {prefix "cn";}
- import mount {prefix "mnt";}
-
- organization "OPEN DAYLIGHT";
- contact "http://www.opendaylight.org/";
-
- description "
- This module contains the definitions of elements that creates network
- topology i.e. definition of network nodes and links. This module is
- not designed to be used solely for network representation. This module
- SHOULD be used as base module in defining the network topology.
- ";
-
- revision "2013-02-08"{
- reference " WILL BE DEFINED LATER";
- }
-
-
-
-
-
- deviation /base:system/base:user/base:type {
- deviate add {
- default "admin"; // new users are 'admin' by default
- }
- }
-
- deviation /base:system/base:name-server {
- deviate replace {
- max-elements 3;
- }
- }
-
- deviation "/base:system" {
- deviate delete {
- must "daytime or time";
- }
- }
-
-
-
-
-
-
- grouping target {
- status "current";
- leaf address {
- type inet:ip-address;
- description "Target IP address";
- }
- leaf port {
- type inet:port-number;
- description "Target port number";
- }
- }
-
- augment "/cn:network/cn:topologies/cn:topology" {
- container prefixes {
- container "prefix" {
- leaf id {
- type string;
-
- description "";
- }
-
- leaf-list advertising-node-id {
- type cn:node-ref;
-
- description "";
- }
- }
- }
- mnt:mountpoint point {
- mnt:target-ref target;
-
- }
- }
-
- container peer {
- container destination {
- uses target;
- }
- }
-
- container topology {
-
- leaf ifType {
- type enumeration {
- enum ethernet;
- enum atm;
- }
- }
- leaf ifMTU {
- type uint32;
- }
- must "ifType != 'ethernet' or " +
- "(ifType = 'ethernet' and ifMTU = 1500)" {
- error-message "An ethernet MTU must be 1500";
- }
-
- presence "test-presence";
-
- description "
- This is the model of abstract topology which contains only Network
- Nodes and Network Links. Each topology MUST be identified by
- unique topology-id for reason that the store could contain many
- topologies.
- ";
-
- leaf topology-id {
- type string;
- description "
- It is presumed that datastore will contain many topologies. To
- distinguish between topologies it is vital to have UNIQUE
- topology identifier.
- ";
- }
-
- container network-nodes {
- list network-node {
- ordered-by system;
- description "The list of network nodes defined for topology.";
-
- key "node-id";
-
- leaf node-id {
- type string;
- description "The Topology identifier of network-node.";
- }
-
- list network-interface {
- key "interface-id";
-
- leaf interface-id {
- type uint8;
- }
-
- leaf interface-address {
- type string;
- }
- }
-
- container node-attributes {
- description "
- Additional attributes that can Network Node contains.
- ";
-
- leaf geo-latitude {
- type decimal64 {
- fraction-digits 2;
- }
- config true;
- }
-
- leaf geo-longitude {
- type decimal64 {
- fraction-digits 2;
- }
- config true;
- }
- }
- }
- }
-
- container network-links {
- list network-link {
- description "
- The Network Link which is defined by Local (Source) and
- Remote (Destination) Network Nodes. Every link MUST be
- defined either by identifier and his local and remote
- Network Nodes (in real applications it is common that many
- links are originated from one node and end up in same
- remote node). To ensure that we would always know to
- distinguish between links, every link SHOULD have
- identifier.
- ";
- key "link-id";
-
- leaf link-id {
- type string;
- description "";
- }
-
- container source {
- leaf node-id {
- type string;
- description "Source node identifier.";
- }
- }
-
- container destination {
- leaf node-id {
- type string;
- description "Destination node identifier.";
- }
- }
-
- container link-attributes {
- description "Aditional attributes that can Network Link contains.";
- }
- }
- }
- }
-
- rpc activate-software-image {
- input {
- leaf image-name {
- type string;
- }
- }
- output {
- leaf status {
- type string;
- }
- }
- }
-
-}
+++ /dev/null
-module types1 {
- yang-version 1;
- namespace "urn:simple.container.demo";
- prefix "t1";
-
-
- organization "Cisco";
-
- contact "WILL-BE-DEFINED-LATER";
-
-
- leaf mybits {
- type bits {
- bit disable-nagle {
- position 0;
- }
- bit auto-sense-speed {
- position 1;
- }
- bit 10-Mb-only {
- position 2;
- }
- }
- default "auto-sense-speed";
- }
-
- container interfaces {
- list ifEntry {
- key "ifIndex";
-
- leaf ifIndex {
- type uint32;
- }
- leaf ifDescr {
- type string;
- }
- leaf ifType {
- type uint8;
- }
- leaf ifMtu {
- type int32;
- }
- }
- }
-
-
- container topology {
- leaf name {
- type string;
- }
- }
-
-
-
-
-
-
-
-// typedef my-string {
-// type string {
-// length "0..4";
-// pattern "[0-9a-fA-F]*";
-// }
-// }
-
-
-// leaf completed {
-// type types2:percent;
-// }
-
-// leaf testleaf {
-// type data:my-base-int32-type;
-// }
-
-// leaf-list domain-search {
-// type string;
-// description "List of domain names to search";
-// }
-
-}
+++ /dev/null
-module types2 {
- yang-version 1;
- namespace "urn:simple.types.data.demo";
- prefix "t2";
-
- import types1 {
- prefix "t1";
- }
-
- organization "Cisco";
-
- contact "WILL-BE-DEFINED-LATER";
-
- description "This is types-data test description";
-
- revision "2013-02-27" {
- reference " WILL BE DEFINED LATER";
- }
-
-
- augment "/t1:interfaces/t1:ifEntry" {
- when "t1:ifType='ds0'";
- leaf ds0ChannelNumber {
- type string;
- }
- }
-
- typedef my-leaf-ref {
- type leafref {
- path "/t1:topology/t1:name";
- }
- description "This type is used for leafs that reference network node instance.";
- }
-
-}
+++ /dev/null
-module types3 {
- yang-version 1;
- namespace "urn:simple.types3.data.demo";
- prefix "scd";
-
- organization "Cisco";
-
- contact "WILL-BE-DEFINED-LATER";
-
- description "This is types-data test description";
-
- revision "2013-02-27" {
- reference " WILL BE DEFINED LATER";
- }
-
- typedef my-decimal {
- type decimal64 {
- fraction-digits 2;
- }
- }
-
- typedef my-base-int32-type {
- type int32 {
- range "0..32";
- }
- }
-
- typedef percent {
- type uint8 {
- range "0 .. 100";
- }
- description "Percentage";
- }
-
-}
augment "/cn:network/cn:network-elements/cn:network-element" {
- container flow-tables {
+ container flow-tables2 {
list flow-table {
key "id";
-// vi: set smarttab sw=4 tabstop=4:
-module abstract-topology {
+module demo-topology {
yang-version 1;
- namespace "pre:simple.test.demo";
+ namespace "urn:model.1demo-275topology.4.5.my";
prefix "tp";
- import ietf-inet-types { prefix "inet"; }
- import abstract-prefixes { prefix "abs-pref"; }
-
- organization "OPEN DAYLIGHT";
+ organization "OPEN DAYLIGHT";
contact "http://www.opendaylight.org/";
description "
not designed to be used solely for network representation. This module
SHOULD be used as base module in defining the network topology.
";
-
- revision "2012-02-08" {
- reference " WILL BE DEFINED LATER";
- }
-
- typedef topology-id-ref {
- type leafref {
- path "/tp:topology/tp:topology-id";
- }
- description "This type is used for leafs that reference topology identifier instance.";
- }
- typedef network-node-id-ref {
- type leafref {
- path "/tp:topology/tp:network-nodes/tp:network-node/tp:node-id";
- }
- description "This type is used for leafs that reference network node instance.";
- }
-
- typedef link-id-ref {
- type leafref {
- path "/tp:topology/tp:network-links/tp:network-link/tp:link-id";
- }
- description "This type is used for leafs that reference network link instance.";
+ revision "2013-02-08"{
+ reference " WILL BE DEFINED LATER";
}
container topology {
";
leaf topology-id {
- type inet:uri;
+ type string;
description "
It is presumed that datastore will contain many topologies. To
distinguish between topologies it is vital to have UNIQUE
key "node-id";
leaf node-id {
- type inet:uri;
+ type string;
description "The Topology identifier of network-node.";
}
-
- container attributes {
+
+ list network-interface {
+ key "interface-id";
+
+ leaf interface-id {
+ type uint8;
+ }
+
+ leaf interface-address {
+ type string;
+ }
+ }
+
+ container node-attributes {
description "
Additional attributes that can Network Node contains.
";
+
+ leaf geo-latitude {
+ type decimal64 {
+ fraction-digits 2;
+ }
+ config true;
+ }
+
+ leaf geo-longitude {
+ type decimal64 {
+ fraction-digits 2;
+ }
+ config true;
+ }
}
}
}
key "link-id";
leaf link-id {
- type inet:uri;
+ type string;
description "";
}
container source {
leaf node-id {
- type node-id-ref;
+ type string;
description "Source node identifier.";
}
}
container destination {
leaf node-id {
- type node-id-ref;
+ type string;
description "Destination node identifier.";
}
}
- container attributes {
+ container link-attributes {
description "Aditional attributes that can Network Link contains.";
}
}
}
}
-
- //TODO: add base operations
-}
+}
\ No newline at end of file
import org.opendaylight.controller.yang.common.QName;
import org.opendaylight.controller.yang.model.api.*;
+/**
+ * The Schema Context Util contains support methods for searching through Schema Context modules for specified schema
+ * nodes via Schema Path or Revision Aware XPath. The Schema Context Util is designed as mixin,
+ * so it is not instantiable.
+ *
+ * @author Lukas Sedlak <lsedlak@cisco.com>
+ */
public final class SchemaContextUtil {
private SchemaContextUtil() {
}
+ /**
+ * Method attempts to find DataSchemaNode in Schema Context via specified Schema Path. The returned
+ * DataSchemaNode from method will be the node at the end of the SchemaPath. If the DataSchemaNode is not present
+ * in the Schema Context the method will return <code>null</code>.
+ * <br>
+ * In case that Schema Context or Schema Path are not specified correctly (i.e. contains <code>null</code>
+ * values) the method will return IllegalArgumentException.
+ *
+ * @throws IllegalArgumentException
+ *
+ * @param context
+ * Schema Context
+ * @param schemaPath
+ * Schema Path to search for
+ * @return DataSchemaNode from the end of the Schema Path or
+ * <code>null</code> if the Node is not present.
+ */
public static DataSchemaNode findDataSchemaNode(final SchemaContext context, final SchemaPath schemaPath) {
- if (schemaPath != null) {
- final Module module = resolveModuleFromSchemaPath(context, schemaPath);
- final Queue<QName> prefixedPath = new LinkedList<>(schemaPath.getPath());
+ if (context == null) {
+ throw new IllegalArgumentException("Schema Context reference cannot be NULL!");
+ }
+ if (schemaPath == null) {
+ throw new IllegalArgumentException("Schema Path reference cannot be NULL");
+ }
- if ((module != null) && (prefixedPath != null)) {
- return findSchemaNodeForGivenPath(context, module, prefixedPath);
- }
+ final Module module = resolveModuleFromSchemaPath(context, schemaPath);
+ final Queue<QName> prefixedPath = new LinkedList<>(schemaPath.getPath());
+
+ if ((module != null) && (prefixedPath != null)) {
+ return findSchemaNodeForGivenPath(context, module, prefixedPath);
}
return null;
}
+ /**
+ * Method attempts to find DataSchemaNode inside of provided Schema Context and Yang Module accordingly to
+ * Non-conditional Revision Aware XPath. The specified Module MUST be present in Schema Context otherwise the
+ * operation would fail and return <code>null</code>.
+ * <br>
+ * The Revision Aware XPath MUST be specified WITHOUT the conditional statement (i.e. without [cond]) in path,
+ * because in this state the Schema Context is completely unaware of data state and will be not able to properly
+ * resolve XPath. If the XPath contains condition the method will return IllegalArgumentException.
+ * <br>
+ * In case that Schema Context or Module or Revision Aware XPath contains <code>null</code> references the method
+ * will throw IllegalArgumentException
+ * <br>
+ * If the Revision Aware XPath is correct and desired Data Schema Node is present in Yang module or in depending
+ * module in Schema Context the method will return specified Data Schema Node, otherwise the operation will fail
+ * and method will return <code>null</code>.
+ *
+ * @throws IllegalArgumentException
+ *
+ * @param context Schema Context
+ * @param module Yang Module
+ * @param nonCondXPath Non Conditional Revision Aware XPath
+ * @return Returns Data Schema Node for specified Schema Context for given Non-conditional Revision Aware XPath,
+ * or <code>null</code> if the DataSchemaNode is not present in Schema Context.
+ */
public static DataSchemaNode findDataSchemaNode(final SchemaContext context, final Module module,
final RevisionAwareXPath nonCondXPath) {
- if (nonCondXPath != null) {
- final String strXPath = nonCondXPath.toString();
+ if (context == null) {
+ throw new IllegalArgumentException("Schema Context reference cannot be NULL!");
+ }
+ if (module == null) {
+ throw new IllegalArgumentException("Module reference cannot be NULL!");
+ }
+ if (nonCondXPath == null) {
+ throw new IllegalArgumentException("Non Conditional Revision Aware XPath cannot be NULL!");
+ }
- if (strXPath != null) {
- if (strXPath.matches(".*//[.* | .*//].*")) {
- // TODO: function to escape conditions in path
- }
- if (nonCondXPath.isAbsolute()) {
- final Queue<QName> qnamedPath = xpathToQNamePath(context, module, strXPath);
- if (qnamedPath != null) {
- final DataSchemaNode dataNode = findSchemaNodeForGivenPath(context, module, qnamedPath);
- return dataNode;
- }
+ final String strXPath = nonCondXPath.toString();
+ if (strXPath != null) {
+ if (strXPath.contains("[")) {
+ throw new IllegalArgumentException("Revision Aware XPath cannot contains condition!");
+ }
+ if (nonCondXPath.isAbsolute()) {
+ final Queue<QName> qnamedPath = xpathToQNamePath(context, module, strXPath);
+ if (qnamedPath != null) {
+ final DataSchemaNode dataNode = findSchemaNodeForGivenPath(context, module, qnamedPath);
+ return dataNode;
}
}
}
return null;
}
+ /**
+ * Method attempts to find DataSchemaNode inside of provided Schema Context and Yang Module accordingly to
+ * Non-conditional relative Revision Aware XPath. The specified Module MUST be present in Schema Context otherwise
+ * the operation would fail and return <code>null</code>.
+ * <br>
+ * The relative Revision Aware XPath MUST be specified WITHOUT the conditional statement (i.e. without [cond]) in
+ * path, because in this state the Schema Context is completely unaware of data state and will be not able to
+ * properly resolve XPath. If the XPath contains condition the method will return IllegalArgumentException.
+ * <br>
+ * The Actual Schema Node MUST be specified correctly because from this Schema Node will search starts. If the
+ * Actual Schema Node is not correct the operation will simply fail, because it will be unable to find desired
+ * DataSchemaNode.
+ * <br>
+ * In case that Schema Context or Module or Actual Schema Node or relative Revision Aware XPath contains
+ * <code>null</code> references the method will throw IllegalArgumentException
+ * <br>
+ * If the Revision Aware XPath doesn't have flag <code>isAbsolute == false</code> the method will
+ * throw IllegalArgumentException.
+ * <br>
+ * If the relative Revision Aware XPath is correct and desired Data Schema Node is present in Yang module or in
+ * depending module in Schema Context the method will return specified Data Schema Node,
+ * otherwise the operation will fail
+ * and method will return <code>null</code>.
+ *
+ * @throws IllegalArgumentException
+ *
+ * @param context Schema Context
+ * @param module Yang Module
+ * @param actualSchemaNode Actual Schema Node
+ * @param relativeXPath Relative Non Conditional Revision Aware XPath
+ * @return DataSchemaNode if is present in specified Schema Context for given relative Revision Aware XPath,
+ * otherwise will return <code>null</code>.
+ */
public static DataSchemaNode findDataSchemaNodeForRelativeXPath(final SchemaContext context, final Module module,
final SchemaNode actualSchemaNode, final RevisionAwareXPath relativeXPath) {
- if ((actualSchemaNode != null) && (relativeXPath != null) && !relativeXPath.isAbsolute()) {
+ if (context == null) {
+ throw new IllegalArgumentException("Schema Context reference cannot be NULL!");
+ }
+ if (module == null) {
+ throw new IllegalArgumentException("Module reference cannot be NULL!");
+ }
+ if (actualSchemaNode == null) {
+ throw new IllegalArgumentException("Actual Schema Node reference cannot be NULL!");
+ }
+ if (relativeXPath == null) {
+ throw new IllegalArgumentException("Non Conditional Revision Aware XPath cannot be NULL!");
+ }
+ if (relativeXPath.isAbsolute()) {
+ throw new IllegalArgumentException("Revision Aware XPath MUST be relative i.e. MUST contains ../, "
+ + "for non relative Revision Aware XPath use findDataSchemaNode method!");
+ }
- final SchemaPath actualNodePath = actualSchemaNode.getPath();
- if (actualNodePath != null) {
- final Queue<QName> qnamePath = resolveRelativeXPath(context, module, relativeXPath, actualNodePath);
+ final SchemaPath actualNodePath = actualSchemaNode.getPath();
+ if (actualNodePath != null) {
+ final Queue<QName> qnamePath = resolveRelativeXPath(context, module, relativeXPath, actualNodePath);
- if (qnamePath != null) {
- final DataSchemaNode dataNode = findSchemaNodeForGivenPath(context, module, qnamePath);
- return dataNode;
- }
+ if (qnamePath != null) {
+ final DataSchemaNode dataNode = findSchemaNodeForGivenPath(context, module, qnamePath);
+ return dataNode;
}
}
-
return null;
}
+ /**
+ * Retrieve information from Schema Path and returns the module reference to which Schema Node belongs. The
+ * search for correct Module is based on namespace within the last item in Schema Path. If schema context
+ * contains module with namespace specified in last item of Schema Path, then operation will returns Module
+ * reference, otherwise returns <code>null</code>
+ * <br>
+ * If Schema Context or Schema Node contains <code>null</code> references the method will throw IllegalArgumentException
+ *
+ * @throws IllegalArgumentException
+ *
+ * @param context Schema Context
+ * @param schemaPath Schema Path
+ * @return Module reference for given Schema Path if module is present in Schema Context,
+ * otherwise returns <code>null</code>
+ */
private static Module resolveModuleFromSchemaPath(final SchemaContext context, final SchemaPath schemaPath) {
- if ((schemaPath != null) && (schemaPath.getPath() != null)) {
- final List<QName> path = schemaPath.getPath();
- if (!path.isEmpty()) {
- final QName qname = path.get(path.size() - 1);
+ if (context == null) {
+ throw new IllegalArgumentException("Schema Context reference cannot be NULL!");
+ }
+ if (schemaPath == null) {
+ throw new IllegalArgumentException("Schema Path reference cannot be NULL");
+ }
- if ((qname != null) && (qname.getNamespace() != null)) {
- return context.findModuleByNamespace(qname.getNamespace());
- }
+ final List<QName> path = schemaPath.getPath();
+ if (!path.isEmpty()) {
+ final QName qname = path.get(path.size() - 1);
+
+ if ((qname != null) && (qname.getNamespace() != null)) {
+ return context.findModuleByNamespace(qname.getNamespace());
}
}
+
return null;
}
+ /**
+ * Returns the Yang Module from specified Schema Context in which the TypeDefinition is declared. If the
+ * TypeDefinition si not present in Schema Context then the method will return <code>null</code>
+ *
+ * If Schema Context or TypeDefinition contains <code>null</code> references the method will throw IllegalArgumentException
+ *
+ * @throws IllegalArgumentException
+ *
+ * @param context Schema Context
+ * @param type Type Definition
+ * @return Yang Module in which the TypeDefinition is declared, if is not present, returns <code>null</code>.
+ */
public static Module findParentModuleForTypeDefinition(final SchemaContext context, final TypeDefinition<?> type) {
final SchemaPath schemaPath = type.getPath();
- if ((schemaPath != null) && (schemaPath.getPath() != null)) {
- if (type instanceof ExtendedType) {
- List<QName> path = schemaPath.getPath();
- final QName qname = path.get(path.size() - 1);
-
- if ((qname != null) && (qname.getNamespace() != null)) {
- return context.findModuleByNamespace(qname.getNamespace());
- }
- } else {
- List<QName> path = schemaPath.getPath();
- final QName qname = path.get(path.size() - 2);
+ if (schemaPath == null) {
+ throw new IllegalArgumentException("Schema Path reference cannot be NULL");
+ }
+ final List<QName> qnamedPath = schemaPath.getPath();
+ if (qnamedPath == null || qnamedPath.isEmpty()) {
+ throw new IllegalStateException("Schema Path contains invalid state of path parts."
+ + "The Schema Path MUST contain at least ONE QName which defines namespace and Local name"
+ + "of path.");
+ }
- if ((qname != null) && (qname.getNamespace() != null)) {
- return context.findModuleByNamespace(qname.getNamespace());
- }
+ if (type instanceof ExtendedType) {
+ final QName qname = qnamedPath.get(qnamedPath.size() - 1);
+ if ((qname != null) && (qname.getNamespace() != null)) {
+ return context.findModuleByNamespace(qname.getNamespace());
+ }
+ } else {
+ final QName qname = qnamedPath.get(qnamedPath.size() - 2);
+ if ((qname != null) && (qname.getNamespace() != null)) {
+ return context.findModuleByNamespace(qname.getNamespace());
}
-
}
return null;
}
+ /**
+ * Returns parent Yang Module for specified Schema Context in which Schema Node is declared. If the Schema Node
+ * is not present in Schema Context the operation will return <code>null</code>.
+ * <br>
+ * If Schema Context or Schema Node contains <code>null</code> references the method will throw IllegalArgumentException
+ *
+ * @throws IllegalArgumentException
+ *
+ * @param context Schema Context
+ * @param schemaNode Schema Node
+ * @return Yang Module for specified Schema Context and Schema Node, if Schema Node is NOT present,
+ * the method will returns <code>null</code>
+ */
public static Module findParentModule(final SchemaContext context, final SchemaNode schemaNode) {
if (context == null) {
throw new IllegalArgumentException("Schema Context reference cannot be NULL!");
return context.findModuleByNamespace(qname.getNamespace());
}
+ /**
+ * Method will attempt to find DataSchemaNode from specified Module and Queue of QNames through the Schema
+ * Context. The QNamed path could be defined across multiple modules in Schema Context so the method is called
+ * recursively. If the QNamed path contains QNames that are not part of any Module or Schema Context Path the
+ * operation will fail and returns <code>null</code>
+ * <br>
+ * If Schema Context, Module or Queue of QNames refers to <code>null</code> values,
+ * the method will throws IllegalArgumentException
+ *
+ * @throws IllegalArgumentException
+ *
+ * @param context Schema Context
+ * @param module Yang Module
+ * @param qnamedPath Queue of QNames
+ * @return DataSchemaNode if is present in Module(s) for specified Schema Context and given QNamed Path,
+ * otherwise will return <code>null</code>.
+ */
private static DataSchemaNode findSchemaNodeForGivenPath(final SchemaContext context, final Module module,
final Queue<QName> qnamedPath) {
- if ((module != null) && (module.getNamespace() != null) && (qnamedPath != null)) {
- DataNodeContainer nextNode = module;
- final URI moduleNamespace = module.getNamespace();
-
- QName childNodeQName;
- DataSchemaNode schemaNode = null;
- while ((nextNode != null) && !qnamedPath.isEmpty()) {
- childNodeQName = qnamedPath.peek();
- if (childNodeQName != null) {
- final URI childNodeNamespace = childNodeQName.getNamespace();
-
- schemaNode = nextNode.getDataChildByName(childNodeQName);
- if (schemaNode != null) {
- if (schemaNode instanceof ContainerSchemaNode) {
- nextNode = (ContainerSchemaNode) schemaNode;
- } else if (schemaNode instanceof ListSchemaNode) {
- nextNode = (ListSchemaNode) schemaNode;
- } else if (schemaNode instanceof ChoiceNode) {
- final ChoiceNode choice = (ChoiceNode) schemaNode;
- qnamedPath.poll();
- if (!qnamedPath.isEmpty()) {
- childNodeQName = qnamedPath.peek();
- nextNode = choice.getCaseNodeByName(childNodeQName);
- schemaNode = (DataSchemaNode)nextNode;
- }
- } else {
- nextNode = null;
+ if (context == null) {
+ throw new IllegalArgumentException("Schema Context reference cannot be NULL!");
+ }
+ if (module == null) {
+ throw new IllegalArgumentException("Module reference cannot be NULL!");
+ }
+ if (module.getNamespace() == null) {
+ throw new IllegalArgumentException("Namespace for Module cannot contains NULL reference!");
+ }
+ if (qnamedPath == null || qnamedPath.isEmpty()) {
+ throw new IllegalStateException("Schema Path contains invalid state of path parts."
+ + "The Schema Path MUST contain at least ONE QName which defines namespace and Local name"
+ + "of path.");
+ }
+
+ DataNodeContainer nextNode = module;
+ final URI moduleNamespace = module.getNamespace();
+
+ QName childNodeQName;
+ DataSchemaNode schemaNode = null;
+ while ((nextNode != null) && !qnamedPath.isEmpty()) {
+ childNodeQName = qnamedPath.peek();
+ if (childNodeQName != null) {
+ final URI childNodeNamespace = childNodeQName.getNamespace();
+
+ schemaNode = nextNode.getDataChildByName(childNodeQName);
+ if (schemaNode != null) {
+ if (schemaNode instanceof ContainerSchemaNode) {
+ nextNode = (ContainerSchemaNode) schemaNode;
+ } else if (schemaNode instanceof ListSchemaNode) {
+ nextNode = (ListSchemaNode) schemaNode;
+ } else if (schemaNode instanceof ChoiceNode) {
+ final ChoiceNode choice = (ChoiceNode) schemaNode;
+ qnamedPath.poll();
+ if (!qnamedPath.isEmpty()) {
+ childNodeQName = qnamedPath.peek();
+ nextNode = choice.getCaseNodeByName(childNodeQName);
+ schemaNode = (DataSchemaNode) nextNode;
}
- } else if (!childNodeNamespace.equals(moduleNamespace)) {
- final Module nextModule = context.findModuleByNamespace(childNodeNamespace);
- schemaNode = findSchemaNodeForGivenPath(context, nextModule, qnamedPath);
- return schemaNode;
+ } else {
+ nextNode = null;
}
- qnamedPath.poll();
+ } else if (!childNodeNamespace.equals(moduleNamespace)) {
+ final Module nextModule = context.findModuleByNamespace(childNodeNamespace);
+ schemaNode = findSchemaNodeForGivenPath(context, nextModule, qnamedPath);
+ return schemaNode;
}
+ qnamedPath.poll();
}
- return schemaNode;
}
- return null;
+ return schemaNode;
}
+ /**
+ * Transforms string representation of XPath to Queue of QNames. The XPath is split by "/" and for each part of
+ * XPath is assigned correct module in Schema Path.
+ * <br>
+ * If Schema Context, Parent Module or XPath string contains <code>null</code> values,
+ * the method will throws IllegalArgumentException
+ *
+ * @throws IllegalArgumentException
+ *
+ * @param context Schema Context
+ * @param parentModule Parent Module
+ * @param xpath XPath String
+ * @return
+ */
private static Queue<QName> xpathToQNamePath(final SchemaContext context, final Module parentModule,
final String xpath) {
- final Queue<QName> path = new LinkedList<>();
- if (xpath != null) {
- final String[] prefixedPath = xpath.split("/");
+ if (context == null) {
+ throw new IllegalArgumentException("Schema Context reference cannot be NULL!");
+ }
+ if (parentModule == null) {
+ throw new IllegalArgumentException("Parent Module reference cannot be NULL!");
+ }
+ if (xpath == null) {
+ throw new IllegalArgumentException("XPath string reference cannot be NULL!");
+ }
- for (int i = 0; i < prefixedPath.length; ++i) {
- if (!prefixedPath[i].isEmpty()) {
- path.add(stringPathPartToQName(context, parentModule, prefixedPath[i]));
- }
+ final Queue<QName> path = new LinkedList<>();
+ final String[] prefixedPath = xpath.split("/");
+ for (int i = 0; i < prefixedPath.length; ++i) {
+ if (!prefixedPath[i].isEmpty()) {
+ path.add(stringPathPartToQName(context, parentModule, prefixedPath[i]));
}
}
return path;
}
+ /**
+ * Transforms part of Prefixed Path as java String to QName.
+ * <br>
+ * If the string contains module prefix separated by ":" (i.e. mod:container) this module is provided from from
+ * Parent Module list of imports. If the Prefixed module is present in Schema Context the QName can be
+ * constructed.
+ * <br>
+ * If the Prefixed Path Part does not contains prefix the Parent's Module namespace is taken for construction of
+ * QName.
+ * <br>
+ * If Schema Context, Parent Module or Prefixed Path Part refers to <code>null</code> the method will throw
+ * IllegalArgumentException
+ *
+ * @throws IllegalArgumentException
+ *
+ * @param context Schema Context
+ * @param parentModule Parent Module
+ * @param prefixedPathPart Prefixed Path Part string
+ * @return QName from prefixed Path Part String.
+ */
private static QName stringPathPartToQName(final SchemaContext context, final Module parentModule,
final String prefixedPathPart) {
- if (parentModule != null && prefixedPathPart != null) {
- if (prefixedPathPart.contains(":")) {
- final String[] prefixedName = prefixedPathPart.split(":");
- final Module module = resolveModuleForPrefix(context, parentModule, prefixedName[0]);
- if (module != null) {
- return new QName(module.getNamespace(), module.getRevision(), prefixedName[1]);
- }
- } else {
- return new QName(parentModule.getNamespace(), parentModule.getRevision(), prefixedPathPart);
+ if (context == null) {
+ throw new IllegalArgumentException("Schema Context reference cannot be NULL!");
+ }
+ if (parentModule == null) {
+ throw new IllegalArgumentException("Parent Module reference cannot be NULL!");
+ }
+ if (prefixedPathPart == null) {
+ throw new IllegalArgumentException("Prefixed Path Part cannot be NULL!");
+ }
+
+ if (prefixedPathPart.contains(":")) {
+ final String[] prefixedName = prefixedPathPart.split(":");
+ final Module module = resolveModuleForPrefix(context, parentModule, prefixedName[0]);
+ if (module != null) {
+ return new QName(module.getNamespace(), module.getRevision(), prefixedName[1]);
}
+ } else {
+ return new QName(parentModule.getNamespace(), parentModule.getRevision(), prefixedPathPart);
}
return null;
}
+ /**
+ * Method will attempt to resolve and provide Module reference for specified module prefix. Each Yang module
+ * could contains multiple imports which MUST be associated with corresponding module prefix. The method simply
+ * looks into module imports and returns the module that is bounded with specified prefix. If the prefix is not
+ * present in module or the prefixed module is not present in specified Schema Context,
+ * the method will return <code>null</code>.
+ * <br>
+ * If String prefix is the same as prefix of the specified Module the reference to this module is returned.
+ * <br>
+ * If Schema Context, Module or Prefix are referring to <code>null</code> the method will return
+ * IllegalArgumentException
+ *
+ * @throws IllegalArgumentException
+ *
+ * @param context Schema Context
+ * @param module Yang Module
+ * @param prefix Module Prefix
+ * @return Module for given prefix in specified Schema Context if is present, otherwise returns <code>null</code>
+ */
private static Module resolveModuleForPrefix(final SchemaContext context, final Module module, final String prefix) {
- if ((module != null) && (prefix != null)) {
- if (prefix.equals(module.getPrefix())) {
- return module;
- }
+ if (context == null) {
+ throw new IllegalArgumentException("Schema Context reference cannot be NULL!");
+ }
+ if (module == null) {
+ throw new IllegalArgumentException("Module reference cannot be NULL!");
+ }
+ if (prefix == null) {
+ throw new IllegalArgumentException("Prefix string cannot be NULL!");
+ }
- final Set<ModuleImport> imports = module.getImports();
+ if (prefix.equals(module.getPrefix())) {
+ return module;
+ }
- for (final ModuleImport mi : imports) {
- if (prefix.equals(mi.getPrefix())) {
- return context.findModuleByName(mi.getModuleName(), mi.getRevision());
- }
+ final Set<ModuleImport> imports = module.getImports();
+ for (final ModuleImport mi : imports) {
+ if (prefix.equals(mi.getPrefix())) {
+ return context.findModuleByName(mi.getModuleName(), mi.getRevision());
}
}
return null;
}
+ /**
+ * @throws IllegalArgumentException
+ *
+ * @param context Schema Context
+ * @param module Yang Module
+ * @param relativeXPath Non conditional Revision Aware Relative XPath
+ * @param leafrefSchemaPath Schema Path for Leafref
+ * @return
+ */
private static Queue<QName> resolveRelativeXPath(final SchemaContext context, final Module module,
final RevisionAwareXPath relativeXPath, final SchemaPath leafrefSchemaPath) {
final Queue<QName> absolutePath = new LinkedList<>();
+ if (context == null) {
+ throw new IllegalArgumentException("Schema Context reference cannot be NULL!");
+ }
+ if (module == null) {
+ throw new IllegalArgumentException("Module reference cannot be NULL!");
+ }
+ if (relativeXPath == null) {
+ throw new IllegalArgumentException("Non Conditional Revision Aware XPath cannot be NULL!");
+ }
+ if (relativeXPath.isAbsolute()) {
+ throw new IllegalArgumentException("Revision Aware XPath MUST be relative i.e. MUST contains ../, "
+ + "for non relative Revision Aware XPath use findDataSchemaNode method!");
+ }
+ if (leafrefSchemaPath == null) {
+ throw new IllegalArgumentException("Schema Path reference for Leafref cannot be NULL!");
+ }
- if ((module != null) && (relativeXPath != null) && !relativeXPath.isAbsolute() && (leafrefSchemaPath != null)) {
- final String strXPath = relativeXPath.toString();
- if (strXPath != null) {
- final String[] xpaths = strXPath.split("/");
-
- if (xpaths != null) {
- int colCount = 0;
- while (xpaths[colCount].contains("..")) {
- ++colCount;
+ final String strXPath = relativeXPath.toString();
+ if (strXPath != null) {
+ final String[] xpaths = strXPath.split("/");
+ if (xpaths != null) {
+ int colCount = 0;
+ while (xpaths[colCount].contains("..")) {
+ ++colCount;
+ }
+ final List<QName> path = leafrefSchemaPath.getPath();
+ if (path != null) {
+ int lenght = path.size() - colCount - 1;
+ for (int i = 0; i < lenght; ++i) {
+ absolutePath.add(path.get(i));
}
- final List<QName> path = leafrefSchemaPath.getPath();
- if (path != null) {
- int lenght = path.size() - colCount - 1;
- for (int i = 0; i < lenght; ++i) {
- absolutePath.add(path.get(i));
- }
- for (int i = colCount; i < xpaths.length; ++i) {
- absolutePath.add(stringPathPartToQName(context, module, xpaths[i]));
- }
+ for (int i = colCount; i < xpaths.length; ++i) {
+ absolutePath.add(stringPathPartToQName(context, module, xpaths[i]));
}
}
}