v.verifyTextInLog("[DEBUG] yang-to-sources: Additional configuration picked up for : org.opendaylight.controller.yang2sources.spi.CodeGeneratorTestImpl: {nm1=abcd=a.b.c.d, nm2=abcd2=a.b.c.d.2}");
v.verifyTextInLog("[DEBUG] yang-to-sources: Additional configuration picked up for : org.opendaylight.controller.yang2sources.spi.CodeGeneratorTestImpl: {c1=config}");
v.verifyTextInLog(File.separator
- + "files marked as resources: META-INF" + File.separator
- + "yang");
+ + "files marked as resources: META-INF/yang");
v.verifyTextInLog("target"
+ File.separator
+ "generated-resources marked as resources for generator: org.opendaylight.controller.yang2sources.spi.CodeGeneratorTestImpl");
throw new MojoFailureException(message, e);
}
- setResource(targetYangDir, META_INF_YANG_DIR.getPath(), project);
+ setResource(targetYangDir, META_INF_YANG_STRING_JAR, project);
log.debug(Util.message(
"Yang files from: %s marked as resources: %s", LOG_PREFIX,
- yangFilesRootDir, META_INF_YANG_DIR.getPath()));
+ yangFilesRootDir, META_INF_YANG_STRING_JAR));
}
private static void setResource(File targetYangDir, String targetPath,
return addedChildNodes;
}
+ @Override
+ public DataSchemaNodeBuilder getDataChildByName(final String name) {
+ for(DataSchemaNodeBuilder child : addedChildNodes) {
+ if(child.getQName().getLocalName().equals(name)) {
+ return child;
+ }
+ }
+ return null;
+ }
+
@Override
public void addChildNode(DataSchemaNodeBuilder childNode) {
addedChildNodes.add(childNode);
Set<DataSchemaNodeBuilder> getChildNodeBuilders();
+ DataSchemaNodeBuilder getDataChildByName(String name);
+
void addChildNode(DataSchemaNodeBuilder childNode);
Set<GroupingDefinition> getGroupings();
import org.opendaylight.controller.yang.parser.builder.api.TypeDefinitionBuilder;
import org.opendaylight.controller.yang.parser.builder.api.UsesNodeBuilder;
import org.opendaylight.controller.yang.parser.util.Comparators;
-import org.opendaylight.controller.yang.parser.util.YangModelBuilderUtil;
+import org.opendaylight.controller.yang.parser.util.ParserListenerUtils;
import org.opendaylight.controller.yang.parser.util.YangParseException;
public final class AugmentationSchemaBuilderImpl implements AugmentationSchemaBuilder {
AugmentationSchemaBuilderImpl(final int line, final String augmentTargetStr) {
this.augmentTargetStr = augmentTargetStr;
this.line = line;
- final SchemaPath targetPath = YangModelBuilderUtil.parseAugmentPath(augmentTargetStr);
+ final SchemaPath targetPath = ParserListenerUtils.parseAugmentPath(augmentTargetStr);
dirtyAugmentTarget = targetPath;
instance = new AugmentationSchemaImpl(targetPath);
}
return Collections.emptySet();
}
+ @Override
+ public DataSchemaNodeBuilder getDataChildByName(final String name) {
+ for(DataSchemaNodeBuilder child : childNodes) {
+ if(child.getQName().getLocalName().equals(name)) {
+ return child;
+ }
+ }
+ return null;
+ }
+
@Override
public Set<DataSchemaNodeBuilder> getChildNodeBuilders() {
return childNodes;
import org.opendaylight.controller.yang.model.api.UnknownSchemaNode;
import org.opendaylight.controller.yang.parser.builder.api.Builder;
import org.opendaylight.controller.yang.parser.util.Comparators;
-import org.opendaylight.controller.yang.parser.util.YangModelBuilderUtil;
+import org.opendaylight.controller.yang.parser.util.ParserListenerUtils;
import org.opendaylight.controller.yang.parser.util.YangParseException;
public final class DeviationBuilder implements Builder {
private final int line;
private Builder parent;
+ private boolean isBuilt;
private final DeviationImpl instance;
+
+ private SchemaPath targetPath;
+ private String reference;
private final List<UnknownSchemaNodeBuilder> addedUnknownNodes = new ArrayList<UnknownSchemaNodeBuilder>();
- DeviationBuilder(final String targetPathStr, final int line) {
+ DeviationBuilder(final int line, final String targetPathStr) {
+ if(!targetPathStr.startsWith("/")) {
+ throw new YangParseException(line, "Deviation argument string must be an absolute schema node identifier.");
+ }
this.line = line;
- final SchemaPath targetPath = YangModelBuilderUtil
- .parseAugmentPath(targetPathStr);
- instance = new DeviationImpl(targetPath);
+ this.targetPath = ParserListenerUtils.parseAugmentPath(targetPathStr);
+ instance = new DeviationImpl();
}
@Override
public Deviation build() {
- // UNKNOWN NODES
- List<UnknownSchemaNode> unknownNodes = new ArrayList<UnknownSchemaNode>();
- for (UnknownSchemaNodeBuilder b : addedUnknownNodes) {
- unknownNodes.add(b.build());
+ if(targetPath == null) {
+ throw new YangParseException(line, "Unresolved deviation target");
+ }
+
+ if(!isBuilt) {
+ instance.setTargetPath(targetPath);
+ instance.setReference(reference);
+
+ // UNKNOWN NODES
+ List<UnknownSchemaNode> unknownNodes = new ArrayList<UnknownSchemaNode>();
+ for (UnknownSchemaNodeBuilder b : addedUnknownNodes) {
+ unknownNodes.add(b.build());
+ }
+ Collections.sort(unknownNodes, Comparators.SCHEMA_NODE_COMP);
+ instance.setUnknownSchemaNodes(unknownNodes);
+
+ isBuilt = true;
}
- Collections.sort(unknownNodes, Comparators.SCHEMA_NODE_COMP);
- instance.setUnknownSchemaNodes(unknownNodes);
return instance;
}
addedUnknownNodes.add(unknownNode);
}
+ public SchemaPath getTargetPath() {
+ return targetPath;
+ }
+
+ public void setTargetPath(final SchemaPath targetPath) {
+ this.targetPath = targetPath;
+ }
+
public void setDeviate(final String deviate) {
if ("not-supported".equals(deviate)) {
instance.setDeviate(Deviate.NOT_SUPPORTED);
}
public void setReference(final String reference) {
- instance.setReference(reference);
+ this.reference = reference;
}
private final class DeviationImpl implements Deviation {
- private final SchemaPath targetPath;
+ private SchemaPath targetPath;
private Deviate deviate;
private String reference;
private List<UnknownSchemaNode> unknownNodes = Collections.emptyList();
- private DeviationImpl(final SchemaPath targetPath) {
- this.targetPath = targetPath;
+ private DeviationImpl() {
}
@Override
return targetPath;
}
+ private void setTargetPath(final SchemaPath targetPath) {
+ this.targetPath = targetPath;
+ }
+
@Override
public Deviate getDeviate() {
return deviate;
return addedChildNodes;
}
+ @Override
+ public DataSchemaNodeBuilder getDataChildByName(final String name) {
+ for(DataSchemaNodeBuilder child : addedChildNodes) {
+ if(child.getQName().getLocalName().equals(name)) {
+ return child;
+ }
+ }
+ return null;
+ }
+
public void setChildNodes(final Set<DataSchemaNode> childNodes) {
this.childNodes = childNodes;
}
private final Set<NotificationBuilder> addedNotifications = new HashSet<NotificationBuilder>();
private final Set<IdentitySchemaNodeBuilder> addedIdentities = new HashSet<IdentitySchemaNodeBuilder>();
private final Set<FeatureBuilder> addedFeatures = new HashSet<FeatureBuilder>();
- private final Map<List<String>, DeviationBuilder> addedDeviations = new HashMap<List<String>, DeviationBuilder>();
+ private final Set<DeviationBuilder> addedDeviations = new HashSet<DeviationBuilder>();
private final Set<TypeDefinitionBuilder> addedTypedefs = new HashSet<TypeDefinitionBuilder>();
private final Map<List<String>, UnionTypeBuilder> addedUnionTypes = new HashMap<List<String>, UnionTypeBuilder>();
private final List<ExtensionBuilder> addedExtensions = new ArrayList<ExtensionBuilder>();
// DEVIATIONS
final Set<Deviation> deviations = new HashSet<Deviation>();
- for (Map.Entry<List<String>, DeviationBuilder> entry : addedDeviations.entrySet()) {
- deviations.add(entry.getValue().build());
+ for (DeviationBuilder entry : addedDeviations) {
+ deviations.add(entry.build());
}
instance.setDeviations(deviations);
return childNodes;
}
+ @Override
+ public DataSchemaNodeBuilder getDataChildByName(final String name) {
+ for(DataSchemaNodeBuilder child : childNodes) {
+ if(child.getQName().getLocalName().equals(name)) {
+ return child;
+ }
+ }
+ return null;
+ }
+
public Map<List<String>, TypeAwareBuilder> getDirtyNodes() {
return dirtyNodes;
}
return allUsesNodes;
}
+ public Set<DeviationBuilder> getDeviations() {
+ return addedDeviations;
+ }
+
public List<UnknownSchemaNodeBuilder> getUnknownNodes() {
List<UnknownSchemaNodeBuilder> result = new ArrayList<UnknownSchemaNodeBuilder>();
for (List<UnknownSchemaNodeBuilder> entry : addedUnknownNodes.values()) {
}
}
- public DeviationBuilder addDeviation(final String targetPath, final List<String> parentPath, final int line) {
+ public DeviationBuilder addDeviation(final int line, final String targetPath) {
Builder parent = getActualNode();
if (parent != null) {
throw new YangParseException(name, line, "deviation can be defined only in module or submodule");
}
- final List<String> pathToDeviation = new ArrayList<String>(parentPath);
- pathToDeviation.add(targetPath);
- final DeviationBuilder builder = new DeviationBuilder(targetPath, line);
- addedDeviations.put(pathToDeviation, builder);
+ final DeviationBuilder builder = new DeviationBuilder(line, targetPath);
+ addedDeviations.add(builder);
return builder;
}
import org.opendaylight.controller.yang.model.api.AnyXmlSchemaNode;
import org.opendaylight.controller.yang.model.api.ChoiceNode;
import org.opendaylight.controller.yang.model.api.ContainerSchemaNode;
+import org.opendaylight.controller.yang.model.api.DataNodeContainer;
import org.opendaylight.controller.yang.model.api.DataSchemaNode;
import org.opendaylight.controller.yang.model.api.GroupingDefinition;
import org.opendaylight.controller.yang.model.api.IdentitySchemaNode;
import org.opendaylight.controller.yang.model.api.ListSchemaNode;
import org.opendaylight.controller.yang.model.api.Module;
import org.opendaylight.controller.yang.model.api.SchemaContext;
+import org.opendaylight.controller.yang.model.api.SchemaNode;
import org.opendaylight.controller.yang.model.api.SchemaPath;
import org.opendaylight.controller.yang.model.api.TypeDefinition;
import org.opendaylight.controller.yang.model.api.UnknownSchemaNode;
import org.opendaylight.controller.yang.parser.builder.impl.AnyXmlBuilder;
import org.opendaylight.controller.yang.parser.builder.impl.ChoiceBuilder;
import org.opendaylight.controller.yang.parser.builder.impl.ContainerSchemaNodeBuilder;
+import org.opendaylight.controller.yang.parser.builder.impl.DeviationBuilder;
import org.opendaylight.controller.yang.parser.builder.impl.GroupingBuilderImpl;
import org.opendaylight.controller.yang.parser.builder.impl.IdentitySchemaNodeBuilder;
import org.opendaylight.controller.yang.parser.builder.impl.IdentityrefTypeBuilder;
}
}
resolveAugments(modules);
+ resolveDeviations(modules);
// build
// LinkedHashMap MUST be used otherwise the values will not maintain
}
}
resolveAugmentsWithContext(modules, context);
+ resolveDeviationsWithContext(modules, context);
// build
// LinkedHashMap MUST be used otherwise the values will not maintain
}
private void resolveUnknownNodesWithContext(final Map<String, TreeMap<Date, ModuleBuilder>> modules,
- final ModuleBuilder module, SchemaContext context) {
+ final ModuleBuilder module, final SchemaContext context) {
for (UnknownSchemaNodeBuilder unknownNodeBuilder : module.getUnknownNodes()) {
QName nodeType = unknownNodeBuilder.getNodeType();
if (nodeType.getNamespace() == null || nodeType.getRevision() == null) {
}
}
+ private void resolveDeviations(final Map<String, TreeMap<Date, ModuleBuilder>> modules) {
+ for (Map.Entry<String, TreeMap<Date, ModuleBuilder>> entry : modules.entrySet()) {
+ for (Map.Entry<Date, ModuleBuilder> inner : entry.getValue().entrySet()) {
+ ModuleBuilder b = inner.getValue();
+ resolveDeviation(modules, b);
+ }
+ }
+ }
+
+ private void resolveDeviation(final Map<String, TreeMap<Date, ModuleBuilder>> modules, final ModuleBuilder module) {
+ for (DeviationBuilder dev : module.getDeviations()) {
+ int line = dev.getLine();
+ SchemaPath targetPath = dev.getTargetPath();
+ List<QName> path = targetPath.getPath();
+ QName q0 = path.get(0);
+ String prefix = q0.getPrefix();
+ if (prefix == null) {
+ prefix = module.getPrefix();
+ }
+
+ ModuleBuilder dependentModuleBuilder = findDependentModuleBuilder(modules, module, prefix, line);
+ processDeviation(dev, dependentModuleBuilder, path, module);
+ }
+ }
+
+ private void resolveDeviationsWithContext(final Map<String, TreeMap<Date, ModuleBuilder>> modules,
+ final SchemaContext context) {
+ for (Map.Entry<String, TreeMap<Date, ModuleBuilder>> entry : modules.entrySet()) {
+ for (Map.Entry<Date, ModuleBuilder> inner : entry.getValue().entrySet()) {
+ ModuleBuilder b = inner.getValue();
+ resolveDeviationWithContext(modules, b, context);
+ }
+ }
+ }
+
+ private void resolveDeviationWithContext(final Map<String, TreeMap<Date, ModuleBuilder>> modules,
+ final ModuleBuilder module, final SchemaContext context) {
+ for (DeviationBuilder dev : module.getDeviations()) {
+ int line = dev.getLine();
+ SchemaPath targetPath = dev.getTargetPath();
+ List<QName> path = targetPath.getPath();
+ QName q0 = path.get(0);
+ String prefix = q0.getPrefix();
+ if (prefix == null) {
+ prefix = module.getPrefix();
+ }
+ String name = null;
+
+ ModuleBuilder dependentModuleBuilder = findDependentModuleBuilder(modules, module, prefix, line);
+ if (dependentModuleBuilder == null) {
+ Module dependentModule = findModuleFromContext(context, module, prefix, line);
+ Object currentParent = dependentModule;
+
+ for (int i = 0; i < path.size(); i++) {
+ if (currentParent == null) {
+ throw new YangParseException(module.getName(), line, "Failed to find deviation target.");
+ }
+ QName q = path.get(i);
+ name = q.getLocalName();
+ if (currentParent instanceof DataNodeContainer) {
+ currentParent = ((DataNodeContainer) currentParent).getDataChildByName(name);
+ }
+ }
+
+ if (currentParent == null) {
+ throw new YangParseException(module.getName(), line, "Failed to find deviation target.");
+ }
+ if (currentParent instanceof SchemaNode) {
+ dev.setTargetPath(((SchemaNode) currentParent).getPath());
+ }
+
+ } else {
+ processDeviation(dev, dependentModuleBuilder, path, module);
+ }
+ }
+ }
+
+ /**
+ * Correct deviation target path in deviation builder.
+ *
+ * @param dev
+ * deviation
+ * @param dependentModuleBuilder
+ * module containing deviation target
+ * @param path
+ * current deviation target path
+ * @param module
+ * current module
+ */
+ private void processDeviation(final DeviationBuilder dev, final ModuleBuilder dependentModuleBuilder,
+ final List<QName> path, final ModuleBuilder module) {
+ final int line = dev.getLine();
+ Builder currentParent = dependentModuleBuilder;
+
+ for (int i = 0; i < path.size(); i++) {
+ if (currentParent == null) {
+ throw new YangParseException(module.getName(), line, "Failed to find deviation target.");
+ }
+ QName q = path.get(i);
+ String name = q.getLocalName();
+ if (currentParent instanceof DataNodeContainerBuilder) {
+ currentParent = ((DataNodeContainerBuilder) currentParent).getDataChildByName(name);
+ }
+ }
+
+ if (currentParent == null || !(currentParent instanceof SchemaNodeBuilder)) {
+ throw new YangParseException(module.getName(), line, "Failed to find deviation target.");
+ }
+ dev.setTargetPath(((SchemaNodeBuilder) currentParent).getPath());
+ }
+
}
*/
package org.opendaylight.controller.yang.parser.impl;
-import static org.opendaylight.controller.yang.parser.util.YangModelBuilderUtil.*;
+import static org.opendaylight.controller.yang.parser.util.ParserListenerUtils.*;
import java.net.URI;
import java.text.DateFormat;
builder.setPath(createActualSchemaPath(actualPath, namespace, revision, yangModelPrefix));
parseSchemaNodeArgs(ctx, builder);
builder.setUnits(parseUnits(ctx));
+ builder.setDefaultValue(parseDefault(ctx));
}
@Override
String reference = null;
String deviate = null;
- DeviationBuilder builder = moduleBuilder.addDeviation(targetPath, actualPath, line);
+ DeviationBuilder builder = moduleBuilder.addDeviation(line, targetPath);
moduleBuilder.enterNode(builder);
actualPath.push(targetPath);
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-public final class YangModelBuilderUtil {
- private static final Logger logger = LoggerFactory.getLogger(YangModelBuilderUtil.class);
+public final class ParserListenerUtils {
+ private static final Logger logger = LoggerFactory.getLogger(ParserListenerUtils.class);
- private YangModelBuilderUtil() {
+ private ParserListenerUtils() {
}
/**
return units;
}
+ /**
+ * Parse given tree and returns default statement as string.
+ *
+ * @param ctx
+ * context to parse
+ * @return value of default statement as string or null if there is no
+ * default statement
+ */
+ public static String parseDefault(final ParseTree ctx) {
+ String defaultValue = null;
+ for (int i = 0; i < ctx.getChildCount(); i++) {
+ ParseTree child = ctx.getChild(i);
+ if (child instanceof Default_stmtContext) {
+ defaultValue = stringFromNode(child);
+ break;
+ }
+ }
+ return defaultValue;
+ }
+
/**
* Create SchemaPath from actualPath and names.
*
ChoiceCaseBuilder choiceCase = (ChoiceCaseBuilder) parent;
Builder choice = choiceCase.getParent();
Boolean parentConfig = null;
- if(choice instanceof ChoiceBuilder) {
- parentConfig = ((ChoiceBuilder)choice).isConfiguration();
+ if (choice instanceof ChoiceBuilder) {
+ parentConfig = ((ChoiceBuilder) choice).isConfiguration();
} else {
parentConfig = true;
}
TypeDefinition<?> baseType = unknownType.build();
TypeDefinition<?> result = null;
QName qname = new QName(namespace, revision, prefix, typeName);
- ExtendedType.Builder typeBuilder = null;
-
SchemaPath schemaPath = createTypeSchemaPath(actualPath, namespace, revision, prefix, typeName, false,
false);
- typeBuilder = new ExtendedType.Builder(qname, baseType, "", "", schemaPath);
+ ExtendedType.Builder typeBuilder = new ExtendedType.Builder(qname, baseType, null, null, schemaPath);
typeBuilder.ranges(rangeStatements);
typeBuilder.lengths(lengthStatements);
typeBuilder.patterns(patternStatements);
typeBuilder.fractionDigits(fractionDigits);
-
result = typeBuilder.build();
return result;
private final int line;
private final List<List<RangeConstraint>> ranges = new ArrayList<List<RangeConstraint>>();
private final List<List<LengthConstraint>> lengths = new ArrayList<List<LengthConstraint>>();
- private final List<PatternConstraint> patterns = new ArrayList<PatternConstraint>();
+ private final List<List<PatternConstraint>> patterns = new ArrayList<List<PatternConstraint>>();
private final List<Integer> fractionDigits = new ArrayList<Integer>();
public TypeConstraints(final String moduleName, final int line) {
}
public List<PatternConstraint> getPatterns() {
- return patterns;
+ if(patterns.isEmpty()) {
+ return Collections.emptyList();
+ }
+ return patterns.get(0);
}
public void addPatterns(final List<PatternConstraint> patterns) {
- this.patterns.addAll(patterns);
+ this.patterns.add(patterns);
}
public Integer getFractionDigits() {
import org.antlr.v4.runtime.tree.ParseTree;
import org.opendaylight.controller.antlrv4.code.gen.YangParser.Module_stmtContext;
import org.opendaylight.controller.antlrv4.code.gen.YangParser.Submodule_stmtContext;
-import org.opendaylight.controller.yang.parser.util.YangModelBuilderUtil;
+import org.opendaylight.controller.yang.parser.util.ParserListenerUtils;
import org.opendaylight.controller.yang.parser.util.YangValidationException;
/**
}
static String getName(ParseTree child) {
- return YangModelBuilderUtil.stringFromNode(child);
+ return ParserListenerUtils.stringFromNode(child);
}
static String f(String base, Object... args) {
--- /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.parser.impl;
+
+import static org.junit.Assert.*;
+
+import java.io.FileNotFoundException;
+import java.net.URI;
+import java.text.DateFormat;
+import java.text.ParseException;
+import java.text.SimpleDateFormat;
+import java.util.Arrays;
+import java.util.Date;
+import java.util.List;
+import java.util.Set;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.opendaylight.controller.yang.common.QName;
+import org.opendaylight.controller.yang.model.api.AugmentationSchema;
+import org.opendaylight.controller.yang.model.api.ChoiceCaseNode;
+import org.opendaylight.controller.yang.model.api.ChoiceNode;
+import org.opendaylight.controller.yang.model.api.ContainerSchemaNode;
+import org.opendaylight.controller.yang.model.api.DataSchemaNode;
+import org.opendaylight.controller.yang.model.api.LeafSchemaNode;
+import org.opendaylight.controller.yang.model.api.ListSchemaNode;
+import org.opendaylight.controller.yang.model.api.Module;
+import org.opendaylight.controller.yang.model.api.SchemaPath;
+import org.opendaylight.controller.yang.model.api.TypeDefinition;
+import org.opendaylight.controller.yang.model.util.ExtendedType;
+import org.opendaylight.controller.yang.model.util.Leafref;
+
+import com.google.common.collect.Lists;
+
+public class AugmentTest {
+
+ private final URI types1NS = URI.create("urn:simple.nodes.test");
+ private final URI types2NS = URI.create("urn:simple.types.test");
+ private final URI types3NS = URI.create("urn:custom.nodes.test");
+ private Date types1Rev;
+ private Date types2Rev;
+ private Date types3Rev;
+ private final String t1 = "n";
+ private final String t2 = "t";
+ private final String t3 = "c";
+ private QName q0;
+ private QName q1;
+ private QName q2;
+
+ private final DateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd");
+ private Set<Module> modules;
+
+ @Before
+ public void init() throws FileNotFoundException, ParseException {
+ types1Rev = simpleDateFormat.parse("2013-02-27");
+ types2Rev = simpleDateFormat.parse("2013-07-03");
+ types3Rev = simpleDateFormat.parse("2013-02-27");
+
+ q0 = new QName(types2NS, types2Rev, t2, "interfaces");
+ q1 = new QName(types2NS, types2Rev, t2, "ifEntry");
+ q2 = new QName(types3NS, types3Rev, t3, "augment-holder");
+
+ modules = TestUtils.loadModules(getClass().getResource("/model").getPath());
+ assertEquals(3, modules.size());
+ }
+
+ @Test
+ public void testAugmentParsing() {
+ SchemaPath expectedPath = null;
+ QName[] qnames = null;
+
+ // testfile1
+ Module module1 = TestUtils.findModule(modules, "nodes");
+ Set<AugmentationSchema> augmentations = module1.getAugmentations();
+ assertEquals(1, augmentations.size());
+ AugmentationSchema augment = augmentations.iterator().next();
+
+ Set<DataSchemaNode> augmentChildren = augment.getChildNodes();
+ assertEquals(5, augmentChildren.size());
+ for(DataSchemaNode dsn : augmentChildren) {
+ assertTrue(dsn.isAugmenting());
+ }
+
+ LeafSchemaNode ds0ChannelNumber = (LeafSchemaNode) augment.getDataChildByName("ds0ChannelNumber");
+ LeafSchemaNode interfaceId = (LeafSchemaNode) augment.getDataChildByName("interface-id");
+ LeafSchemaNode myType = (LeafSchemaNode) augment.getDataChildByName("my-type");
+ ContainerSchemaNode schemas = (ContainerSchemaNode) augment.getDataChildByName("schemas");
+ ChoiceNode odl = (ChoiceNode)augment.getDataChildByName("odl");
+
+ assertNotNull(ds0ChannelNumber);
+ assertNotNull(interfaceId);
+ assertNotNull(myType);
+ assertNotNull(schemas);
+ assertNotNull(odl);
+
+ qnames = new QName[4];
+ qnames[0] = q0;
+ qnames[1] = q1;
+ qnames[2] = q2;
+
+ // leaf ds0ChannelNumber
+ qnames[3] = new QName(types1NS, types1Rev, t1, "ds0ChannelNumber");
+ expectedPath = new SchemaPath(Lists.newArrayList(qnames), true);
+ assertEquals(expectedPath, ds0ChannelNumber.getPath());
+
+ // leaf interface-id
+ qnames[3] = new QName(types1NS, types1Rev, t1, "interface-id");
+ expectedPath = new SchemaPath(Lists.newArrayList(qnames), true);
+ assertEquals(expectedPath, interfaceId.getPath());
+
+ // leaf my-type
+ qnames[3] = new QName(types1NS, types1Rev, t1, "my-type");
+ expectedPath = new SchemaPath(Lists.newArrayList(qnames), true);
+ assertEquals(expectedPath, myType.getPath());
+
+ // container schemas
+ qnames[3] = new QName(types1NS, types1Rev, t1, "schemas");
+ expectedPath = new SchemaPath(Lists.newArrayList(qnames), true);
+ assertEquals(expectedPath, schemas.getPath());
+
+ // choice odl
+ qnames[3] = new QName(types1NS, types1Rev, t1, "odl");
+ expectedPath = new SchemaPath(Lists.newArrayList(qnames), true);
+ assertEquals(expectedPath, odl.getPath());
+
+
+ // testfile3
+ Module module3 = TestUtils.findModule(modules, "custom");
+ augmentations = module3.getAugmentations();
+ assertEquals(3, augmentations.size());
+ AugmentationSchema augment1 = null;
+ AugmentationSchema augment2 = null;
+ AugmentationSchema augment3 = null;
+ for (AugmentationSchema as : augmentations) {
+ if("if:ifType='ds0'".equals(as.getWhenCondition().toString())) {
+ augment1 = as;
+ } else if("if:ifType='ds2'".equals(as.getWhenCondition().toString())) {
+ augment2 = as;
+ } else if ("if:leafType='ds1'".equals(as.getWhenCondition().toString())) {
+ augment3 = as;
+ }
+ }
+ assertNotNull(augment1);
+ assertNotNull(augment2);
+ assertNotNull(augment3);
+
+ assertEquals(1, augment1.getChildNodes().size());
+ ContainerSchemaNode augmentHolder = (ContainerSchemaNode) augment1.getDataChildByName("augment-holder");
+ assertTrue(augmentHolder.isAugmenting());
+
+ assertEquals(1, augment2.getChildNodes().size());
+ ContainerSchemaNode augmentHolder2 = (ContainerSchemaNode) augment2.getDataChildByName("augment-holder2");
+ assertTrue(augmentHolder2.isAugmenting());
+
+ assertEquals(1, augment3.getChildNodes().size());
+ LeafSchemaNode linkleaf = (LeafSchemaNode) augment3.getDataChildByName("linkleaf");
+ assertTrue(linkleaf.isAugmenting());
+ }
+
+ @Test
+ public void testAugmentResolving() throws ParseException {
+ SchemaPath expectedPath = null;
+ QName[] qnames = null;
+
+ Module module2 = TestUtils.findModule(modules, "types");
+ ContainerSchemaNode interfaces = (ContainerSchemaNode) module2.getDataChildByName("interfaces");
+ ListSchemaNode ifEntry = (ListSchemaNode) interfaces.getDataChildByName("ifEntry");
+ ContainerSchemaNode augmentedContainer = (ContainerSchemaNode) ifEntry.getDataChildByName("augment-holder");
+
+ // testfile1.yang
+ // augment "/data:interfaces/data:ifEntry/t3:augment-holder"
+ LeafSchemaNode ds0ChannelNumber = (LeafSchemaNode) augmentedContainer.getDataChildByName("ds0ChannelNumber");
+ LeafSchemaNode interfaceId = (LeafSchemaNode) augmentedContainer.getDataChildByName("interface-id");
+ LeafSchemaNode myType = (LeafSchemaNode) augmentedContainer.getDataChildByName("my-type");
+ ContainerSchemaNode schemas = (ContainerSchemaNode) augmentedContainer.getDataChildByName("schemas");
+ ChoiceNode odl = (ChoiceNode)augmentedContainer.getDataChildByName("odl");
+
+ assertNotNull(ds0ChannelNumber);
+ assertNotNull(interfaceId);
+ assertNotNull(myType);
+ assertNotNull(schemas);
+ assertNotNull(odl);
+
+ qnames = new QName[4];
+ qnames[0] = q0;
+ qnames[1] = q1;
+ qnames[2] = q2;
+
+ // leaf ds0ChannelNumber
+ qnames[3] = new QName(types1NS, types1Rev, t1, "ds0ChannelNumber");
+ expectedPath = new SchemaPath(Lists.newArrayList(qnames), true);
+ assertEquals(expectedPath, ds0ChannelNumber.getPath());
+
+ // leaf interface-id
+ qnames[3] = new QName(types1NS, types1Rev, t1, "interface-id");
+ expectedPath = new SchemaPath(Lists.newArrayList(qnames), true);
+ assertEquals(expectedPath, interfaceId.getPath());
+
+ // leaf my-type
+ qnames[3] = new QName(types1NS, types1Rev, t1, "my-type");
+ expectedPath = new SchemaPath(Lists.newArrayList(qnames), true);
+ assertEquals(expectedPath, myType.getPath());
+
+ // container schemas
+ qnames[3] = new QName(types1NS, types1Rev, t1, "schemas");
+ expectedPath = new SchemaPath(Lists.newArrayList(qnames), true);
+ assertEquals(expectedPath, schemas.getPath());
+
+ // choice odl
+ qnames[3] = new QName(types1NS, types1Rev, t1, "odl");
+ expectedPath = new SchemaPath(Lists.newArrayList(qnames), true);
+ assertEquals(expectedPath, odl.getPath());
+
+ // testfile3.yang
+ // augment "/data:interfaces/data:ifEntry/t3:augment-holder/t1:schemas"
+ LeafSchemaNode linkleaf = (LeafSchemaNode) schemas.getDataChildByName("linkleaf");
+ assertNotNull(linkleaf);
+
+ qnames = new QName[5];
+ qnames[0] = q0;
+ qnames[1] = q1;
+ qnames[2] = q2;
+ qnames[3] = new QName(types1NS, types1Rev, t1, "schemas");
+ qnames[4] = new QName(types3NS, types3Rev, t3, "linkleaf");
+ expectedPath = new SchemaPath(Arrays.asList(qnames), true);
+ assertEquals(expectedPath, linkleaf.getPath());
+ }
+
+ @Test
+ public void testAugmentChoice() throws ParseException {
+ SchemaPath expectedPath = null;
+ QName[] qnames = null;
+
+ Module module2 = TestUtils.findModule(modules, "types");
+ ContainerSchemaNode interfaces = (ContainerSchemaNode) module2.getDataChildByName("interfaces");
+ ListSchemaNode ifEntry = (ListSchemaNode) interfaces.getDataChildByName("ifEntry");
+ ContainerSchemaNode augmentedContainer = (ContainerSchemaNode) ifEntry.getDataChildByName("augment-holder");
+
+ // testfile1.yang
+ // augment "/data:interfaces/data:ifEntry/t3:augment-holder"
+ ChoiceNode odl = (ChoiceNode)augmentedContainer.getDataChildByName("odl");
+ assertNotNull(odl);
+ Set<ChoiceCaseNode> cases = odl.getCases();
+ assertEquals(4, cases.size());
+
+ ChoiceCaseNode id = null;
+ ChoiceCaseNode node1 = null;
+ ChoiceCaseNode node2 = null;
+ ChoiceCaseNode node3 = null;
+
+ for(ChoiceCaseNode ccn : cases) {
+ if("id".equals(ccn.getQName().getLocalName())) {
+ id = ccn;
+ } else if("node1".equals(ccn.getQName().getLocalName())) {
+ node1 = ccn;
+ } else if("node2".equals(ccn.getQName().getLocalName())) {
+ node2 = ccn;
+ } else if("node3".equals(ccn.getQName().getLocalName())) {
+ node3 = ccn;
+ }
+ }
+
+ assertNotNull(id);
+ assertNotNull(node1);
+ assertNotNull(node2);
+ assertNotNull(node3);
+
+ qnames = new QName[5];
+ qnames[0] = q0;
+ qnames[1] = q1;
+ qnames[2] = q2;
+ qnames[3] = new QName(types1NS, types1Rev, t1, "odl");
+
+ // case id
+ qnames[4] = new QName(types1NS, types1Rev, t1, "id");
+ expectedPath = new SchemaPath(Lists.newArrayList(qnames), true);
+ assertEquals(expectedPath, id.getPath());
+ Set<DataSchemaNode> idChildren = id.getChildNodes();
+ assertEquals(1, idChildren.size());
+
+ // case node1
+ qnames[4] = new QName(types1NS, types1Rev, t1, "node1");
+ expectedPath = new SchemaPath(Lists.newArrayList(qnames), true);
+ assertEquals(expectedPath, node1.getPath());
+ Set<DataSchemaNode> node1Children = node1.getChildNodes();
+ assertTrue(node1Children.isEmpty());
+
+ // case node2
+ qnames[4] = new QName(types1NS, types1Rev, t1, "node2");
+ expectedPath = new SchemaPath(Lists.newArrayList(qnames), true);
+ assertEquals(expectedPath, node2.getPath());
+ Set<DataSchemaNode> node2Children = node2.getChildNodes();
+ assertTrue(node2Children.isEmpty());
+
+ // case node3
+ qnames[4] = new QName(types1NS, types1Rev, t1, "node3");
+ expectedPath = new SchemaPath(Lists.newArrayList(qnames), true);
+ assertEquals(expectedPath, node3.getPath());
+ Set<DataSchemaNode> node3Children = node3.getChildNodes();
+ assertEquals(1, node3Children.size());
+
+ // test cases
+ qnames = new QName[6];
+ qnames[0] = q0;
+ qnames[1] = q1;
+ qnames[2] = q2;
+ qnames[3] = new QName(types1NS, types1Rev, t1, "odl");
+
+ // case id child
+ qnames[4] = new QName(types1NS, types1Rev, t1, "id");
+ qnames[5] = new QName(types1NS, types1Rev, t1, "id");
+ LeafSchemaNode caseIdChild = (LeafSchemaNode)idChildren.iterator().next();
+ assertNotNull(caseIdChild);
+ expectedPath = new SchemaPath(Lists.newArrayList(qnames), true);
+ assertEquals(expectedPath, caseIdChild.getPath());
+
+ // case node3 child
+ qnames[4] = new QName(types1NS, types1Rev, t1, "node3");
+ qnames[5] = new QName(types1NS, types1Rev, t1, "node3");
+ ContainerSchemaNode caseNode3Child = (ContainerSchemaNode)node3Children.iterator().next();
+ assertNotNull(caseNode3Child);
+ expectedPath = new SchemaPath(Lists.newArrayList(qnames), true);
+ assertEquals(expectedPath, caseNode3Child.getPath());
+ }
+
+ @Test
+ public void testAugmentNodesTypeSchemaPath() throws Exception {
+ Module testModule = TestUtils.findModule(modules, "nodes");
+ Set<AugmentationSchema> augments = testModule.getAugmentations();
+ assertEquals(1, augments.size());
+ AugmentationSchema augment = augments.iterator().next();
+
+ LeafSchemaNode ifcId = (LeafSchemaNode) augment.getDataChildByName("interface-id");
+ Leafref ifcIdType = (Leafref) ifcId.getType();
+ SchemaPath ifcIdTypeSchemaPath = ifcIdType.getPath();
+ List<QName> ifcIdTypePath = ifcIdTypeSchemaPath.getPath();
+
+ Date expectedDate = simpleDateFormat.parse("2013-02-27");
+
+ QName q3 = new QName(types1NS, expectedDate, "data", "interface-id");
+ assertEquals(q0, ifcIdTypePath.get(0));
+ assertEquals(q1, ifcIdTypePath.get(1));
+ assertEquals(q2, ifcIdTypePath.get(2));
+ assertEquals(q3, ifcIdTypePath.get(3));
+
+ LeafSchemaNode myType = (LeafSchemaNode) augment.getDataChildByName("my-type");
+ ExtendedType leafType = (ExtendedType) myType.getType();
+
+ testModule = TestUtils.findModule(modules, "types");
+ TypeDefinition<?> typedef = TestUtils.findTypedef(testModule.getTypeDefinitions(), "int32-ext2");
+
+ assertEquals(typedef, leafType);
+ }
+
+}
@Test
public void testRefine() {
- Module testModule = TestUtils.findModule(modules, "types2");
+ Module testModule = TestUtils.findModule(modules, "nodes");
ContainerSchemaNode peer = (ContainerSchemaNode) testModule.getDataChildByName("peer");
ContainerSchemaNode destination = (ContainerSchemaNode) peer.getDataChildByName("destination");
@Test
public void testGrouping() {
- Module testModule = TestUtils.findModule(modules, "types2");
+ Module testModule = TestUtils.findModule(modules, "custom");
Set<GroupingDefinition> groupings = testModule.getGroupings();
assertEquals(1, groupings.size());
GroupingDefinition grouping = groupings.iterator().next();
// suffix _u = added by uses
// suffix _g = defined in grouping
- Module testModule = TestUtils.findModule(modules, "types2");
+ Module testModule = TestUtils.findModule(modules, "custom");
// get grouping
Set<GroupingDefinition> groupings = testModule.getGroupings();
assertEquals(1, groupings.size());
GroupingDefinition grouping = groupings.iterator().next();
+ testModule = TestUtils.findModule(modules, "nodes");
+
// get node containing uses
ContainerSchemaNode peer = (ContainerSchemaNode) testModule.getDataChildByName("peer");
ContainerSchemaNode destination = (ContainerSchemaNode) peer.getDataChildByName("destination");
import org.opendaylight.controller.yang.model.api.ExtensionDefinition;
import org.opendaylight.controller.yang.model.api.FeatureDefinition;
import org.opendaylight.controller.yang.model.api.GroupingDefinition;
-import org.opendaylight.controller.yang.model.api.LeafListSchemaNode;
import org.opendaylight.controller.yang.model.api.LeafSchemaNode;
import org.opendaylight.controller.yang.model.api.ListSchemaNode;
import org.opendaylight.controller.yang.model.api.Module;
import org.opendaylight.controller.yang.model.util.ExtendedType;
import org.opendaylight.controller.yang.model.util.Int16;
import org.opendaylight.controller.yang.model.util.Int32;
-import org.opendaylight.controller.yang.model.util.Int8;
-import org.opendaylight.controller.yang.model.util.Leafref;
import org.opendaylight.controller.yang.model.util.StringType;
import org.opendaylight.controller.yang.model.util.Uint32;
import org.opendaylight.controller.yang.model.util.UnionType;
public class YangParserTest {
+
+ private final URI nodesNS = URI.create("urn:simple.nodes.test");
+ private final URI typesNS = URI.create("urn:simple.types.test");
+ private final URI customNS = URI.create("urn:custom.nodes.test");
+ private Date nodesRev;
+ private Date typesRev;
+ private Date customRev;
+
private final DateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd");
private Set<Module> modules;
@Before
- public void init() throws FileNotFoundException {
+ public void init() throws FileNotFoundException, ParseException {
+ nodesRev = simpleDateFormat.parse("2013-02-27");
+ typesRev = simpleDateFormat.parse("2013-07-03");
+ customRev = simpleDateFormat.parse("2013-02-27");
+
modules = TestUtils.loadModules(getClass().getResource("/model").getPath());
assertEquals(3, modules.size());
}
@Test
- public void testHeaders() {
- Module test = TestUtils.findModule(modules, "types1");
+ public void testHeaders() throws ParseException {
+ Module test = TestUtils.findModule(modules, "nodes");
- assertEquals("types1", test.getName());
+ assertEquals("nodes", test.getName());
assertEquals("1", test.getYangVersion());
- URI expectedNamespace = URI.create("urn:simple.container.demo");
- assertEquals(expectedNamespace, test.getNamespace());
- assertEquals("t1", test.getPrefix());
+ assertEquals(nodesNS, test.getNamespace());
+ assertEquals("n", test.getPrefix());
Set<ModuleImport> imports = test.getImports();
assertEquals(2, imports.size());
- ModuleImport import2 = TestUtils.findImport(imports, "data");
- assertEquals("types2", import2.getModuleName());
- assertEquals(TestUtils.createDate("2013-02-27"), import2.getRevision());
+ ModuleImport import2 = TestUtils.findImport(imports, "t");
+ assertEquals("types", import2.getModuleName());
+ assertEquals(typesRev, import2.getRevision());
- ModuleImport import3 = TestUtils.findImport(imports, "t3");
- assertEquals("types3", import3.getModuleName());
- assertEquals(TestUtils.createDate("2013-02-27"), import3.getRevision());
+ ModuleImport import3 = TestUtils.findImport(imports, "c");
+ assertEquals("custom", import3.getModuleName());
+ assertEquals(customRev, import3.getRevision());
assertEquals("opendaylight", test.getOrganization());
assertEquals("http://www.opendaylight.org/", test.getContact());
@Test
public void testOrderingTypedef() {
- Module test = TestUtils.findModule(modules, "types2");
+ Module test = TestUtils.findModule(modules, "types");
Set<TypeDefinition<?>> typedefs = test.getTypeDefinitions();
- String[] expectedOrder = new String[] { "my-base-int32-type", "my-custom-string", "my-decimal-type",
- "my-decimal-type-ext", "my-int-type", "my-int-type-ext", "my-int-type2", "my-string-type",
- "my-string-type-ext", "my-string-type2", "my-type1", "my-union", "my-union-ext", "nested-union1",
- "nested-union2" };
+ String[] expectedOrder = new String[] { "int32-ext1", "int32-ext2", "my-decimal-type", "my-union",
+ "my-union-ext", "nested-union2", "string-ext1", "string-ext2", "string-ext3", "string-ext4" };
String[] actualOrder = new String[typedefs.size()];
int i = 0;
@Test
public void testOrderingChildNodes() {
- Module test = TestUtils.findModule(modules, "types2");
- Set<DataSchemaNode> childNodes = test.getChildNodes();
- String[] expectedOrder = new String[] { "count", "if-name", "interfaces", "name", "nested-type-leaf", "peer",
- "system" };
- String[] actualOrder = new String[childNodes.size()];
+ Module test = TestUtils.findModule(modules, "nodes");
+ AugmentationSchema augment1 = null;
+ for (AugmentationSchema as : test.getAugmentations()) {
+ if ("if:ifType='ds0'".equals(as.getWhenCondition().toString())) {
+ augment1 = as;
+ break;
+ }
+ }
+ assertNotNull(augment1);
+
+ String[] expectedOrder = new String[] { "ds0ChannelNumber", "interface-id", "my-type", "odl", "schemas" };
+ String[] actualOrder = new String[expectedOrder.length];
int i = 0;
- for (DataSchemaNode child : childNodes) {
- actualOrder[i] = child.getQName().getLocalName();
+ for (DataSchemaNode augmentChild : augment1.getChildNodes()) {
+ actualOrder[i] = augmentChild.getQName().getLocalName();
i++;
}
+
assertArrayEquals(expectedOrder, actualOrder);
}
@Test
public void testOrderingNestedChildNodes() {
- Module test = TestUtils.findModule(modules, "types2");
+ Module test = TestUtils.findModule(modules, "custom");
Set<GroupingDefinition> groupings = test.getGroupings();
assertEquals(1, groupings.size());
GroupingDefinition target = groupings.iterator().next();
@Test
public void testParseContainer() {
- Module test = TestUtils.findModule(modules, "types2");
- URI expectedNamespace = URI.create("urn:simple.types.data.demo");
- String expectedPrefix = "t2";
- Date expectedRevision = TestUtils.createDate("2013-02-27");
+ Module test = TestUtils.findModule(modules, "types");
+ URI expectedNamespace = URI.create("urn:simple.types.test");
+ String expectedPrefix = "t";
ContainerSchemaNode interfaces = (ContainerSchemaNode) test.getDataChildByName("interfaces");
// test SchemaNode args
- QName expectedQName = new QName(expectedNamespace, expectedRevision, expectedPrefix, "interfaces");
+ QName expectedQName = new QName(expectedNamespace, typesRev, expectedPrefix, "interfaces");
assertEquals(expectedQName, interfaces.getQName());
- SchemaPath expectedPath = TestUtils.createPath(true, expectedNamespace, expectedRevision, expectedPrefix,
- "interfaces");
+ SchemaPath expectedPath = TestUtils.createPath(true, expectedNamespace, typesRev, expectedPrefix, "interfaces");
assertEquals(expectedPath, interfaces.getPath());
assertNull(interfaces.getDescription());
assertNull(interfaces.getReference());
@Test
public void testParseList() {
- Module test = TestUtils.findModule(modules, "types2");
- URI expectedNamespace = URI.create("urn:simple.types.data.demo");
- String expectedPrefix = "t2";
- Date expectedRevision = TestUtils.createDate("2013-02-27");
+ Module test = TestUtils.findModule(modules, "types");
+ URI expectedNamespace = URI.create("urn:simple.types.test");
+ String expectedPrefix = "t";
ContainerSchemaNode interfaces = (ContainerSchemaNode) test.getDataChildByName("interfaces");
ListSchemaNode ifEntry = (ListSchemaNode) interfaces.getDataChildByName("ifEntry");
// test SchemaNode args
- QName expectedQName = new QName(expectedNamespace, expectedRevision, expectedPrefix, "ifEntry");
+ QName expectedQName = new QName(expectedNamespace, typesRev, expectedPrefix, "ifEntry");
assertEquals(expectedQName, ifEntry.getQName());
- SchemaPath expectedPath = TestUtils.createPath(true, expectedNamespace, expectedRevision, expectedPrefix,
- "interfaces", "ifEntry");
+ SchemaPath expectedPath = TestUtils.createPath(true, expectedNamespace, typesRev, expectedPrefix, "interfaces",
+ "ifEntry");
assertEquals(expectedPath, ifEntry.getPath());
assertNull(ifEntry.getDescription());
assertNull(ifEntry.getReference());
assertEquals(2, availableAugmentations.size());
// test ListSchemaNode args
List<QName> expectedKey = new ArrayList<QName>();
- expectedKey.add(new QName(expectedNamespace, expectedRevision, expectedPrefix, "ifIndex"));
+ expectedKey.add(new QName(expectedNamespace, typesRev, expectedPrefix, "ifIndex"));
assertEquals(expectedKey, ifEntry.getKeyDefinition());
assertFalse(ifEntry.isUserOrdered());
// test DataNodeContainer args
assertTrue(ifMtu.getType() instanceof Int32);
}
- @Test
- public void testParseLeaf() throws ParseException {
- Module test = TestUtils.findModule(modules, "types2");
-
- // leaf if-name
- LeafSchemaNode ifName = (LeafSchemaNode) test.getDataChildByName("if-name");
- Leafref ifNameType = (Leafref) ifName.getType();
- QName qname = ifNameType.getQName();
-
- URI baseYangTypeNS = URI.create("urn:ietf:params:xml:ns:yang:1");
- assertEquals(baseYangTypeNS, qname.getNamespace());
- assertNull(qname.getRevision());
- assertEquals("", qname.getPrefix());
- assertEquals("leafref", qname.getLocalName());
-
- // leaf name
- LeafSchemaNode name = (LeafSchemaNode) test.getDataChildByName("name");
- StringType nameType = (StringType) name.getType();
- QName nameQName = nameType.getQName();
-
- assertEquals(baseYangTypeNS, nameQName.getNamespace());
- assertNull(nameQName.getRevision());
- assertEquals("", nameQName.getPrefix());
- assertEquals("string", nameQName.getLocalName());
-
- // leaf count
- LeafSchemaNode count = (LeafSchemaNode) test.getDataChildByName("count");
- ExtendedType countType = (ExtendedType) count.getType();
- QName countTypeQName = countType.getQName();
-
- URI expectedNS = URI.create("urn:simple.types.data.demo");
- Date expectedDate = simpleDateFormat.parse("2013-02-27");
- assertEquals(expectedNS, countTypeQName.getNamespace());
- assertEquals(expectedDate, countTypeQName.getRevision());
- assertEquals("t2", countTypeQName.getPrefix());
- assertEquals("int8", countTypeQName.getLocalName());
-
- Int8 countTypeBase = (Int8) countType.getBaseType();
- QName countTypeBaseQName = countTypeBase.getQName();
-
- assertEquals(baseYangTypeNS, countTypeBaseQName.getNamespace());
- assertNull(countTypeBaseQName.getRevision());
- assertEquals("", countTypeBaseQName.getPrefix());
- assertEquals("int8", countTypeBaseQName.getLocalName());
- }
-
- @Test
- public void testAugmentResolving() {
- // testfile1
- Module module1 = TestUtils.findModule(modules, "types1");
-
- Set<AugmentationSchema> module1Augmentations = module1.getAugmentations();
- AugmentationSchema augment1 = module1Augmentations.iterator().next();
- LeafSchemaNode augmentedLeafDefinition = (LeafSchemaNode) augment1.getDataChildByName("ds0ChannelNumber");
- assertTrue(augmentedLeafDefinition.isAugmenting());
-
- // testfile2
- Module module2 = TestUtils.findModule(modules, "types2");
-
- ContainerSchemaNode interfaces = (ContainerSchemaNode) module2.getDataChildByName("interfaces");
- ListSchemaNode ifEntry = (ListSchemaNode) interfaces.getDataChildByName("ifEntry");
- ContainerSchemaNode augmentedContainer = (ContainerSchemaNode) ifEntry.getDataChildByName("augment-holder");
-
- ContainerSchemaNode schemas = (ContainerSchemaNode) augmentedContainer.getDataChildByName("schemas");
- LeafSchemaNode linkleaf = (LeafSchemaNode) schemas.getDataChildByName("linkleaf");
- assertNotNull(linkleaf);
-
- // augmentation defined in testfile1 and augmentation returned from
- // augmented container have to be same
- Set<AugmentationSchema> augmentedContainerAugments = augmentedContainer.getAvailableAugmentations();
- AugmentationSchema augmentDefinition = augmentedContainerAugments.iterator().next();
- assertEquals(augment1, augmentDefinition);
-
- LeafSchemaNode augmentedLeaf = (LeafSchemaNode) augmentedContainer.getDataChildByName("ds0ChannelNumber");
- assertTrue(augmentedLeaf.isAugmenting());
- assertEquals(augmentedLeafDefinition, augmentedLeaf);
-
- Set<AugmentationSchema> ifEntryAugments = ifEntry.getAvailableAugmentations();
- assertEquals(2, ifEntryAugments.size());
-
- // testfile3
- Module module3 = TestUtils.findModule(modules, "types3");
-
- Set<AugmentationSchema> module3Augmentations = module3.getAugmentations();
- assertEquals(3, module3Augmentations.size());
- AugmentationSchema augment3 = null;
- for (AugmentationSchema as : module3Augmentations) {
- if ("if:ifType='ds0'".equals(as.getWhenCondition().toString())) {
- augment3 = as;
- }
- }
- ContainerSchemaNode augmentedContainerDefinition = (ContainerSchemaNode) augment3
- .getDataChildByName("augment-holder");
- assertTrue(augmentedContainerDefinition.isAugmenting());
-
- // check
- assertEquals(augmentedContainer, augmentedContainerDefinition);
- assertEquals(augmentedLeaf, augmentedLeafDefinition);
- }
-
- @Test
- public void testAugmentTarget() {
- Module test = TestUtils.findModule(modules, "types2");
-
- ContainerSchemaNode interfaces = (ContainerSchemaNode) test.getDataChildByName("interfaces");
- ListSchemaNode ifEntry = (ListSchemaNode) interfaces.getDataChildByName("ifEntry");
- Set<AugmentationSchema> augmentations = ifEntry.getAvailableAugmentations();
- assertEquals(2, augmentations.size());
-
- AugmentationSchema augment = null;
- for (AugmentationSchema as : augmentations) {
- if ("if:ifType='ds0'".equals(as.getWhenCondition().toString())) {
- augment = as;
- }
- }
- ContainerSchemaNode augmentHolder = (ContainerSchemaNode) augment.getDataChildByName("augment-holder");
- assertNotNull(augmentHolder);
- assertTrue(augmentHolder.isAugmenting());
- QName augmentHolderQName = augmentHolder.getQName();
- assertEquals("augment-holder", augmentHolderQName.getLocalName());
- assertEquals("t3", augmentHolderQName.getPrefix());
- assertEquals("Description for augment holder", augmentHolder.getDescription());
- }
-
@Test
public void testTypedefRangesResolving() throws ParseException {
- Module testModule = TestUtils.findModule(modules, "types1");
+ Module testModule = TestUtils.findModule(modules, "nodes");
+ LeafSchemaNode int32Leaf = (LeafSchemaNode) testModule.getDataChildByName("int32-leaf");
- LeafSchemaNode testleaf = (LeafSchemaNode) testModule.getDataChildByName("testleaf");
- ExtendedType leafType = (ExtendedType) testleaf.getType();
+ ExtendedType leafType = (ExtendedType) int32Leaf.getType();
QName leafTypeQName = leafType.getQName();
- assertEquals("my-type1", leafTypeQName.getLocalName());
- assertEquals("t1", leafTypeQName.getPrefix());
- assertEquals(URI.create("urn:simple.container.demo"), leafTypeQName.getNamespace());
- Date expectedDate = simpleDateFormat.parse("2013-02-27");
- assertEquals(expectedDate, leafTypeQName.getRevision());
- assertEquals(1, leafType.getRanges().size());
-
- ExtendedType baseType = (ExtendedType) leafType.getBaseType();
- QName baseTypeQName = baseType.getQName();
- assertEquals("my-type1", baseTypeQName.getLocalName());
- assertEquals("t2", baseTypeQName.getPrefix());
- assertEquals(URI.create("urn:simple.types.data.demo"), baseTypeQName.getNamespace());
- assertEquals(expectedDate, baseTypeQName.getRevision());
- assertEquals(2, baseType.getRanges().size());
-
+ assertEquals("int32-ext2", leafTypeQName.getLocalName());
+ assertEquals("n", leafTypeQName.getPrefix());
+ assertEquals(nodesNS, leafTypeQName.getNamespace());
+ assertEquals(nodesRev, leafTypeQName.getRevision());
+ assertNull(leafType.getUnits());
+ assertNull(leafType.getDefaultValue());
+ assertTrue(leafType.getLengths().isEmpty());
+ assertTrue(leafType.getPatterns().isEmpty());
List<RangeConstraint> ranges = leafType.getRanges();
assertEquals(1, ranges.size());
RangeConstraint range = ranges.get(0);
assertEquals(12L, range.getMin());
assertEquals(20L, range.getMax());
+
+ ExtendedType baseType = (ExtendedType) leafType.getBaseType();
+ QName baseTypeQName = baseType.getQName();
+ assertEquals("int32-ext2", baseTypeQName.getLocalName());
+ assertEquals("t", baseTypeQName.getPrefix());
+ assertEquals(typesNS, baseTypeQName.getNamespace());
+ assertEquals(typesRev, baseTypeQName.getRevision());
+ assertEquals("mile", baseType.getUnits());
+ assertEquals("11", baseType.getDefaultValue());
+ assertTrue(leafType.getLengths().isEmpty());
+ assertTrue(leafType.getPatterns().isEmpty());
+ List<RangeConstraint> baseTypeRanges = baseType.getRanges();
+ assertEquals(2, baseTypeRanges.size());
+ RangeConstraint baseTypeRange1 = baseTypeRanges.get(0);
+ assertEquals(3L, baseTypeRange1.getMin());
+ assertEquals(9L, baseTypeRange1.getMax());
+ RangeConstraint baseTypeRange2 = baseTypeRanges.get(1);
+ assertEquals(11L, baseTypeRange2.getMin());
+ assertEquals(20L, baseTypeRange2.getMax());
+
+ ExtendedType base = (ExtendedType) baseType.getBaseType();
+ QName baseQName = base.getQName();
+ assertEquals("int32-ext1", baseQName.getLocalName());
+ assertEquals("t", baseQName.getPrefix());
+ assertEquals(typesNS, baseQName.getNamespace());
+ assertEquals(typesRev, baseQName.getRevision());
+ assertNull(base.getUnits());
+ assertNull(base.getDefaultValue());
+ assertTrue(leafType.getLengths().isEmpty());
+ assertTrue(leafType.getPatterns().isEmpty());
+ List<RangeConstraint> baseRanges = base.getRanges();
+ assertEquals(1, baseRanges.size());
+ RangeConstraint baseRange = baseRanges.get(0);
+ assertEquals(2L, baseRange.getMin());
+ assertEquals(20L, baseRange.getMax());
+
+ assertTrue(base.getBaseType() instanceof Int32);
}
@Test
public void testTypedefPatternsResolving() {
- Module testModule = TestUtils.findModule(modules, "types1");
-
- LeafSchemaNode testleaf = (LeafSchemaNode) testModule.getDataChildByName("test-string-leaf");
- ExtendedType testleafType = (ExtendedType) testleaf.getType();
- QName testleafTypeQName = testleafType.getQName();
- assertEquals("my-string-type-ext", testleafTypeQName.getLocalName());
- assertEquals("t2", testleafTypeQName.getPrefix());
-
- List<PatternConstraint> patterns = testleafType.getPatterns();
+ Module testModule = TestUtils.findModule(modules, "nodes");
+ LeafSchemaNode stringleaf = (LeafSchemaNode) testModule.getDataChildByName("string-leaf");
+
+ ExtendedType type = (ExtendedType) stringleaf.getType();
+ QName typeQName = type.getQName();
+ assertEquals("string-ext4", typeQName.getLocalName());
+ assertEquals("t", typeQName.getPrefix());
+ assertEquals(typesNS, typeQName.getNamespace());
+ assertEquals(typesRev, typeQName.getRevision());
+ assertNull(type.getUnits());
+ assertNull(type.getDefaultValue());
+ List<PatternConstraint> patterns = type.getPatterns();
assertEquals(1, patterns.size());
PatternConstraint pattern = patterns.iterator().next();
assertEquals("[e-z]*", pattern.getRegularExpression());
-
- ExtendedType baseType = (ExtendedType) testleafType.getBaseType();
- assertEquals("my-string-type2", baseType.getQName().getLocalName());
-
- patterns = baseType.getPatterns();
+ assertTrue(type.getLengths().isEmpty());
+ assertTrue(type.getRanges().isEmpty());
+
+ ExtendedType baseType1 = (ExtendedType) type.getBaseType();
+ QName baseType1QName = baseType1.getQName();
+ assertEquals("string-ext3", baseType1QName.getLocalName());
+ assertEquals("t", baseType1QName.getPrefix());
+ assertEquals(typesNS, baseType1QName.getNamespace());
+ assertEquals(typesRev, baseType1QName.getRevision());
+ assertNull(baseType1.getUnits());
+ assertNull(baseType1.getDefaultValue());
+ patterns = baseType1.getPatterns();
assertEquals(1, patterns.size());
pattern = patterns.iterator().next();
assertEquals("[b-u]*", pattern.getRegularExpression());
-
- List<LengthConstraint> lengths = testleafType.getLengths();
- assertTrue(lengths.isEmpty());
+ assertTrue(baseType1.getLengths().isEmpty());
+ assertTrue(baseType1.getRanges().isEmpty());
+
+ ExtendedType baseType2 = (ExtendedType) baseType1.getBaseType();
+ QName baseType2QName = baseType2.getQName();
+ assertEquals("string-ext2", baseType2QName.getLocalName());
+ assertEquals("t", baseType2QName.getPrefix());
+ assertEquals(typesNS, baseType2QName.getNamespace());
+ assertEquals(typesRev, baseType2QName.getRevision());
+ assertNull(baseType2.getUnits());
+ assertNull(baseType2.getDefaultValue());
+ assertTrue(baseType2.getPatterns().isEmpty());
+ List<LengthConstraint> baseType2Lengths = baseType2.getLengths();
+ assertEquals(1, baseType2Lengths.size());
+ LengthConstraint length = baseType2Lengths.get(0);
+ assertEquals(6L, length.getMin());
+ assertEquals(10L, length.getMax());
+ assertTrue(baseType2.getRanges().isEmpty());
+
+ ExtendedType baseType3 = (ExtendedType) baseType2.getBaseType();
+ QName baseType3QName = baseType3.getQName();
+ assertEquals("string-ext1", baseType3QName.getLocalName());
+ assertEquals("t", baseType3QName.getPrefix());
+ assertEquals(typesNS, baseType3QName.getNamespace());
+ assertEquals(typesRev, baseType3QName.getRevision());
+ assertNull(baseType3.getUnits());
+ assertNull(baseType3.getDefaultValue());
+ patterns = baseType3.getPatterns();
+ assertEquals(1, patterns.size());
+ pattern = patterns.iterator().next();
+ assertEquals("[a-k]*", pattern.getRegularExpression());
+ List<LengthConstraint> baseType3Lengths = baseType3.getLengths();
+ assertEquals(1, baseType3Lengths.size());
+ length = baseType3Lengths.get(0);
+ assertEquals(5L, length.getMin());
+ assertEquals(11L, length.getMax());
+ assertTrue(baseType3.getRanges().isEmpty());
+
+ assertTrue(baseType3.getBaseType() instanceof StringType);
}
@Test
public void testTypedefLengthsResolving() {
- Module testModule = TestUtils.findModule(modules, "types1");
-
- LeafSchemaNode testleaf = (LeafSchemaNode) testModule.getDataChildByName("leaf-with-length");
- ExtendedType testleafType = (ExtendedType) testleaf.getType();
- assertEquals("my-string-type", testleafType.getQName().getLocalName());
-
- List<LengthConstraint> lengths = testleafType.getLengths();
- assertEquals(1, lengths.size());
-
- LengthConstraint length = lengths.get(0);
+ Module testModule = TestUtils.findModule(modules, "nodes");
+
+ LeafSchemaNode lengthLeaf = (LeafSchemaNode) testModule.getDataChildByName("length-leaf");
+ ExtendedType type = (ExtendedType) lengthLeaf.getType();
+
+ QName typeQName = type.getQName();
+ assertEquals("string-ext2", typeQName.getLocalName());
+ assertEquals("n", typeQName.getPrefix());
+ assertEquals(nodesNS, typeQName.getNamespace());
+ assertEquals(nodesRev, typeQName.getRevision());
+ assertNull(type.getUnits());
+ assertNull(type.getDefaultValue());
+ assertTrue(type.getPatterns().isEmpty());
+ List<LengthConstraint> typeLengths = type.getLengths();
+ assertEquals(1, typeLengths.size());
+ LengthConstraint length = typeLengths.get(0);
assertEquals(7L, length.getMin());
assertEquals(10L, length.getMax());
- }
-
- @Test
- public void testTypeDef() {
- Module testModule = TestUtils.findModule(modules, "types2");
-
- LeafSchemaNode testleaf = (LeafSchemaNode) testModule.getDataChildByName("nested-type-leaf");
- ExtendedType testleafType = (ExtendedType) testleaf.getType();
- assertEquals("my-type1", testleafType.getQName().getLocalName());
-
- ExtendedType baseType = (ExtendedType) testleafType.getBaseType();
- assertEquals("my-base-int32-type", baseType.getQName().getLocalName());
-
- Int32 int32Type = (Int32) baseType.getBaseType();
- QName qname = int32Type.getQName();
- assertEquals(URI.create("urn:ietf:params:xml:ns:yang:1"), qname.getNamespace());
- assertNull(qname.getRevision());
- assertEquals("", qname.getPrefix());
- assertEquals("int32", qname.getLocalName());
- List<RangeConstraint> ranges = baseType.getRanges();
- assertEquals(1, ranges.size());
- RangeConstraint range = ranges.get(0);
- assertEquals(2L, range.getMin());
- assertEquals(20L, range.getMax());
+ assertTrue(type.getRanges().isEmpty());
+
+ ExtendedType baseType1 = (ExtendedType) type.getBaseType();
+ QName baseType1QName = baseType1.getQName();
+ assertEquals("string-ext2", baseType1QName.getLocalName());
+ assertEquals("t", baseType1QName.getPrefix());
+ assertEquals(typesNS, baseType1QName.getNamespace());
+ assertEquals(typesRev, baseType1QName.getRevision());
+ assertNull(baseType1.getUnits());
+ assertNull(baseType1.getDefaultValue());
+ assertTrue(baseType1.getPatterns().isEmpty());
+ List<LengthConstraint> baseType2Lengths = baseType1.getLengths();
+ assertEquals(1, baseType2Lengths.size());
+ length = baseType2Lengths.get(0);
+ assertEquals(6L, length.getMin());
+ assertEquals(10L, length.getMax());
+ assertTrue(baseType1.getRanges().isEmpty());
+
+ ExtendedType baseType2 = (ExtendedType) baseType1.getBaseType();
+ QName baseType2QName = baseType2.getQName();
+ assertEquals("string-ext1", baseType2QName.getLocalName());
+ assertEquals("t", baseType2QName.getPrefix());
+ assertEquals(typesNS, baseType2QName.getNamespace());
+ assertEquals(typesRev, baseType2QName.getRevision());
+ assertNull(baseType2.getUnits());
+ assertNull(baseType2.getDefaultValue());
+ List<PatternConstraint> patterns = baseType2.getPatterns();
+ assertEquals(1, patterns.size());
+ PatternConstraint pattern = patterns.iterator().next();
+ assertEquals("[a-k]*", pattern.getRegularExpression());
+ List<LengthConstraint> baseType3Lengths = baseType2.getLengths();
+ assertEquals(1, baseType3Lengths.size());
+ length = baseType3Lengths.get(0);
+ assertEquals(5L, length.getMin());
+ assertEquals(11L, length.getMax());
+ assertTrue(baseType2.getRanges().isEmpty());
+
+ assertTrue(baseType2.getBaseType() instanceof StringType);
}
@Test
public void testTypedefDecimal1() {
- Module testModule = TestUtils.findModule(modules, "types1");
+ Module testModule = TestUtils.findModule(modules, "nodes");
+ LeafSchemaNode testleaf = (LeafSchemaNode) testModule.getDataChildByName("decimal-leaf");
- LeafSchemaNode testleaf = (LeafSchemaNode) testModule.getDataChildByName("test-decimal-leaf");
ExtendedType type = (ExtendedType) testleaf.getType();
+ QName typeQName = type.getQName();
+ assertEquals("my-decimal-type", typeQName.getLocalName());
+ assertEquals("n", typeQName.getPrefix());
+ assertEquals(nodesNS, typeQName.getNamespace());
+ assertEquals(nodesRev, typeQName.getRevision());
+ assertNull(type.getUnits());
+ assertNull(type.getDefaultValue());
assertEquals(4, (int) type.getFractionDigits());
+ assertTrue(type.getLengths().isEmpty());
+ assertTrue(type.getPatterns().isEmpty());
+ assertTrue(type.getRanges().isEmpty());
ExtendedType typeBase = (ExtendedType) type.getBaseType();
- assertEquals("my-decimal-type", typeBase.getQName().getLocalName());
+ QName typeBaseQName = typeBase.getQName();
+ assertEquals("my-decimal-type", typeBaseQName.getLocalName());
+ assertEquals("t", typeBaseQName.getPrefix());
+ assertEquals(typesNS, typeBaseQName.getNamespace());
+ assertEquals(typesRev, typeBaseQName.getRevision());
+ assertNull(typeBase.getUnits());
+ assertNull(typeBase.getDefaultValue());
assertNull(typeBase.getFractionDigits());
+ assertTrue(typeBase.getLengths().isEmpty());
+ assertTrue(typeBase.getPatterns().isEmpty());
+ assertTrue(typeBase.getRanges().isEmpty());
Decimal64 decimal = (Decimal64) typeBase.getBaseType();
assertEquals(6, (int) decimal.getFractionDigits());
@Test
public void testTypedefDecimal2() {
- Module testModule = TestUtils.findModule(modules, "types1");
+ Module testModule = TestUtils.findModule(modules, "nodes");
+ LeafSchemaNode testleaf = (LeafSchemaNode) testModule.getDataChildByName("decimal-leaf2");
- LeafSchemaNode testleaf = (LeafSchemaNode) testModule.getDataChildByName("test-decimal-leaf2");
- TypeDefinition<?> baseType = testleaf.getType().getBaseType();
- assertTrue(testleaf.getType().getBaseType() instanceof Decimal64);
- Decimal64 baseTypeCast = (Decimal64) baseType;
- assertEquals(5, (int) baseTypeCast.getFractionDigits());
+ ExtendedType type = (ExtendedType) testleaf.getType();
+ QName typeQName = type.getQName();
+ assertEquals("my-decimal-type", typeQName.getLocalName());
+ assertEquals("t", typeQName.getPrefix());
+ assertEquals(typesNS, typeQName.getNamespace());
+ assertEquals(typesRev, typeQName.getRevision());
+ assertNull(type.getUnits());
+ assertNull(type.getDefaultValue());
+ assertNull(type.getFractionDigits());
+ assertTrue(type.getLengths().isEmpty());
+ assertTrue(type.getPatterns().isEmpty());
+ assertTrue(type.getRanges().isEmpty());
+
+ Decimal64 baseTypeDecimal = (Decimal64) type.getBaseType();
+ assertEquals(6, (int) baseTypeDecimal.getFractionDigits());
}
@Test
public void testTypedefUnion() {
- Module testModule = TestUtils.findModule(modules, "types1");
-
- LeafSchemaNode testleaf = (LeafSchemaNode) testModule.getDataChildByName("union-leaf");
- ExtendedType testleafType = (ExtendedType) testleaf.getType();
- assertEquals("my-union-ext", testleafType.getQName().getLocalName());
-
- ExtendedType baseType = (ExtendedType) testleafType.getBaseType();
- assertEquals("my-union", baseType.getQName().getLocalName());
-
- UnionType unionBase = (UnionType) baseType.getBaseType();
+ Module testModule = TestUtils.findModule(modules, "nodes");
+ LeafSchemaNode unionleaf = (LeafSchemaNode) testModule.getDataChildByName("union-leaf");
+
+ ExtendedType type = (ExtendedType) unionleaf.getType();
+ QName typeQName = type.getQName();
+ assertEquals("my-union-ext", typeQName.getLocalName());
+ assertEquals("t", typeQName.getPrefix());
+ assertEquals(typesNS, typeQName.getNamespace());
+ assertEquals(typesRev, typeQName.getRevision());
+ assertNull(type.getUnits());
+ assertNull(type.getDefaultValue());
+ assertNull(type.getFractionDigits());
+ assertTrue(type.getLengths().isEmpty());
+ assertTrue(type.getPatterns().isEmpty());
+ assertTrue(type.getRanges().isEmpty());
+
+ ExtendedType baseType = (ExtendedType) type.getBaseType();
+ QName baseTypeQName = baseType.getQName();
+ assertEquals("my-union", baseTypeQName.getLocalName());
+ assertEquals("t", baseTypeQName.getPrefix());
+ assertEquals(typesNS, baseTypeQName.getNamespace());
+ assertEquals(typesRev, baseTypeQName.getRevision());
+ assertNull(baseType.getUnits());
+ assertNull(baseType.getDefaultValue());
+ assertNull(baseType.getFractionDigits());
+ assertTrue(baseType.getLengths().isEmpty());
+ assertTrue(baseType.getPatterns().isEmpty());
+ assertTrue(baseType.getRanges().isEmpty());
+
+ UnionType unionType = (UnionType) baseType.getBaseType();
+ List<TypeDefinition<?>> unionTypes = unionType.getTypes();
+ assertEquals(2, unionTypes.size());
- List<TypeDefinition<?>> unionTypes = unionBase.getTypes();
ExtendedType unionType1 = (ExtendedType) unionTypes.get(0);
+ QName unionType1QName = baseType.getQName();
+ assertEquals("my-union", unionType1QName.getLocalName());
+ assertEquals("t", unionType1QName.getPrefix());
+ assertEquals(typesNS, unionType1QName.getNamespace());
+ assertEquals(typesRev, unionType1QName.getRevision());
+ assertNull(unionType1.getUnits());
+ assertNull(unionType1.getDefaultValue());
+ assertNull(unionType1.getFractionDigits());
+ assertTrue(unionType1.getLengths().isEmpty());
+ assertTrue(unionType1.getPatterns().isEmpty());
List<RangeConstraint> ranges = unionType1.getRanges();
assertEquals(1, ranges.size());
RangeConstraint range = ranges.get(0);
assertEquals(1L, range.getMin());
assertEquals(100L, range.getMax());
-
assertTrue(unionType1.getBaseType() instanceof Int16);
- assertTrue(unionTypes.get(1) instanceof Int32);
- }
-
- @Test
- public void testNestedUnionResolving1() {
- Module testModule = TestUtils.findModule(modules, "types1");
-
- LeafSchemaNode testleaf = (LeafSchemaNode) testModule.getDataChildByName("nested-union-leaf");
-
- ExtendedType nestedUnion1 = (ExtendedType) testleaf.getType();
- assertEquals("nested-union1", nestedUnion1.getQName().getLocalName());
-
- ExtendedType nestedUnion2 = (ExtendedType) nestedUnion1.getBaseType();
- assertEquals("nested-union2", nestedUnion2.getQName().getLocalName());
-
- UnionType unionType1 = (UnionType) nestedUnion2.getBaseType();
- List<TypeDefinition<?>> unionTypes = unionType1.getTypes();
- assertEquals(2, unionTypes.size());
- assertTrue(unionTypes.get(0) instanceof StringType);
- assertTrue(unionTypes.get(1) instanceof ExtendedType);
-
- ExtendedType extendedUnion = (ExtendedType) unionTypes.get(1);
- ExtendedType extendedUnionBase = (ExtendedType) extendedUnion.getBaseType();
- assertEquals("my-union", extendedUnionBase.getQName().getLocalName());
- UnionType extendedTargetUnion = (UnionType) extendedUnionBase.getBaseType();
- List<TypeDefinition<?>> extendedTargetTypes = extendedTargetUnion.getTypes();
- assertTrue(extendedTargetTypes.get(0).getBaseType() instanceof Int16);
- assertTrue(extendedTargetTypes.get(1) instanceof Int32);
-
- ExtendedType int16 = (ExtendedType) extendedTargetTypes.get(0);
- assertTrue(int16.getBaseType() instanceof Int16);
- List<RangeConstraint> ranges = int16.getRanges();
- assertEquals(1, ranges.size());
- RangeConstraint range = ranges.get(0);
- assertEquals(1L, range.getMin());
- assertEquals(100L, range.getMax());
+ assertTrue(unionTypes.get(1) instanceof Int32);
}
@Test
- public void testNestedUnionResolving2() {
- Module testModule = TestUtils.findModule(modules, "types1");
-
+ public void testNestedUnionResolving() {
+ Module testModule = TestUtils.findModule(modules, "nodes");
LeafSchemaNode testleaf = (LeafSchemaNode) testModule.getDataChildByName("custom-union-leaf");
- ExtendedType testleafType = (ExtendedType) testleaf.getType();
- QName testleafTypeQName = testleafType.getQName();
- assertEquals(URI.create("urn:simple.container.demo.test"), testleafTypeQName.getNamespace());
- assertEquals(TestUtils.createDate("2013-02-27"), testleafTypeQName.getRevision());
- assertEquals("t3", testleafTypeQName.getPrefix());
+ ExtendedType type = (ExtendedType) testleaf.getType();
+ QName testleafTypeQName = type.getQName();
+ assertEquals(customNS, testleafTypeQName.getNamespace());
+ assertEquals(customRev, testleafTypeQName.getRevision());
+ assertEquals("c", testleafTypeQName.getPrefix());
assertEquals("union1", testleafTypeQName.getLocalName());
+ assertNull(type.getUnits());
+ assertNull(type.getDefaultValue());
+ assertNull(type.getFractionDigits());
+ assertTrue(type.getLengths().isEmpty());
+ assertTrue(type.getPatterns().isEmpty());
+ assertTrue(type.getRanges().isEmpty());
- ExtendedType union2 = (ExtendedType) testleafType.getBaseType();
- QName union2QName = union2.getQName();
- assertEquals(URI.create("urn:simple.container.demo.test"), union2QName.getNamespace());
- assertEquals(TestUtils.createDate("2013-02-27"), union2QName.getRevision());
- assertEquals("t3", union2QName.getPrefix());
- assertEquals("union2", union2QName.getLocalName());
+ ExtendedType typeBase = (ExtendedType) type.getBaseType();
+ QName typeBaseQName = typeBase.getQName();
+ assertEquals(customNS, typeBaseQName.getNamespace());
+ assertEquals(customRev, typeBaseQName.getRevision());
+ assertEquals("c", typeBaseQName.getPrefix());
+ assertEquals("union2", typeBaseQName.getLocalName());
+ assertNull(typeBase.getUnits());
+ assertNull(typeBase.getDefaultValue());
+ assertNull(typeBase.getFractionDigits());
+ assertTrue(typeBase.getLengths().isEmpty());
+ assertTrue(typeBase.getPatterns().isEmpty());
+ assertTrue(typeBase.getRanges().isEmpty());
- UnionType union2Base = (UnionType) union2.getBaseType();
- List<TypeDefinition<?>> unionTypes = union2Base.getTypes();
+ UnionType union = (UnionType) typeBase.getBaseType();
+ List<TypeDefinition<?>> unionTypes = union.getTypes();
assertEquals(2, unionTypes.size());
assertTrue(unionTypes.get(0) instanceof Int32);
assertTrue(unionTypes.get(1) instanceof ExtendedType);
- ExtendedType nestedUnion2 = (ExtendedType) unionTypes.get(1);
- QName nestedUnion2QName = nestedUnion2.getQName();
- assertEquals(URI.create("urn:simple.types.data.demo"), nestedUnion2QName.getNamespace());
- assertEquals(TestUtils.createDate("2013-02-27"), nestedUnion2QName.getRevision());
- assertEquals("t2", nestedUnion2QName.getPrefix());
- assertEquals("nested-union2", nestedUnion2QName.getLocalName());
-
- UnionType nestedUnion2Base = (UnionType) nestedUnion2.getBaseType();
- List<TypeDefinition<?>> nestedUnion2Types = nestedUnion2Base.getTypes();
+ ExtendedType unionType1 = (ExtendedType) unionTypes.get(1);
+ QName uniontType1QName = unionType1.getQName();
+ assertEquals(typesNS, uniontType1QName.getNamespace());
+ assertEquals(typesRev, uniontType1QName.getRevision());
+ assertEquals("t", uniontType1QName.getPrefix());
+ assertEquals("nested-union2", uniontType1QName.getLocalName());
+ assertNull(unionType1.getUnits());
+ assertNull(unionType1.getDefaultValue());
+ assertNull(unionType1.getFractionDigits());
+ assertTrue(unionType1.getLengths().isEmpty());
+ assertTrue(unionType1.getPatterns().isEmpty());
+ assertTrue(unionType1.getRanges().isEmpty());
+
+ UnionType nestedUnion = (UnionType) unionType1.getBaseType();
+ List<TypeDefinition<?>> nestedUnion2Types = nestedUnion.getTypes();
assertEquals(2, nestedUnion2Types.size());
assertTrue(nestedUnion2Types.get(0) instanceof StringType);
assertTrue(nestedUnion2Types.get(1) instanceof ExtendedType);
ExtendedType myUnionExt = (ExtendedType) nestedUnion2Types.get(1);
QName myUnionExtQName = myUnionExt.getQName();
- assertEquals(URI.create("urn:simple.types.data.demo"), myUnionExtQName.getNamespace());
- assertEquals(TestUtils.createDate("2013-02-27"), myUnionExtQName.getRevision());
- assertEquals("t2", myUnionExtQName.getPrefix());
+ assertEquals(typesNS, myUnionExtQName.getNamespace());
+ assertEquals(typesRev, myUnionExtQName.getRevision());
+ assertEquals("t", myUnionExtQName.getPrefix());
assertEquals("my-union-ext", myUnionExtQName.getLocalName());
+ assertNull(myUnionExt.getUnits());
+ assertNull(myUnionExt.getDefaultValue());
+ assertNull(myUnionExt.getFractionDigits());
+ assertTrue(myUnionExt.getLengths().isEmpty());
+ assertTrue(myUnionExt.getPatterns().isEmpty());
+ assertTrue(myUnionExt.getRanges().isEmpty());
ExtendedType myUnion = (ExtendedType) myUnionExt.getBaseType();
QName myUnionQName = myUnion.getQName();
- assertEquals(URI.create("urn:simple.types.data.demo"), myUnionQName.getNamespace());
- assertEquals(TestUtils.createDate("2013-02-27"), myUnionQName.getRevision());
- assertEquals("t2", myUnionQName.getPrefix());
+ assertEquals(typesNS, myUnionQName.getNamespace());
+ assertEquals(typesRev, myUnionQName.getRevision());
+ assertEquals("t", myUnionQName.getPrefix());
assertEquals("my-union", myUnionQName.getLocalName());
+ assertNull(myUnion.getUnits());
+ assertNull(myUnion.getDefaultValue());
+ assertNull(myUnion.getFractionDigits());
+ assertTrue(myUnion.getLengths().isEmpty());
+ assertTrue(myUnion.getPatterns().isEmpty());
+ assertTrue(myUnion.getRanges().isEmpty());
UnionType myUnionBase = (UnionType) myUnion.getBaseType();
List<TypeDefinition<?>> myUnionBaseTypes = myUnionBase.getTypes();
assertEquals(2, myUnionBaseTypes.size());
- assertTrue(myUnionBaseTypes.get(0).getBaseType() instanceof Int16);
+ assertTrue(myUnionBaseTypes.get(0) instanceof ExtendedType);
assertTrue(myUnionBaseTypes.get(1) instanceof Int32);
- ExtendedType int16 = (ExtendedType) myUnionBaseTypes.get(0);
- List<RangeConstraint> ranges = int16.getRanges();
+
+ ExtendedType int16Ext = (ExtendedType) myUnionBaseTypes.get(0);
+ QName int16ExtQName = int16Ext.getQName();
+ assertEquals(typesNS, int16ExtQName.getNamespace());
+ assertEquals(typesRev, int16ExtQName.getRevision());
+ assertEquals("t", int16ExtQName.getPrefix());
+ assertEquals("int16", int16ExtQName.getLocalName());
+ assertNull(int16Ext.getUnits());
+ assertNull(int16Ext.getDefaultValue());
+ assertNull(int16Ext.getFractionDigits());
+ assertTrue(int16Ext.getLengths().isEmpty());
+ assertTrue(int16Ext.getPatterns().isEmpty());
+ List<RangeConstraint> ranges = int16Ext.getRanges();
assertEquals(1, ranges.size());
RangeConstraint range = ranges.get(0);
assertEquals(1L, range.getMin());
assertEquals(100L, range.getMax());
+
+ assertTrue(int16Ext.getBaseType() instanceof Int16);
}
@Test
public void testChoice() {
- Module testModule = TestUtils.findModule(modules, "types1");
- ContainerSchemaNode peer = (ContainerSchemaNode) testModule.getDataChildByName("transfer");
- ChoiceNode how = (ChoiceNode) peer.getDataChildByName("how");
+ Module testModule = TestUtils.findModule(modules, "nodes");
+ ContainerSchemaNode transfer = (ContainerSchemaNode) testModule.getDataChildByName("transfer");
+ ChoiceNode how = (ChoiceNode) transfer.getDataChildByName("how");
Set<ChoiceCaseNode> cases = how.getCases();
assertEquals(5, cases.size());
ChoiceCaseNode input = null;
@Test
public void testAnyXml() {
- Module testModule = TestUtils.findModule(modules, "types1");
+ Module testModule = TestUtils.findModule(modules, "nodes");
AnyXmlSchemaNode data = (AnyXmlSchemaNode) testModule.getDataChildByName("data");
- assertNotNull(data);
+ assertNotNull("anyxml data not found", data);
+
+ // test SchemaNode args
+ QName qname = data.getQName();
+ assertEquals("data", qname.getLocalName());
+ assertEquals("n", qname.getPrefix());
+ assertEquals(nodesNS, qname.getNamespace());
+ assertEquals(nodesRev, qname.getRevision());
+ assertTrue(data.getDescription().contains("Copy of the source typesstore subset that matched"));
+ assertNull(data.getReference());
+ assertEquals(Status.OBSOLETE, data.getStatus());
+ assertEquals(0, data.getUnknownSchemaNodes().size());
+ // test DataSchemaNode args
+ assertFalse(data.isAugmenting());
+ assertTrue(data.isConfiguration());
+ ConstraintDefinition constraints = data.getConstraints();
+ assertNull(constraints.getWhenCondition());
+ assertEquals(0, constraints.getMustConstraints().size());
+ assertFalse(constraints.isMandatory());
+ assertNull(constraints.getMinElements());
+ assertNull(constraints.getMaxElements());
}
@Test
public void testDeviation() {
- Module testModule = TestUtils.findModule(modules, "types1");
+ Module testModule = TestUtils.findModule(modules, "nodes");
Set<Deviation> deviations = testModule.getDeviations();
assertEquals(1, deviations.size());
-
Deviation dev = deviations.iterator().next();
- SchemaPath expectedPath = TestUtils.createPath(true, null, null, "data", "system", "user");
+
+ assertEquals("system/user ref", dev.getReference());
+
+ List<QName> path = new ArrayList<QName>();
+ path.add(new QName(typesNS, typesRev, "t", "interfaces"));
+ path.add(new QName(typesNS, typesRev, "t", "ifEntry"));
+ SchemaPath expectedPath = new SchemaPath(path, true);
+
assertEquals(expectedPath, dev.getTargetPath());
assertEquals(Deviate.ADD, dev.getDeviate());
}
@Test
public void testUnknownNode() {
- Module testModule = TestUtils.findModule(modules, "types3");
+ Module testModule = TestUtils.findModule(modules, "custom");
ContainerSchemaNode network = (ContainerSchemaNode) testModule.getDataChildByName("network");
List<UnknownSchemaNode> unknownNodes = network.getUnknownSchemaNodes();
assertEquals(1, unknownNodes.size());
@Test
public void testFeature() {
- Module testModule = TestUtils.findModule(modules, "types3");
+ Module testModule = TestUtils.findModule(modules, "custom");
Set<FeatureDefinition> features = testModule.getFeatures();
assertEquals(1, features.size());
}
@Test
public void testExtension() {
- Module testModule = TestUtils.findModule(modules, "types3");
+ Module testModule = TestUtils.findModule(modules, "custom");
List<ExtensionDefinition> extensions = testModule.getExtensionSchemaNodes();
assertEquals(1, extensions.size());
ExtensionDefinition extension = extensions.get(0);
assertEquals("name", extension.getArgument());
- assertFalse(extension.isYinElement());
+ assertTrue(extension.isYinElement());
}
@Test
public void testNotification() {
- Module testModule = TestUtils.findModule(modules, "types3");
- URI expectedNamespace = URI.create("urn:simple.container.demo.test");
- String expectedPrefix = "t3";
- Date expectedRevision = TestUtils.createDate("2013-02-27");
+ Module testModule = TestUtils.findModule(modules, "custom");
+ String expectedPrefix = "c";
Set<NotificationDefinition> notifications = testModule.getNotifications();
assertEquals(1, notifications.size());
NotificationDefinition notification = notifications.iterator().next();
// test SchemaNode args
- QName expectedQName = new QName(expectedNamespace, expectedRevision, expectedPrefix, "event");
+ QName expectedQName = new QName(customNS, customRev, expectedPrefix, "event");
assertEquals(expectedQName, notification.getQName());
- SchemaPath expectedPath = TestUtils.createPath(true, expectedNamespace, expectedRevision, expectedPrefix,
- "event");
+ SchemaPath expectedPath = TestUtils.createPath(true, customNS, customRev, expectedPrefix, "event");
assertEquals(expectedPath, notification.getPath());
assertNull(notification.getDescription());
assertNull(notification.getReference());
@Test
public void testRpc() {
- Module testModule = TestUtils.findModule(modules, "types3");
+ Module testModule = TestUtils.findModule(modules, "custom");
Set<RpcDefinition> rpcs = testModule.getRpcs();
assertEquals(1, rpcs.size());
assertNotNull(output.getDataChildByName("data"));
}
- @Test
- public void testAugmentNodesTypesSchemaPath() throws Exception {
- Module testModule = TestUtils.findModule(modules, "types1");
- Set<AugmentationSchema> augments = testModule.getAugmentations();
- assertEquals(1, augments.size());
- AugmentationSchema augment = augments.iterator().next();
-
- LeafSchemaNode ifcId = (LeafSchemaNode) augment.getDataChildByName("interface-id");
- Leafref ifcIdType = (Leafref) ifcId.getType();
- SchemaPath ifcIdTypeSchemaPath = ifcIdType.getPath();
- List<QName> ifcIdTypePath = ifcIdTypeSchemaPath.getPath();
-
- URI types1URI = URI.create("urn:simple.container.demo");
- URI types2URI = URI.create("urn:simple.types.data.demo");
- URI types3URI = URI.create("urn:simple.container.demo.test");
- Date expectedDate = simpleDateFormat.parse("2013-02-27");
-
- QName q0 = new QName(types2URI, expectedDate, "data", "interfaces");
- QName q1 = new QName(types2URI, expectedDate, "data", "ifEntry");
- QName q2 = new QName(types3URI, expectedDate, "data", "augment-holder");
- QName q3 = new QName(types1URI, expectedDate, "data", "interface-id");
- assertEquals(q0, ifcIdTypePath.get(0));
- assertEquals(q1, ifcIdTypePath.get(1));
- assertEquals(q2, ifcIdTypePath.get(2));
- assertEquals(q3, ifcIdTypePath.get(3));
-
- LeafListSchemaNode higherLayer = (LeafListSchemaNode) augment.getDataChildByName("higher-layer-if");
- Leafref higherLayerType = (Leafref) higherLayer.getType();
- SchemaPath higherLayerTypeSchemaPath = higherLayerType.getPath();
- List<QName> higherLayerTypePath = higherLayerTypeSchemaPath.getPath();
- assertEquals(q0, higherLayerTypePath.get(0));
- assertEquals(q1, higherLayerTypePath.get(1));
- assertEquals(q2, higherLayerTypePath.get(2));
- q3 = new QName(types1URI, expectedDate, "data", "higher-layer-if");
- assertEquals(q3, higherLayerTypePath.get(3));
-
- LeafSchemaNode myType = (LeafSchemaNode) augment.getDataChildByName("my-type");
- ExtendedType leafType = (ExtendedType) myType.getType();
-
- testModule = TestUtils.findModule(modules, "types2");
- TypeDefinition<?> typedef = TestUtils.findTypedef(testModule.getTypeDefinitions(), "my-type1");
-
- assertEquals(typedef, leafType);
- }
-
@Test
public void testTypePath() throws ParseException {
- Module test = TestUtils.findModule(modules, "types2");
+ Module test = TestUtils.findModule(modules, "types");
Set<TypeDefinition<?>> types = test.getTypeDefinitions();
// my-base-int32-type
- ExtendedType int32Typedef = (ExtendedType) TestUtils.findTypedef(types, "my-base-int32-type");
+ ExtendedType int32Typedef = (ExtendedType) TestUtils.findTypedef(types, "int32-ext1");
QName int32TypedefQName = int32Typedef.getQName();
- URI expectedNS = URI.create("urn:simple.types.data.demo");
- Date expectedDate = simpleDateFormat.parse("2013-02-27");
- assertEquals(expectedNS, int32TypedefQName.getNamespace());
- assertEquals(expectedDate, int32TypedefQName.getRevision());
- assertEquals("t2", int32TypedefQName.getPrefix());
- assertEquals("my-base-int32-type", int32TypedefQName.getLocalName());
+ assertEquals(typesNS, int32TypedefQName.getNamespace());
+ assertEquals(typesRev, int32TypedefQName.getRevision());
+ assertEquals("t", int32TypedefQName.getPrefix());
+ assertEquals("int32-ext1", int32TypedefQName.getLocalName());
SchemaPath typeSchemaPath = int32Typedef.getPath();
List<QName> typePath = typeSchemaPath.getPath();
@Test
public void testTypePath2() throws ParseException {
- Module test = TestUtils.findModule(modules, "types2");
+ Module test = TestUtils.findModule(modules, "types");
Set<TypeDefinition<?>> types = test.getTypeDefinitions();
// my-base-int32-type
ExtendedType myDecType = (ExtendedType) TestUtils.findTypedef(types, "my-decimal-type");
QName myDecTypeQName = myDecType.getQName();
- URI expectedNS = URI.create("urn:simple.types.data.demo");
- Date expectedDate = simpleDateFormat.parse("2013-02-27");
- assertEquals(expectedNS, myDecTypeQName.getNamespace());
- assertEquals(expectedDate, myDecTypeQName.getRevision());
- assertEquals("t2", myDecTypeQName.getPrefix());
+ assertEquals(typesNS, myDecTypeQName.getNamespace());
+ assertEquals(typesRev, myDecTypeQName.getRevision());
+ assertEquals("t", myDecTypeQName.getPrefix());
assertEquals("my-decimal-type", myDecTypeQName.getLocalName());
SchemaPath typeSchemaPath = myDecType.getPath();
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
+import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.Set;
import org.opendaylight.controller.yang.model.api.ChoiceNode;
import org.opendaylight.controller.yang.model.api.ContainerSchemaNode;
import org.opendaylight.controller.yang.model.api.DataSchemaNode;
+import org.opendaylight.controller.yang.model.api.Deviation;
+import org.opendaylight.controller.yang.model.api.Deviation.Deviate;
import org.opendaylight.controller.yang.model.api.GroupingDefinition;
import org.opendaylight.controller.yang.model.api.IdentitySchemaNode;
import org.opendaylight.controller.yang.model.api.LeafSchemaNode;
assertEquals("inet", qname.getPrefix());
assertEquals("port-number", qname.getLocalName());
- ExtendedType dscpExt = (ExtendedType)TestUtils.findTypedef(module.getTypeDefinitions(), "dscp-ext");
+ ExtendedType dscpExt = (ExtendedType) TestUtils.findTypedef(module.getTypeDefinitions(), "dscp-ext");
List<RangeConstraint> ranges = dscpExt.getRanges();
assertEquals(1, ranges.size());
RangeConstraint range = ranges.get(0);
@Test
public void testUsesFromContext() throws Exception {
SchemaContext context = null;
- try (InputStream stream = new FileInputStream(getClass().getResource("/model/testfile2.yang").getPath())) {
- context = parser.resolveSchemaContext(TestUtils.loadModules(Lists.newArrayList(stream)));
+ try (InputStream stream1 = new FileInputStream(getClass().getResource("/model/custom.yang").getPath());
+ InputStream stream2 = new FileInputStream(getClass().getResource("/model/types.yang").getPath());
+ InputStream stream3 = new FileInputStream(getClass().getResource("/model/nodes.yang").getPath())) {
+ context = parser.resolveSchemaContext(TestUtils.loadModules(Lists.newArrayList(stream1, stream2, stream3)));
}
Module testModule = null;
try (InputStream stream = new FileInputStream(getClass().getResource("/context-test/test2.yang").getPath())) {
// suffix _g = defined in grouping from context
// get grouping
- Module contextModule = context.findModuleByNamespace(URI.create("urn:simple.types.data.demo"));
+ Module contextModule = context.findModuleByNamespace(URI.create("urn:custom.nodes.test"));
assertNotNull(contextModule);
Set<GroupingDefinition> groupings = contextModule.getGroupings();
assertEquals(1, groupings.size());
GroupingDefinition grouping = groupings.iterator().next();
// get node containing uses
- ContainerSchemaNode peer = (ContainerSchemaNode)testModule.getDataChildByName("peer");
- ContainerSchemaNode destination = (ContainerSchemaNode)peer.getDataChildByName("destination");
+ ContainerSchemaNode peer = (ContainerSchemaNode) testModule.getDataChildByName("peer");
+ ContainerSchemaNode destination = (ContainerSchemaNode) peer.getDataChildByName("destination");
// check uses
Set<UsesNode> uses = destination.getUses();
assertEquals(1, uses.size());
// check uses process
- AnyXmlSchemaNode data_u = (AnyXmlSchemaNode)destination.getDataChildByName("data");
+ AnyXmlSchemaNode data_u = (AnyXmlSchemaNode) destination.getDataChildByName("data");
assertNotNull(data_u);
assertTrue(data_u.isAddedByUses());
- AnyXmlSchemaNode data_g = (AnyXmlSchemaNode)grouping.getDataChildByName("data");
+ AnyXmlSchemaNode data_g = (AnyXmlSchemaNode) grouping.getDataChildByName("data");
assertNotNull(data_g);
assertFalse(data_g.isAddedByUses());
assertFalse(data_u.equals(data_g));
- ChoiceNode how_u = (ChoiceNode)destination.getDataChildByName("how");
+ ChoiceNode how_u = (ChoiceNode) destination.getDataChildByName("how");
assertNotNull(how_u);
assertTrue(how_u.isAddedByUses());
- ChoiceNode how_g = (ChoiceNode)grouping.getDataChildByName("how");
+ ChoiceNode how_g = (ChoiceNode) grouping.getDataChildByName("how");
assertNotNull(how_g);
assertFalse(how_g.isAddedByUses());
assertFalse(how_u.equals(how_g));
- LeafSchemaNode address_u = (LeafSchemaNode)destination.getDataChildByName("address");
+ LeafSchemaNode address_u = (LeafSchemaNode) destination.getDataChildByName("address");
assertNotNull(address_u);
assertTrue(address_u.isAddedByUses());
- LeafSchemaNode address_g = (LeafSchemaNode)grouping.getDataChildByName("address");
+ LeafSchemaNode address_g = (LeafSchemaNode) grouping.getDataChildByName("address");
assertNotNull(address_g);
assertFalse(address_g.isAddedByUses());
assertFalse(address_u.equals(address_g));
- ContainerSchemaNode port_u = (ContainerSchemaNode)destination.getDataChildByName("port");
+ ContainerSchemaNode port_u = (ContainerSchemaNode) destination.getDataChildByName("port");
assertNotNull(port_u);
assertTrue(port_u.isAddedByUses());
- ContainerSchemaNode port_g = (ContainerSchemaNode)grouping.getDataChildByName("port");
+ ContainerSchemaNode port_g = (ContainerSchemaNode) grouping.getDataChildByName("port");
assertNotNull(port_g);
assertFalse(port_g.isAddedByUses());
assertFalse(port_u.equals(port_g));
- ListSchemaNode addresses_u = (ListSchemaNode)destination.getDataChildByName("addresses");
+ ListSchemaNode addresses_u = (ListSchemaNode) destination.getDataChildByName("addresses");
assertNotNull(addresses_u);
assertTrue(addresses_u.isAddedByUses());
- ListSchemaNode addresses_g = (ListSchemaNode)grouping.getDataChildByName("addresses");
+ ListSchemaNode addresses_g = (ListSchemaNode) grouping.getDataChildByName("addresses");
assertNotNull(addresses_g);
assertFalse(addresses_g.isAddedByUses());
assertFalse(addresses_u.equals(addresses_g));
@Test
public void testUsesRefineFromContext() throws Exception {
SchemaContext context = null;
- try (InputStream stream = new FileInputStream(getClass().getResource("/model/testfile2.yang").getPath())) {
- context = parser.resolveSchemaContext(TestUtils.loadModules(Lists.newArrayList(stream)));
+ try (InputStream stream1 = new FileInputStream(getClass().getResource("/model/custom.yang").getPath());
+ InputStream stream2 = new FileInputStream(getClass().getResource("/model/types.yang").getPath());
+ InputStream stream3 = new FileInputStream(getClass().getResource("/model/nodes.yang").getPath())) {
+ context = parser.resolveSchemaContext(TestUtils.loadModules(Lists.newArrayList(stream1, stream2, stream3)));
}
Module module = null;
try (InputStream stream = new FileInputStream(getClass().getResource("/context-test/test2.yang").getPath())) {
// test grouping path
List<QName> path = new ArrayList<QName>();
- QName qname = new QName(URI.create("urn:simple.types.data.demo"), simpleDateFormat.parse("2013-02-27"), "t2",
+ QName qname = new QName(URI.create("urn:custom.nodes.test"), simpleDateFormat.parse("2013-02-27"), "c",
"target");
path.add(qname);
SchemaPath expectedPath = new SchemaPath(path, true);
@Test
public void testUnknownNodes() throws Exception {
SchemaContext context = null;
- try (InputStream stream = new FileInputStream(getClass().getResource("/types/custom-types-test@2012-4-4.yang").getPath())) {
+ try (InputStream stream = new FileInputStream(getClass().getResource("/types/custom-types-test@2012-4-4.yang")
+ .getPath())) {
context = parser.resolveSchemaContext(TestUtils.loadModules(Lists.newArrayList(stream)));
}
assertTrue(ifEntry == ifEntryAfterAugment);
}
+ @Test
+ public void testDeviation() throws Exception {
+ // load first module
+ SchemaContext context = null;
+ String resource = "/model/types.yang";
+
+ try (InputStream stream = new FileInputStream(getClass().getResource(resource).getPath())) {
+ context = parser.resolveSchemaContext(TestUtils.loadModules(Lists.newArrayList(stream)));
+ }
+
+ // load another modules and parse them against already existing context
+ Set<Module> modules = null;
+ try (InputStream stream = new FileInputStream(getClass().getResource("/context-test/deviation-test.yang")
+ .getPath())) {
+ List<InputStream> input = Lists.newArrayList(stream);
+ modules = TestUtils.loadModulesWithContext(input, context);
+ }
+ assertNotNull(modules);
+
+ // test deviation
+ Module testModule = TestUtils.findModule(modules, "deviation-test");
+ Set<Deviation> deviations = testModule.getDeviations();
+ assertEquals(1, deviations.size());
+ Deviation dev = deviations.iterator().next();
+
+ assertEquals("system/user ref", dev.getReference());
+
+ URI expectedNS = URI.create("urn:simple.types.test");
+ DateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd");
+ Date expectedRev = simpleDateFormat.parse("2013-07-03");
+ List<QName> path = new ArrayList<QName>();
+ path.add(new QName(expectedNS, expectedRev, "t", "interfaces"));
+ path.add(new QName(expectedNS, expectedRev, "t", "ifEntry"));
+ SchemaPath expectedPath = new SchemaPath(path, true);
+
+ assertEquals(expectedPath, dev.getTargetPath());
+ assertEquals(Deviate.ADD, dev.getDeviate());
+ }
+
}
--- /dev/null
+module deviation-test {
+ yang-version 1;
+ namespace "urn:simple.deviation.test";
+ prefix "dev";
+
+ import types {
+ prefix "t";
+ revision-date 2013-07-03;
+ }
+
+ organization "opendaylight";
+ contact "http://www.opendaylight.org/";
+
+ revision "2013-02-27" {
+ reference " WILL BE DEFINED LATER";
+ }
+
+
+ deviation /t:interfaces/t:ifEntry {
+ deviate add {
+ default "admin"; // new users are 'admin' by default
+ config "true";
+ }
+ reference "system/user ref";
+ }
+
+}
namespace "urn:simple.demo.test2";
prefix "t2";
- import types2 {
+ import custom {
prefix "data";
}
-module types3 {
+module custom {
yang-version 1;
- namespace "urn:simple.container.demo.test";
- prefix "t3";
+ namespace "urn:custom.nodes.test";
+ prefix "c";
- import types2 {
- prefix "data";
- revision-date 2013-02-27;
+ import types {
+ prefix "types";
+ revision-date 2013-07-03;
}
organization "opendaylight";
typedef union2 {
type union {
type int32;
- type data:nested-union2;
+ type types:nested-union2;
}
}
- augment "/data:interfaces/data:ifEntry" {
+ augment "/types:interfaces/types:ifEntry" {
when "if:ifType='ds0'";
container augment-holder {
description "Description for augment holder";
}
}
- augment "/data:interfaces/data:ifEntry" {
+ augment "/types:interfaces/types:ifEntry" {
when "if:ifType='ds2'";
container augment-holder2 {
description "Description for augment holder";
}
}
- augment "/data:interfaces/data:ifEntry/t3:augment-holder/t1:schemas" {
+ augment "/types:interfaces/types:ifEntry/t3:augment-holder/t1:schemas" {
when "if:leafType='ds1'";
leaf linkleaf {
type binary;
extension c-define {
description
- "Takes as argument a name string.
- Makes the code generator use the given name in the
- #define.";
- argument "name";
+ "Takes as argument a name string. Makes the code generator use the given name in the #define.";
+ argument "name" {
+ yin-element "true";
+ }
}
notification event {
}
}
+ grouping target {
+ anyxml data {
+ config true;
+ description "Copy of the source datastore subset.";
+ mandatory false;
+ must "test-condition-text";
+ reference "test-no-reference";
+ status "obsolete";
+ when "test-when-text";
+ }
+ choice how {
+ description "test choice description";
+ default interval;
+ case interval {
+ leaf interval {
+ type uint16;
+ default 30;
+ units minutes;
+ }
+ }
+ case daily {
+ leaf daily {
+ type empty;
+ }
+ leaf time-of-day {
+ type string;
+ units 24-hour-clock;
+ default 1am;
+ }
+ }
+ }
+ leaf address {
+ type string;
+ description "Target IP address";
+ }
+ container port {
+ description "Target port container";
+ }
+ list addresses {
+ key "id";
+ leaf id {
+ type int8;
+ }
+ }
+ grouping target-inner {
+ description "target-inner default description";
+ leaf inner-grouping-id {
+ type int8;
+ }
+ }
+ typedef group-type {
+ type types:my-decimal-type;
+ }
+
+ opendaylight;
+ }
+
}
--- /dev/null
+module nodes {
+ yang-version 1;
+ namespace "urn:simple.nodes.test";
+ prefix "n";
+
+ import types {
+ prefix "t";
+ revision-date 2013-07-03;
+ }
+
+ import custom {
+ prefix "c";
+ revision-date 2013-02-27;
+ }
+
+ organization "opendaylight";
+ contact "http://www.opendaylight.org/";
+
+ revision "2013-02-27" {
+ reference " WILL BE DEFINED LATER";
+ }
+
+ leaf int32-leaf {
+ type t:int32-ext2 {
+ range "12..max";
+ }
+ }
+
+ leaf string-leaf {
+ type t:string-ext4;
+ }
+
+ leaf length-leaf {
+ type t:string-ext2 {
+ length "7..max";
+ }
+ }
+
+ leaf decimal-leaf {
+ type t:my-decimal-type {
+ fraction-digits 4;
+ }
+ }
+
+ leaf decimal-leaf2 {
+ type t:my-decimal-type;
+ }
+
+ container ext {
+ types:c-define "MY_INTERFACES";
+ }
+
+ leaf union-leaf {
+ type t:my-union-ext;
+ }
+
+ deviation /t:interfaces/t:ifEntry {
+ deviate add {
+ default "admin"; // new users are 'admin' by default
+ config "true";
+ }
+ reference "system/user ref";
+ }
+
+ leaf custom-union-leaf {
+ type c:union1;
+ }
+
+ container transfer {
+ choice how {
+ default interval;
+ container input {
+ }
+ list output {
+ leaf id {
+ type string;
+ }
+ }
+ case interval {
+ leaf interval {
+ type uint16;
+ default 30;
+ units minutes;
+ }
+ }
+ case daily {
+ leaf daily {
+ type empty;
+ }
+ leaf time-of-day {
+ type string;
+ units 24-hour-clock;
+ default 1am;
+ }
+ }
+ case manual {
+ leaf manual {
+ type empty;
+ }
+ }
+ }
+ }
+
+ anyxml data {
+ description
+ "Copy of the source typesstore subset that matched
+ the filter criteria (if any). An empty types container
+ indicates that the request did not produce any results.";
+ status obsolete;
+ }
+
+ augment "/t:interfaces/t:ifEntry/c:augment-holder" {
+ when "if:ifType='ds0'";
+ leaf ds0ChannelNumber {
+ type string;
+ }
+ leaf interface-id {
+ type leafref {
+ path "/if:interfaces/if:interface/if:name";
+ }
+ }
+ leaf my-type {
+ type t:int32-ext2;
+ }
+ container schemas {
+ }
+ choice odl {
+ leaf id {
+ type int8;
+ }
+ case node1 {
+ description "node1";
+ }
+ case node2 {
+ description "node2";
+ }
+ container node3 {
+ description "node3";
+ }
+ }
+ }
+
+ container mycont {
+ container innercont {
+ typedef mytype {
+ type string;
+ }
+ leaf myleaf {
+ type mytype;
+ }
+ }
+ }
+
+ container peer {
+ container destination {
+ uses c:target {
+ refine address {
+ default "1.2.3.4";
+ description "IP address of target node";
+ reference "address reference added by refine";
+ config false;
+ mandatory true;
+ must "ifType != 'ethernet' or " +
+ "(ifType = 'ethernet' and ifMTU = 1500)" {
+ error-message "An ethernet MTU must be 1500";
+ }
+ }
+ refine port {
+ description "description of port defined by refine";
+ reference "port reference added by refine";
+ config false;
+ presence "presence is required";
+ }
+ refine addresses {
+ description "description of addresses defined by refine";
+ reference "addresses reference added by refine";
+ config false;
+ min-elements 2;
+ max-elements 12;
+ }
+ refine target-inner {
+ description "new target-inner grouping description";
+ }
+ refine group-type {
+ description "new group-type description";
+ reference "new group-type reference";
+ }
+ }
+ }
+ }
+
+}
+++ /dev/null
-module types1 {
- yang-version 1;
- namespace "urn:simple.container.demo";
- prefix "t1";
-
- import types2 {
- prefix "data";
- revision-date 2013-02-27;
- }
-
- import types3 {
- prefix "t3";
- revision-date 2013-02-27;
- }
-
- organization "opendaylight";
- contact "http://www.opendaylight.org/";
-
- revision "2013-02-27" {
- reference " WILL BE DEFINED LATER";
- }
-
- leaf testleaf {
- type data:my-type1 {
- range "12..max";
- }
- }
-
- leaf test-string-leaf {
- type data:my-string-type-ext;
- }
-
- leaf leaf-with-length {
- type data:my-string-type {
- length "7..max";
- }
- }
-
- leaf test-int-leaf {
- type data:my-int-type-ext;
- }
-
- leaf test-decimal-leaf {
- type data:my-decimal-type {
- fraction-digits 4;
- }
- }
-
- leaf test-decimal-leaf2 {
- type data:my-decimal-type-ext;
- }
-
- container ext {
- data:c-define "MY_INTERFACES";
- }
-
- leaf union-leaf {
- type data:my-union-ext;
- }
-
- deviation /data:system/data:user {
- deviate add {
- default "admin"; // new users are 'admin' by default
- config "true";
- }
- }
-
- leaf nested-union-leaf {
- type data:nested-union1;
- }
-
- leaf custom-union-leaf {
- type t3:union1;
- }
-
- container transfer {
- choice how {
- default interval;
- container input {
- }
- list output {
- leaf id {
- type string;
- }
- }
- case interval {
- leaf interval {
- type uint16;
- default 30;
- units minutes;
- }
- }
- case daily {
- leaf daily {
- type empty;
- }
- leaf time-of-day {
- type string;
- units 24-hour-clock;
- default 1am;
- }
- }
- case manual {
- leaf manual {
- type empty;
- }
- }
- }
- }
-
- anyxml data {
- description
- "Copy of the source datastore subset that matched
- the filter criteria (if any). An empty data container
- indicates that the request did not produce any results.";
- }
-
- augment "/data:interfaces/data:ifEntry/t3:augment-holder" {
- when "if:ifType='ds0'";
- leaf ds0ChannelNumber {
- type string;
- }
- leaf interface-id {
- type leafref {
- path "/if:interfaces/if:interface/if:name";
- }
- }
- leaf-list higher-layer-if {
- type leafref {
- path "/if:interfaces/if:interface/if:higher-layer-if";
- }
- }
- leaf my-type {
- type data:my-type1;
- }
- container schemas {
- }
- choice odl {
- leaf id {
- type int8;
- }
- }
- }
-
- container mycont {
- container innercont {
- typedef mytype {
- type string;
- }
-
- leaf myleaf {
- type mytype;
- }
- }
- }
-
-}
+++ /dev/null
-module types2 {
- yang-version 1;
- namespace "urn:simple.types.data.demo";
- prefix "t2";
-
- organization "opendaylight";
- contact "http://www.opendaylight.org/";
-
- description "This is types-data test description";
-
- revision "2013-02-27" {
- reference " WILL BE DEFINED LATER";
- }
-
- typedef my-base-int32-type {
- type int32 {
- range "2..20";
- }
- }
-
- typedef my-type1 {
- type my-base-int32-type {
- range "3..9|11..max";
- }
- units "mile";
- default "11";
- }
-
- typedef my-custom-string {
- type string {
- pattern "[a-k]*";
- length "5..11";
- }
- }
-
- typedef my-string-type {
- type my-custom-string {
- length "6..10";
- }
- }
-
- typedef my-string-type2 {
- type my-string-type {
- pattern "[b-u]*";
- }
- }
-
- typedef my-string-type-ext {
- type my-string-type2 {
- pattern "[e-z]*";
- }
- }
-
- typedef my-int-type {
- type int32 {
- range "10..20";
- }
- }
-
- typedef my-int-type2 {
- type my-int-type {
- range "12..18";
- }
- }
-
- typedef my-int-type-ext {
- type my-int-type2 {
- range "14..16";
- }
- }
-
- typedef my-decimal-type {
- type decimal64 {
- fraction-digits 6;
- }
- }
-
- typedef my-decimal-type-ext {
- type decimal64 {
- fraction-digits 5;
- }
- }
-
- typedef my-union {
- type union {
- type int16 {
- range "1..100";
- }
- type int32;
- }
- }
-
- typedef my-union-ext {
- type my-union;
- }
-
- typedef nested-union1 {
- type nested-union2;
- }
-
- typedef nested-union2 {
- type union {
- type my-union-ext;
- type string;
- }
- }
-
- leaf if-name {
- type leafref {
- path "/interface/name";
- }
- }
-
- leaf name {
- type string;
- }
-
- leaf count {
- type int8 {
- range "1..10";
- }
- }
-
- leaf nested-type-leaf {
- type my-type1;
- }
-
- extension c-define {
- description
- "Takes as argument a name string.
- Makes the code generator use the given name in the
- #define.";
- argument "name" {
- yin-element "true";
- }
- }
-
- container system {
- leaf user {
- type string;
- }
- }
-
- grouping target {
- anyxml data {
- config true;
- description "Copy of the source datastore subset.";
- mandatory false;
- must "test-condition-text";
- reference "test-no-reference";
- status "obsolete";
- when "test-when-text";
- }
- choice how {
- description "test choice description";
- default interval;
- case interval {
- leaf interval {
- type uint16;
- default 30;
- units minutes;
- }
- }
- case daily {
- leaf daily {
- type empty;
- }
- leaf time-of-day {
- type string;
- units 24-hour-clock;
- default 1am;
- }
- }
- }
- leaf address {
- type string;
- description "Target IP address";
- }
- container port {
- description "Target port container";
- }
- list addresses {
- key "id";
- leaf id {
- type int8;
- }
- }
- grouping target-inner {
- description "target-inner default description";
- leaf inner-grouping-id {
- type int8;
- }
- }
- typedef group-type {
- type my-decimal-type;
- }
-
- opendaylight;
- }
-
- container peer {
- container destination {
- uses target {
- refine address {
- default "1.2.3.4";
- description "IP address of target node";
- reference "address reference added by refine";
- config false;
- mandatory true;
- must "ifType != 'ethernet' or " +
- "(ifType = 'ethernet' and ifMTU = 1500)" {
- error-message "An ethernet MTU must be 1500";
- }
- }
- refine port {
- description "description of port defined by refine";
- reference "port reference added by refine";
- config false;
- presence "presence is required";
- }
- refine addresses {
- description "description of addresses defined by refine";
- reference "addresses reference added by refine";
- config false;
- min-elements 2;
- max-elements 12;
- }
- refine target-inner {
- description "new target-inner grouping description";
- }
- refine group-type {
- description "new group-type description";
- reference "new group-type reference";
- }
- }
- }
- }
-
- container interfaces {
- list ifEntry {
- key "ifIndex";
-
- leaf ifIndex {
- type uint32;
- units minutes;
- }
-
- leaf ifMtu {
- type int32;
- }
-
- min-elements 1;
- max-elements 11;
- }
- }
-
-}
--- /dev/null
+module types {
+ yang-version 1;
+ namespace "urn:simple.types.test";
+ prefix "t";
+
+ organization "opendaylight";
+ contact "http://www.opendaylight.org/";
+ description "This is types-data test description";
+
+ revision "2013-07-03" {
+ reference " WILL BE DEFINED LATER";
+ }
+
+ typedef int32-ext1 {
+ type int32 {
+ range "2..20";
+ }
+ }
+
+ typedef int32-ext2 {
+ type int32-ext1 {
+ range "3..9|11..max";
+ }
+ units "mile";
+ default "11";
+ }
+
+ typedef string-ext1 {
+ type string {
+ pattern "[a-k]*";
+ length "5..11";
+ }
+ }
+
+ typedef string-ext2 {
+ type string-ext1 {
+ length "6..10";
+ }
+ }
+
+ typedef string-ext3 {
+ type string-ext2 {
+ pattern "[b-u]*";
+ }
+ }
+
+ typedef string-ext4 {
+ type string-ext3 {
+ pattern "[e-z]*";
+ }
+ }
+
+ typedef my-decimal-type {
+ type decimal64 {
+ fraction-digits 6;
+ }
+ }
+
+ typedef my-union {
+ type union {
+ type int16 {
+ range "1..100";
+ }
+ type int32;
+ }
+ }
+
+ typedef my-union-ext {
+ type my-union;
+ }
+
+ typedef nested-union2 {
+ type union {
+ type my-union-ext;
+ type string;
+ }
+ }
+
+ container interfaces {
+ list ifEntry {
+ key "ifIndex";
+
+ leaf ifIndex {
+ type uint32;
+ units minutes;
+ }
+
+ leaf ifMtu {
+ type int32;
+ }
+
+ min-elements 1;
+ max-elements 11;
+ }
+ }
+
+}
<module>yang-common</module>
<module>yang-data-api</module>
<module>yang-data-util</module>
+ <module>yang-data-impl</module>
<module>yang-model-api</module>
<module>yang-model-util</module>
<module>yang-binding</module>
+++ /dev/null
-/*\r
- * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.\r
- *\r
- * This program and the accompanying materials are made available under the\r
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,\r
- * and is available at http://www.eclipse.org/legal/epl-v10.html\r
- */\r
-package org.opendaylight.controller.yang.data.api;\r
-\r
-import org.opendaylight.controller.yang.common.QName;\r
-\r
-/**\r
- * For the use cases of changing the state data, the node modifications are\r
- * modeled as part of additional metadata in data tree. The modification types\r
- * are based on Netconf edit-config RPCs. In order to modify the configuration\r
- * or state data tree the user must create a tree representing the modification\r
- * of the data and apply that modification to the target tree.\r
- * \r
- * \r
- * @see <a href="http://tools.ietf.org/html/rfc6241">Network Configuration\r
- * Protocol (NETCONF)</a>\r
- * \r
- */\r
-public interface CompositeNodeModification extends CompositeNode {\r
-\r
- ModifyAction getModificationAction();\r
-\r
- // Container Modification\r
-\r
- /**\r
- * The data identified by the node containing this modification is merged\r
- * with the data at the corresponding level in the data tree\r
- * \r
- * @param node\r
- * in data tree\r
- */\r
- void mergeChild(CompositeNode node);\r
-\r
- /**\r
- * The data identified by the node containing this modification replaces any\r
- * related data in the target data tree If no such data exists in the target\r
- * data tree, the child node is created.\r
- * \r
- * @param node\r
- * composite node\r
- */\r
- void replaceChild(CompositeNode node);\r
-\r
- /**\r
- * Adds new composite node into data tree\r
- * \r
- * @param node\r
- * composite node\r
- */\r
- void addChild(CompositeNode node);\r
-\r
- /**\r
- * The data identified by the node containing this modification is deleted\r
- * from the target data tree if and only if the data currently exists in the\r
- * target data tree. If the data does not exist, an error is returned with\r
- * an error value of "data-missing".\r
- * \r
- * @param node\r
- */\r
- void deleteChild(CompositeNode node);\r
-\r
- /**\r
- * The data identified by the node containing this attribute is deleted from\r
- * the target data tree if the data currently exists in the target data\r
- * tree. If the data does not exist, the modification is silently ignored.\r
- * \r
- * @param node\r
- * composite node\r
- */\r
- void removeChild(CompositeNode node);\r
-\r
- // Leaf Modifications\r
-\r
- /**\r
- * The data identified by the node containing this modification replaces any\r
- * related data in the target data tree If no such data exists in the target\r
- * data tree, it is created.\r
- * \r
- * @param leaf\r
- */\r
- void replaceSimpleNode(SimpleNode<?> leaf);\r
-\r
- /**\r
- * The data identified by the node containing this modification is deleted\r
- * from the target data tree if and only if the data currently exists in the\r
- * target data tree. If the data does not exist, an error is returned with\r
- * an error value of "data-missing".\r
- * \r
- * @param leaf\r
- */\r
- void deleteSimpleNode(SimpleNode<?> leaf);\r
-\r
- /**\r
- * The data identified by the node containing this attribute is deleted from\r
- * the target data tree if the data currently exists in the target data\r
- * tree. If the data does not exist, the modification is silently ignored.\r
- * \r
- * @param leaf\r
- */\r
- void removeSimpleNode(SimpleNode<?> leaf);\r
-\r
- void removeLeaf(SimpleNode<?> leaf);\r
-\r
- void removeLeaf(QName leaf);\r
-}\r
--- /dev/null
+/*\r
+ * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.\r
+ *\r
+ * This program and the accompanying materials are made available under the\r
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,\r
+ * and is available at http://www.eclipse.org/legal/epl-v10.html\r
+ */\r
+package org.opendaylight.controller.yang.data.api;\r
+\r
+import java.util.List;\r
+\r
+\r
+/**\r
+ * @author michal.rehak\r
+ *\r
+ */\r
+public interface MutableCompositeNode extends MutableNode<List<Node<?>>>, CompositeNode {\r
+ \r
+ /**\r
+ * update internal map\r
+ */\r
+ public void init();\r
+}\r
--- /dev/null
+/*\r
+ * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.\r
+ *\r
+ * This program and the accompanying materials are made available under the\r
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,\r
+ * and is available at http://www.eclipse.org/legal/epl-v10.html\r
+ */\r
+package org.opendaylight.controller.yang.data.api;\r
+\r
+\r
+/**\r
+ * Base representation of node in the data tree, defines basic parameters of\r
+ * node such as a QName.\r
+ * \r
+ * \r
+ * @param <T>\r
+ */\r
+public interface MutableNode<T> extends Node<T> {\r
+\r
+ /**\r
+ * @param parent value to set\r
+ */\r
+ void setParent(CompositeNode parent);\r
+ \r
+ /**\r
+ * @param value value to set (children list or leaf value)\r
+ */\r
+ void setValue(T value);\r
+ \r
+ /**\r
+ * @param action value to set\r
+ */\r
+ void setModifyAction(ModifyAction action);\r
+}\r
--- /dev/null
+/*\r
+ * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.\r
+ *\r
+ * This program and the accompanying materials are made available under the\r
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,\r
+ * and is available at http://www.eclipse.org/legal/epl-v10.html\r
+ */\r
+package org.opendaylight.controller.yang.data.api;\r
+\r
+\r
+/**\r
+ * @author michal.rehak\r
+ * @param <T> node value type\r
+ *\r
+ */\r
+public interface MutableSimpleNode<T> extends MutableNode<T>, SimpleNode<T> {\r
+ \r
+ // nothing\r
+ \r
+}\r
/**\r
* Returns the name of the Node\r
* \r
- * @return\r
+ * @return qName of node\r
*/\r
QName getNodeType();\r
\r
--- /dev/null
+/*\r
+ * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.\r
+ *\r
+ * This program and the accompanying materials are made available under the\r
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,\r
+ * and is available at http://www.eclipse.org/legal/epl-v10.html\r
+ */\r
+package org.opendaylight.controller.yang.data.api;\r
+\r
+/**\r
+ * @author michal.rehak\r
+ * \r
+ */\r
+public interface NodeModification {\r
+\r
+ /**\r
+ * @return modify action\r
+ */\r
+ ModifyAction getModificationAction();\r
+\r
+}\r
--- /dev/null
+/*\r
+ * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.\r
+ *\r
+ * This program and the accompanying materials are made available under the\r
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,\r
+ * and is available at http://www.eclipse.org/legal/epl-v10.html\r
+ */\r
+package org.opendaylight.controller.yang.data.api;\r
+\r
+\r
+/**\r
+ * @author michal.rehak\r
+ *\r
+ */\r
+public interface NodeModificationBuilder {\r
+\r
+ public abstract Node<?> getMutableEquivalent(Node<?> originalNode);\r
+\r
+ public abstract CompositeNode buildDiffTree();\r
+\r
+ public abstract void mergeNode(MutableCompositeNode alteredNode);\r
+\r
+ public abstract void removeNode(MutableCompositeNode deadNode);\r
+\r
+ public abstract void removeNode(MutableSimpleNode<?> deadNode);\r
+\r
+ public abstract void deleteNode(MutableSimpleNode<?> deadNode);\r
+\r
+ public abstract void deleteNode(MutableCompositeNode deadNode);\r
+\r
+ public abstract void replaceNode(MutableCompositeNode replacementNode);\r
+\r
+ public abstract void replaceNode(MutableSimpleNode<?> replacementNode);\r
+\r
+ public abstract void addNode(MutableCompositeNode newNode);\r
+\r
+ public abstract void addNode(MutableSimpleNode<?> newNode);\r
+\r
+}\r
--- /dev/null
+<project xmlns="http://maven.apache.org/POM/4.0.0"\r
+ 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
+ <parent>\r
+ <groupId>org.opendaylight.controller</groupId>\r
+ <artifactId>yang</artifactId>\r
+ <version>0.5.3-SNAPSHOT</version>\r
+ </parent>\r
+ <artifactId>yang-data-impl</artifactId>\r
+\r
+ <properties>\r
+ <groovy.version>2.1.5</groovy.version>\r
+ </properties>\r
+\r
+ <build>\r
+ <plugins>\r
+ <plugin>\r
+ <groupId>org.apache.maven.plugins</groupId>\r
+ <artifactId>maven-surefire-plugin</artifactId>\r
+ <configuration>\r
+ <argLine>-Dlog4j.configuration=log4j-test.xml</argLine>\r
+ <redirectTestOutputToFile>true</redirectTestOutputToFile>\r
+ </configuration>\r
+ </plugin>\r
+ </plugins>\r
+ </build>\r
+\r
+\r
+ <dependencies>\r
+ <dependency>\r
+ <groupId>org.opendaylight.controller</groupId>\r
+ <artifactId>yang-common</artifactId>\r
+ </dependency>\r
+ <dependency>\r
+ <groupId>org.opendaylight.controller</groupId>\r
+ <artifactId>yang-data-api</artifactId>\r
+ </dependency>\r
+ <dependency>\r
+ <groupId>org.opendaylight.controller</groupId>\r
+ <artifactId>yang-model-parser-impl</artifactId>\r
+ </dependency>\r
+ <dependency>\r
+ <groupId>com.google.guava</groupId>\r
+ <artifactId>guava</artifactId>\r
+ <version>14.0.1</version>\r
+ </dependency>\r
+ <dependency>\r
+ <groupId>junit</groupId>\r
+ <artifactId>junit</artifactId>\r
+ <scope>test</scope>\r
+ </dependency>\r
+ <dependency>\r
+ <groupId>org.slf4j</groupId>\r
+ <artifactId>slf4j-log4j12</artifactId>\r
+ <version>${slf4j.version}</version>\r
+ <scope>test</scope>\r
+ </dependency>\r
+ <dependency>\r
+ <groupId>org.codehaus.groovy</groupId>\r
+ <artifactId>groovy</artifactId>\r
+ <version>${groovy.version}</version>\r
+ <scope>test</scope>\r
+ </dependency>\r
+ <dependency>\r
+ <groupId>org.codehaus.groovy</groupId>\r
+ <artifactId>groovy-xml</artifactId>\r
+ <version>${groovy.version}</version>\r
+ <scope>test</scope>\r
+ </dependency>\r
+ </dependencies>\r
+</project>
\ No newline at end of file
--- /dev/null
+/*\r
+ * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.\r
+ *\r
+ * This program and the accompanying materials are made available under the\r
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,\r
+ * and is available at http://www.eclipse.org/legal/epl-v10.html\r
+ */\r
+package org.opendaylight.controller.yang.data.impl;\r
+\r
+import org.opendaylight.controller.yang.common.QName;\r
+import org.opendaylight.controller.yang.data.api.CompositeNode;\r
+import org.opendaylight.controller.yang.data.api.Node;\r
+\r
+/**\r
+ * @author michal.rehak\r
+ * @param <T>\r
+ * type of node value\r
+ * \r
+ */\r
+public abstract class AbstractNodeTO<T> implements Node<T> {\r
+\r
+ private QName qName;\r
+ private CompositeNode parent;\r
+ private T value;\r
+\r
+ /**\r
+ * @param qname\r
+ * @param parent\r
+ * @param value\r
+ */\r
+ public AbstractNodeTO(QName qname, CompositeNode parent, T value) {\r
+ this.qName = qname;\r
+ this.parent = parent;\r
+ this.value = value;\r
+ }\r
+\r
+ @Override\r
+ public QName getNodeType() {\r
+ return qName;\r
+ }\r
+\r
+ /**\r
+ * @return the qName\r
+ */\r
+ protected QName getQName() {\r
+ return qName;\r
+ }\r
+\r
+ @Override\r
+ public CompositeNode getParent() {\r
+ return parent;\r
+ }\r
+ \r
+ /**\r
+ * @param parent the parent to set\r
+ */\r
+ public void setParent(CompositeNode parent) {\r
+ this.parent = parent;\r
+ }\r
+ \r
+ /**\r
+ * @param value the value to set\r
+ */\r
+ protected void setValue(T value) {\r
+ this.value = value;\r
+ }\r
+\r
+ @Override\r
+ public T getValue() {\r
+ return value;\r
+ }\r
+}\r
--- /dev/null
+/**\r
+ * \r
+ */\r
+package org.opendaylight.controller.yang.data.impl;\r
+\r
+import java.util.List;\r
+\r
+import org.opendaylight.controller.yang.common.QName;\r
+import org.opendaylight.controller.yang.data.api.CompositeNode;\r
+import org.opendaylight.controller.yang.data.api.ModifyAction;\r
+import org.opendaylight.controller.yang.data.api.Node;\r
+import org.opendaylight.controller.yang.data.api.NodeModification;\r
+\r
+/**\r
+ * @author michal.rehak\r
+ * \r
+ */\r
+public class CompositeNodeModificationTOImpl extends CompositeNodeTOImpl\r
+ implements NodeModification {\r
+\r
+ private ModifyAction modifyAction;\r
+\r
+ /**\r
+ * @param qname\r
+ * @param parent\r
+ * @param value\r
+ * @param modifyAction\r
+ */\r
+ public CompositeNodeModificationTOImpl(QName qname, CompositeNode parent,\r
+ List<Node<?>> value, ModifyAction modifyAction) {\r
+ super(qname, parent, value);\r
+ this.modifyAction = modifyAction;\r
+ }\r
+\r
+ /**\r
+ * @return modification action\r
+ * @see org.opendaylight.controller.yang.data.impl.NodeModificationSupport#getModificationAction()\r
+ */\r
+ @Override\r
+ public ModifyAction getModificationAction() {\r
+ return modifyAction;\r
+ }\r
+\r
+ /**\r
+ * @param modifyAction\r
+ * the modifyAction to set\r
+ */\r
+ protected void setModificationAction(ModifyAction modifyAction) {\r
+ this.modifyAction = modifyAction;\r
+ }\r
+\r
+}\r
--- /dev/null
+/*\r
+ * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.\r
+ *\r
+ * This program and the accompanying materials are made available under the\r
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,\r
+ * and is available at http://www.eclipse.org/legal/epl-v10.html\r
+ */\r
+package org.opendaylight.controller.yang.data.impl;\r
+\r
+import java.util.ArrayList;\r
+import java.util.List;\r
+import java.util.Map;\r
+\r
+import org.opendaylight.controller.yang.common.QName;\r
+import org.opendaylight.controller.yang.data.api.CompositeNode;\r
+import org.opendaylight.controller.yang.data.api.Node;\r
+import org.opendaylight.controller.yang.data.api.SimpleNode;\r
+\r
+/**\r
+ * @author michal.rehak\r
+ * \r
+ */\r
+public class CompositeNodeTOImpl extends AbstractNodeTO<List<Node<?>>>\r
+ implements CompositeNode {\r
+\r
+ private Map<QName, List<Node<?>>> nodeMap;\r
+\r
+ /**\r
+ * @param qname\r
+ * @param parent use null to create top composite node (without parent)\r
+ * @param value\r
+ */\r
+ public CompositeNodeTOImpl(QName qname, CompositeNode parent,\r
+ List<Node<?>> value) {\r
+ super(qname, parent, value);\r
+ if (value != null) {\r
+ nodeMap = NodeUtils.buildNodeMap(getValue());\r
+ }\r
+ }\r
+ \r
+\r
+ /**\r
+ * @return the nodeMap\r
+ */\r
+ protected Map<QName, List<Node<?>>> getNodeMap() {\r
+ return nodeMap;\r
+ }\r
+ \r
+ @Override\r
+ public List<Node<?>> getChildren() {\r
+ return getValue();\r
+ }\r
+\r
+ @Override\r
+ public SimpleNode<?> getFirstSimpleByName(QName leafQName) {\r
+ List<SimpleNode<?>> list = getSimpleNodesByName(leafQName);\r
+ if (list.isEmpty())\r
+ return null;\r
+ return list.get(0);\r
+ }\r
+\r
+ @Override\r
+ public List<CompositeNode> getCompositesByName(QName children) {\r
+ List<Node<?>> toFilter = getNodeMap().get(children);\r
+ List<CompositeNode> list = new ArrayList<CompositeNode>();\r
+ for (Node<?> node : toFilter) {\r
+ if (node instanceof CompositeNode)\r
+ list.add((CompositeNode) node);\r
+ }\r
+ return list;\r
+ }\r
+\r
+ @Override\r
+ public List<SimpleNode<?>> getSimpleNodesByName(QName children) {\r
+ List<Node<?>> toFilter = getNodeMap().get(children);\r
+ List<SimpleNode<?>> list = new ArrayList<SimpleNode<?>>();\r
+\r
+ for (Node<?> node : toFilter) {\r
+ if (node instanceof SimpleNode<?>)\r
+ list.add((SimpleNode<?>) node);\r
+ }\r
+ return list;\r
+ }\r
+\r
+ @Override\r
+ public CompositeNode getFirstCompositeByName(QName container) {\r
+ List<CompositeNode> list = getCompositesByName(container);\r
+ if (list.isEmpty()) {\r
+ return null;\r
+ }\r
+ return list.get(0);\r
+ }\r
+\r
+ /**\r
+ * @param leaf\r
+ * @return TODO:: do we need this method?\r
+ */\r
+ public SimpleNode<?> getFirstLeafByName(QName leaf) {\r
+ List<SimpleNode<?>> list = getSimpleNodesByName(leaf);\r
+ if (list.isEmpty()) {\r
+ return null;\r
+ }\r
+ return list.get(0);\r
+ }\r
+\r
+ @Override\r
+ public List<CompositeNode> getCompositesByName(String children) {\r
+ return getCompositesByName(localQName(children));\r
+ }\r
+ \r
+ @Override\r
+ public List<SimpleNode<?>> getSimpleNodesByName(String children) {\r
+ return getSimpleNodesByName(localQName(children));\r
+ }\r
+\r
+ private QName localQName(String str) {\r
+ return new QName(getNodeType(), str);\r
+ }\r
+\r
+}\r
--- /dev/null
+/*\r
+ * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.\r
+ *\r
+ * This program and the accompanying materials are made available under the\r
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,\r
+ * and is available at http://www.eclipse.org/legal/epl-v10.html\r
+ */\r
+package org.opendaylight.controller.yang.data.impl;\r
+\r
+import java.util.List;\r
+import java.util.Map;\r
+\r
+import org.opendaylight.controller.yang.common.QName;\r
+import org.opendaylight.controller.yang.data.api.CompositeNode;\r
+import org.opendaylight.controller.yang.data.api.ModifyAction;\r
+import org.opendaylight.controller.yang.data.api.MutableCompositeNode;\r
+import org.opendaylight.controller.yang.data.api.Node;\r
+\r
+/**\r
+ * @author michal.rehak\r
+ * \r
+ */\r
+public class MutableCompositeNodeTOImpl extends CompositeNodeModificationTOImpl\r
+ implements MutableCompositeNode {\r
+\r
+ private Map<QName, List<Node<?>>> nodeMap;\r
+\r
+ /**\r
+ * @param qname\r
+ * @param parent\r
+ * @param value\r
+ * @param modifyAction\r
+ */\r
+ public MutableCompositeNodeTOImpl(QName qname, CompositeNode parent,\r
+ List<Node<?>> value, ModifyAction modifyAction) {\r
+ super(qname, parent, value, modifyAction);\r
+ }\r
+ \r
+ /**\r
+ * update nodeMap\r
+ */\r
+ @Override\r
+ public void init() {\r
+ nodeMap = NodeUtils.buildNodeMap(getChildren());\r
+ }\r
+\r
+ @Override\r
+ public void setValue(List<Node<?>> value) {\r
+ super.setValue(value);\r
+ }\r
+ \r
+ @Override\r
+ public void setModifyAction(ModifyAction action) {\r
+ super.setModificationAction(action);\r
+ }\r
+ \r
+ @Override\r
+ protected Map<QName, List<Node<?>>> getNodeMap() {\r
+ return nodeMap;\r
+ }\r
+}\r
--- /dev/null
+/*\r
+ * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.\r
+ *\r
+ * This program and the accompanying materials are made available under the\r
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,\r
+ * and is available at http://www.eclipse.org/legal/epl-v10.html\r
+ */\r
+package org.opendaylight.controller.yang.data.impl;\r
+\r
+import org.opendaylight.controller.yang.common.QName;\r
+import org.opendaylight.controller.yang.data.api.CompositeNode;\r
+import org.opendaylight.controller.yang.data.api.ModifyAction;\r
+import org.opendaylight.controller.yang.data.api.MutableSimpleNode;\r
+\r
+/**\r
+ * @author michal.rehak\r
+ * @param <T> type of simple node value\r
+ * \r
+ */\r
+public class MutableSimpleNodeTOImpl<T> extends SimpleNodeModificationTOImpl<T> \r
+ implements MutableSimpleNode<T> {\r
+\r
+ /**\r
+ * @param qname\r
+ * @param parent\r
+ * @param value\r
+ * @param modifyAction\r
+ */\r
+ public MutableSimpleNodeTOImpl(QName qname, CompositeNode parent, T value,\r
+ ModifyAction modifyAction) {\r
+ super(qname, parent, value, modifyAction);\r
+ }\r
+\r
+ @Override\r
+ public void setValue(T value) {\r
+ super.setValue(value);\r
+ }\r
+ \r
+ @Override\r
+ public void setModifyAction(ModifyAction action) {\r
+ super.setModificationAction(action);\r
+ }\r
+}\r
--- /dev/null
+/*\r
+ * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.\r
+ *\r
+ * This program and the accompanying materials are made available under the\r
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,\r
+ * and is available at http://www.eclipse.org/legal/epl-v10.html\r
+ */\r
+package org.opendaylight.controller.yang.data.impl;\r
+\r
+import java.util.AbstractMap.SimpleEntry;\r
+import java.util.ArrayList;\r
+import java.util.Arrays;\r
+import java.util.List;\r
+import java.util.Map;\r
+import java.util.Stack;\r
+\r
+import org.opendaylight.controller.yang.common.QName;\r
+import org.opendaylight.controller.yang.data.api.CompositeNode;\r
+import org.opendaylight.controller.yang.data.api.ModifyAction;\r
+import org.opendaylight.controller.yang.data.api.MutableCompositeNode;\r
+import org.opendaylight.controller.yang.data.api.MutableSimpleNode;\r
+import org.opendaylight.controller.yang.data.api.Node;\r
+import org.opendaylight.controller.yang.data.api.SimpleNode;\r
+\r
+/**\r
+ * @author michal.rehak\r
+ * \r
+ */\r
+public abstract class NodeFactory {\r
+\r
+ /**\r
+ * @param qName\r
+ * @param parent\r
+ * @param value\r
+ * @return simple node modification, based on given qname, value and parent\r
+ */\r
+ public static <T> SimpleNode<T> createSimpleNode(QName qName,\r
+ CompositeNode parent, T value) {\r
+ SimpleNodeTOImpl<T> simpleNodeTOImpl = new SimpleNodeTOImpl<T>(qName, parent, value);\r
+ return simpleNodeTOImpl;\r
+ }\r
+ \r
+ /**\r
+ * @param qName\r
+ * @param parent\r
+ * @param value\r
+ * @return simple node modification, based on given qname, value and parent\r
+ */\r
+ public static <T> MutableSimpleNode<T> createMutableSimpleNode(QName qName,\r
+ CompositeNode parent, T value) {\r
+ MutableSimpleNodeTOImpl<T> simpleNodeTOImpl = \r
+ new MutableSimpleNodeTOImpl<T>(qName, parent, value, null);\r
+ return simpleNodeTOImpl;\r
+ }\r
+\r
+ /**\r
+ * @param qName\r
+ * @param parent\r
+ * @param value\r
+ * @return composite node modification, based on given qname, value (children), parent and modifyAction\r
+ */\r
+ public static CompositeNode createCompositeNode(QName qName,\r
+ CompositeNode parent, List<Node<?>> value) {\r
+ CompositeNode compositeNodeTOImpl = new CompositeNodeTOImpl(qName, parent, value);\r
+ return compositeNodeTOImpl;\r
+ }\r
+ \r
+ /**\r
+ * @param qName\r
+ * @param parent\r
+ * @param value\r
+ * @return composite node modification, based on given qname, value (children), parent and modifyAction\r
+ */\r
+ public static MutableCompositeNode createMutableCompositeNode(QName qName,\r
+ CompositeNode parent, List<Node<?>> value) {\r
+ MutableCompositeNodeTOImpl compositeNodeTOImpl = \r
+ new MutableCompositeNodeTOImpl(qName, parent, value, null);\r
+ return compositeNodeTOImpl;\r
+ }\r
+ \r
+ \r
+ /**\r
+ * @param qName\r
+ * @param parent\r
+ * @param value\r
+ * @param modifyAction\r
+ * @return simple node modification, based on given qname, value, parent and modifyAction\r
+ */\r
+ public static <T> SimpleNodeModificationTOImpl<T> createSimpleNodeModification(QName qName,\r
+ CompositeNode parent, T value, ModifyAction modifyAction) {\r
+ SimpleNodeModificationTOImpl<T> simpleNodeModTOImpl = \r
+ new SimpleNodeModificationTOImpl<T>(qName, parent, value, modifyAction);\r
+ return simpleNodeModTOImpl;\r
+ }\r
+\r
+ /**\r
+ * @param qName\r
+ * @param parent\r
+ * @param value\r
+ * @param modifyAction \r
+ * @return composite node modification, based on given qname, value (children), parent and modifyAction\r
+ */\r
+ public static CompositeNodeModificationTOImpl createCompositeNodeModification(QName qName,\r
+ CompositeNode parent, List<Node<?>> value, ModifyAction modifyAction) {\r
+ CompositeNodeModificationTOImpl compositeNodeModTOImpl = \r
+ new CompositeNodeModificationTOImpl(qName, parent, value, modifyAction);\r
+ return compositeNodeModTOImpl;\r
+ }\r
+\r
+ /**\r
+ * @param node\r
+ * @return copy of given node, parent and value are the same, but parent \r
+ * has no reference to this copy \r
+ */\r
+ public static <T> SimpleNode<T> copyNode(SimpleNode<T> node) {\r
+ SimpleNode<T> twinNode = createSimpleNode(\r
+ node.getNodeType(), node.getParent(), node.getValue());\r
+ return twinNode;\r
+ }\r
+ \r
+ /**\r
+ * @param node\r
+ * @return copy of given node, parent and value are the same, but parent \r
+ * has no reference to this copy \r
+ */\r
+ public static <T> SimpleNode<T> copyNodeAsMutable(SimpleNode<T> node) {\r
+ SimpleNode<T> twinNode = createMutableSimpleNode(\r
+ node.getNodeType(), node.getParent(), node.getValue());\r
+ return twinNode;\r
+ }\r
+\r
+ /**\r
+ * @param node\r
+ * @param children \r
+ * @return copy of given node, parent and children are the same, but parent and children \r
+ * have no reference to this copy\r
+ */\r
+ public static CompositeNode copyNode(CompositeNode node, Node<?>... children) {\r
+ CompositeNode twinNode = createCompositeNode(\r
+ node.getNodeType(), node.getParent(), Arrays.asList(children));\r
+ return twinNode;\r
+ }\r
+ \r
+ /**\r
+ * @param node\r
+ * @return copy of given node, parent and children are the same, but parent and children \r
+ * have no reference to this copy\r
+ */\r
+ public static CompositeNode copyNode(CompositeNode node) {\r
+ return copyNode(node, node.getChildren().toArray(new Node<?>[0]));\r
+ }\r
+ \r
+ /**\r
+ * @param node root of original tree\r
+ * @param originalToMutable (optional) empty map, where binding between original and copy \r
+ * will be stored\r
+ * @return copy of given node, parent and children are the same, but parent and children \r
+ * have no reference to this copy\r
+ */\r
+ public static MutableCompositeNode copyDeepNode(CompositeNode node, \r
+ Map<Node<?>, Node<?>> originalToMutable) {\r
+ \r
+ MutableCompositeNode mutableRoot = \r
+ createMutableCompositeNode(node.getNodeType(), null, null);\r
+ Stack<SimpleEntry<CompositeNode, MutableCompositeNode>> jobQueue = new Stack<>();\r
+ jobQueue.push(new SimpleEntry<CompositeNode, MutableCompositeNode>(node, mutableRoot));\r
+ if (originalToMutable != null) {\r
+ originalToMutable.put(node, mutableRoot);\r
+ }\r
+ \r
+ while (!jobQueue.isEmpty()) {\r
+ SimpleEntry<CompositeNode, MutableCompositeNode> job = jobQueue.pop();\r
+ CompositeNode originalNode = job.getKey();\r
+ MutableCompositeNode mutableNode = job.getValue();\r
+ mutableNode.setValue(new ArrayList<Node<?>>());\r
+ \r
+ for (Node<?> child : originalNode.getChildren()) {\r
+ Node<?> mutableAscendant = null;\r
+ if (child instanceof CompositeNode) {\r
+ MutableCompositeNode newMutable = \r
+ createMutableCompositeNode(child.getNodeType(), mutableNode, null);\r
+ jobQueue.push(new SimpleEntry<CompositeNode, MutableCompositeNode>(\r
+ (CompositeNode) child, newMutable));\r
+ mutableAscendant = newMutable;\r
+ } else if (child instanceof SimpleNode<?>) {\r
+ mutableAscendant = \r
+ createMutableSimpleNode(child.getNodeType(), mutableNode, child.getValue());\r
+ } else {\r
+ throw new IllegalStateException("Node class deep copy not supported: "\r
+ +child.getClass().getName());\r
+ }\r
+ \r
+ mutableNode.getChildren().add(mutableAscendant);\r
+ if (originalToMutable != null) {\r
+ originalToMutable.put(child, mutableAscendant);\r
+ }\r
+ }\r
+ mutableNode.init();\r
+ }\r
+ \r
+ return mutableRoot;\r
+ }\r
+ \r
+}\r
--- /dev/null
+/**\r
+ * \r
+ */\r
+package org.opendaylight.controller.yang.data.impl;\r
+\r
+import java.util.HashMap;\r
+import java.util.HashSet;\r
+import java.util.List;\r
+import java.util.Map;\r
+import java.util.Set;\r
+import java.util.Stack;\r
+\r
+import org.opendaylight.controller.yang.common.QName;\r
+import org.opendaylight.controller.yang.data.api.CompositeNode;\r
+import org.opendaylight.controller.yang.data.api.ModifyAction;\r
+import org.opendaylight.controller.yang.data.api.MutableCompositeNode;\r
+import org.opendaylight.controller.yang.data.api.MutableNode;\r
+import org.opendaylight.controller.yang.data.api.MutableSimpleNode;\r
+import org.opendaylight.controller.yang.data.api.Node;\r
+import org.opendaylight.controller.yang.data.api.NodeModificationBuilder;\r
+import org.opendaylight.controller.yang.model.api.ListSchemaNode;\r
+import org.opendaylight.controller.yang.model.api.SchemaContext;\r
+\r
+/**\r
+ * @author michal.rehak\r
+ *\r
+ */\r
+public class NodeModificationBuilderImpl implements NodeModificationBuilder {\r
+ \r
+ private SchemaContext context;\r
+ \r
+ private Set<MutableNode<?>> changeLog;\r
+ private Map<Node<?>, Node<?>> originalToMutable;\r
+\r
+ private MutableCompositeNode mutableRoot;\r
+\r
+ /**\r
+ * @param originalTreeRootNode \r
+ * @param context\r
+ */\r
+ public NodeModificationBuilderImpl(CompositeNode originalTreeRootNode, SchemaContext context) {\r
+ this.context = context;\r
+ originalToMutable = new HashMap<>();\r
+ mutableRoot = NodeFactory.copyDeepNode(originalTreeRootNode, originalToMutable);\r
+ changeLog = new HashSet<>();\r
+ }\r
+\r
+ /**\r
+ * add given node to it's parent's list of children\r
+ * @param newNode\r
+ */\r
+ private static void fixParentRelation(Node<?> newNode) {\r
+ if (newNode.getParent() != null) {\r
+ List<Node<?>> siblings = newNode.getParent().getChildren();\r
+ if (!siblings.contains(newNode)) {\r
+ siblings.add(newNode);\r
+ }\r
+ }\r
+ }\r
+\r
+ /**\r
+ * @param modNode\r
+ * @param action \r
+ */\r
+ private void addModificationToLog(MutableNode<?> modNode, ModifyAction action) {\r
+ modNode.setModifyAction(action);\r
+ changeLog.add(modNode);\r
+ }\r
+\r
+ @Override\r
+ public void addNode(MutableSimpleNode<?> newNode) {\r
+ fixParentRelation(newNode);\r
+ addModificationToLog(newNode, ModifyAction.CREATE);\r
+ }\r
+ \r
+ @Override\r
+ public void addNode(MutableCompositeNode newNode) {\r
+ fixParentRelation(newNode);\r
+ addModificationToLog(newNode, ModifyAction.CREATE);\r
+ }\r
+ \r
+ @Override\r
+ public void replaceNode(MutableSimpleNode<?> replacementNode) {\r
+ addModificationToLog(replacementNode, ModifyAction.REPLACE);\r
+ }\r
+ \r
+ @Override\r
+ public void replaceNode(MutableCompositeNode replacementNode) {\r
+ addModificationToLog(replacementNode, ModifyAction.REPLACE);\r
+ }\r
+\r
+ @Override\r
+ public void deleteNode(MutableCompositeNode deadNode) {\r
+ addModificationToLog(deadNode, ModifyAction.DELETE);\r
+ }\r
+ \r
+ @Override\r
+ public void deleteNode(MutableSimpleNode<?> deadNode) {\r
+ addModificationToLog(deadNode, ModifyAction.DELETE);\r
+ }\r
+\r
+ @Override\r
+ public void removeNode(MutableSimpleNode<?> deadNode) {\r
+ addModificationToLog(deadNode, ModifyAction.REMOVE);\r
+ }\r
+ \r
+ @Override\r
+ public void removeNode(MutableCompositeNode deadNode) {\r
+ addModificationToLog(deadNode, ModifyAction.REMOVE);\r
+ }\r
+ \r
+ @Override\r
+ public void mergeNode(MutableCompositeNode alteredNode) {\r
+ addModificationToLog(alteredNode, ModifyAction.MERGE);\r
+ }\r
+\r
+ /**\r
+ * @return minimalistic tree containing diffs only\r
+ */\r
+ @Override\r
+ public CompositeNode buildDiffTree() {\r
+ Set<Node<?>> wanted = new HashSet<>();\r
+ \r
+ // walk changeLog, collect all required nodes\r
+ for (MutableNode<?> mutant : changeLog) {\r
+ wanted.addAll(collectSelfAndAllParents(mutant));\r
+ }\r
+ \r
+ // TODO:: walk wanted and add relevant keys\r
+ Map<String, ListSchemaNode> mapOfLists = NodeUtils.buildMapOfListNodes(context);\r
+ Set<Node<?>> wantedKeys = new HashSet<>();\r
+ for (Node<?> outlaw : wanted) {\r
+ if (outlaw instanceof CompositeNode) {\r
+ String path = NodeUtils.buildPath(outlaw);\r
+ if (mapOfLists.containsKey(path)) {\r
+ ListSchemaNode listSchema = mapOfLists.get(path);\r
+ if (listSchema.getQName().equals(outlaw.getNodeType())) {\r
+ // try to add key subnode to wanted list\r
+ List<QName> supportedKeys = listSchema.getKeyDefinition();\r
+ for (Node<?> outlawChildren : ((CompositeNode) outlaw).getChildren()) {\r
+ if (supportedKeys.contains(outlawChildren.getNodeType())) {\r
+ wantedKeys.add(outlawChildren);\r
+ }\r
+ }\r
+ }\r
+ }\r
+ }\r
+ }\r
+ wanted.addAll(wantedKeys);\r
+ \r
+ // remove all unwanted nodes from tree\r
+ removeUnrelevantNodes(mutableRoot, wanted);\r
+ \r
+ return mutableRoot;\r
+ }\r
+\r
+ /**\r
+ * @param mutableRoot2\r
+ * @param wanted\r
+ */\r
+ private static void removeUnrelevantNodes(MutableCompositeNode mutRoot,\r
+ Set<Node<?>> wanted) {\r
+ Stack<MutableNode<?>> jobQueue = new Stack<>();\r
+ jobQueue.push(mutRoot);\r
+ while (!jobQueue.isEmpty()) {\r
+ MutableNode<?> mutNode = jobQueue.pop();\r
+ if (!wanted.contains(mutNode)) {\r
+ if (mutNode.getParent() != null) {\r
+ mutNode.getParent().getChildren().remove(mutNode);\r
+ }\r
+ } else {\r
+ if (mutNode instanceof MutableCompositeNode) {\r
+ for (Node<?> mutChild : ((MutableCompositeNode) mutNode).getChildren()) {\r
+ jobQueue.push((MutableNode<?>) mutChild);\r
+ }\r
+ }\r
+ }\r
+ }\r
+ }\r
+\r
+ /**\r
+ * @param focusedAncestor\r
+ * @return set of parents and focusedAncestor itself\r
+ */\r
+ private static Set<Node<?>> collectSelfAndAllParents(Node<?> focusedAncestor) {\r
+ Set<Node<?>> family = new HashSet<>();\r
+ Node<?> tmpNode = focusedAncestor;\r
+ while (tmpNode != null) {\r
+ family.add(tmpNode);\r
+ tmpNode = tmpNode.getParent();\r
+ }\r
+ return family;\r
+ }\r
+\r
+ /**\r
+ * @param originalNode\r
+ * @return mutable version of given node\r
+ */\r
+ @Override\r
+ public Node<?> getMutableEquivalent(Node<?> originalNode) {\r
+ return originalToMutable.get(originalNode);\r
+ }\r
+\r
+}\r
--- /dev/null
+/*\r
+ * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.\r
+ *\r
+ * This program and the accompanying materials are made available under the\r
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,\r
+ * and is available at http://www.eclipse.org/legal/epl-v10.html\r
+ */\r
+package org.opendaylight.controller.yang.data.impl;\r
+\r
+import java.util.AbstractMap.SimpleEntry;\r
+import java.util.ArrayList;\r
+import java.util.HashMap;\r
+import java.util.List;\r
+import java.util.Map;\r
+import java.util.Stack;\r
+import java.util.Vector;\r
+\r
+import javax.xml.parsers.DocumentBuilder;\r
+import javax.xml.parsers.DocumentBuilderFactory;\r
+import javax.xml.parsers.ParserConfigurationException;\r
+import javax.xml.xpath.XPath;\r
+import javax.xml.xpath.XPathConstants;\r
+import javax.xml.xpath.XPathExpression;\r
+import javax.xml.xpath.XPathExpressionException;\r
+import javax.xml.xpath.XPathFactory;\r
+\r
+import org.opendaylight.controller.yang.common.QName;\r
+import org.opendaylight.controller.yang.data.api.CompositeNode;\r
+import org.opendaylight.controller.yang.data.api.ModifyAction;\r
+import org.opendaylight.controller.yang.data.api.Node;\r
+import org.opendaylight.controller.yang.data.api.NodeModification;\r
+import org.opendaylight.controller.yang.data.api.SimpleNode;\r
+import org.opendaylight.controller.yang.model.api.DataNodeContainer;\r
+import org.opendaylight.controller.yang.model.api.DataSchemaNode;\r
+import org.opendaylight.controller.yang.model.api.ListSchemaNode;\r
+import org.opendaylight.controller.yang.model.api.SchemaContext;\r
+import org.slf4j.Logger;\r
+import org.slf4j.LoggerFactory;\r
+import org.w3c.dom.Document;\r
+import org.w3c.dom.Element;\r
+\r
+import com.google.common.base.Joiner;\r
+\r
+\r
+/**\r
+ * @author michal.rehak\r
+ *\r
+ */\r
+public abstract class NodeUtils {\r
+ \r
+ /**\r
+ * \r
+ */\r
+ private static final String USER_KEY_NODE = "node";\r
+ private static final Logger LOG = LoggerFactory.getLogger(NodeUtils.class);\r
+ \r
+ /**\r
+ * @param node\r
+ * @return node path up till root node\r
+ */\r
+ public static String buildPath(Node<?> node) {\r
+ Vector<String> breadCrumbs = new Vector<>();\r
+ Node<?> tmpNode = node;\r
+ while (tmpNode != null) {\r
+ breadCrumbs.insertElementAt(tmpNode.getNodeType().getLocalName(), 0);\r
+ tmpNode = tmpNode.getParent();\r
+ }\r
+ \r
+ return Joiner.on(".").join(breadCrumbs);\r
+ }\r
+\r
+ \r
+ /**\r
+ * @param treeRootNode\r
+ * @return dom tree, containing same node structure, yang nodes are associated \r
+ * to dom nodes as user data\r
+ */\r
+ public static Document buildShadowDomTree(CompositeNode treeRootNode) {\r
+ DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();\r
+ Document doc = null;\r
+ try {\r
+ DocumentBuilder bob = dbf.newDocumentBuilder();\r
+ doc = bob.newDocument();\r
+ } catch (ParserConfigurationException e) {\r
+ LOG.error("documentBuilder problem", e);\r
+ return null;\r
+ }\r
+ \r
+ Stack<SimpleEntry<org.w3c.dom.Node, Node<?>>> jobQueue = new Stack<>();\r
+ jobQueue.push(new SimpleEntry<org.w3c.dom.Node, Node<?>>(doc, treeRootNode));\r
+ \r
+ while (!jobQueue.isEmpty()) {\r
+ SimpleEntry<org.w3c.dom.Node, Node<?>> job = jobQueue.pop();\r
+ org.w3c.dom.Node jointPlace = job.getKey();\r
+ Node<?> item = job.getValue();\r
+ Element itemEl = doc.createElement(item.getNodeType().getLocalName());\r
+ itemEl.setUserData(USER_KEY_NODE, item, null);\r
+ if (item instanceof SimpleNode<?>) {\r
+ Object value = ((SimpleNode<?>) item).getValue();\r
+ itemEl.setTextContent(String.valueOf(value));\r
+ itemEl.setAttribute("type", value.getClass().getSimpleName());\r
+ }\r
+ if (item instanceof NodeModification) {\r
+ ModifyAction modificationAction = ((NodeModification) item).getModificationAction();\r
+ if (modificationAction != null) {\r
+ itemEl.setAttribute("modifyAction", modificationAction.toString());\r
+ }\r
+ }\r
+ \r
+ jointPlace.appendChild(itemEl);\r
+ \r
+ if (item instanceof CompositeNode) {\r
+ for (Node<?> child : ((CompositeNode) item).getChildren()) {\r
+ jobQueue.push(new SimpleEntry<org.w3c.dom.Node, Node<?>>(itemEl, child));\r
+ }\r
+ }\r
+ }\r
+ \r
+ return doc;\r
+ }\r
+ \r
+ /**\r
+ * @param doc\r
+ * @param xpathEx\r
+ * @return user data value on found node\r
+ * @throws XPathExpressionException\r
+ */\r
+ @SuppressWarnings("unchecked")\r
+ public static <T> T findNodeByXpath(Document doc, String xpathEx) \r
+ throws XPathExpressionException {\r
+ T userNode = null;\r
+ XPathFactory xPathfactory = XPathFactory.newInstance();\r
+ XPath xpath = xPathfactory.newXPath();\r
+ XPathExpression expr = xpath.compile(xpathEx);\r
+ \r
+ org.w3c.dom.Node result = (org.w3c.dom.Node) expr.evaluate(doc, XPathConstants.NODE);\r
+ if (result != null) {\r
+ userNode = (T) result.getUserData(USER_KEY_NODE);\r
+ } \r
+ \r
+ return userNode;\r
+ }\r
+\r
+\r
+ /**\r
+ * build NodeMap, where key = qName; value = node\r
+ * \r
+ * @param value\r
+ * @return map of children, where key = qName and value is list of children groupped by qName \r
+ */\r
+ public static Map<QName, List<Node<?>>> buildNodeMap(List<Node<?>> value) {\r
+ Map<QName, List<Node<?>>> nodeMapTmp = new HashMap<>();\r
+ if (value == null || value.isEmpty()) {\r
+ throw new IllegalStateException(\r
+ "nodeList should not be null or empty");\r
+ }\r
+ for (Node<?> node : value) {\r
+ List<Node<?>> qList = nodeMapTmp.get(node.getNodeType());\r
+ if (qList == null) {\r
+ qList = new ArrayList<>();\r
+ nodeMapTmp.put(node.getNodeType(), qList);\r
+ }\r
+ qList.add(node);\r
+ }\r
+ return nodeMapTmp;\r
+ }\r
+\r
+\r
+ /**\r
+ * @param context\r
+ * @return map of lists, where key = path; value = {@link DataSchemaNode}\r
+ */\r
+ public static Map<String, ListSchemaNode> buildMapOfListNodes(\r
+ SchemaContext context) {\r
+ Map<String, ListSchemaNode> mapOfLists = new HashMap<>();\r
+ \r
+ Stack<DataSchemaNode> jobQueue = new Stack<>();\r
+ jobQueue.addAll(context.getDataDefinitions());\r
+ \r
+ while (!jobQueue.isEmpty()) {\r
+ DataSchemaNode dataSchema = jobQueue.pop();\r
+ if (dataSchema instanceof ListSchemaNode) {\r
+ mapOfLists.put(schemaPathToPath(dataSchema.getPath().getPath()), (ListSchemaNode) dataSchema);\r
+ }\r
+ \r
+ if (dataSchema instanceof DataNodeContainer) {\r
+ jobQueue.addAll(((DataNodeContainer) dataSchema).getChildNodes());\r
+ }\r
+ }\r
+ \r
+ return mapOfLists;\r
+ }\r
+\r
+\r
+ /**\r
+ * @param path\r
+ * @return\r
+ */\r
+ private static String schemaPathToPath(List<QName> qNamesPath) {\r
+ List<String> pathSeed = new ArrayList<>();\r
+ for (QName qNameItem : qNamesPath) {\r
+ pathSeed.add(qNameItem.getLocalName());\r
+ }\r
+ return Joiner.on(".").join(pathSeed);\r
+ }\r
+}\r
--- /dev/null
+/**\r
+ * \r
+ */\r
+package org.opendaylight.controller.yang.data.impl;\r
+\r
+import org.opendaylight.controller.yang.common.QName;\r
+import org.opendaylight.controller.yang.data.api.CompositeNode;\r
+import org.opendaylight.controller.yang.data.api.ModifyAction;\r
+import org.opendaylight.controller.yang.data.api.NodeModification;\r
+\r
+/**\r
+ * @author michal.rehak\r
+ * @param <T> type of node value\r
+ * \r
+ */\r
+public class SimpleNodeModificationTOImpl<T> extends SimpleNodeTOImpl<T>\r
+ implements NodeModification {\r
+\r
+ private ModifyAction modifyAction;\r
+\r
+ /**\r
+ * @param qname\r
+ * @param parent\r
+ * @param value\r
+ * @param modifyAction \r
+ */\r
+ public SimpleNodeModificationTOImpl(QName qname, CompositeNode parent,\r
+ T value, ModifyAction modifyAction) {\r
+ super(qname, parent, value);\r
+ this.modifyAction = modifyAction;\r
+ }\r
+\r
+ /**\r
+ * @return modification action\r
+ * @see org.opendaylight.controller.yang.data.impl.NodeModificationSupport#getModificationAction()\r
+ */\r
+ @Override\r
+ public ModifyAction getModificationAction() {\r
+ return modifyAction;\r
+ }\r
+\r
+ /**\r
+ * @param modifyAction\r
+ * the modifyAction to set\r
+ */\r
+ protected void setModificationAction(ModifyAction modifyAction) {\r
+ this.modifyAction = modifyAction;\r
+ }\r
+}\r
--- /dev/null
+/*\r
+ * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.\r
+ *\r
+ * This program and the accompanying materials are made available under the\r
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,\r
+ * and is available at http://www.eclipse.org/legal/epl-v10.html\r
+ */\r
+package org.opendaylight.controller.yang.data.impl;\r
+\r
+import org.opendaylight.controller.yang.common.QName;\r
+import org.opendaylight.controller.yang.data.api.CompositeNode;\r
+import org.opendaylight.controller.yang.data.api.SimpleNode;\r
+\r
+/**\r
+ * @author michal.rehak\r
+ * @param <T> type of simple node value\r
+ * \r
+ */\r
+public class SimpleNodeTOImpl<T> extends AbstractNodeTO<T> implements\r
+ SimpleNode<T> {\r
+\r
+ /**\r
+ * @param qname\r
+ * @param parent\r
+ * @param value\r
+ */\r
+ public SimpleNodeTOImpl(QName qname, CompositeNode parent, T value) {\r
+ super(qname, parent, value);\r
+ }\r
+\r
+}\r
--- /dev/null
+/*\r
+ * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.\r
+ *\r
+ * This program and the accompanying materials are made available under the\r
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,\r
+ * and is available at http://www.eclipse.org/legal/epl-v10.html\r
+ */\r
+package org.opendaylight.controller.yang.data.impl;\r
+\r
+import java.io.ByteArrayOutputStream;\r
+import java.io.PrintStream;\r
+import java.net.URI;\r
+import java.util.ArrayList;\r
+import java.util.Date;\r
+import java.util.HashMap;\r
+import java.util.List;\r
+import java.util.Map;\r
+\r
+import org.junit.Assert;\r
+import org.junit.Test;\r
+import org.opendaylight.controller.yang.common.QName;\r
+import org.opendaylight.controller.yang.data.api.CompositeNode;\r
+import org.opendaylight.controller.yang.data.api.ModifyAction;\r
+import org.opendaylight.controller.yang.data.api.MutableCompositeNode;\r
+import org.opendaylight.controller.yang.data.api.Node;\r
+import org.opendaylight.controller.yang.data.api.NodeModification;\r
+import org.w3c.dom.Document;\r
+\r
+/**\r
+ * @author michal.rehak\r
+ * \r
+ */\r
+public class NodeFactoryTest {\r
+\r
+ /**\r
+ * Test method for methods creating immutable nodes in\r
+ * {@link org.opendaylight.controller.yang.data.impl.NodeFactory}.\r
+ * @throws Exception \r
+ */\r
+ @Test\r
+ public void testImmutableNodes() throws Exception {\r
+ QName qName = new QName(\r
+ new URI("urn:opendaylight:controller:network"), \r
+ new Date(42), "yang-data-impl-immutableTest_", null);\r
+ \r
+ CompositeNode network = NodeHelper.buildTestConfigTree(qName);\r
+ \r
+ \r
+ Assert.assertEquals(1, network.getChildren().size());\r
+ Document domTree = NodeUtils.buildShadowDomTree(network);\r
+ NodeHelper.dumpDoc(domTree, System.out);\r
+ \r
+ CompositeNode tpList = NodeUtils.findNodeByXpath(domTree, \r
+ "//node[node-id/text()='nodeId_19']/termination-points");\r
+ \r
+ \r
+ Assert.assertEquals(2, tpList.getCompositesByName("termination-point").size());\r
+// Assert.assertEquals(1, topologies.getCompositesByName("topology").size());\r
+// Assert.assertEquals(2, destination.getChildren().size());\r
+ }\r
+\r
+ /**\r
+ * Test method for methods creating immutable nodes in\r
+ * {@link org.opendaylight.controller.yang.data.impl.NodeFactory}.\r
+ * @throws Exception \r
+ */\r
+ @Test\r
+ public void testMutableNodes() throws Exception {\r
+ // <config>\r
+ // <top xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">\r
+ // <interface xc:operation="delete">\r
+ // <name>Ethernet0/0</name>\r
+ // <mtu>1500</mtu>\r
+ // </interface>\r
+ // <interface>\r
+ // <name>Ethernet0/1</name>\r
+ // <mtu>1501</mtu>\r
+ // </interface>\r
+ // </top>\r
+ // </config>\r
+ \r
+ QName qName = new QName(\r
+ new URI("urn:ietf:params:xml:ns:netconf:base:1.0"), \r
+ new Date(42), "yang-data-impl-mutableTest");\r
+ \r
+ List<Node<?>> value = new ArrayList<Node<?>>(); \r
+ value.add(NodeFactory.createSimpleNode(new QName(qName, "name"), null, "Ethernet0/0"));\r
+ value.add(NodeFactory.createSimpleNode(new QName(qName, "mtu"), null, 1500));\r
+ \r
+ CompositeNodeModificationTOImpl ifNode = NodeFactory.createCompositeNodeModification(\r
+ new QName(qName, "interface"), null, value, ModifyAction.DELETE);\r
+ NodeHelper.assignParentToChildren(ifNode);\r
+ \r
+ value = new ArrayList<Node<?>>(); \r
+ value.add(NodeFactory.createSimpleNode(new QName(qName, "name"), null, "Ethernet1/0"));\r
+ value.add(NodeFactory.createSimpleNode(new QName(qName, "mtu"), null, 1501));\r
+ \r
+ CompositeNode ifNode2 = NodeFactory.createCompositeNode(new QName(qName, "interface"), null, value);\r
+ NodeHelper.assignParentToChildren(ifNode2);\r
+\r
+ value = new ArrayList<Node<?>>(); \r
+ value.add(ifNode);\r
+ value.add(ifNode2);\r
+ \r
+ CompositeNode topNode = NodeFactory.createCompositeNode(new QName(qName, "top"), null, value);\r
+ NodeHelper.assignParentToChildren(topNode);\r
+ value = new ArrayList<Node<?>>(); \r
+ value.add(topNode);\r
+ \r
+ CompositeNode root = NodeFactory.createCompositeNode(new QName(qName, "config"), null, value);\r
+ \r
+ \r
+ Assert.assertEquals(1, root.getChildren().size());\r
+ Assert.assertEquals(1, ifNode.getSimpleNodesByName("name").size());\r
+ Assert.assertEquals(1, ifNode.getSimpleNodesByName("mtu").size());\r
+ Assert.assertEquals(2, topNode.getCompositesByName("interface").size());\r
+ NodeModification interfaceMod = (NodeModification) \r
+ topNode.getCompositesByName("interface").get(0);\r
+ Assert.assertEquals(ModifyAction.DELETE, interfaceMod.getModificationAction());\r
+ }\r
+\r
+ /**\r
+ * test modifications builder\r
+ * @throws Exception \r
+ */\r
+ @Test\r
+ public void testCopyDeepNode() throws Exception {\r
+ QName qName = new QName(\r
+ new URI("urn:opendaylight:controller:network"), \r
+ new Date(42), "yang-data-impl-immutableTest_", null);\r
+ \r
+ CompositeNode network = NodeHelper.buildTestConfigTree(qName);\r
+ Map<Node<?>, Node<?>> mutableToOrig = new HashMap<>();\r
+ MutableCompositeNode mutableNetwork = NodeFactory.copyDeepNode(network, mutableToOrig );\r
+\r
+ Document networkShadow = NodeUtils.buildShadowDomTree(network);\r
+ ByteArrayOutputStream expected = new ByteArrayOutputStream();\r
+ NodeHelper.dumpDoc(networkShadow, new PrintStream(expected));\r
+ \r
+ Document mutableNetworkShadow = NodeUtils.buildShadowDomTree(mutableNetwork);\r
+ ByteArrayOutputStream actual = new ByteArrayOutputStream();\r
+ NodeHelper.dumpDoc(mutableNetworkShadow, new PrintStream(actual));\r
+ \r
+ Assert.assertEquals(new String(expected.toByteArray()), new String(actual.toByteArray()));\r
+ }\r
+\r
+}\r
--- /dev/null
+/*\r
+ * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.\r
+ *\r
+ * This program and the accompanying materials are made available under the\r
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,\r
+ * and is available at http://www.eclipse.org/legal/epl-v10.html\r
+ */\r
+package org.opendaylight.controller.yang.data.impl;\r
+\r
+import java.io.InputStream;\r
+import java.io.PrintStream;\r
+import java.io.StringWriter;\r
+import java.util.ArrayList;\r
+import java.util.List;\r
+import java.util.Set;\r
+\r
+import javax.xml.transform.OutputKeys;\r
+import javax.xml.transform.Transformer;\r
+import javax.xml.transform.TransformerFactory;\r
+import javax.xml.transform.dom.DOMSource;\r
+import javax.xml.transform.stream.StreamResult;\r
+\r
+import org.opendaylight.controller.yang.common.QName;\r
+import org.opendaylight.controller.yang.data.api.CompositeNode;\r
+import org.opendaylight.controller.yang.data.api.Node;\r
+import org.opendaylight.controller.yang.model.api.Module;\r
+import org.opendaylight.controller.yang.model.api.SchemaContext;\r
+import org.opendaylight.controller.yang.model.parser.api.YangModelParser;\r
+import org.opendaylight.controller.yang.parser.impl.YangParserImpl;\r
+import org.w3c.dom.Document;\r
+\r
+/**\r
+ * @author michal.rehak\r
+ *\r
+ */\r
+public abstract class NodeHelper {\r
+ \r
+ /** xml source of example network configuration */\r
+ public static final String NETWORK_XML = \r
+ "<network xmlns=\"urn:opendaylight:controller:network\">\n" +\r
+ //"<network>\n" +\r
+ " <topologies>\n" +\r
+ " <topology>\n" +\r
+ " <topology-id>topId_01</topology-id>\n" +\r
+ " <nodes>\n" +\r
+ " <node>\n" +\r
+ " <node-id>nodeId_02</node-id>\n" +\r
+ " <supporting-ne>networkId_02</supporting-ne>\n" +\r
+ " <termination-points>\n" +\r
+ " <termination-point>\n" +\r
+ " <tp-id>tpId_03</tp-id>\n" +\r
+ " </termination-point>\n" +\r
+ " </termination-points>\n" +\r
+ " </node>\n" +\r
+ " <node>\n" +\r
+ " <node-id>nodeId_16</node-id>\n" +\r
+ " <supporting-ne>networkId_17</supporting-ne>\n" +\r
+ " <termination-points>\n" +\r
+ " <termination-point>\n" +\r
+ " <tp-id>tpId_18</tp-id>\n" +\r
+ " </termination-point>\n" +\r
+ " </termination-points>\n" +\r
+ " </node>\n" +\r
+ " <node>\n" +\r
+ " <node-id>nodeId_19</node-id>\n" +\r
+ " <supporting-ne>networkId_20</supporting-ne>\n" +\r
+ " <termination-points>\n" +\r
+ " <termination-point>\n" +\r
+ " <tp-id>tpId_18</tp-id>\n" +\r
+ " </termination-point>\n" +\r
+ " <termination-point>\n" +\r
+ " <tp-id>tpId_19</tp-id>\n" +\r
+ " </termination-point>\n" +\r
+ " </termination-points>\n" +\r
+ " </node>\n" +\r
+ " </nodes>\n" +\r
+ " <links>\n" +\r
+ " <link>\n" +\r
+ " <link-id>linkId_04</link-id>\n" +\r
+ " <source>\n" +\r
+ " <source-node>nodeId_05</source-node>\n" +\r
+ " <source-tp>tpId_06</source-tp>\n" +\r
+ " </source>\n" +\r
+ " <destination>\n" +\r
+ " <dest-node>nodeId_07</dest-node>\n" +\r
+ " <dest-tp>tpId_08</dest-tp>\n" +\r
+ " </destination>\n" +\r
+ " </link>\n" +\r
+ " <link>\n" +\r
+ " <link-id>linkId_11</link-id>\n" +\r
+ " <source>\n" +\r
+ " <source-node>nodeId_12</source-node>\n" +\r
+ " <source-tp>tpId_13</source-tp>\n" +\r
+ " </source>\n" +\r
+ " <destination>\n" +\r
+ " <dest-node>nodeId_14</dest-node>\n" +\r
+ " <dest-tp>tpId_15</dest-tp>\n" +\r
+ " </destination>\n" +\r
+ " </link>\n" +\r
+ " </links>\n" +\r
+ " </topology>\n" +\r
+ " </topologies>\n" +\r
+ " <network-elements>\n" +\r
+ " <network-element>\n" +\r
+ " <element-id>ntElementId_09</element-id>\n" +\r
+ " </network-element>\n" +\r
+ " <network-element>\n" +\r
+ " <element-id>ntElementId_10</element-id>\n" +\r
+ " </network-element>\n" +\r
+ " </network-elements>\n" +\r
+ "</network>";\r
+\r
+ /**\r
+ * @param domTree\r
+ * @param out\r
+ * @throws Exception \r
+ */\r
+ public static void dumpDoc(Document domTree, PrintStream out) throws Exception {\r
+ TransformerFactory transformerFact = TransformerFactory.newInstance();\r
+ transformerFact.setAttribute("indent-number", 4);\r
+ Transformer transformer = transformerFact.newTransformer();\r
+ transformer.setOutputProperty(OutputKeys.INDENT, "yes");\r
+ //initialize StreamResult with File object to save to file\r
+ StreamResult result = new StreamResult(new StringWriter());\r
+ DOMSource source = new DOMSource(domTree);\r
+ transformer.transform(source, result);\r
+ String xmlString = result.getWriter().toString();\r
+ out.println(xmlString);\r
+ }\r
+\r
+ /**\r
+ * @param qName\r
+ * @return example tree, see {@link #NETWORK_XML}\r
+ */\r
+ public static CompositeNode buildTestConfigTree(QName qName) {\r
+ List<Node<?>> value = new ArrayList<Node<?>>(); \r
+ value.add(NodeFactory.createSimpleNode(new QName(qName, "element-id"), null, "ntElementId_09"));\r
+ CompositeNode ntElementNode1 = NodeFactory.createCompositeNode(new QName(qName, "network-element"), null, value);\r
+ assignParentToChildren(ntElementNode1);\r
+ \r
+ value = new ArrayList<Node<?>>(); \r
+ value.add(NodeFactory.createSimpleNode(new QName(qName, "element-id"), null, "ntElementId_10"));\r
+ CompositeNode ntElementNode2 = NodeFactory.createCompositeNode(new QName(qName, "network-element"), null, value);\r
+ assignParentToChildren(ntElementNode2);\r
+ \r
+ value = new ArrayList<Node<?>>();\r
+ value.add(ntElementNode1);\r
+ value.add(ntElementNode2);\r
+ CompositeNode ntElementsNode = NodeFactory.createCompositeNode(\r
+ new QName(qName, "network-elements"), null, value);\r
+ assignParentToChildren(ntElementsNode);\r
+ \r
+ value = new ArrayList<Node<?>>(); \r
+ value.add(NodeFactory.createSimpleNode(new QName(qName, "dest-node"), null, "nodeId_07"));\r
+ value.add(NodeFactory.createSimpleNode(new QName(qName, "dest-tp"), null, "tpId_08"));\r
+ CompositeNode destination = NodeFactory.createCompositeNode(\r
+ new QName(qName, "destination"), null, value);\r
+ assignParentToChildren(destination);\r
+ \r
+ value = new ArrayList<Node<?>>(); \r
+ value.add(NodeFactory.createSimpleNode(new QName(qName, "source-node"), null, "nodeId_05"));\r
+ value.add(NodeFactory.createSimpleNode(new QName(qName, "source-tp"), null, "tpId_06"));\r
+ CompositeNode source = NodeFactory.createCompositeNode(\r
+ new QName(qName, "source"), null, value);\r
+ assignParentToChildren(source);\r
+ \r
+ value = new ArrayList<Node<?>>(); \r
+ value.add(NodeFactory.createSimpleNode(new QName(qName, "link-id"), null, "linkId_04"));\r
+ value.add(source);\r
+ value.add(destination);\r
+ CompositeNode link1 = NodeFactory.createCompositeNode(\r
+ new QName(qName, "link"), null, value);\r
+ assignParentToChildren(link1);\r
+ \r
+ value = new ArrayList<Node<?>>(); \r
+ value.add(NodeFactory.createSimpleNode(new QName(qName, "dest-node"), null, "nodeId_14"));\r
+ value.add(NodeFactory.createSimpleNode(new QName(qName, "dest-tp"), null, "tpId_15"));\r
+ destination = NodeFactory.createCompositeNode(\r
+ new QName(qName, "destination"), null, value);\r
+ assignParentToChildren(destination);\r
+ \r
+ value = new ArrayList<Node<?>>(); \r
+ value.add(NodeFactory.createSimpleNode(new QName(qName, "source-node"), null, "nodeId_12"));\r
+ value.add(NodeFactory.createSimpleNode(new QName(qName, "source-tp"), null, "tpId_13"));\r
+ source = NodeFactory.createCompositeNode(\r
+ new QName(qName, "source"), null, value);\r
+ assignParentToChildren(source);\r
+ \r
+ value = new ArrayList<Node<?>>(); \r
+ value.add(NodeFactory.createSimpleNode(new QName(qName, "link-id"), null, "linkId_11"));\r
+ value.add(source);\r
+ value.add(destination);\r
+ CompositeNode link2 = NodeFactory.createCompositeNode(\r
+ new QName(qName, "link"), null, value);\r
+ assignParentToChildren(link2);\r
+ \r
+ value = new ArrayList<Node<?>>(); \r
+ value.add(link1);\r
+ value.add(link2);\r
+ CompositeNode links = NodeFactory.createCompositeNode(\r
+ new QName(qName, "links"), null, value);\r
+ assignParentToChildren(links);\r
+ \r
+ \r
+ value = new ArrayList<Node<?>>(); \r
+ value.add(NodeFactory.createSimpleNode(new QName(qName, "tp-id"), null, "tpId_03"));\r
+ CompositeNode terminationPointNode1 = NodeFactory.createCompositeNode(\r
+ new QName(qName, "termination-point"), null, value);\r
+ assignParentToChildren(terminationPointNode1);\r
+ \r
+ value = new ArrayList<Node<?>>(); \r
+ value.add(terminationPointNode1);\r
+ CompositeNode terminationPointsNode = NodeFactory.createCompositeNode(\r
+ new QName(qName, "termination-points"), null, value);\r
+ assignParentToChildren(terminationPointsNode);\r
+ \r
+ value = new ArrayList<Node<?>>(); \r
+ value.add(NodeFactory.createSimpleNode(new QName(qName, "node-id"), null, "nodeId_02"));\r
+ value.add(NodeFactory.createSimpleNode(new QName(qName, "supporting-ne"), null, "networkId_02"));\r
+ value.add(terminationPointsNode);\r
+ CompositeNode node1Node = NodeFactory.createCompositeNode(\r
+ new QName(qName, "node"), null, value);\r
+ assignParentToChildren(node1Node);\r
+ \r
+ value = new ArrayList<Node<?>>(); \r
+ value.add(NodeFactory.createSimpleNode(new QName(qName, "tp-id"), null, "tpId_18"));\r
+ terminationPointNode1 = NodeFactory.createCompositeNode(\r
+ new QName(qName, "termination-point"), null, value);\r
+ assignParentToChildren(terminationPointNode1);\r
+ \r
+ value = new ArrayList<Node<?>>(); \r
+ value.add(terminationPointNode1);\r
+ terminationPointsNode = NodeFactory.createCompositeNode(\r
+ new QName(qName, "termination-points"), null, value);\r
+ assignParentToChildren(terminationPointsNode);\r
+ \r
+ value = new ArrayList<Node<?>>(); \r
+ value.add(NodeFactory.createSimpleNode(new QName(qName, "node-id"), null, "nodeId_16"));\r
+ value.add(NodeFactory.createSimpleNode(new QName(qName, "supporting-ne"), null, "networkId_17"));\r
+ value.add(terminationPointsNode);\r
+ CompositeNode node2Node = NodeFactory.createCompositeNode(\r
+ new QName(qName, "node"), null, value);\r
+ assignParentToChildren(node2Node);\r
+ \r
+ value = new ArrayList<Node<?>>(); \r
+ value.add(NodeFactory.createSimpleNode(new QName(qName, "tp-id"), null, "tpId_18"));\r
+ terminationPointNode1 = NodeFactory.createCompositeNode(\r
+ new QName(qName, "termination-point"), null, value);\r
+ assignParentToChildren(terminationPointNode1);\r
+ \r
+ value = new ArrayList<Node<?>>(); \r
+ value.add(NodeFactory.createSimpleNode(new QName(qName, "tp-id"), null, "tpId_19"));\r
+ CompositeNode terminationPointNode2 = NodeFactory.createCompositeNode(\r
+ new QName(qName, "termination-point"), null, value);\r
+ assignParentToChildren(terminationPointNode2);\r
+ \r
+ value = new ArrayList<Node<?>>(); \r
+ value.add(terminationPointNode1);\r
+ value.add(terminationPointNode2);\r
+ terminationPointsNode = NodeFactory.createCompositeNode(\r
+ new QName(qName, "termination-points"), null, value);\r
+ assignParentToChildren(terminationPointsNode);\r
+ \r
+ value = new ArrayList<Node<?>>(); \r
+ value.add(NodeFactory.createSimpleNode(new QName(qName, "node-id"), null, "nodeId_19"));\r
+ value.add(NodeFactory.createSimpleNode(new QName(qName, "supporting-ne"), null, "networkId_20"));\r
+ value.add(terminationPointsNode);\r
+ CompositeNode node3Node = NodeFactory.createCompositeNode(\r
+ new QName(qName, "node"), null, value);\r
+ assignParentToChildren(node3Node);\r
+ \r
+ value = new ArrayList<Node<?>>(); \r
+ value.add(node1Node);\r
+ value.add(node2Node);\r
+ value.add(node3Node);\r
+ CompositeNode nodesNode = NodeFactory.createCompositeNode(\r
+ new QName(qName, "nodes"), null, value);\r
+ assignParentToChildren(nodesNode);\r
+ \r
+ value = new ArrayList<Node<?>>();\r
+ value.add(links);\r
+ value.add(nodesNode);\r
+ value.add(NodeFactory.createSimpleNode(new QName(qName, "topology-id"), null, "topId_01"));\r
+ CompositeNode topology = NodeFactory.createCompositeNode(\r
+ new QName(qName, "topology"), null, value);\r
+ assignParentToChildren(topology);\r
+ \r
+ value = new ArrayList<Node<?>>();\r
+ value.add(topology);\r
+ CompositeNode topologies = NodeFactory.createCompositeNode(\r
+ new QName(qName, "topologies"), null, value);\r
+ assignParentToChildren(topologies);\r
+ \r
+ value = new ArrayList<Node<?>>();\r
+ value.add(topologies);\r
+ CompositeNode network = NodeFactory.createCompositeNode(\r
+ new QName(qName, "network"), null, value);\r
+ assignParentToChildren(network);\r
+ \r
+ return network;\r
+ }\r
+\r
+ /**\r
+ * @param parentNode\r
+ */\r
+ public static void assignParentToChildren(CompositeNode parentNode) {\r
+ for (Node<?> child : parentNode.getChildren()) {\r
+ ((AbstractNodeTO<?>) child).setParent(parentNode);\r
+ }\r
+ }\r
+\r
+ /**\r
+ * @return schema context of controller-network.yang\r
+ */\r
+ public static SchemaContext loadSchemaContext() {\r
+ YangModelParser yParser = new YangParserImpl();\r
+ List<InputStream> yangInputStreams = new ArrayList<>();\r
+ yangInputStreams.add(NodeHelper.class.getResourceAsStream(\r
+ "/controller-network.yang"));\r
+ yangInputStreams.add(NodeHelper.class.getResourceAsStream(\r
+ "/ietf-inet-types@2010-09-24.yang"));\r
+ Set<Module> modules = yParser\r
+ .parseYangModelsFromStreams(yangInputStreams);\r
+ return yParser.resolveSchemaContext(modules);\r
+ }\r
+\r
+}\r
--- /dev/null
+/*\r
+ * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.\r
+ *\r
+ * This program and the accompanying materials are made available under the\r
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,\r
+ * and is available at http://www.eclipse.org/legal/epl-v10.html\r
+ */\r
+package org.opendaylight.controller.yang.data.impl;\r
+\r
+import java.net.URI;\r
+import java.util.Date;\r
+\r
+import junit.framework.Assert;\r
+\r
+import org.junit.Before;\r
+import org.junit.Test;\r
+import org.opendaylight.controller.yang.common.QName;\r
+import org.opendaylight.controller.yang.data.api.CompositeNode;\r
+import org.opendaylight.controller.yang.data.api.MutableCompositeNode;\r
+import org.opendaylight.controller.yang.data.api.MutableSimpleNode;\r
+import org.opendaylight.controller.yang.data.api.SimpleNode;\r
+import org.opendaylight.controller.yang.model.api.SchemaContext;\r
+import org.w3c.dom.Document;\r
+\r
+/**\r
+ * @author michal.rehak\r
+ * \r
+ */\r
+public class NodeModificationBuilderImplTest {\r
+\r
+ private SchemaContext schemaCtx;\r
+ private QName qName;\r
+ private CompositeNode network;\r
+ private NodeModificationBuilderImpl nodeModificationBuilder;\r
+\r
+ /**\r
+ * prepare schemaContext\r
+ * @throws Exception \r
+ */\r
+ @Before\r
+ public void setUp() throws Exception {\r
+ schemaCtx = NodeHelper.loadSchemaContext();\r
+\r
+ qName = new QName(\r
+ new URI("urn:opendaylight:controller:network"), \r
+ new Date(1369000800000L), "topos");\r
+ network = NodeHelper.buildTestConfigTree(qName);\r
+ \r
+ nodeModificationBuilder = new NodeModificationBuilderImpl(network, schemaCtx);\r
+ }\r
+\r
+ /**\r
+ * Test method for\r
+ * {@link org.opendaylight.controller.yang.data.impl.NodeModificationBuilderImpl#buildDiffTree()}\r
+ * .\r
+ * @throws Exception \r
+ */\r
+ @Test\r
+ public void testBuildDiffTree() throws Exception {\r
+ Document networkShadow = NodeUtils.buildShadowDomTree(network);\r
+ SimpleNode<String> needle = NodeUtils.findNodeByXpath(networkShadow, \r
+ "//node[node-id='nodeId_19']//termination-point[2]/tp-id");\r
+ \r
+ @SuppressWarnings("unchecked")\r
+ MutableSimpleNode<String> mutableNeedle = (MutableSimpleNode<String>) \r
+ nodeModificationBuilder.getMutableEquivalent(needle);\r
+ \r
+ mutableNeedle.setValue("tpId_18x");\r
+ nodeModificationBuilder.replaceNode(mutableNeedle);\r
+ CompositeNode diffTree = nodeModificationBuilder.buildDiffTree();\r
+ \r
+ Document diffShadow = NodeUtils.buildShadowDomTree(diffTree);\r
+ NodeHelper.dumpDoc(diffShadow, System.out);\r
+ }\r
+\r
+ /**\r
+ * Test method for\r
+ * {@link org.opendaylight.controller.yang.data.impl.NodeModificationBuilderImpl#getMutableEquivalent(org.opendaylight.controller.yang.data.api.Node)}\r
+ * .\r
+ */\r
+ @Test\r
+ public void testGetMutableEquivalent() {\r
+ MutableCompositeNode rootMutable = (MutableCompositeNode) \r
+ nodeModificationBuilder.getMutableEquivalent(network);\r
+ \r
+ CompositeNode topologies = network.getCompositesByName("topologies").iterator().next();\r
+ CompositeNode topologiesMutable = rootMutable.getCompositesByName("topologies").iterator().next();\r
+ \r
+ Assert.assertSame(topologiesMutable, nodeModificationBuilder.getMutableEquivalent(topologies));\r
+ }\r
+\r
+}\r
--- /dev/null
+/*\r
+ * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.\r
+ *\r
+ * This program and the accompanying materials are made available under the\r
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,\r
+ * and is available at http://www.eclipse.org/legal/epl-v10.html\r
+ */\r
+package org.opendaylight.controller.yang.data.impl;\r
+\r
+import java.io.ByteArrayOutputStream;\r
+import java.io.PrintStream;\r
+import java.net.URI;\r
+import java.util.Date;\r
+import java.util.List;\r
+import java.util.Map;\r
+\r
+import org.junit.Assert;\r
+import org.junit.Before;\r
+import org.junit.Test;\r
+import org.opendaylight.controller.yang.common.QName;\r
+import org.opendaylight.controller.yang.data.api.CompositeNode;\r
+import org.opendaylight.controller.yang.data.api.Node;\r
+import org.opendaylight.controller.yang.data.api.SimpleNode;\r
+import org.opendaylight.controller.yang.model.api.ListSchemaNode;\r
+import org.opendaylight.controller.yang.model.api.SchemaContext;\r
+import org.w3c.dom.Document;\r
+\r
+/**\r
+ * @author michal.rehak\r
+ *\r
+ */\r
+public class NodeUtilsTest {\r
+ \r
+ private QName qName;\r
+ private CompositeNode network;\r
+\r
+ /**\r
+ * @throws Exception\r
+ */\r
+ @Before\r
+ public void setUp() throws Exception {\r
+ qName = new QName(\r
+ new URI("urn:ietf:params:xml:ns:netconf:base:1.0"), \r
+ new Date(42), "yang-data-impl-mutableTest");\r
+ network = NodeHelper.buildTestConfigTree(qName);\r
+ }\r
+\r
+ /**\r
+ * Test method for {@link org.opendaylight.controller.yang.data.impl.NodeUtils#buildPath(org.opendaylight.controller.yang.data.api.Node)}.\r
+ * @throws Exception \r
+ */\r
+ @Test\r
+ public void testBuildPath() throws Exception {\r
+ SimpleNode<?> needle = network.getCompositesByName("topologies").iterator().next()\r
+ .getCompositesByName("topology").iterator().next()\r
+ .getSimpleNodesByName("topology-id").iterator().next();\r
+ String breadCrumbs = NodeUtils.buildPath(needle);\r
+ \r
+ Assert.assertEquals("network.topologies.topology.topology-id", breadCrumbs);\r
+ }\r
+\r
+ /**\r
+ * Test method for {@link org.opendaylight.controller.yang.data.impl.NodeUtils#buildShadowDomTree(org.opendaylight.controller.yang.data.api.CompositeNode)}.\r
+ * @throws Exception \r
+ */\r
+ @Test\r
+ public void testBuildShadowDomTree() throws Exception {\r
+ Document networkShadow = NodeUtils.buildShadowDomTree(network);\r
+ ByteArrayOutputStream actual = new ByteArrayOutputStream();\r
+ NodeHelper.dumpDoc(networkShadow, new PrintStream(actual));\r
+ \r
+ Assert.assertEquals(2760, new String(actual.toByteArray()).length());\r
+ }\r
+\r
+ /**\r
+ * Test method for {@link org.opendaylight.controller.yang.data.impl.NodeUtils#findNodeByXpath(org.w3c.dom.Document, java.lang.String)}.\r
+ * @throws Exception \r
+ */\r
+ @Test\r
+ public void testFindNodeByXpath() throws Exception {\r
+ Document networkShadow = NodeUtils.buildShadowDomTree(network);\r
+ SimpleNode<String> needle = NodeUtils.findNodeByXpath(networkShadow, \r
+ "//node[node-id='nodeId_19']//termination-point[2]/tp-id");\r
+ Assert.assertNotNull(needle);\r
+ Assert.assertEquals("tpId_18", needle.getValue());\r
+ }\r
+\r
+ /**\r
+ * Test method for {@link org.opendaylight.controller.yang.data.impl.NodeUtils#buildNodeMap(java.util.List)}.\r
+ */\r
+ @Test\r
+ public void testBuildNodeMap() {\r
+ CompositeNode topology = network.getCompositesByName("topologies").iterator().next()\r
+ .getCompositesByName("topology").iterator().next();\r
+ \r
+ Map<QName, List<Node<?>>> nodeMap = NodeUtils.buildNodeMap(topology.getChildren());\r
+ Assert.assertEquals(3, nodeMap.size());\r
+ }\r
+ \r
+ /**\r
+ * Test method for {@link org.opendaylight.controller.yang.data.impl.NodeUtils#buildMapOfListNodes(org.opendaylight.controller.yang.model.api.SchemaContext)}.\r
+ */\r
+ @Test\r
+ public void testBuildMapOfListNodes() {\r
+ SchemaContext schemaCtx = NodeHelper.loadSchemaContext();\r
+ Map<String, ListSchemaNode> mapOfLists = NodeUtils.buildMapOfListNodes(schemaCtx);\r
+ Assert.assertEquals(5, mapOfLists.size());\r
+ }\r
+\r
+}\r
--- /dev/null
+<?xml version="1.0" encoding="ISO-8859-1"?>\r
+<rpc message-id="101" xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">\r
+ <edit-config>\r
+ <target>\r
+ <running />\r
+ </target>\r
+ <config>\r
+ <top xmlns="http://example.com/schema/1.2/config">\r
+ <interface>\r
+ <name>Ethernet0/0</name>\r
+ <mtu>1500</mtu>\r
+ </interface>\r
+ </top>\r
+ </config>\r
+ </edit-config>\r
+</rpc>\r
+
\ No newline at end of file
--- /dev/null
+xmlDoc.network(xmlns: 'urn:opendaylight:controller:network') {\r
+ topologies {\r
+ topology {\r
+ 'topology-id'('topId_'+cnt.get())\r
+ \r
+ types()\r
+ nodes {\r
+ node {\r
+ 'node-id'('nodeId_'+cnt.get())\r
+ 'supporting-ne'('networkId_'+cnt.get())\r
+ 'termination-points' {\r
+ 'termination-point' {\r
+ 'tp-id'('tpId_'+cnt.get())\r
+ }\r
+ }\r
+ }\r
+ node {\r
+ 'node-id'('nodeId_'+cnt.get())\r
+ 'supporting-ne'('networkId_'+cnt.get())\r
+ 'termination-points' {\r
+ 'termination-point' {\r
+ 'tp-id'('tpId_'+cnt.get())\r
+ }\r
+ }\r
+ }\r
+ node {\r
+ 'node-id'('nodeId_'+cnt.get())\r
+ 'supporting-ne'('networkId_'+cnt.get())\r
+ 'termination-points' {\r
+ 'termination-point' {\r
+ 'tp-id'('tpId_'+cnt.get())\r
+ }\r
+ 'termination-point' {\r
+ 'tp-id'('tpId_'+cnt.get())\r
+ }\r
+ }\r
+ }\r
+ }\r
+ links {\r
+ link {\r
+ 'link-id'('linkId_'+cnt.get())\r
+ source {\r
+ 'source-node'('nodeId_'+cnt.get())\r
+ 'source-tp'('tpId_'+cnt.get(false))\r
+ }\r
+ destination {\r
+ 'dest-node'('nodeId_'+cnt.get())\r
+ 'dest-tp'('tpId_'+cnt.get(false))\r
+ }\r
+ }\r
+ link {\r
+ 'link-id'('linkId_'+cnt.get())\r
+ source {\r
+ 'source-node'('nodeId_'+cnt.get())\r
+ 'source-tp'('tpId_'+cnt.get(false))\r
+ }\r
+ destination {\r
+ 'dest-node'('nodeId_'+cnt.get())\r
+ 'dest-tp'('tpId_'+cnt.get(false))\r
+ }\r
+ }\r
+ }\r
+ }\r
+ }\r
+ 'network-elements' {\r
+ 'network-element' {\r
+ 'element-id'('ntElementId_'+cnt.get())\r
+ }\r
+ 'network-element' {\r
+ 'element-id'('ntElementId_'+cnt.get())\r
+ }\r
+ }\r
+ }
\ No newline at end of file
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>\r
+<network xmlns="urn:opendaylight:controller:network">\r
+ <topologies>\r
+ <topology>\r
+ <topology-id>topId_01</topology-id>\r
+ <types></types>\r
+ <nodes>\r
+ <node>\r
+ <node-id>nodeId_02</node-id>\r
+ <supporting-ne>networkId_02</supporting-ne>\r
+ <termination-points>\r
+ <termination-point>\r
+ <tp-id>tpId_03</tp-id>\r
+ </termination-point>\r
+ </termination-points>\r
+ </node>\r
+ <node>\r
+ <node-id>nodeId_16</node-id>\r
+ <supporting-ne>networkId_17</supporting-ne>\r
+ <termination-points>\r
+ <termination-point>\r
+ <tp-id>tpId_18</tp-id>\r
+ </termination-point>\r
+ </termination-points>\r
+ </node>\r
+ <node>\r
+ <node-id>nodeId_19</node-id>\r
+ <supporting-ne>networkId_20</supporting-ne>\r
+ <termination-points>\r
+ <termination-point>\r
+ <tp-id>tpId_18</tp-id>\r
+ </termination-point>\r
+ <termination-point>\r
+ <tp-id>tpId_19</tp-id>\r
+ </termination-point>\r
+ </termination-points>\r
+ </node>\r
+ </nodes>\r
+ <links>\r
+ <link>\r
+ <link-id>linkId_04</link-id>\r
+ <source>\r
+ <source-node>nodeId_05</source-node>\r
+ <source-tp>tpId_06</source-tp>\r
+ </source>\r
+ <destination>\r
+ <dest-node>nodeId_07</dest-node>\r
+ <dest-tp>tpId_08</dest-tp>\r
+ </destination>\r
+ </link>\r
+ <link>\r
+ <link-id>linkId_11</link-id>\r
+ <source>\r
+ <source-node>nodeId_12</source-node>\r
+ <source-tp>tpId_13</source-tp>\r
+ </source>\r
+ <destination>\r
+ <dest-node>nodeId_14</dest-node>\r
+ <dest-tp>tpId_15</dest-tp>\r
+ </destination>\r
+ </link>\r
+ </links>\r
+ </topology>\r
+ </topologies>\r
+ <network-elements>\r
+ <network-element>\r
+ <element-id>ntElementId_09</element-id>\r
+ </network-element>\r
+ <network-element>\r
+ <element-id>ntElementId_10</element-id>\r
+ </network-element>\r
+ </network-elements>\r
+</network>\r
+\r
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+<network xmlns="urn:opendaylight:controller:network">
+ <topologies>
+ <topology>
+ <topology-id>topId_01</topology-id>
+ <types />
+ <nodes>
+ <node>
+ <node-id>nodeId_02</node-id>
+ <supporting-ne>networkId_03</supporting-ne>
+ <termination-points>
+ <termination-point>
+ <tp-id>tpId_04</tp-id>
+ </termination-point>
+ </termination-points>
+ </node>
+ <node>
+ <node-id>nodeId_05</node-id>
+ <supporting-ne>networkId_06</supporting-ne>
+ <termination-points>
+ <termination-point>
+ <tp-id>tpId_07</tp-id>
+ </termination-point>
+ </termination-points>
+ </node>
+ <node>
+ <node-id>nodeId_08</node-id>
+ <supporting-ne>networkId_09</supporting-ne>
+ <termination-points>
+ <termination-point>
+ <tp-id>tpId_10</tp-id>
+ </termination-point>
+ <termination-point>
+ <tp-id>tpId_11</tp-id>
+ </termination-point>
+ </termination-points>
+ </node>
+ </nodes>
+ <links>
+ <link>
+ <link-id>linkId_12</link-id>
+ <source>
+ <source-node>nodeId_13</source-node>
+ <source-tp>tpId_13</source-tp>
+ </source>
+ <destination>
+ <dest-node>nodeId_14</dest-node>
+ <dest-tp>tpId_14</dest-tp>
+ </destination>
+ </link>
+ <link>
+ <link-id>linkId_15</link-id>
+ <source>
+ <source-node>nodeId_16</source-node>
+ <source-tp>tpId_16</source-tp>
+ </source>
+ <destination>
+ <dest-node>nodeId_17</dest-node>
+ <dest-tp>tpId_17</dest-tp>
+ </destination>
+ </link>
+ </links>
+ </topology>
+ </topologies>
+ <network-elements>
+ <network-element>
+ <element-id>ntElementId_18</element-id>
+ </network-element>
+ <network-element>
+ <element-id>ntElementId_19</element-id>
+ </network-element>
+ </network-elements>
+</network>\r
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
+ xmlns:yin="urn:ietf:params:xml:schema:yang:yin:1"
+ targetNamespace="urn:opendaylight:controller:network"
+ xmlns="urn:opendaylight:controller:network"
+ elementFormDefault="qualified"
+ attributeFormDefault="unqualified"
+ version="2013-05-20"
+ xml:lang="en"
+ xmlns:topos="urn:opendaylight:controller:network"
+ xmlns:inet="urn:ietf:params:xml:ns:yang:ietf-inet-types">
+
+ <xs:import namespace="urn:ietf:params:xml:ns:yang:ietf-inet-types"
+ schemaLocation="ietf-inet-types@2010-09-24.xsd"/>
+
+ <xs:annotation>
+ <xs:documentation>
+ This schema was generated from the YANG module controller-network
+ by pyang version 1.2.
+
+ The schema describes an instance document consisting
+ of the entire configuration data store, operational
+ data, rpc operations, and notifications.
+ This schema can thus NOT be used as-is to
+ validate NETCONF PDUs.
+ </xs:documentation>
+ </xs:annotation>
+
+
+ <!-- YANG typedefs -->
+ <xs:simpleType name="topology-id">
+ <xs:restriction base="xs:string">
+ </xs:restriction>
+ </xs:simpleType>
+ <xs:simpleType name="node-id">
+ <xs:restriction base="xs:string">
+ </xs:restriction>
+ </xs:simpleType>
+ <xs:simpleType name="link-id">
+ <xs:restriction base="xs:string">
+ </xs:restriction>
+ </xs:simpleType>
+ <xs:simpleType name="tp-id">
+ <xs:annotation>
+ <xs:documentation>
+ identifier for termination points on a port
+ </xs:documentation>
+ </xs:annotation>
+
+ <xs:restriction base="xs:string">
+ </xs:restriction>
+ </xs:simpleType>
+ <xs:simpleType name="tp-ref">
+ <xs:restriction base="tp-id">
+ </xs:restriction>
+ </xs:simpleType>
+ <xs:simpleType name="topology-ref">
+ <xs:annotation>
+ <xs:documentation>
+ This type is used for leafs that reference topology identifier instance.
+ </xs:documentation>
+ </xs:annotation>
+
+ <xs:restriction base="topology-id">
+ </xs:restriction>
+ </xs:simpleType>
+ <xs:simpleType name="node-ref">
+ <xs:annotation>
+ <xs:documentation>
+ This type is used for leafs that reference a node instance.
+ </xs:documentation>
+ </xs:annotation>
+
+ <xs:restriction base="node-id">
+ </xs:restriction>
+ </xs:simpleType>
+ <xs:simpleType name="link-ref">
+ <xs:annotation>
+ <xs:documentation>
+ This type is used for leafs that reference a link instance.
+ </xs:documentation>
+ </xs:annotation>
+
+ <xs:restriction base="link-id">
+ </xs:restriction>
+ </xs:simpleType>
+ <xs:simpleType name="network-element-ref">
+ <xs:restriction base="element-id">
+ </xs:restriction>
+ </xs:simpleType>
+ <xs:simpleType name="element-id">
+ <xs:restriction base="xs:string">
+ </xs:restriction>
+ </xs:simpleType>
+
+ <xs:element name="network">
+ <xs:complexType>
+ <xs:sequence>
+ <xs:element name="topologies" minOccurs="0">
+ <xs:complexType>
+ <xs:sequence>
+ <xs:element name="topology" minOccurs="0" maxOccurs="unbounded">
+ <xs:annotation>
+ <xs:documentation>
+
+ 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.
+
+ </xs:documentation>
+ </xs:annotation>
+ <xs:complexType>
+ <xs:sequence>
+ <xs:element name="topology-id" type="topology-id">
+ <xs:annotation>
+ <xs:documentation>
+
+ It is presumed that datastore will contain many topologies. To
+ distinguish between topologies it is vital to have UNIQUE
+ topology identifier.
+
+ </xs:documentation>
+ </xs:annotation>
+ </xs:element>
+ <xs:element name="types" minOccurs="0">
+ <xs:annotation>
+ <xs:documentation>
+
+ The container for definition of topology types.
+ The augmenting modules should add empty optional leaf
+ to this container to signalize topology type.
+
+ </xs:documentation>
+ </xs:annotation>
+ <xs:complexType>
+ <xs:sequence>
+ <xs:any minOccurs="0" maxOccurs="unbounded"
+ namespace="##other" processContents="lax"/>
+ </xs:sequence>
+ </xs:complexType>
+ </xs:element>
+ <xs:element name="nodes" minOccurs="0">
+ <xs:complexType>
+ <xs:sequence>
+ <xs:element name="node" minOccurs="0" maxOccurs="unbounded">
+ <xs:annotation>
+ <xs:documentation>
+ The list of network nodes defined for topology.
+ </xs:documentation>
+ </xs:annotation>
+ <xs:complexType>
+ <xs:sequence>
+ <xs:element name="node-id" type="node-id">
+ <xs:annotation>
+ <xs:documentation>
+ The Topology identifier of network-node.
+ </xs:documentation>
+ </xs:annotation>
+ </xs:element>
+ <xs:element name="supporting-ne" minOccurs="0" type="network-element-ref">
+ </xs:element>
+ <xs:element name="termination-points" minOccurs="0">
+ <xs:complexType>
+ <xs:sequence>
+ <xs:element name="termination-point" minOccurs="0" maxOccurs="unbounded">
+ <xs:complexType>
+ <xs:sequence>
+ <xs:element name="tp-id" type="tp-id">
+ </xs:element>
+ <xs:any minOccurs="0" maxOccurs="unbounded"
+ namespace="##other" processContents="lax"/>
+ </xs:sequence>
+ </xs:complexType>
+ </xs:element>
+ <xs:any minOccurs="0" maxOccurs="unbounded"
+ namespace="##other" processContents="lax"/>
+ </xs:sequence>
+ </xs:complexType>
+ <xs:key name="key_termination-points_node_nodes_topology_topologies_network_termination-point">
+ <xs:selector xpath="topos:termination-point"/>
+ <xs:field xpath="topos:tp-id"/>
+ </xs:key>
+ </xs:element>
+ <xs:any minOccurs="0" maxOccurs="unbounded"
+ namespace="##other" processContents="lax"/>
+ </xs:sequence>
+ </xs:complexType>
+ </xs:element>
+ <xs:any minOccurs="0" maxOccurs="unbounded"
+ namespace="##other" processContents="lax"/>
+ </xs:sequence>
+ </xs:complexType>
+ <xs:key name="key_nodes_topology_topologies_network_node">
+ <xs:selector xpath="topos:node"/>
+ <xs:field xpath="topos:node-id"/>
+ </xs:key>
+ </xs:element>
+ <xs:element name="links" minOccurs="0">
+ <xs:complexType>
+ <xs:sequence>
+ <xs:element name="link" minOccurs="0" maxOccurs="unbounded">
+ <xs:annotation>
+ <xs:documentation>
+
+ 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.
+
+ </xs:documentation>
+ </xs:annotation>
+ <xs:complexType>
+ <xs:sequence>
+ <xs:element name="link-id" type="link-id">
+ </xs:element>
+ <xs:element name="source" minOccurs="0">
+ <xs:complexType>
+ <xs:sequence>
+ <xs:element name="source-node" minOccurs="0" type="node-ref">
+ <xs:annotation>
+ <xs:documentation>
+ Source node identifier.
+ </xs:documentation>
+ </xs:annotation>
+ </xs:element>
+ <xs:element name="source-tp" minOccurs="0" type="tp-ref">
+ </xs:element>
+ <xs:any minOccurs="0" maxOccurs="unbounded"
+ namespace="##other" processContents="lax"/>
+ </xs:sequence>
+ </xs:complexType>
+ </xs:element>
+ <xs:element name="destination" minOccurs="0">
+ <xs:complexType>
+ <xs:sequence>
+ <xs:element name="dest-node" minOccurs="0" type="node-ref">
+ <xs:annotation>
+ <xs:documentation>
+ Destination node identifier.
+ </xs:documentation>
+ </xs:annotation>
+ </xs:element>
+ <xs:element name="dest-tp" minOccurs="0" type="tp-ref">
+ </xs:element>
+ <xs:any minOccurs="0" maxOccurs="unbounded"
+ namespace="##other" processContents="lax"/>
+ </xs:sequence>
+ </xs:complexType>
+ </xs:element>
+ <xs:any minOccurs="0" maxOccurs="unbounded"
+ namespace="##other" processContents="lax"/>
+ </xs:sequence>
+ </xs:complexType>
+ </xs:element>
+ <xs:any minOccurs="0" maxOccurs="unbounded"
+ namespace="##other" processContents="lax"/>
+ </xs:sequence>
+ </xs:complexType>
+ <xs:key name="key_links_topology_topologies_network_link">
+ <xs:selector xpath="topos:link"/>
+ <xs:field xpath="topos:link-id"/>
+ </xs:key>
+ </xs:element>
+ <xs:any minOccurs="0" maxOccurs="unbounded"
+ namespace="##other" processContents="lax"/>
+ </xs:sequence>
+ </xs:complexType>
+ </xs:element>
+ <xs:any minOccurs="0" maxOccurs="unbounded"
+ namespace="##other" processContents="lax"/>
+ </xs:sequence>
+ </xs:complexType>
+ <xs:key name="key_topologies_network_topology">
+ <xs:selector xpath="topos:topology"/>
+ <xs:field xpath="topos:topology-id"/>
+ </xs:key>
+ </xs:element>
+ <xs:element name="network-elements" minOccurs="0">
+ <xs:complexType>
+ <xs:sequence>
+ <xs:element name="network-element" minOccurs="0" maxOccurs="unbounded">
+ <xs:complexType>
+ <xs:sequence>
+ <xs:element name="element-id" type="element-id">
+ </xs:element>
+ <xs:any minOccurs="0" maxOccurs="unbounded"
+ namespace="##other" processContents="lax"/>
+ </xs:sequence>
+ </xs:complexType>
+ </xs:element>
+ <xs:any minOccurs="0" maxOccurs="unbounded"
+ namespace="##other" processContents="lax"/>
+ </xs:sequence>
+ </xs:complexType>
+ <xs:key name="key_network-elements_network_network-element">
+ <xs:selector xpath="topos:network-element"/>
+ <xs:field xpath="topos:element-id"/>
+ </xs:key>
+ </xs:element>
+ <xs:any minOccurs="0" maxOccurs="unbounded"
+ namespace="##other" processContents="lax"/>
+ </xs:sequence>
+ </xs:complexType>
+ </xs:element>
+
+</xs:schema>
--- /dev/null
+module controller-network {
+ yang-version 1;
+ namespace "urn:opendaylight:controller:network";
+ prefix "topos";
+
+ import ietf-inet-types { prefix "inet"; }
+
+ revision 2013-05-20 {
+ description "Initial demo";
+ }
+
+
+
+
+ typedef topology-id {
+ type string;
+ }
+
+ typedef node-id {
+ type string;
+ }
+
+ typedef link-id {
+ type string;
+ }
+
+ typedef tp-id {
+ type string;
+ description "identifier for termination points on a port";
+ }
+
+ typedef tp-ref {
+ type leafref {
+ path "/network/topologies/topology/nodes/node/termination-points/termination-point/tp-id";
+ }
+ }
+ typedef topology-ref {
+ type leafref {
+ path "/network/topologies/topology/topology-id";
+ }
+ description "This type is used for leafs that reference topology identifier instance.";
+ // currently not used
+ }
+
+ typedef node-ref {
+ type leafref {
+ path "/network/topologies/topology/nodes/node/node-id";
+ }
+ description "This type is used for leafs that reference a node instance.";
+ }
+
+ typedef link-ref {
+ type leafref {
+ path "/network/topologies/topology/links/link/link-id";
+ }
+ description "This type is used for leafs that reference a link instance.";
+ // currently not used
+ }
+
+ typedef network-element-ref {
+ type leafref {
+ path "/network/network-elements/network-element/element-id";
+ }
+ }
+
+
+ typedef element-id {
+ type string;
+ }
+
+ container network {
+ container topologies {
+ list topology {
+ 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.
+ ";
+ key "topology-id";
+ leaf topology-id {
+ type topology-id;
+ description "
+ It is presumed that datastore will contain many topologies. To
+ distinguish between topologies it is vital to have UNIQUE
+ topology identifier.
+ ";
+ }
+
+ container types {
+ description "
+ The container for definition of topology types.
+ The augmenting modules should add empty optional leaf
+ to this container to signalize topology type.
+ ";
+ }
+
+ container nodes {
+ list node {
+ description "The list of network nodes defined for topology.";
+
+ key "node-id";
+ leaf node-id {
+ type node-id;
+ description "The Topology identifier of network-node.";
+ }
+
+ leaf supporting-ne {
+ type network-element-ref;
+ }
+
+ container termination-points {
+ list termination-point {
+ key "tp-id";
+ leaf tp-id {
+ type tp-id;
+ }
+ }
+ }
+ }
+ }
+
+ container links {
+ list 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 link-id;
+ }
+ container source {
+ leaf source-node {
+ type node-ref;
+ description "Source node identifier.";
+ }
+ leaf source-tp {
+ type tp-ref;
+ }
+ }
+ container destination {
+ leaf dest-node {
+ type node-ref;
+ description "Destination node identifier.";
+ }
+ leaf dest-tp {
+ type tp-ref;
+ }
+ }
+ }
+ }
+ }
+ }
+ container network-elements {
+ config true;
+ list network-element {
+ key "element-id";
+ leaf element-id {
+ type element-id;
+ }
+ }
+ }
+ }
+}
--- /dev/null
+//import groovy.xml.StreamingMarkupBuilder
+import groovy.xml.MarkupBuilder
+import groovy.xml.XmlUtil
+
+class Counter {
+ def counter = 0
+ def get() {
+ return get(true)
+ }
+ def get(isInc) {
+ if (isInc) {
+ counter++
+ }
+ return String.format('%02d', counter)
+ }
+}
+
+
+cnt = new Counter()
+def writer = new StringWriter()
+xmlDoc = new MarkupBuilder(writer)
+xmlDoc.setDoubleQuotes(true)
+xmlDoc.getMkp().xmlDeclaration(version:'1.0', encoding: 'UTF-8')
+
+//def data = {
+// mkp.xmlDeclaration()
+// network(xmlns: 'urn:opendaylight:controller:network') {
+dataFile = new File(args[0])
+evaluate(dataFile)
+// xmlDoc.network(xmlns: 'urn:opendaylight:controller:network') {
+ // topologies {
+ // topology {
+ // 'topology-id'('topId_'+cnt.get())
+ // types()
+ // nodes {
+ // node {
+ // 'node-id'('nodeId_'+cnt.get())
+ // 'supporting-ne'('networkId_'+cnt.get())
+ // 'termination-points' {
+ // 'termination-point' {
+ // 'tp-id'('tpId_'+cnt.get())
+ // }
+ // }
+ // }
+ // node {
+ // 'node-id'('nodeId_'+cnt.get())
+ // 'supporting-ne'('networkId_'+cnt.get())
+ // 'termination-points' {
+ // 'termination-point' {
+ // 'tp-id'('tpId_'+cnt.get())
+ // }
+ // }
+ // }
+ // node {
+ // 'node-id'('nodeId_'+cnt.get())
+ // 'supporting-ne'('networkId_'+cnt.get())
+ // 'termination-points' {
+ // 'termination-point' {
+ // 'tp-id'('tpId_'+cnt.get())
+ // }
+ // 'termination-point' {
+ // 'tp-id'('tpId_'+cnt.get())
+ // }
+ // }
+ // }
+ // }
+ // links {
+ // link {
+ // 'link-id'('linkId_'+cnt.get())
+ // source {
+ // 'source-node'('nodeId_'+cnt.get())
+ // 'source-tp'('tpId_'+cnt.get(false))
+ // }
+ // destination {
+ // 'dest-node'('nodeId_'+cnt.get())
+ // 'dest-tp'('tpId_'+cnt.get(false))
+ // }
+ // }
+ // link {
+ // 'link-id'('linkId_'+cnt.get())
+ // source {
+ // 'source-node'('nodeId_'+cnt.get())
+ // 'source-tp'('tpId_'+cnt.get(false))
+ // }
+ // destination {
+ // 'dest-node'('nodeId_'+cnt.get())
+ // 'dest-tp'('tpId_'+cnt.get(false))
+ // }
+ // }
+ // }
+ // }
+ // }
+ // 'network-elements' {
+ // 'network-element' {
+ // 'element-id'('ntElementId_'+cnt.get())
+ // }
+ // 'network-element' {
+ // 'element-id'('ntElementId_'+cnt.get())
+ // }
+ // }
+ // }
+
+//}
+
+
+// def xmlDoc = new StreamingMarkupBuilder()
+// xmlDoc.encoding = 'UTF'
+//println XmlUtil.serialize(xmlDoc.bind(data))
+
+println writer
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
+ xmlns:yin="urn:ietf:params:xml:schema:yang:yin:1"
+ targetNamespace="urn:ietf:params:xml:ns:yang:ietf-inet-types"
+ xmlns="urn:ietf:params:xml:ns:yang:ietf-inet-types"
+ elementFormDefault="qualified"
+ attributeFormDefault="unqualified"
+ version="2010-09-24"
+ xml:lang="en"
+ xmlns:inet="urn:ietf:params:xml:ns:yang:ietf-inet-types">
+
+ <xs:annotation>
+ <xs:documentation>
+ This schema was generated from the YANG module ietf-inet-types
+ by pyang version 1.2.
+
+ The schema describes an instance document consisting
+ of the entire configuration data store, operational
+ data, rpc operations, and notifications.
+ This schema can thus NOT be used as-is to
+ validate NETCONF PDUs.
+ </xs:documentation>
+ </xs:annotation>
+
+ <xs:annotation>
+ <xs:documentation>
+ This module contains a collection of generally useful derived
+ YANG data types for Internet addresses and related things.
+
+ Copyright (c) 2010 IETF Trust and the persons identified as
+ authors of the code. All rights reserved.
+
+ Redistribution and use in source and binary forms, with or without
+ modification, is permitted pursuant to, and subject to the license
+ terms contained in, the Simplified BSD License set forth in Section
+ 4.c of the IETF Trust's Legal Provisions Relating to IETF Documents
+ (http://trustee.ietf.org/license-info).
+
+ This version of this YANG module is part of RFC 6021; see
+ the RFC itself for full legal notices.
+ </xs:documentation>
+ </xs:annotation>
+
+ <!-- YANG typedefs -->
+ <xs:simpleType name="ip-version">
+ <xs:annotation>
+ <xs:documentation>
+ This value represents the version of the IP protocol.
+
+ In the value set and its semantics, this type is equivalent
+ to the InetVersion textual convention of the SMIv2.
+ </xs:documentation>
+ </xs:annotation>
+
+ <xs:restriction base="xs:string">
+ <xs:enumeration value="unknown"/>
+ <xs:enumeration value="ipv4"/>
+ <xs:enumeration value="ipv6"/>
+ </xs:restriction>
+ </xs:simpleType>
+ <xs:simpleType name="dscp">
+ <xs:annotation>
+ <xs:documentation>
+ The dscp type represents a Differentiated Services Code-Point
+ that may be used for marking packets in a traffic stream.
+
+ In the value set and its semantics, this type is equivalent
+ to the Dscp textual convention of the SMIv2.
+ </xs:documentation>
+ </xs:annotation>
+
+ <xs:restriction base="xs:unsignedByte">
+ <xs:minInclusive value="0"/>
+ <xs:maxInclusive value="63"/>
+ </xs:restriction>
+ </xs:simpleType>
+ <xs:simpleType name="ipv6-flow-label">
+ <xs:annotation>
+ <xs:documentation>
+ The flow-label type represents flow identifier or Flow Label
+ in an IPv6 packet header that may be used to discriminate
+ traffic flows.
+
+ In the value set and its semantics, this type is equivalent
+ to the IPv6FlowLabel textual convention of the SMIv2.
+ </xs:documentation>
+ </xs:annotation>
+
+ <xs:restriction base="xs:unsignedInt">
+ <xs:minInclusive value="0"/>
+ <xs:maxInclusive value="1048575"/>
+ </xs:restriction>
+ </xs:simpleType>
+ <xs:simpleType name="port-number">
+ <xs:annotation>
+ <xs:documentation>
+ The port-number type represents a 16-bit port number of an
+ Internet transport layer protocol such as UDP, TCP, DCCP, or
+ SCTP. Port numbers are assigned by IANA. A current list of
+ all assignments is available from <http://www.iana.org/>.
+
+ Note that the port number value zero is reserved by IANA. In
+ situations where the value zero does not make sense, it can
+ be excluded by subtyping the port-number type.
+
+ In the value set and its semantics, this type is equivalent
+ to the InetPortNumber textual convention of the SMIv2.
+ </xs:documentation>
+ </xs:annotation>
+
+ <xs:restriction base="xs:unsignedShort">
+ <xs:minInclusive value="0"/>
+ <xs:maxInclusive value="65535"/>
+ </xs:restriction>
+ </xs:simpleType>
+ <xs:simpleType name="as-number">
+ <xs:annotation>
+ <xs:documentation>
+ The as-number type represents autonomous system numbers
+ which identify an Autonomous System (AS). An AS is a set
+ of routers under a single technical administration, using
+ an interior gateway protocol and common metrics to route
+ packets within the AS, and using an exterior gateway
+ protocol to route packets to other ASs'. IANA maintains
+ the AS number space and has delegated large parts to the
+ regional registries.
+
+ Autonomous system numbers were originally limited to 16
+ bits. BGP extensions have enlarged the autonomous system
+ number space to 32 bits. This type therefore uses an uint32
+ base type without a range restriction in order to support
+ a larger autonomous system number space.
+
+ In the value set and its semantics, this type is equivalent
+ to the InetAutonomousSystemNumber textual convention of
+ the SMIv2.
+ </xs:documentation>
+ </xs:annotation>
+
+ <xs:restriction base="xs:unsignedInt">
+ </xs:restriction>
+ </xs:simpleType>
+ <xs:simpleType name="ip-address">
+ <xs:annotation>
+ <xs:documentation>
+ The ip-address type represents an IP address and is IP
+ version neutral. The format of the textual representations
+ implies the IP version.
+ </xs:documentation>
+ </xs:annotation>
+
+ <xs:union>
+ <xs:simpleType>
+ <xs:restriction base="ipv4-address">
+ </xs:restriction>
+ </xs:simpleType>
+ <xs:simpleType>
+ <xs:restriction base="ipv6-address">
+ </xs:restriction>
+ </xs:simpleType>
+ </xs:union>
+ </xs:simpleType>
+ <xs:simpleType name="ipv4-address">
+ <xs:annotation>
+ <xs:documentation>
+ The ipv4-address type represents an IPv4 address in
+ dotted-quad notation. The IPv4 address may include a zone
+ index, separated by a % sign.
+
+ The zone index is used to disambiguate identical address
+ values. For link-local addresses, the zone index will
+ typically be the interface index number or the name of an
+ interface. If the zone index is not present, the default
+ zone of the device will be used.
+
+ The canonical format for the zone index is the numerical
+ format
+ </xs:documentation>
+ </xs:annotation>
+
+ <xs:restriction base="xs:string">
+ <xs:pattern value="(([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])(%[\p{N}\p{L}]+)?"/>
+ </xs:restriction>
+ </xs:simpleType>
+ <xs:simpleType name="ipv6-address">
+ <xs:annotation>
+ <xs:documentation>
+ The ipv6-address type represents an IPv6 address in full,
+ mixed, shortened, and shortened-mixed notation. The IPv6
+ address may include a zone index, separated by a % sign.
+
+ The zone index is used to disambiguate identical address
+ values. For link-local addresses, the zone index will
+ typically be the interface index number or the name of an
+ interface. If the zone index is not present, the default
+ zone of the device will be used.
+
+ The canonical format of IPv6 addresses uses the compressed
+ format described in RFC 4291, Section 2.2, item 2 with the
+ following additional rules: the :: substitution must be
+ applied to the longest sequence of all-zero 16-bit chunks
+ in an IPv6 address. If there is a tie, the first sequence
+ of all-zero 16-bit chunks is replaced by ::. Single
+ all-zero 16-bit chunks are not compressed. The canonical
+ format uses lowercase characters and leading zeros are
+ not allowed. The canonical format for the zone index is
+ the numerical format as described in RFC 4007, Section
+ 11.2.
+ </xs:documentation>
+ </xs:annotation>
+
+ <xs:restriction base="xs:string">
+ <xs:pattern value="(((:|[0-9a-fA-F]{0,4}):)([0-9a-fA-F]{0,4}:){0,5}((([0-9a-fA-F]{0,4}:)?(:|[0-9a-fA-F]{0,4}))|(((25[0-5]|2[0-4][0-9]|[01]?[0-9]?[0-9])\.){3}(25[0-5]|2[0-4][0-9]|[01]?[0-9]?[0-9])))(%[\p{N}\p{L}]+)?)|((([^:]+:){6}(([^:]+:[^:]+)|(.*\..*)))|((([^:]+:)*[^:]+)?::(([^:]+:)*[^:]+)?)(%.+)?)"/>
+ </xs:restriction>
+ </xs:simpleType>
+ <xs:simpleType name="ip-prefix">
+ <xs:annotation>
+ <xs:documentation>
+ The ip-prefix type represents an IP prefix and is IP
+ version neutral. The format of the textual representations
+ implies the IP version.
+ </xs:documentation>
+ </xs:annotation>
+
+ <xs:union>
+ <xs:simpleType>
+ <xs:restriction base="ipv4-prefix">
+ </xs:restriction>
+ </xs:simpleType>
+ <xs:simpleType>
+ <xs:restriction base="ipv6-prefix">
+ </xs:restriction>
+ </xs:simpleType>
+ </xs:union>
+ </xs:simpleType>
+ <xs:simpleType name="ipv4-prefix">
+ <xs:annotation>
+ <xs:documentation>
+ The ipv4-prefix type represents an IPv4 address prefix.
+ The prefix length is given by the number following the
+ slash character and must be less than or equal to 32.
+
+ A prefix length value of n corresponds to an IP address
+ mask that has n contiguous 1-bits from the most
+ significant bit (MSB) and all other bits set to 0.
+
+ The canonical format of an IPv4 prefix has all bits of
+ the IPv4 address set to zero that are not part of the
+ IPv4 prefix.
+ </xs:documentation>
+ </xs:annotation>
+
+ <xs:restriction base="xs:string">
+ <xs:pattern value="(([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])/(([0-9])|([1-2][0-9])|(3[0-2]))"/>
+ </xs:restriction>
+ </xs:simpleType>
+ <xs:simpleType name="ipv6-prefix">
+ <xs:annotation>
+ <xs:documentation>
+ The ipv6-prefix type represents an IPv6 address prefix.
+ The prefix length is given by the number following the
+ slash character and must be less than or equal 128.
+
+ A prefix length value of n corresponds to an IP address
+ mask that has n contiguous 1-bits from the most
+ significant bit (MSB) and all other bits set to 0.
+
+ The IPv6 address should have all bits that do not belong
+ to the prefix set to zero.
+
+ The canonical format of an IPv6 prefix has all bits of
+ the IPv6 address set to zero that are not part of the
+ IPv6 prefix. Furthermore, IPv6 address is represented
+ in the compressed format described in RFC 4291, Section
+ 2.2, item 2 with the following additional rules: the ::
+ substitution must be applied to the longest sequence of
+ all-zero 16-bit chunks in an IPv6 address. If there is
+ a tie, the first sequence of all-zero 16-bit chunks is
+ replaced by ::. Single all-zero 16-bit chunks are not
+ compressed. The canonical format uses lowercase
+ characters and leading zeros are not allowed.
+ </xs:documentation>
+ </xs:annotation>
+
+ <xs:restriction base="xs:string">
+ <xs:pattern value="(((:|[0-9a-fA-F]{0,4}):)([0-9a-fA-F]{0,4}:){0,5}((([0-9a-fA-F]{0,4}:)?(:|[0-9a-fA-F]{0,4}))|(((25[0-5]|2[0-4][0-9]|[01]?[0-9]?[0-9])\.){3}(25[0-5]|2[0-4][0-9]|[01]?[0-9]?[0-9])))(/(([0-9])|([0-9]{2})|(1[0-1][0-9])|(12[0-8]))))|((([^:]+:){6}(([^:]+:[^:]+)|(.*\..*)))|((([^:]+:)*[^:]+)?::(([^:]+:)*[^:]+)?)(/.+))"/>
+ </xs:restriction>
+ </xs:simpleType>
+ <xs:simpleType name="domain-name">
+ <xs:annotation>
+ <xs:documentation>
+ The domain-name type represents a DNS domain name. The
+ name SHOULD be fully qualified whenever possible.
+
+ Internet domain names are only loosely specified. Section
+ 3.5 of RFC 1034 recommends a syntax (modified in Section
+ 2.1 of RFC 1123). The pattern above is intended to allow
+ for current practice in domain name use, and some possible
+ future expansion. It is designed to hold various types of
+ domain names, including names used for A or AAAA records
+ (host names) and other records, such as SRV records. Note
+ that Internet host names have a stricter syntax (described
+ in RFC 952) than the DNS recommendations in RFCs 1034 and
+ 1123, and that systems that want to store host names in
+ schema nodes using the domain-name type are recommended to
+ adhere to this stricter standard to ensure interoperability.
+
+ The encoding of DNS names in the DNS protocol is limited
+ to 255 characters. Since the encoding consists of labels
+ prefixed by a length bytes and there is a trailing NULL
+ byte, only 253 characters can appear in the textual dotted
+ notation.
+
+ The description clause of schema nodes using the domain-name
+ type MUST describe when and how these names are resolved to
+ IP addresses. Note that the resolution of a domain-name value
+ may require to query multiple DNS records (e.g., A for IPv4
+ and AAAA for IPv6). The order of the resolution process and
+ which DNS record takes precedence can either be defined
+ explicitely or it may depend on the configuration of the
+ resolver.
+
+ Domain-name values use the US-ASCII encoding. Their canonical
+ format uses lowercase US-ASCII characters. Internationalized
+ domain names MUST be encoded in punycode as described in RFC
+ 3492
+ </xs:documentation>
+ </xs:annotation>
+
+ <xs:restriction base="t0">
+ <xs:minLength value="1"/>
+ <xs:maxLength value="253"/>
+ </xs:restriction>
+ </xs:simpleType>
+ <xs:simpleType name="host">
+ <xs:annotation>
+ <xs:documentation>
+ The host type represents either an IP address or a DNS
+ domain name.
+ </xs:documentation>
+ </xs:annotation>
+
+ <xs:union>
+ <xs:simpleType>
+ <xs:restriction base="ip-address">
+ </xs:restriction>
+ </xs:simpleType>
+ <xs:simpleType>
+ <xs:restriction base="domain-name">
+ </xs:restriction>
+ </xs:simpleType>
+ </xs:union>
+ </xs:simpleType>
+ <xs:simpleType name="uri">
+ <xs:annotation>
+ <xs:documentation>
+ The uri type represents a Uniform Resource Identifier
+ (URI) as defined by STD 66.
+
+ Objects using the uri type MUST be in US-ASCII encoding,
+ and MUST be normalized as described by RFC 3986 Sections
+ 6.2.1, 6.2.2.1, and 6.2.2.2. All unnecessary
+ percent-encoding is removed, and all case-insensitive
+ characters are set to lowercase except for hexadecimal
+ digits, which are normalized to uppercase as described in
+ Section 6.2.2.1.
+
+ The purpose of this normalization is to help provide
+ unique URIs. Note that this normalization is not
+ sufficient to provide uniqueness. Two URIs that are
+ textually distinct after this normalization may still be
+ equivalent.
+
+ Objects using the uri type may restrict the schemes that
+ they permit. For example, 'data:' and 'urn:' schemes
+ might not be appropriate.
+
+ A zero-length URI is not a valid URI. This can be used to
+ express 'URI absent' where required.
+
+ In the value set and its semantics, this type is equivalent
+ to the Uri SMIv2 textual convention defined in RFC 5017.
+ </xs:documentation>
+ </xs:annotation>
+
+ <xs:restriction base="xs:string">
+ </xs:restriction>
+ </xs:simpleType>
+
+
+ <!-- locally generated simpleType helpers -->
+
+ <xs:simpleType name="t0">
+ <xs:restriction base="xs:string">
+ <xs:pattern value="((([a-zA-Z0-9_]([a-zA-Z0-9\-_]){0,61})?[a-zA-Z0-9]\.)*([a-zA-Z0-9_]([a-zA-Z0-9\-_]){0,61})?[a-zA-Z0-9]\.?)|\."/>
+ </xs:restriction>
+ </xs:simpleType>
+
+</xs:schema>
--- /dev/null
+ module ietf-inet-types {
+
+ namespace "urn:ietf:params:xml:ns:yang:ietf-inet-types";
+ prefix "inet";
+
+ organization
+ "IETF NETMOD (NETCONF Data Modeling Language) Working Group";
+
+ contact
+ "WG Web: <http://tools.ietf.org/wg/netmod/>
+ WG List: <mailto:netmod@ietf.org>
+
+ WG Chair: David Partain
+ <mailto:david.partain@ericsson.com>
+
+ WG Chair: David Kessens
+ <mailto:david.kessens@nsn.com>
+
+ Editor: Juergen Schoenwaelder
+ <mailto:j.schoenwaelder@jacobs-university.de>";
+
+ description
+ "This module contains a collection of generally useful derived
+ YANG data types for Internet addresses and related things.
+
+ Copyright (c) 2010 IETF Trust and the persons identified as
+ authors of the code. All rights reserved.
+
+ Redistribution and use in source and binary forms, with or without
+ modification, is permitted pursuant to, and subject to the license
+ terms contained in, the Simplified BSD License set forth in Section
+ 4.c of the IETF Trust's Legal Provisions Relating to IETF Documents
+ (http://trustee.ietf.org/license-info).
+
+ This version of this YANG module is part of RFC 6021; see
+ the RFC itself for full legal notices.";
+
+ revision 2010-09-24 {
+ description
+ "Initial revision.";
+ reference
+ "RFC 6021: Common YANG Data Types";
+ }
+
+ /*** collection of protocol field related types ***/
+
+ typedef ip-version {
+ type enumeration {
+ enum unknown {
+ value "0";
+ description
+ "An unknown or unspecified version of the Internet protocol.";
+ }
+ enum ipv4 {
+ value "1";
+ description
+ "The IPv4 protocol as defined in RFC 791.";
+ }
+ enum ipv6 {
+ value "2";
+ description
+ "The IPv6 protocol as defined in RFC 2460.";
+ }
+ }
+ description
+ "This value represents the version of the IP protocol.
+
+ In the value set and its semantics, this type is equivalent
+ to the InetVersion textual convention of the SMIv2.";
+ reference
+ "RFC 791: Internet Protocol
+ RFC 2460: Internet Protocol, Version 6 (IPv6) Specification
+ RFC 4001: Textual Conventions for Internet Network Addresses";
+ }
+
+ typedef dscp {
+ type uint8 {
+ range "0..63";
+ }
+ description
+ "The dscp type represents a Differentiated Services Code-Point
+ that may be used for marking packets in a traffic stream.
+
+ In the value set and its semantics, this type is equivalent
+ to the Dscp textual convention of the SMIv2.";
+ reference
+ "RFC 3289: Management Information Base for the Differentiated
+ Services Architecture
+ RFC 2474: Definition of the Differentiated Services Field
+ (DS Field) in the IPv4 and IPv6 Headers
+ RFC 2780: IANA Allocation Guidelines For Values In
+ the Internet Protocol and Related Headers";
+ }
+
+ typedef ipv6-flow-label {
+ type uint32 {
+ range "0..1048575";
+ }
+ description
+ "The flow-label type represents flow identifier or Flow Label
+ in an IPv6 packet header that may be used to discriminate
+ traffic flows.
+
+ In the value set and its semantics, this type is equivalent
+ to the IPv6FlowLabel textual convention of the SMIv2.";
+ reference
+ "RFC 3595: Textual Conventions for IPv6 Flow Label
+ RFC 2460: Internet Protocol, Version 6 (IPv6) Specification";
+ }
+
+ typedef port-number {
+ type uint16 {
+ range "0..65535";
+ }
+ description
+ "The port-number type represents a 16-bit port number of an
+ Internet transport layer protocol such as UDP, TCP, DCCP, or
+ SCTP. Port numbers are assigned by IANA. A current list of
+ all assignments is available from <http://www.iana.org/>.
+
+ Note that the port number value zero is reserved by IANA. In
+ situations where the value zero does not make sense, it can
+ be excluded by subtyping the port-number type.
+
+ In the value set and its semantics, this type is equivalent
+ to the InetPortNumber textual convention of the SMIv2.";
+ reference
+ "RFC 768: User Datagram Protocol
+ RFC 793: Transmission Control Protocol
+ RFC 4960: Stream Control Transmission Protocol
+ RFC 4340: Datagram Congestion Control Protocol (DCCP)
+ RFC 4001: Textual Conventions for Internet Network Addresses";
+ }
+
+ /*** collection of autonomous system related types ***/
+
+ typedef as-number {
+ type uint32;
+ description
+ "The as-number type represents autonomous system numbers
+ which identify an Autonomous System (AS). An AS is a set
+ of routers under a single technical administration, using
+ an interior gateway protocol and common metrics to route
+ packets within the AS, and using an exterior gateway
+ protocol to route packets to other ASs'. IANA maintains
+ the AS number space and has delegated large parts to the
+ regional registries.
+
+ Autonomous system numbers were originally limited to 16
+ bits. BGP extensions have enlarged the autonomous system
+ number space to 32 bits. This type therefore uses an uint32
+ base type without a range restriction in order to support
+ a larger autonomous system number space.
+
+ In the value set and its semantics, this type is equivalent
+ to the InetAutonomousSystemNumber textual convention of
+ the SMIv2.";
+ reference
+ "RFC 1930: Guidelines for creation, selection, and registration
+ of an Autonomous System (AS)
+ RFC 4271: A Border Gateway Protocol 4 (BGP-4)
+ RFC 4893: BGP Support for Four-octet AS Number Space
+ RFC 4001: Textual Conventions for Internet Network Addresses";
+ }
+
+ /*** collection of IP address and hostname related types ***/
+
+ typedef ip-address {
+ type union {
+ type inet:ipv4-address;
+ type inet:ipv6-address;
+ }
+ description
+ "The ip-address type represents an IP address and is IP
+ version neutral. The format of the textual representations
+ implies the IP version.";
+ }
+
+ typedef ipv4-address {
+ type string {
+ pattern
+ '(([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])\.){3}'
+ + '([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])'
+ + '(%[\p{N}\p{L}]+)?';
+ }
+ description
+ "The ipv4-address type represents an IPv4 address in
+ dotted-quad notation. The IPv4 address may include a zone
+ index, separated by a % sign.
+
+ The zone index is used to disambiguate identical address
+ values. For link-local addresses, the zone index will
+ typically be the interface index number or the name of an
+ interface. If the zone index is not present, the default
+ zone of the device will be used.
+
+ The canonical format for the zone index is the numerical
+ format";
+ }
+
+ typedef ipv6-address {
+ type string {
+ pattern '((:|[0-9a-fA-F]{0,4}):)([0-9a-fA-F]{0,4}:){0,5}'
+ + '((([0-9a-fA-F]{0,4}:)?(:|[0-9a-fA-F]{0,4}))|'
+ + '(((25[0-5]|2[0-4][0-9]|[01]?[0-9]?[0-9])\.){3}'
+ + '(25[0-5]|2[0-4][0-9]|[01]?[0-9]?[0-9])))'
+ + '(%[\p{N}\p{L}]+)?';
+ pattern '(([^:]+:){6}(([^:]+:[^:]+)|(.*\..*)))|'
+ + '((([^:]+:)*[^:]+)?::(([^:]+:)*[^:]+)?)'
+ + '(%.+)?';
+ }
+ description
+ "The ipv6-address type represents an IPv6 address in full,
+ mixed, shortened, and shortened-mixed notation. The IPv6
+ address may include a zone index, separated by a % sign.
+
+ The zone index is used to disambiguate identical address
+ values. For link-local addresses, the zone index will
+ typically be the interface index number or the name of an
+ interface. If the zone index is not present, the default
+ zone of the device will be used.
+
+ The canonical format of IPv6 addresses uses the compressed
+ format described in RFC 4291, Section 2.2, item 2 with the
+ following additional rules: the :: substitution must be
+ applied to the longest sequence of all-zero 16-bit chunks
+ in an IPv6 address. If there is a tie, the first sequence
+ of all-zero 16-bit chunks is replaced by ::. Single
+ all-zero 16-bit chunks are not compressed. The canonical
+ format uses lowercase characters and leading zeros are
+ not allowed. The canonical format for the zone index is
+ the numerical format as described in RFC 4007, Section
+ 11.2.";
+ reference
+ "RFC 4291: IP Version 6 Addressing Architecture
+ RFC 4007: IPv6 Scoped Address Architecture
+ RFC 5952: A Recommendation for IPv6 Address Text Representation";
+ }
+
+ typedef ip-prefix {
+ type union {
+ type inet:ipv4-prefix;
+ type inet:ipv6-prefix;
+ }
+ description
+ "The ip-prefix type represents an IP prefix and is IP
+ version neutral. The format of the textual representations
+ implies the IP version.";
+ }
+
+ typedef ipv4-prefix {
+ type string {
+ pattern
+ '(([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])\.){3}'
+ + '([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])'
+ + '/(([0-9])|([1-2][0-9])|(3[0-2]))';
+ }
+ description
+ "The ipv4-prefix type represents an IPv4 address prefix.
+ The prefix length is given by the number following the
+ slash character and must be less than or equal to 32.
+
+ A prefix length value of n corresponds to an IP address
+ mask that has n contiguous 1-bits from the most
+ significant bit (MSB) and all other bits set to 0.
+
+ The canonical format of an IPv4 prefix has all bits of
+ the IPv4 address set to zero that are not part of the
+ IPv4 prefix.";
+ }
+
+ typedef ipv6-prefix {
+ type string {
+ pattern '((:|[0-9a-fA-F]{0,4}):)([0-9a-fA-F]{0,4}:){0,5}'
+ + '((([0-9a-fA-F]{0,4}:)?(:|[0-9a-fA-F]{0,4}))|'
+ + '(((25[0-5]|2[0-4][0-9]|[01]?[0-9]?[0-9])\.){3}'
+ + '(25[0-5]|2[0-4][0-9]|[01]?[0-9]?[0-9])))'
+ + '(/(([0-9])|([0-9]{2})|(1[0-1][0-9])|(12[0-8])))';
+ pattern '(([^:]+:){6}(([^:]+:[^:]+)|(.*\..*)))|'
+ + '((([^:]+:)*[^:]+)?::(([^:]+:)*[^:]+)?)'
+ + '(/.+)';
+ }
+ description
+ "The ipv6-prefix type represents an IPv6 address prefix.
+ The prefix length is given by the number following the
+ slash character and must be less than or equal 128.
+
+ A prefix length value of n corresponds to an IP address
+ mask that has n contiguous 1-bits from the most
+ significant bit (MSB) and all other bits set to 0.
+
+ The IPv6 address should have all bits that do not belong
+ to the prefix set to zero.
+
+ The canonical format of an IPv6 prefix has all bits of
+ the IPv6 address set to zero that are not part of the
+ IPv6 prefix. Furthermore, IPv6 address is represented
+ in the compressed format described in RFC 4291, Section
+ 2.2, item 2 with the following additional rules: the ::
+ substitution must be applied to the longest sequence of
+ all-zero 16-bit chunks in an IPv6 address. If there is
+ a tie, the first sequence of all-zero 16-bit chunks is
+ replaced by ::. Single all-zero 16-bit chunks are not
+ compressed. The canonical format uses lowercase
+ characters and leading zeros are not allowed.";
+ reference
+ "RFC 4291: IP Version 6 Addressing Architecture";
+ }
+
+ /*** collection of domain name and URI types ***/
+
+ typedef domain-name {
+ type string {
+ pattern '((([a-zA-Z0-9_]([a-zA-Z0-9\-_]){0,61})?[a-zA-Z0-9]\.)*'
+ + '([a-zA-Z0-9_]([a-zA-Z0-9\-_]){0,61})?[a-zA-Z0-9]\.?)'
+ + '|\.';
+ length "1..253";
+ }
+ description
+ "The domain-name type represents a DNS domain name. The
+ name SHOULD be fully qualified whenever possible.
+
+ Internet domain names are only loosely specified. Section
+ 3.5 of RFC 1034 recommends a syntax (modified in Section
+ 2.1 of RFC 1123). The pattern above is intended to allow
+ for current practice in domain name use, and some possible
+ future expansion. It is designed to hold various types of
+ domain names, including names used for A or AAAA records
+ (host names) and other records, such as SRV records. Note
+ that Internet host names have a stricter syntax (described
+ in RFC 952) than the DNS recommendations in RFCs 1034 and
+ 1123, and that systems that want to store host names in
+ schema nodes using the domain-name type are recommended to
+ adhere to this stricter standard to ensure interoperability.
+
+ The encoding of DNS names in the DNS protocol is limited
+ to 255 characters. Since the encoding consists of labels
+ prefixed by a length bytes and there is a trailing NULL
+ byte, only 253 characters can appear in the textual dotted
+ notation.
+
+ The description clause of schema nodes using the domain-name
+ type MUST describe when and how these names are resolved to
+ IP addresses. Note that the resolution of a domain-name value
+ may require to query multiple DNS records (e.g., A for IPv4
+ and AAAA for IPv6). The order of the resolution process and
+ which DNS record takes precedence can either be defined
+ explicitely or it may depend on the configuration of the
+ resolver.
+
+ Domain-name values use the US-ASCII encoding. Their canonical
+ format uses lowercase US-ASCII characters. Internationalized
+ domain names MUST be encoded in punycode as described in RFC
+ 3492";
+ reference
+ "RFC 952: DoD Internet Host Table Specification
+ RFC 1034: Domain Names - Concepts and Facilities
+ RFC 1123: Requirements for Internet Hosts -- Application
+ and Support
+ RFC 2782: A DNS RR for specifying the location of services
+ (DNS SRV)
+ RFC 3492: Punycode: A Bootstring encoding of Unicode for
+ Internationalized Domain Names in Applications
+ (IDNA)
+ RFC 5891: Internationalizing Domain Names in Applications
+ (IDNA): Protocol";
+ }
+
+ typedef host {
+ type union {
+ type inet:ip-address;
+ type inet:domain-name;
+ }
+ description
+ "The host type represents either an IP address or a DNS
+ domain name.";
+ }
+
+ typedef uri {
+ type string;
+ description
+ "The uri type represents a Uniform Resource Identifier
+ (URI) as defined by STD 66.
+
+ Objects using the uri type MUST be in US-ASCII encoding,
+ and MUST be normalized as described by RFC 3986 Sections
+ 6.2.1, 6.2.2.1, and 6.2.2.2. All unnecessary
+ percent-encoding is removed, and all case-insensitive
+ characters are set to lowercase except for hexadecimal
+ digits, which are normalized to uppercase as described in
+ Section 6.2.2.1.
+
+ The purpose of this normalization is to help provide
+ unique URIs. Note that this normalization is not
+ sufficient to provide uniqueness. Two URIs that are
+ textually distinct after this normalization may still be
+ equivalent.
+
+ Objects using the uri type may restrict the schemes that
+ they permit. For example, 'data:' and 'urn:' schemes
+ might not be appropriate.
+
+ A zero-length URI is not a valid URI. This can be used to
+ express 'URI absent' where required.
+
+ In the value set and its semantics, this type is equivalent
+ to the Uri SMIv2 textual convention defined in RFC 5017.";
+ reference
+ "RFC 3986: Uniform Resource Identifier (URI): Generic Syntax
+ RFC 3305: Report from the Joint W3C/IETF URI Planning Interest
+ Group: Uniform Resource Identifiers (URIs), URLs,
+ and Uniform Resource Names (URNs): Clarifications
+ and Recommendations
+ RFC 5017: MIB Textual Conventions for Uniform Resource
+ Identifiers (URIs)";
+ }
+
+ }
private List<UnknownSchemaNode> unknownSchemaNodes = Collections
.emptyList();
private Status status = Status.CURRENT;
- private String units = "";
+ private String units = null;
private Object defaultValue = null;
private boolean addedByUses;