--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- vi: set et smarttab sw=4 tabstop=4: -->
+<!--
+ Copyright (c) 2016 Red Hat, 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
+-->
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+
+ <parent>
+ <groupId>org.opendaylight.odlparent</groupId>
+ <artifactId>odlparent</artifactId>
+ <version>1.8.0-SNAPSHOT</version>
+ <relativePath />
+ </parent>
+
+ <groupId>org.opendaylight.mdsal</groupId>
+ <artifactId>mdsal-binding-test-utils</artifactId>
+ <version>2.2.0-SNAPSHOT</version>
+
+ <dependencyManagement>
+ <dependencies>
+ <dependency>
+ <groupId>org.opendaylight.mdsal</groupId>
+ <artifactId>mdsal-artifacts</artifactId>
+ <version>${project.version}</version>
+ <type>pom</type>
+ <scope>import</scope>
+ </dependency>
+ </dependencies>
+ </dependencyManagement>
+
+ <dependencies>
+ <!-- NB: All of these are, intentionally, NOT <scope>test</scope>,
+ because downstream consumer projects of the test utilities
+ will necessarily also require these dependencies in order
+ to run tests such as the AssertDataObjectsTest. -->
+ <dependency>
+ <groupId>junit</groupId>
+ <artifactId>junit</artifactId>
+ <scope>compile</scope>
+ </dependency>
+ <dependency>
+ <groupId>ch.vorburger</groupId>
+ <artifactId>xtendbeans</artifactId>
+ <scope>compile</scope>
+ <version>1.2.0</version>
+ </dependency>
+ <dependency>
+ <groupId>org.opendaylight.mdsal</groupId>
+ <artifactId>mdsal-binding-dom-adapter</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.opendaylight.mdsal</groupId>
+ <artifactId>mdsal-binding-dom-adapter</artifactId>
+ <type>test-jar</type>
+ </dependency>
+ <!-- The following are dependencies which are listed
+ as scope test in mdsal-binding-dom-adapter; we
+ wanted most of them as scope compile here... -->
+ <dependency>
+ <groupId>org.opendaylight.mdsal</groupId>
+ <artifactId>mdsal-dom-broker</artifactId>
+ </dependency>
+
+ <!-- The following, contrary to the above, ARE <scope>test,
+ because they are only required by the test utilities
+ self test code in src/test, but not (necessarily)
+ by a downstream consumer of the test utilities. -->
+ <dependency>
+ <groupId>org.opendaylight.mdsal</groupId>
+ <artifactId>mdsal-binding-test-model</artifactId>
+ <scope>test</scope>
+ </dependency>
+ </dependencies>
+
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-checkstyle-plugin</artifactId>
+ <configuration>
+ <propertyExpansion>checkstyle.violationSeverity=error</propertyExpansion>
+ </configuration>
+ </plugin>
+ </plugins>
+ </build>
+
+ <!--
+ Maven Site Configuration
+
+ The following configuration is necessary for maven-site-plugin to
+ correctly identify the correct deployment path for OpenDaylight Maven
+ sites.
+ -->
+ <url>${odl.site.url}/${project.groupId}/${stream}/${project.artifactId}/</url>
+
+ <distributionManagement>
+ <site>
+ <id>opendaylight-site</id>
+ <url>${nexus.site.url}/${project.artifactId}/</url>
+ </site>
+ </distributionManagement>
+
+</project>
--- /dev/null
+/*
+ * Copyright (c) 2016 Red Hat, 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.mdsal.binding.testutils;
+
+import ch.vorburger.xtendbeans.AssertBeans;
+import org.junit.ComparisonFailure;
+import org.opendaylight.yangtools.yang.binding.DataObject;
+
+/**
+ * Assertion utilities for YANG {@link DataObject}s.
+ *
+ * <p>This compares two {@link DataObject}s by creating a textual representation of them,
+ * and comparing them. If they are not equals, then the thrown ComparisonFailure provides
+ * for a very highly readable comparison due to a syntax which immediately makes the difference obvious.
+ *
+ * <p>The syntax used happens to be valid Xtend code, and as such could be directly copy/pasted
+ * into an *.xtend source file of an expected object definition. This is optional though; this
+ * utility can very well be used with any object, not necessarily created by Xtend source code.
+ *
+ * <p>This also works for any Java object that is not a {@link DataObject},
+ * like the {@link AssertBeans} which this is based upon.
+ *
+ * @see AssertBeans for more background
+ *
+ * @author Michael Vorburger
+ */
+public final class AssertDataObjects {
+
+ private static final XtendYangBeanGenerator GENERATOR = new XtendYangBeanGenerator();
+
+ private AssertDataObjects() {
+ }
+
+ /**
+ * Assert that an actual YANG DataObject (DataContainer) is equals to an expected one.
+ *
+ * <p>The argument types are intentionally of type Object instead of YANG DataContainer or DataObject.
+ * This is important so that this can be directly used on e.g. a List or Map etc. of DataObjects.
+ *
+ * @param expected the expected object
+ * @param actual the actual object to check against <code>expected</code>
+ *
+ * @see AssertBeans#assertEqualBeans(Object, Object)
+ */
+ public static void assertEqualBeans(Object expected, Object actual) throws ComparisonFailure {
+ String expectedText = GENERATOR.getExpression(expected);
+ assertEqualByText(expectedText, actual);
+ }
+
+ // package local method used only in the self tests of this utility (not intended for usage by client code)
+ static void assertEqualByText(String expectedText, Object actual) throws ComparisonFailure {
+ String actualText = GENERATOR.getExpression(actual);
+ if (!expectedText.equals(actualText)) {
+ throw new ComparisonFailure("Expected and actual beans do not match", expectedText, actualText);
+ }
+ }
+
+}
--- /dev/null
+/*
+ * Copyright (c) 2016 Red Hat, 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.mdsal.binding.testutils;
+
+import com.google.common.collect.ClassToInstanceMap;
+import com.google.common.collect.ImmutableClassToInstanceMap;
+import java.lang.reflect.InvocationHandler;
+import java.lang.reflect.Proxy;
+import org.eclipse.xtext.xbase.lib.util.ReflectExtensions;
+import org.opendaylight.yangtools.binding.data.codec.util.AugmentationReader;
+import org.opendaylight.yangtools.yang.binding.Augmentable;
+import org.opendaylight.yangtools.yang.binding.Augmentation;
+
+/**
+ * Adds an {@link #getAugmentations(Augmentable)} method to {@link Augmentable}.
+ *
+ * <p>Note that the generated *Impl classes in the *Builder do not implement
+ * {@link AugmentationReader}, only the LazyDataObject (package local) does.
+ *
+ * @see Augmentable
+ * @see AugmentationReader
+ *
+ * @author Michael Vorburger
+ */
+//package-local: no need to expose this, consider it an implementation detail; public API is the AssertDataObjects
+class AugmentableExtension {
+
+ private static final ReflectExtensions REFLECT_EXTENSIONS = new ReflectExtensions();
+
+ public ClassToInstanceMap<Augmentation<?>> getAugmentations(Augmentable<?> augmentable) {
+ if (augmentable instanceof AugmentationReader) {
+ AugmentationReader augmentationReader = (AugmentationReader) augmentable;
+ return ImmutableClassToInstanceMap.copyOf(augmentationReader.getAugmentations(augmentable));
+ } else if (Proxy.isProxyClass(augmentable.getClass())) {
+ InvocationHandler invocationHandler = Proxy.getInvocationHandler(augmentable);
+ // class LazyDataObject implements InvocationHandler, AugmentationReader
+ AugmentationReader augmentationReader = (AugmentationReader) invocationHandler;
+ return ImmutableClassToInstanceMap.copyOf(augmentationReader.getAugmentations(augmentable));
+ } else {
+ try {
+ return ImmutableClassToInstanceMap.copyOf(REFLECT_EXTENSIONS.get(augmentable, "augmentation"));
+ } catch (ClassCastException | SecurityException | NoSuchFieldException | IllegalArgumentException
+ | IllegalAccessException e) {
+ throw new IllegalArgumentException("TODO Implement getAugmentations() for an Augmentable which "
+ + "is neither a (Proxy of an) AugmentationReader nor has an internal field named "
+ + "'augmentation': " + augmentable.getClass(), e);
+ }
+ }
+ }
+
+}
--- /dev/null
+/**
+ * Copyright (c) 2016 Red Hat, 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.mdsal.binding.testutils;
+
+import org.eclipse.xtext.xbase.lib.Procedures.Procedure1;
+import org.opendaylight.yangtools.concepts.Builder;
+
+/**
+ * Xtend extension method for >> operator support for {@link Builder}s.
+ *
+ * <pre>import static extension org.opendaylight.mdsal.binding.testutils
+ * .XtendBuilderExtensions.operator_doubleGreaterThan</pre>
+ *
+ * <p>allows to write (in an *.xtend, not *.java):
+ *
+ * <pre>new InterfaceBuilder >> [
+ * name = "hello, world"
+ * ]</pre>
+ *
+ * <p>instead of:
+ *
+ * <pre>(new InterfaceBuilder => [
+ * name = "hello, world"
+ * ]).build</pre>
+ *
+ * <p>See also org.eclipse.xtext.xbase.lib.ObjectExtensions.operator_doubleArrow for background.
+ *
+ * @author Michael Vorburger
+ */
+public final class XtendBuilderExtensions {
+
+ private XtendBuilderExtensions() { }
+
+ public static <P extends Object, T extends Builder<P>> P operator_doubleGreaterThan(
+ final T object, final Procedure1<? super T> block) {
+
+ block.apply(object);
+ return object.build();
+ }
+
+}
--- /dev/null
+/*
+ * Copyright (c) 2016 Red Hat, 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.mdsal.binding.testutils;
+
+import ch.vorburger.xtendbeans.XtendBeanGenerator;
+import com.google.common.collect.ClassToInstanceMap;
+import com.google.common.collect.Iterables;
+import java.util.Optional;
+import org.opendaylight.yangtools.yang.binding.Augmentable;
+import org.opendaylight.yangtools.yang.binding.Augmentation;
+import org.opendaylight.yangtools.yang.binding.DataContainer;
+import org.opendaylight.yangtools.yang.binding.DataObject;
+
+/**
+ * {@link XtendBeanGenerator} customized for YANG beans stored in MD SAL
+ * DataBroker.
+ *
+ * <p>This is required: (a) because YANG model DataObject beans (when read from a
+ * DataBroker) are funky java.lang.reflect.Proxy instances, and XtendBeanGenerator
+ * cannot find the Builder or the property getters for them without a bit of help,
+ * which this class provides;
+ *
+ * <p>(b) to integrate it with the {@link XtendBuilderExtensions}
+ * (for ">>" instead of "->" and no build() method calls);
+ *
+ * <p>(c) to integrate it with the {@link AugmentableExtension}.
+ *
+ * @see XtendBeanGenerator
+ *
+ * @author Michael Vorburger
+ */
+// package-local: no need to expose this, consider it an implementation detail; public API is the AssertDataObjects
+class XtendYangBeanGenerator extends XtendBeanGenerator {
+
+ private final AugmentableExtension augmentableExtension = new AugmentableExtension();
+
+ private boolean useBuilderExtensions(Object bean) {
+ return bean instanceof DataObject;
+ }
+
+ @Override
+ public String getExpression(Object bean) {
+ final String beanText = super.getExpression(bean);
+ if (useBuilderExtensions(bean)) {
+ return new StringBuilder("import static extension ").append(XtendBuilderExtensions.class.getName())
+ .append(".operator_doubleGreaterThan\n\n").append(beanText).toString();
+ } else {
+ return beanText;
+ }
+ }
+
+ @Override
+ protected boolean isUsingBuilder(Object bean, Class<?> builderClass) {
+ if (useBuilderExtensions(bean)) {
+ return false;
+ } else {
+ return super.isUsingBuilder(bean, builderClass);
+ }
+ }
+
+ @Override
+ protected String getOperator(Object bean, Class<?> builderClass) {
+ if (useBuilderExtensions(bean)) {
+ return ">>";
+ } else {
+ return super.getOperator(bean, builderClass);
+ }
+ }
+
+ @Override
+ protected CharSequence getNewBeanExpression(Object bean) {
+ if (bean instanceof DataContainer) {
+ DataContainer dataContainerBean = (DataContainer) bean;
+ Class<?> builderClass = getBuilderClassByAppendingBuilderToClassName(
+ dataContainerBean.getImplementedInterface());
+ return super.getNewBeanExpression(dataContainerBean, builderClass);
+ } else {
+ return super.getNewBeanExpression(bean);
+ }
+ }
+
+ @Override
+ protected String stringify(Class<?> klass) {
+ return klass.getSimpleName();
+ }
+
+ @Override
+ protected Iterable<Property> filter(Iterable<Property> properties) {
+ // YANG keys duplicate existing other properties (there are getter/setter for both), so filter them
+ return Iterables.filter(properties, property -> !property.getName().equals("key"));
+ }
+
+ private Optional<ClassToInstanceMap<Augmentation<?>>> getAugmentations(Object bean) {
+ if (bean instanceof Augmentable<?>) {
+ Augmentable<?> augmentable = (Augmentable<?>) bean;
+ ClassToInstanceMap<Augmentation<?>> augmentables = augmentableExtension.getAugmentations(augmentable);
+ if (!augmentables.isEmpty()) {
+ return Optional.of(augmentables);
+ }
+ }
+ return Optional.empty();
+ }
+
+ @Override
+ protected CharSequence getAdditionalInitializationExpression(Object bean, Class<?> builderClass) {
+ Optional<ClassToInstanceMap<Augmentation<?>>> optional = getAugmentations(bean);
+ if (optional.isPresent()) {
+ StringBuilder sb = new StringBuilder();
+ optional.get().forEach((klass, augmentation) -> {
+ sb.append("addAugmentation(");
+ sb.append(stringify(klass));
+ sb.append(", ");
+ sb.append(getNewBeanExpression(augmentation));
+ sb.append(")");
+ });
+ return sb;
+ } else {
+ return "";
+ }
+ }
+
+/*
+ TODO activate this once YANG objects either have a setAugmentations(Map)
+ or implement a new TBD interface AugmentableBuilder with a method like:
+ <E extends Augmentation<T>> Builder? addAugmentation(Class<E> augmentationType, E augmentation);
+ which an extension method could jump on.
+
+ @Override
+ public Iterable<Property> getAdditionalSpecialProperties(Object bean, Class<?> builderClass) {
+ Optional<ClassToInstanceMap<Augmentation<?>>> optional = getAugmentations(bean);
+ if (optional.isPresent()) {
+ Property augmentableProperty = new Property("augmentations", true, Map.class, () -> optional.get(), null);
+ return Collections.singleton(augmentableProperty);
+ } else {
+ return Collections.emptyList();
+ }
+ }
+ */
+
+}
--- /dev/null
+/*
+ * Copyright (c) 2016 Red Hat, 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.mdsal.binding.testutils;
+
+import static org.opendaylight.mdsal.common.api.LogicalDatastoreType.OPERATIONAL;
+
+import java.util.Map;
+import org.junit.Test;
+import org.opendaylight.mdsal.binding.api.ReadTransaction;
+import org.opendaylight.mdsal.binding.api.WriteTransaction;
+import org.opendaylight.mdsal.binding.dom.adapter.test.AbstractDataBrokerTest;
+import org.opendaylight.mdsal.common.api.LogicalDatastoreType;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.mdsal.test.binding.rev140701.Top;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.mdsal.test.binding.rev140701.two.level.list.TopLevelListKey;
+import org.opendaylight.yangtools.yang.binding.DataObject;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+
+/**
+ * Tests the {@link AssertDataObjects} utility.
+ *
+ * @author Michael Vorburger
+ */
+public class AssertDataObjectsTest extends AbstractDataBrokerTest {
+
+ private static final String HEADER = "import static extension org.opendaylight.mdsal.binding.testutils."
+ + "XtendBuilderExtensions.operator_doubleGreaterThan\n\n";
+
+ @Test
+ public void testAssertDataObjectsWithTopLevelListKey() {
+ AssertDataObjects.assertEqualByText("new TopLevelListKey(\"test\")\n", new TopLevelListKey("test"));
+ }
+
+ @Test
+ public void testAssertDataObjectsWithEmptyTop() {
+ AssertDataObjects.assertEqualByText(HEADER + "new TopBuilder\n", ExampleYangObjects.topEmpty().getValue());
+ }
+
+ @Test
+ public void testAssertDataObjectsWithComplexTopWithKey() {
+ AssertDataObjects.assertEqualByText(HEADER + "new TopBuilder >> [\n"
+ + " topLevelList = #[\n"
+ + " new TopLevelListBuilder >> [\n"
+ + " name = \"foo\"\n"
+ + " addAugmentation(TreeComplexUsesAugment, new TreeComplexUsesAugmentBuilder >> [\n"
+ + " containerWithUses = new ContainerWithUsesBuilder >> [\n"
+ + " leafFromGrouping = \"foo\"\n"
+ + " ]\n"
+ + " ])\n"
+ + " ]\n"
+ + " ]\n"
+ + "]", ExpectedObjects.top());
+ }
+
+ @Test
+ public void testAssertDataObjectsWithTopLevelList() {
+ AssertDataObjects.assertEqualBeans(ExpectedObjects.topLevelList(),
+ ExampleYangObjects.topLevelList().getValue());
+ AssertDataObjects.assertEqualByText(HEADER + "new TopLevelListBuilder >> [\n"
+ + " name = \"foo\"\n"
+ + " addAugmentation(TreeComplexUsesAugment, new TreeComplexUsesAugmentBuilder >> [\n"
+ + " containerWithUses = new ContainerWithUsesBuilder >> [\n"
+ + " leafFromGrouping = \"foo\"\n"
+ + " ]\n"
+ + " ])\n"
+ + "]", ExampleYangObjects.topLevelList().getValue());
+ }
+
+ @Test
+ public void testAssertDataObjectsWithDataBroker() throws Exception {
+ WriteTransaction initialTx = getDataBroker().newWriteOnlyTransaction();
+ put(initialTx, OPERATIONAL, ExampleYangObjects.topEmpty());
+ put(initialTx, OPERATIONAL, ExampleYangObjects.topLevelList());
+ initialTx.submit().checkedGet();
+
+ ReadTransaction readTx = getDataBroker().newReadOnlyTransaction();
+ InstanceIdentifier<Top> id = InstanceIdentifier.create(Top.class);
+ Top actualTop = readTx.read(OPERATIONAL, id).checkedGet().get();
+
+ AssertDataObjects.assertEqualBeans(ExpectedObjects.top(), actualTop);
+
+ String expectedTopText = "import static extension org.opendaylight.mdsal.binding.testutils."
+ + "XtendBuilderExtensions.operator_doubleGreaterThan\n\n"
+ + "new TopBuilder >> [\n"
+ + " topLevelList = #[\n"
+ + " new TopLevelListBuilder >> [\n"
+ + " name = \"foo\"\n"
+ + " addAugmentation(TreeComplexUsesAugment, new TreeComplexUsesAugmentBuilder >> [\n"
+ + " containerWithUses = new ContainerWithUsesBuilder >> [\n"
+ + " leafFromGrouping = \"foo\"\n"
+ + " ]\n"
+ + " ])\n"
+ + " ]\n"
+ + " ]\n"
+ + "]";
+ AssertDataObjects.assertEqualByText(expectedTopText, actualTop);
+ }
+
+ <T extends DataObject> void put(WriteTransaction tx, LogicalDatastoreType store,
+ Map.Entry<InstanceIdentifier<T>, T> obj) {
+ tx.put(OPERATIONAL, obj.getKey(), obj.getValue());
+ }
+
+}
--- /dev/null
+/*
+ * Copyright (c) 2016 Red Hat, 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.mdsal.binding.testutils;
+
+import ch.vorburger.xtendbeans.AssertBeans;
+import org.junit.Test;
+import org.opendaylight.yangtools.yang.binding.DataObject;
+
+/**
+ * Tests that the {@link AssertDataObjects} utility also works for any Java
+ * object that is not a {@link DataObject}, like the {@link AssertBeans} which
+ * it's based on. There is absolutely no particular reason why it wouldn't,
+ * because {@link AssertDataObjects} is essentially just a customization of
+ * {@link AssertBeans} - this is just to make sure none of the base
+ * functionality gets broken in the customization.
+ *
+ * @author Michael Vorburger
+ */
+public class AssertNonDataObjectsTest {
+
+ public static class SomeBean {
+ private String name;
+
+ public String getName() {
+ return name;
+ }
+
+ public void setName(String name) {
+ this.name = name;
+ }
+ }
+
+ @Test
+ public void testString() {
+ AssertDataObjects.assertEqualBeans("hello, world", "hello, world");
+ }
+
+ @Test
+ public void testSomeBean() {
+ SomeBean first = new SomeBean();
+ first.setName("hello, world");
+
+ SomeBean second = new SomeBean();
+ second.setName("hello, world");
+
+ AssertDataObjects.assertEqualBeans(first, second);
+ }
+
+}
--- /dev/null
+/*
+ * Copyright (c) 2016 Red Hat, 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.mdsal.binding.testutils;
+
+import static org.opendaylight.mdsal.common.api.LogicalDatastoreType.OPERATIONAL;
+
+import ch.vorburger.xtendbeans.AssertBeans;
+import java.util.Map;
+import org.junit.Test;
+import org.opendaylight.mdsal.binding.api.ReadTransaction;
+import org.opendaylight.mdsal.binding.api.WriteTransaction;
+import org.opendaylight.mdsal.binding.dom.adapter.test.AbstractDataBrokerTest;
+import org.opendaylight.mdsal.common.api.LogicalDatastoreType;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.mdsal.test.binding.rev140701.Top;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.mdsal.test.binding.rev140701.two.level.list.TopLevelList;
+import org.opendaylight.yangtools.yang.binding.Augmentation;
+import org.opendaylight.yangtools.yang.binding.DataObject;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+
+/**
+ * Test for {@link AugmentableExtension}.
+ *
+ * @author Michael Vorburger
+ */
+public class AugmentableExtensionTest extends AbstractDataBrokerTest {
+
+ private final AugmentableExtension augmentableExtension = new AugmentableExtension();
+
+ @Test
+ public void testAugmentableExtensionOnYangObjectByBuilder() {
+ TopLevelList topLevelList = ExampleYangObjects.topLevelList().getValue();
+ Map<Class<? extends Augmentation<?>>, Augmentation<?>> augmentations = augmentableExtension
+ .getAugmentations(topLevelList);
+ AssertBeans.assertEqualByText("#{\n"
+ + " org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.mdsal.test"
+ + ".augment.rev140709.TreeComplexUsesAugment -> (new TreeComplexUsesAugmentBuilder => [\n"
+ + " containerWithUses = (new ContainerWithUsesBuilder => [\n"
+ + " leafFromGrouping = \"foo\"\n"
+ + " ]).build()\n"
+ + " ]).build()\n"
+ + "}", augmentations);
+ }
+
+ @Test
+ public void testAugmentableExtensionWithDataBroker() throws Exception {
+ WriteTransaction writeTx = getDataBroker().newWriteOnlyTransaction();
+ put(writeTx, OPERATIONAL, ExampleYangObjects.topLevelList());
+ writeTx.submit().checkedGet();
+
+ ReadTransaction readTx = getDataBroker().newReadOnlyTransaction();
+ InstanceIdentifier<Top> id = InstanceIdentifier.create(Top.class);
+ Top actualTop = readTx.read(OPERATIONAL, id).checkedGet().get();
+ AssertBeans.assertEqualByText("#{\n}", augmentableExtension.getAugmentations(actualTop));
+
+ TopLevelList topLevelList = actualTop.getTopLevelList().get(0);
+ AssertDataObjects.assertEqualByText("#{\n"
+ + " TreeComplexUsesAugment -> new TreeComplexUsesAugmentBuilder >> [\n"
+ + " containerWithUses = new ContainerWithUsesBuilder >> [\n"
+ + " leafFromGrouping = \"foo\"\n"
+ + " ]\n"
+ + " ]\n"
+ + "}", augmentableExtension.getAugmentations(topLevelList));
+ }
+
+ <T extends DataObject> void put(WriteTransaction tx, LogicalDatastoreType store,
+ Map.Entry<InstanceIdentifier<T>, T> obj) {
+ tx.put(OPERATIONAL, obj.getKey(), obj.getValue());
+ }
+
+}
--- /dev/null
+/*
+ * Copyright (c) 2016 Red Hat, 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.mdsal.binding.testutils;
+
+import java.util.AbstractMap;
+import java.util.AbstractMap.SimpleImmutableEntry;
+import org.opendaylight.mdsal.binding.test.model.util.ListsBindingUtils;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.mdsal.test.augment.rev140709.TreeComplexUsesAugment;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.mdsal.test.augment.rev140709.TreeComplexUsesAugmentBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.mdsal.test.augment.rev140709.complex.from.grouping.ContainerWithUsesBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.mdsal.test.binding.rev140701.Top;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.mdsal.test.binding.rev140701.TopBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.mdsal.test.binding.rev140701.two.level.list.TopLevelList;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+
+public class ExampleYangObjects {
+
+ public static AbstractMap.SimpleImmutableEntry<InstanceIdentifier<Top>, Top> topEmpty() {
+ return new SimpleImmutableEntry<>(InstanceIdentifier.create(Top.class), new TopBuilder().build());
+ }
+
+ public static AbstractMap.SimpleImmutableEntry<InstanceIdentifier<TopLevelList>, TopLevelList> topLevelList() {
+ TreeComplexUsesAugment fooAugment = new TreeComplexUsesAugmentBuilder()
+ .setContainerWithUses(new ContainerWithUsesBuilder().setLeafFromGrouping("foo").build()).build();
+ return new SimpleImmutableEntry<>(
+ ListsBindingUtils.path(ListsBindingUtils.TOP_FOO_KEY),
+ ListsBindingUtils.topLevelList(ListsBindingUtils.TOP_FOO_KEY, fooAugment));
+ }
+}
--- /dev/null
+/*
+ * Copyright (c) 2016 Red Hat, 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.mdsal.binding.testutils;
+
+import java.util.Collections;
+import org.eclipse.xtext.xbase.lib.CollectionLiterals;
+import org.eclipse.xtext.xbase.lib.Procedures.Procedure1;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.mdsal.test.augment.rev140709.TreeComplexUsesAugment;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.mdsal.test.augment.rev140709.TreeComplexUsesAugmentBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.mdsal.test.augment.rev140709.complex.from.grouping.ContainerWithUses;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.mdsal.test.augment.rev140709.complex.from.grouping.ContainerWithUsesBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.mdsal.test.binding.rev140701.Top;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.mdsal.test.binding.rev140701.TopBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.mdsal.test.binding.rev140701.two.level.list.TopLevelList;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.mdsal.test.binding.rev140701.two.level.list.TopLevelListBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.mdsal.test.binding.rev140701.two.level.list.TopLevelListKey;
+
+/**
+ * The object initialization code in this class was generated by AssertDataObjects.
+ *
+ * @see AssertDataObjects
+ * @see AssertDataObjectsTest
+ */
+public class ExpectedObjects {
+
+ public static TopLevelList topLevelList() {
+ TopLevelListBuilder it = new TopLevelListBuilder();
+ TopLevelListKey topLevelListKey = new TopLevelListKey("foo");
+ it.setKey(topLevelListKey);
+ it.setName("foo");
+ TreeComplexUsesAugmentBuilder treeComplexUsesAugmentBuilder = new TreeComplexUsesAugmentBuilder();
+ ContainerWithUsesBuilder containerWithUsesBuilder = new ContainerWithUsesBuilder();
+ containerWithUsesBuilder.setLeafFromGrouping("foo");
+ ContainerWithUses containerWithUses = containerWithUsesBuilder.build();
+ treeComplexUsesAugmentBuilder.setContainerWithUses(containerWithUses);
+ TreeComplexUsesAugment treeComplexUsesAugment = treeComplexUsesAugmentBuilder.build();
+ it.addAugmentation(TreeComplexUsesAugment.class, treeComplexUsesAugment);
+ return it.build();
+ }
+
+ public static Top top() {
+ TopBuilder topBuilder = new TopBuilder();
+ final Procedure1<TopBuilder> _function = (TopBuilder it) -> {
+ TopLevelListBuilder topLevelListBuilder = new TopLevelListBuilder();
+ final Procedure1<TopLevelListBuilder> _function_1 = (TopLevelListBuilder it1) -> {
+ it1.setName("foo");
+ TreeComplexUsesAugmentBuilder treeComplexUsesAugmentBuilder = new TreeComplexUsesAugmentBuilder();
+ final Procedure1<TreeComplexUsesAugmentBuilder> _function_2 = (TreeComplexUsesAugmentBuilder it2) -> {
+ ContainerWithUsesBuilder containerWithUsesBuilder = new ContainerWithUsesBuilder();
+ final Procedure1<ContainerWithUsesBuilder> _function_3 = (ContainerWithUsesBuilder it3) -> {
+ it3.setLeafFromGrouping("foo");
+ };
+ ContainerWithUses doubleGreaterThan = XtendBuilderExtensions
+ .<ContainerWithUses, ContainerWithUsesBuilder>operator_doubleGreaterThan(
+ containerWithUsesBuilder, _function_3);
+ it2.setContainerWithUses(doubleGreaterThan);
+ };
+ TreeComplexUsesAugment doubleGreaterThan = XtendBuilderExtensions
+ .<TreeComplexUsesAugment, TreeComplexUsesAugmentBuilder>operator_doubleGreaterThan(
+ treeComplexUsesAugmentBuilder, _function_2);
+ it1.addAugmentation(TreeComplexUsesAugment.class, doubleGreaterThan);
+ };
+ TopLevelList doubleGreaterThan = XtendBuilderExtensions
+ .<TopLevelList, TopLevelListBuilder>operator_doubleGreaterThan(topLevelListBuilder, _function_1);
+ it.setTopLevelList(Collections
+ .<TopLevelList>unmodifiableList(CollectionLiterals.<TopLevelList>newArrayList(doubleGreaterThan)));
+ };
+ return XtendBuilderExtensions.<Top, TopBuilder>operator_doubleGreaterThan(topBuilder, _function);
+ }
+}
<module>mdsal-binding-api</module>
<module>mdsal-binding-util</module>
+ <module>mdsal-binding-test-utils</module>
<module>mdsal-binding-dom-adapter</module>
</modules>
<artifactId>mdsal-binding-dom-adapter</artifactId>
<version>${project.version}</version>
</dependency>
+ <dependency>
+ <groupId>org.opendaylight.mdsal</groupId>
+ <artifactId>mdsal-binding-dom-adapter</artifactId>
+ <version>${project.version}</version>
+ <type>test-jar</type>
+ <scope>test</scope>
+ </dependency>
<dependency>
<groupId>org.opendaylight.mdsal</groupId>
<artifactId>mdsal-binding-util</artifactId>
<version>${project.version}</version>
</dependency>
+ <dependency>
+ <groupId>org.opendaylight.mdsal</groupId>
+ <artifactId>mdsal-binding-test-utils</artifactId>
+ <version>${project.version}</version>
+ </dependency>
<dependency>
<groupId>org.opendaylight.mdsal.model</groupId>