Binding v2 runtime - adapters - impl - data tree 68/59168/2
authorJakub Toth <jakub.toth@pantheon.tech>
Thu, 15 Jun 2017 12:17:16 +0000 (14:17 +0200)
committerMartin Ciglan <martin.ciglan@pantheon.tech>
Mon, 19 Jun 2017 17:16:28 +0000 (17:16 +0000)
Change-Id: Ice951cd38386a50efdf084f209faa5a902817e48
Signed-off-by: Jakub Toth <jakub.toth@pantheon.tech>
(cherry picked from commit 5e845756f6d4f3f4734fd73f3bef893212ef3b7d)

binding2/mdsal-binding2-dom-adapter/src/main/java/org/opendaylight/mdsal/binding/javav2/dom/adapter/impl/data/tree/BindingDOMCursorAwareWriteTransactionAdapter.java [new file with mode: 0644]
binding2/mdsal-binding2-dom-adapter/src/main/java/org/opendaylight/mdsal/binding/javav2/dom/adapter/impl/data/tree/BindingDOMDataTreeCommitCohortAdapter.java [new file with mode: 0644]
binding2/mdsal-binding2-dom-adapter/src/main/java/org/opendaylight/mdsal/binding/javav2/dom/adapter/impl/data/tree/BindingDOMDataTreeCommitCohortRegistryAdapter.java [new file with mode: 0644]
binding2/mdsal-binding2-dom-adapter/src/main/java/org/opendaylight/mdsal/binding/javav2/dom/adapter/impl/data/tree/BindingDOMDataTreeListenerAdapter.java [new file with mode: 0644]
binding2/mdsal-binding2-dom-adapter/src/main/java/org/opendaylight/mdsal/binding/javav2/dom/adapter/impl/data/tree/BindingDOMDataTreeProducerAdapter.java [new file with mode: 0644]
binding2/mdsal-binding2-dom-adapter/src/main/java/org/opendaylight/mdsal/binding/javav2/dom/adapter/impl/data/tree/BindingDOMDataTreeServiceAdapter.java [new file with mode: 0644]
binding2/mdsal-binding2-dom-adapter/src/main/java/org/opendaylight/mdsal/binding/javav2/dom/adapter/impl/data/tree/BindingDOMDataTreeWriteCursorAdapter.java [new file with mode: 0644]
binding2/mdsal-binding2-dom-adapter/src/test/java/org/opendaylight/mdsal/binding/javav2/dom/adapter/impl/data/tree/BindingDOMCursorAwareWriteTransactionAdapterTest.java [new file with mode: 0644]
binding2/mdsal-binding2-dom-adapter/src/test/java/org/opendaylight/mdsal/binding/javav2/dom/adapter/impl/data/tree/BindingDOMDataTreeCommitCohortAdapterTest.java [new file with mode: 0644]
binding2/mdsal-binding2-dom-adapter/src/test/java/org/opendaylight/mdsal/binding/javav2/dom/adapter/impl/data/tree/BindingDOMDataTreeWriteCursorAdapterTest.java [new file with mode: 0644]

diff --git a/binding2/mdsal-binding2-dom-adapter/src/main/java/org/opendaylight/mdsal/binding/javav2/dom/adapter/impl/data/tree/BindingDOMCursorAwareWriteTransactionAdapter.java b/binding2/mdsal-binding2-dom-adapter/src/main/java/org/opendaylight/mdsal/binding/javav2/dom/adapter/impl/data/tree/BindingDOMCursorAwareWriteTransactionAdapter.java
new file mode 100644 (file)
index 0000000..0bffaa5
--- /dev/null
@@ -0,0 +1,62 @@
+/*
+ * Copyright (c) 2017 Pantheon Technologies s.r.o. 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.javav2.dom.adapter.impl.data.tree;
+
+import com.google.common.annotations.Beta;
+import java.util.function.BiConsumer;
+import javax.annotation.Nonnull;
+import javax.annotation.Nullable;
+import org.opendaylight.mdsal.binding.javav2.api.CursorAwareWriteTransaction;
+import org.opendaylight.mdsal.binding.javav2.api.DataTreeIdentifier;
+import org.opendaylight.mdsal.binding.javav2.api.DataTreeWriteCursor;
+import org.opendaylight.mdsal.binding.javav2.dom.codec.impl.BindingToNormalizedNodeCodec;
+import org.opendaylight.mdsal.binding.javav2.spec.base.TreeNode;
+import org.opendaylight.mdsal.common.api.TransactionCommitFailedException;
+import org.opendaylight.mdsal.dom.api.DOMDataTreeCursorAwareTransaction;
+import org.opendaylight.mdsal.dom.api.DOMDataTreeIdentifier;
+import org.opendaylight.mdsal.dom.api.DOMDataTreeWriteCursor;
+import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
+
+/**
+ * Allowing cursor to provides write operations(delete, merge, write).
+ *
+ * @param <T>
+ *            - {@link DOMDataTreeCursorAwareTransaction} type
+ */
+@Beta
+public class BindingDOMCursorAwareWriteTransactionAdapter<T extends DOMDataTreeCursorAwareTransaction>
+        implements CursorAwareWriteTransaction {
+
+    private final T delegate;
+    private final BindingToNormalizedNodeCodec codec;
+
+    public BindingDOMCursorAwareWriteTransactionAdapter(final T delegate, final BindingToNormalizedNodeCodec codec) {
+        this.delegate = delegate;
+        this.codec = codec;
+    }
+
+    @Nullable
+    @Override
+    public <P extends TreeNode> DataTreeWriteCursor createCursor(@Nonnull final DataTreeIdentifier<P> path) {
+        final YangInstanceIdentifier yPath = codec.toNormalized(path.getRootIdentifier());
+        final DOMDataTreeWriteCursor cursor =
+                delegate.createCursor(new DOMDataTreeIdentifier(path.getDatastoreType(), yPath));
+        return new BindingDOMDataTreeWriteCursorAdapter<>(path, cursor, codec);
+    }
+
+    @Override
+    public boolean cancel() {
+        return delegate.cancel();
+    }
+
+    @Override
+    public <V extends TreeNode> void submit(final BiConsumer<TransactionCommitFailedException, V> callback) {
+        delegate.submit();
+    }
+}
+
diff --git a/binding2/mdsal-binding2-dom-adapter/src/main/java/org/opendaylight/mdsal/binding/javav2/dom/adapter/impl/data/tree/BindingDOMDataTreeCommitCohortAdapter.java b/binding2/mdsal-binding2-dom-adapter/src/main/java/org/opendaylight/mdsal/binding/javav2/dom/adapter/impl/data/tree/BindingDOMDataTreeCommitCohortAdapter.java
new file mode 100644 (file)
index 0000000..359e975
--- /dev/null
@@ -0,0 +1,69 @@
+/*
+ * Copyright (c) 2017 Pantheon Technologies s.r.o. 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.javav2.dom.adapter.impl.data.tree;
+
+import com.google.common.annotations.Beta;
+import com.google.common.base.Preconditions;
+import com.google.common.util.concurrent.AsyncFunction;
+import com.google.common.util.concurrent.CheckedFuture;
+import com.google.common.util.concurrent.Futures;
+import com.google.common.util.concurrent.ListenableFuture;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.function.BiConsumer;
+import javax.annotation.Nonnull;
+import org.opendaylight.mdsal.binding.javav2.api.DataTreeCommitCohort;
+import org.opendaylight.mdsal.binding.javav2.api.DataTreeModification;
+import org.opendaylight.mdsal.binding.javav2.dom.codec.impl.BindingToNormalizedNodeCodec;
+import org.opendaylight.mdsal.binding.javav2.dom.codec.modification.LazyDataTreeModification;
+import org.opendaylight.mdsal.binding.javav2.spec.base.TreeNode;
+import org.opendaylight.mdsal.common.api.DataValidationFailedException;
+import org.opendaylight.mdsal.common.api.PostCanCommitStep;
+import org.opendaylight.mdsal.dom.api.DOMDataTreeCandidate;
+import org.opendaylight.mdsal.dom.api.DOMDataTreeCommitCohort;
+import org.opendaylight.yangtools.util.concurrent.MappingCheckedFuture;
+import org.opendaylight.yangtools.yang.model.api.SchemaContext;
+
+/**
+ * Data tree commit cohort adapter.
+ *
+ * @param <T>
+ *            - {@link TreeNode} type
+ */
+@Beta
+public class BindingDOMDataTreeCommitCohortAdapter<T extends TreeNode> implements DOMDataTreeCommitCohort {
+
+    private final BindingToNormalizedNodeCodec codec;
+    private final DataTreeCommitCohort<T> cohort;
+
+    public BindingDOMDataTreeCommitCohortAdapter(final BindingToNormalizedNodeCodec codec,
+            final DataTreeCommitCohort<T> cohort) {
+        this.codec = Preconditions.checkNotNull(codec);
+        this.cohort = Preconditions.checkNotNull(cohort);
+    }
+
+    @Nonnull
+    @Override
+    public CheckedFuture<PostCanCommitStep, DataValidationFailedException> canCommit(@Nonnull final Object txId,
+            @Nonnull final DOMDataTreeCandidate candidate, @Nonnull final SchemaContext ctx) {
+        final DataTreeModification<T> modification = LazyDataTreeModification.create(codec, candidate);
+        final List<CheckedFuture<PostCanCommitStep, DataValidationFailedException>> futures = new ArrayList<>();
+        final BiConsumer<DataValidationFailedException, PostCanCommitStep> biConsumer = (ex, cc) -> {
+            final ListenableFuture<PostCanCommitStep> immediateFuture = Futures.immediateFuture(cc);
+            futures.add(MappingCheckedFuture.create(immediateFuture,
+                            new DataValidationFailedExceptionMapper("canCommit", candidate.getRootPath())));
+        };
+        final ListenableFuture<PostCanCommitStep> resultFuture =
+                Futures.transform(Futures.allAsList(futures), (AsyncFunction<List<PostCanCommitStep>,
+                        PostCanCommitStep>) input -> Futures.immediateFuture(input.get(input.size() - 1)));
+        cohort.canCommit(txId, modification, biConsumer);
+        return MappingCheckedFuture.create(resultFuture,
+                new DataValidationFailedExceptionMapper("canCommit", candidate.getRootPath()));
+    }
+}
+
diff --git a/binding2/mdsal-binding2-dom-adapter/src/main/java/org/opendaylight/mdsal/binding/javav2/dom/adapter/impl/data/tree/BindingDOMDataTreeCommitCohortRegistryAdapter.java b/binding2/mdsal-binding2-dom-adapter/src/main/java/org/opendaylight/mdsal/binding/javav2/dom/adapter/impl/data/tree/BindingDOMDataTreeCommitCohortRegistryAdapter.java
new file mode 100644 (file)
index 0000000..2a15d08
--- /dev/null
@@ -0,0 +1,73 @@
+/*
+ * Copyright (c) 2017 Pantheon Technologies s.r.o. 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.javav2.dom.adapter.impl.data.tree;
+
+import com.google.common.annotations.Beta;
+import com.google.common.base.Preconditions;
+import javax.annotation.Nonnull;
+import org.opendaylight.mdsal.binding.javav2.api.DataTreeCommitCohort;
+import org.opendaylight.mdsal.binding.javav2.api.DataTreeCommitCohortRegistry;
+import org.opendaylight.mdsal.binding.javav2.api.DataTreeIdentifier;
+import org.opendaylight.mdsal.binding.javav2.dom.codec.impl.BindingToNormalizedNodeCodec;
+import org.opendaylight.mdsal.binding.javav2.spec.base.TreeNode;
+import org.opendaylight.mdsal.dom.api.DOMDataTreeCommitCohortRegistration;
+import org.opendaylight.mdsal.dom.api.DOMDataTreeCommitCohortRegistry;
+import org.opendaylight.mdsal.dom.api.DOMDataTreeIdentifier;
+import org.opendaylight.yangtools.concepts.ObjectRegistration;
+
+/**
+ * Data tree commit cohort registry adapter.
+ */
+@Beta
+public class BindingDOMDataTreeCommitCohortRegistryAdapter implements DataTreeCommitCohortRegistry {
+
+    private final BindingToNormalizedNodeCodec codec;
+    private final DOMDataTreeCommitCohortRegistry registry;
+
+    private BindingDOMDataTreeCommitCohortRegistryAdapter(final BindingToNormalizedNodeCodec codec,
+            final DOMDataTreeCommitCohortRegistry registry) {
+        this.codec = Preconditions.checkNotNull(codec);
+        this.registry = Preconditions.checkNotNull(registry);
+    }
+
+    /**
+     * Create instance of registry of commit cohort.
+     *
+     * @param codec
+     *            - codec for serialize/deserialize
+     * @param registry
+     *            - dom registry
+     * @return binding registry
+     */
+    public static DataTreeCommitCohortRegistry from(final BindingToNormalizedNodeCodec codec,
+            final DOMDataTreeCommitCohortRegistry registry) {
+        return new BindingDOMDataTreeCommitCohortRegistryAdapter(codec, registry);
+    }
+
+    @Override
+    public <D extends TreeNode, T extends DataTreeCommitCohort<D>> ObjectRegistration<T>
+            registerCommitCohort(final DataTreeIdentifier<D> subtree, final T cohort) {
+        final BindingDOMDataTreeCommitCohortAdapter<D> adapter =
+                new BindingDOMDataTreeCommitCohortAdapter<>(codec, cohort);
+        final DOMDataTreeIdentifier domPath = codec.toDOMDataTreeIdentifier(subtree);
+        final DOMDataTreeCommitCohortRegistration<?> domReg = registry.registerCommitCohort(domPath, adapter);
+        return new ObjectRegistration<T>() {
+
+            @Nonnull
+            @Override
+            public T getInstance() {
+                return cohort;
+            }
+
+            @Override
+            public void close() throws Exception {
+                domReg.close();
+            }
+        };
+    }
+}
\ No newline at end of file
diff --git a/binding2/mdsal-binding2-dom-adapter/src/main/java/org/opendaylight/mdsal/binding/javav2/dom/adapter/impl/data/tree/BindingDOMDataTreeListenerAdapter.java b/binding2/mdsal-binding2-dom-adapter/src/main/java/org/opendaylight/mdsal/binding/javav2/dom/adapter/impl/data/tree/BindingDOMDataTreeListenerAdapter.java
new file mode 100644 (file)
index 0000000..9353920
--- /dev/null
@@ -0,0 +1,93 @@
+/*
+ * Copyright (c) 2017 Pantheon Technologies s.r.o. 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.javav2.dom.adapter.impl.data.tree;
+
+import com.google.common.annotations.Beta;
+import com.google.common.base.Preconditions;
+import com.google.common.collect.Maps;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
+import java.util.Map;
+import java.util.Map.Entry;
+import javax.annotation.Nonnull;
+import org.opendaylight.mdsal.binding.javav2.api.DataTreeIdentifier;
+import org.opendaylight.mdsal.binding.javav2.api.DataTreeListener;
+import org.opendaylight.mdsal.binding.javav2.api.DataTreeListeningException;
+import org.opendaylight.mdsal.binding.javav2.api.DataTreeModification;
+import org.opendaylight.mdsal.binding.javav2.dom.codec.impl.BindingToNormalizedNodeCodec;
+import org.opendaylight.mdsal.binding.javav2.dom.codec.modification.LazyDataTreeModification;
+import org.opendaylight.mdsal.binding.javav2.spec.base.InstanceIdentifier;
+import org.opendaylight.mdsal.binding.javav2.spec.base.TreeNode;
+import org.opendaylight.mdsal.common.api.LogicalDatastoreType;
+import org.opendaylight.mdsal.dom.api.DOMDataTreeIdentifier;
+import org.opendaylight.mdsal.dom.api.DOMDataTreeListener;
+import org.opendaylight.mdsal.dom.api.DOMDataTreeListeningException;
+import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
+import org.opendaylight.yangtools.yang.data.api.schema.tree.DataTreeCandidate;
+
+/**
+ * Data tree listener adapter.
+ */
+@Beta
+public class BindingDOMDataTreeListenerAdapter implements DOMDataTreeListener {
+
+    private final DataTreeListener delegate;
+    private final BindingToNormalizedNodeCodec codec;
+    private final LogicalDatastoreType store;
+
+    public BindingDOMDataTreeListenerAdapter(final DataTreeListener delegate,
+            final BindingToNormalizedNodeCodec codec, final LogicalDatastoreType store) {
+        this.delegate = Preconditions.checkNotNull(delegate, "delegate");
+        this.codec = Preconditions.checkNotNull(codec, "codec");
+        this.store = Preconditions.checkNotNull(store, "store");
+    }
+
+    @Override
+    public void onDataTreeChanged(@Nonnull final Collection<DataTreeCandidate> domChanges,
+            @Nonnull final Map<DOMDataTreeIdentifier, NormalizedNode<?, ?>> domSubtrees) {
+
+        final Collection<DataTreeModification<?>> changes = toBinding(domChanges);
+        final Map<DataTreeIdentifier<?>, TreeNode> subtrees = toBinding(domSubtrees);
+
+        delegate.onDataTreeChanged(changes, subtrees);
+    }
+
+    private Map<DataTreeIdentifier<?>, TreeNode>
+            toBinding(final Map<DOMDataTreeIdentifier, NormalizedNode<?, ?>> domSubtrees) {
+        // FIXME: Introduce lazy translating map
+        final Map<DataTreeIdentifier<?>, TreeNode> ret = Maps.newHashMapWithExpectedSize(domSubtrees.size());
+        for (final Entry<DOMDataTreeIdentifier, NormalizedNode<?, ?>> domEntry : domSubtrees.entrySet()) {
+            final Entry<InstanceIdentifier<?>, TreeNode> bindingEntry =
+                    codec.fromNormalizedNode(domEntry.getKey().getRootIdentifier(), domEntry.getValue());
+            ret.put(DataTreeIdentifier.create(store, bindingEntry.getKey()), bindingEntry.getValue());
+        }
+        return ret;
+    }
+
+    @SuppressWarnings("unchecked")
+    private Collection<DataTreeModification<?>> toBinding(final Collection<DataTreeCandidate> domChanges) {
+        return Collection.class.cast(LazyDataTreeModification.from(codec, domChanges, store));
+    }
+
+    @Override
+    public void onDataTreeFailed(@Nonnull final Collection<DOMDataTreeListeningException> causes) {
+        final List<DataTreeListeningException> bindingCauses = new ArrayList<>(causes.size());
+        for (final DOMDataTreeListeningException cause : causes) {
+            bindingCauses.add(mapException(cause));
+        }
+
+        delegate.onDataTreeFailed(bindingCauses);
+    }
+
+    private DataTreeListeningException mapException(final DOMDataTreeListeningException cause) {
+        // FIXME: Extend logic
+        return new DataTreeListeningException(cause.getMessage(), cause);
+    }
+}
+
diff --git a/binding2/mdsal-binding2-dom-adapter/src/main/java/org/opendaylight/mdsal/binding/javav2/dom/adapter/impl/data/tree/BindingDOMDataTreeProducerAdapter.java b/binding2/mdsal-binding2-dom-adapter/src/main/java/org/opendaylight/mdsal/binding/javav2/dom/adapter/impl/data/tree/BindingDOMDataTreeProducerAdapter.java
new file mode 100644 (file)
index 0000000..a9d59c8
--- /dev/null
@@ -0,0 +1,77 @@
+/*
+ * Copyright (c) 2017 Pantheon Technologies s.r.o. 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.javav2.dom.adapter.impl.data.tree;
+
+import com.google.common.annotations.Beta;
+import com.google.common.base.Preconditions;
+import java.util.Collection;
+import javax.annotation.Nonnull;
+import org.opendaylight.mdsal.binding.javav2.api.CursorAwareWriteTransaction;
+import org.opendaylight.mdsal.binding.javav2.api.DataTreeIdentifier;
+import org.opendaylight.mdsal.binding.javav2.api.DataTreeProducer;
+import org.opendaylight.mdsal.binding.javav2.api.DataTreeProducerException;
+import org.opendaylight.mdsal.binding.javav2.dom.codec.impl.BindingToNormalizedNodeCodec;
+import org.opendaylight.mdsal.dom.api.DOMDataTreeCursorAwareTransaction;
+import org.opendaylight.mdsal.dom.api.DOMDataTreeIdentifier;
+import org.opendaylight.mdsal.dom.api.DOMDataTreeProducer;
+import org.opendaylight.mdsal.dom.api.DOMDataTreeProducerException;
+
+/**
+ * Producer adapter.
+ */
+@Beta
+public class BindingDOMDataTreeProducerAdapter implements DataTreeProducer {
+
+    private final DOMDataTreeProducer delegate;
+    private final BindingToNormalizedNodeCodec codec;
+
+    private BindingDOMDataTreeProducerAdapter(final DOMDataTreeProducer delegate,
+            final BindingToNormalizedNodeCodec codec) {
+        this.delegate = Preconditions.checkNotNull(delegate);
+        this.codec = codec;
+    }
+
+    /**
+     * Create instance of producer data tree.
+     *
+     * @param domProducer
+     *            - DOM producer
+     * @param codec
+     *            - codec for serialize/deserialize
+     * @return instance of producer
+     */
+    public static DataTreeProducer create(final DOMDataTreeProducer domProducer,
+            final BindingToNormalizedNodeCodec codec) {
+        return new BindingDOMDataTreeProducerAdapter(domProducer, codec);
+    }
+
+    @Nonnull
+    @Override
+    public CursorAwareWriteTransaction createTransaction(final boolean isolated) {
+        final DOMDataTreeCursorAwareTransaction domTx = delegate.createTransaction(isolated);
+        return new BindingDOMCursorAwareWriteTransactionAdapter<>(domTx, codec);
+    }
+
+    @Nonnull
+    @Override
+    public DataTreeProducer createProducer(@Nonnull final Collection<DataTreeIdentifier<?>> subtrees) {
+        final Collection<DOMDataTreeIdentifier> domSubtrees = codec.toDOMDataTreeIdentifiers(subtrees);
+        final DOMDataTreeProducer domChildProducer = delegate.createProducer(domSubtrees);
+        return BindingDOMDataTreeProducerAdapter.create(domChildProducer, codec);
+    }
+
+    @Override
+    public void close() throws DataTreeProducerException {
+        try {
+            delegate.close();
+        } catch (final DOMDataTreeProducerException e) {
+            throw new DataTreeProducerException(e.getMessage(), e);
+        }
+    }
+}
+
diff --git a/binding2/mdsal-binding2-dom-adapter/src/main/java/org/opendaylight/mdsal/binding/javav2/dom/adapter/impl/data/tree/BindingDOMDataTreeServiceAdapter.java b/binding2/mdsal-binding2-dom-adapter/src/main/java/org/opendaylight/mdsal/binding/javav2/dom/adapter/impl/data/tree/BindingDOMDataTreeServiceAdapter.java
new file mode 100644 (file)
index 0000000..5edda40
--- /dev/null
@@ -0,0 +1,69 @@
+/*
+ * Copyright (c) 2017 Pantheon Technologies s.r.o. 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.javav2.dom.adapter.impl.data.tree;
+
+import com.google.common.annotations.Beta;
+import com.google.common.base.Preconditions;
+import java.util.Collection;
+import javax.annotation.Nonnull;
+import org.opendaylight.mdsal.binding.javav2.api.DataTreeIdentifier;
+import org.opendaylight.mdsal.binding.javav2.api.DataTreeListener;
+import org.opendaylight.mdsal.binding.javav2.api.DataTreeLoopException;
+import org.opendaylight.mdsal.binding.javav2.api.DataTreeProducer;
+import org.opendaylight.mdsal.binding.javav2.api.DataTreeService;
+import org.opendaylight.mdsal.binding.javav2.dom.codec.impl.BindingToNormalizedNodeCodec;
+import org.opendaylight.mdsal.dom.api.DOMDataTreeIdentifier;
+import org.opendaylight.mdsal.dom.api.DOMDataTreeProducer;
+import org.opendaylight.mdsal.dom.api.DOMDataTreeService;
+import org.opendaylight.yangtools.concepts.ListenerRegistration;
+
+/**
+ * Data tree service adapter.
+ *
+ */
+@Beta
+public class BindingDOMDataTreeServiceAdapter implements DataTreeService {
+
+    private final DOMDataTreeService delegate;
+    private final BindingToNormalizedNodeCodec codec;
+
+    private BindingDOMDataTreeServiceAdapter(final DOMDataTreeService delegate,
+            final BindingToNormalizedNodeCodec codec) {
+        this.delegate = Preconditions.checkNotNull(delegate, "delegate");
+        this.codec = Preconditions.checkNotNull(codec, "codec");
+    }
+
+    /**
+     * Create instance of data tree service adapter.
+     *
+     * @param domService
+     *            - data tree service
+     * @param codec
+     *            - codec foer serialize/deserialize
+     * @return instance of data tree service adapter
+     */
+    public static BindingDOMDataTreeServiceAdapter create(final DOMDataTreeService domService,
+            final BindingToNormalizedNodeCodec codec) {
+        return new BindingDOMDataTreeServiceAdapter(domService, codec);
+    }
+
+    @Override
+    public DataTreeProducer createProducer(final Collection<DataTreeIdentifier<?>> subtrees) {
+        final Collection<DOMDataTreeIdentifier> domSubtrees = codec.toDOMDataTreeIdentifiers(subtrees);
+        final DOMDataTreeProducer domChildProducer = delegate.createProducer(domSubtrees);
+        return BindingDOMDataTreeProducerAdapter.create(domChildProducer, codec);
+    }
+
+    @Nonnull
+    @Override
+    public <T extends DataTreeListener> ListenerRegistration<T> registerListener(@Nonnull final T listener,
+            @Nonnull final Collection<DataTreeIdentifier<?>> subtrees, final boolean allowRxMerges,
+            @Nonnull final Collection<DataTreeProducer> producers) throws DataTreeLoopException {
+        throw new UnsupportedOperationException("Not implemented yet.");
+    }
+}
diff --git a/binding2/mdsal-binding2-dom-adapter/src/main/java/org/opendaylight/mdsal/binding/javav2/dom/adapter/impl/data/tree/BindingDOMDataTreeWriteCursorAdapter.java b/binding2/mdsal-binding2-dom-adapter/src/main/java/org/opendaylight/mdsal/binding/javav2/dom/adapter/impl/data/tree/BindingDOMDataTreeWriteCursorAdapter.java
new file mode 100644 (file)
index 0000000..455e340
--- /dev/null
@@ -0,0 +1,115 @@
+/*
+ * Copyright (c) 2017 Pantheon Technologies s.r.o. 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.javav2.dom.adapter.impl.data.tree;
+
+import com.google.common.annotations.Beta;
+import java.util.AbstractMap.SimpleEntry;
+import java.util.ArrayDeque;
+import java.util.Deque;
+import java.util.Map.Entry;
+import javax.annotation.Nonnull;
+import org.opendaylight.mdsal.binding.javav2.api.DataTreeIdentifier;
+import org.opendaylight.mdsal.binding.javav2.api.DataTreeWriteCursor;
+import org.opendaylight.mdsal.binding.javav2.dom.codec.impl.BindingToNormalizedNodeCodec;
+import org.opendaylight.mdsal.binding.javav2.spec.base.InstanceIdentifier;
+import org.opendaylight.mdsal.binding.javav2.spec.base.TreeArgument;
+import org.opendaylight.mdsal.binding.javav2.spec.base.TreeNode;
+import org.opendaylight.mdsal.dom.api.DOMDataTreeWriteCursor;
+import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
+import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
+
+/**
+ * Data tree write cursor adapter.
+ *
+ * @param <T>
+ *            - {@link DOMDataTreeWriteCursor} type
+ */
+@Beta
+public class BindingDOMDataTreeWriteCursorAdapter<T extends DOMDataTreeWriteCursor> implements DataTreeWriteCursor {
+
+    private final T delegate;
+    private final BindingToNormalizedNodeCodec codec;
+    private final Deque<TreeArgument<?>> stack = new ArrayDeque<>();
+
+    public BindingDOMDataTreeWriteCursorAdapter(final DataTreeIdentifier<?> path, final T delegate,
+            final BindingToNormalizedNodeCodec codec) {
+
+        this.delegate = delegate;
+        this.codec = codec;
+        path.getRootIdentifier().getPathArguments().forEach(stack::push);
+    }
+
+    private YangInstanceIdentifier.PathArgument convertToNormalized(final TreeArgument<?> child) {
+        stack.push(child);
+        final InstanceIdentifier<?> iid = InstanceIdentifier.create(stack);
+        final YangInstanceIdentifier ret = codec.toNormalized(iid);
+        stack.pop();
+        return ret.getLastPathArgument();
+    }
+
+    private <P extends TreeNode> Entry<YangInstanceIdentifier, NormalizedNode<?, ?>>
+            convertToNormalized(final TreeArgument<?> child, final P data) {
+        stack.push(child);
+        final InstanceIdentifier<?> iid = InstanceIdentifier.create(stack);
+        final Entry<YangInstanceIdentifier, NormalizedNode<?, ?>> entry =
+                codec.toNormalizedNode(new SimpleEntry<>(iid, data));
+        stack.pop();
+        return entry;
+    }
+
+    @Override
+    public void delete(final TreeArgument<?> child) {
+        delegate.delete(convertToNormalized(child));
+    }
+
+    @Override
+    public <U extends TreeNode> void merge(final TreeArgument<U> child, final U data) {
+        final Entry<YangInstanceIdentifier, NormalizedNode<?, ?>> entry = convertToNormalized(child, data);
+        delegate.merge(entry.getKey().getLastPathArgument(), entry.getValue());
+    }
+
+    @Override
+    public <P extends TreeNode> void write(final TreeArgument<P> child, final P data) {
+        final Entry<YangInstanceIdentifier, NormalizedNode<?, ?>> entry = convertToNormalized(child, data);
+        delegate.write(entry.getKey().getLastPathArgument(), entry.getValue());
+    }
+
+    @Override
+    public void enter(@Nonnull final TreeArgument<?> child) {
+        stack.push(child);
+    }
+
+    @Override
+    public void enter(@Nonnull final TreeArgument<?>... path) {
+        for (final TreeArgument<?> pathArgument : path) {
+            enter(pathArgument);
+        }
+    }
+
+    @Override
+    public void enter(@Nonnull final Iterable<TreeArgument<?>> path) {
+        path.forEach(this::enter);
+    }
+
+    @Override
+    public void exit() {
+        stack.pop();
+    }
+
+    @Override
+    public void exit(final int depth) {
+        for (int i = 0; i < depth; i++) {
+            exit();
+        }
+    }
+
+    @Override
+    public void close() {
+        delegate.close();
+    }
+}
diff --git a/binding2/mdsal-binding2-dom-adapter/src/test/java/org/opendaylight/mdsal/binding/javav2/dom/adapter/impl/data/tree/BindingDOMCursorAwareWriteTransactionAdapterTest.java b/binding2/mdsal-binding2-dom-adapter/src/test/java/org/opendaylight/mdsal/binding/javav2/dom/adapter/impl/data/tree/BindingDOMCursorAwareWriteTransactionAdapterTest.java
new file mode 100644 (file)
index 0000000..80aec4e
--- /dev/null
@@ -0,0 +1,67 @@
+/*
+ * Copyright (c) 2017 Pantheon Technologies s.r.o. 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.javav2.dom.adapter.impl.data.tree;
+
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+import static org.mockito.Matchers.any;
+import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.verify;
+
+import java.util.function.BiConsumer;
+import org.junit.Test;
+import org.opendaylight.mdsal.binding.javav2.api.DataTreeIdentifier;
+import org.opendaylight.mdsal.binding.javav2.api.DataTreeWriteCursor;
+import org.opendaylight.mdsal.binding.javav2.dom.codec.impl.BindingNormalizedNodeCodecRegistry;
+import org.opendaylight.mdsal.binding.javav2.dom.codec.impl.BindingToNormalizedNodeCodec;
+import org.opendaylight.mdsal.binding.javav2.generator.impl.GeneratedClassLoadingStrategy;
+import org.opendaylight.mdsal.binding.javav2.spec.base.InstanceIdentifier;
+import org.opendaylight.mdsal.binding.javav2.spec.base.TreeNode;
+import org.opendaylight.mdsal.common.api.LogicalDatastoreType;
+import org.opendaylight.mdsal.dom.api.DOMDataTreeCursorAwareTransaction;
+import org.opendaylight.mdsal.dom.api.DOMDataTreeIdentifier;
+import org.opendaylight.mdsal.dom.api.DOMDataTreeWriteCursor;
+import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
+
+public class BindingDOMCursorAwareWriteTransactionAdapterTest {
+
+    @SuppressWarnings({ "rawtypes", "unchecked" })
+    @Test
+    public void basicTest() throws Exception {
+        final DOMDataTreeCursorAwareTransaction delegate = mock(DOMDataTreeCursorAwareTransaction.class);
+        final BindingNormalizedNodeCodecRegistry registry = mock(BindingNormalizedNodeCodecRegistry.class);
+        final BindingToNormalizedNodeCodec codec =
+                new BindingToNormalizedNodeCodec(
+                        (GeneratedClassLoadingStrategy) GeneratedClassLoadingStrategy.getTCCLClassLoadingStrategy(),
+                        registry);
+        final YangInstanceIdentifier yangInstanceIdentifier = YangInstanceIdentifier.EMPTY;
+        doReturn(yangInstanceIdentifier).when(registry).toYangInstanceIdentifier(any());
+
+        final BindingDOMCursorAwareWriteTransactionAdapter adapter =
+                new BindingDOMCursorAwareWriteTransactionAdapter<>(delegate, codec);
+
+        final DataTreeIdentifier<TreeNode> dti =
+                DataTreeIdentifier.create(LogicalDatastoreType.OPERATIONAL, InstanceIdentifier.create(TreeNode.class));
+
+        final DOMDataTreeWriteCursor dtwc = mock(DOMDataTreeWriteCursor.class);
+        doReturn(dtwc).when(delegate)
+                .createCursor(new DOMDataTreeIdentifier(dti.getDatastoreType(), yangInstanceIdentifier));
+        final DataTreeWriteCursor cursor = adapter.createCursor(dti);
+        assertNotNull(cursor);
+
+        doReturn(null).when(delegate).submit();
+        final BiConsumer callback = mock(BiConsumer.class);
+        adapter.submit(callback);
+        verify(delegate).submit();
+
+        doReturn(true).when(delegate).cancel();
+        assertTrue(adapter.cancel());
+        verify(delegate).cancel();
+    }
+}
\ No newline at end of file
diff --git a/binding2/mdsal-binding2-dom-adapter/src/test/java/org/opendaylight/mdsal/binding/javav2/dom/adapter/impl/data/tree/BindingDOMDataTreeCommitCohortAdapterTest.java b/binding2/mdsal-binding2-dom-adapter/src/test/java/org/opendaylight/mdsal/binding/javav2/dom/adapter/impl/data/tree/BindingDOMDataTreeCommitCohortAdapterTest.java
new file mode 100644 (file)
index 0000000..beeca8e
--- /dev/null
@@ -0,0 +1,73 @@
+/*
+ * Copyright (c) 2017 Pantheon Technologies s.r.o. 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.javav2.dom.adapter.impl.data.tree;
+
+import static org.junit.Assert.assertNotNull;
+import static org.mockito.Matchers.any;
+import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.verify;
+
+import org.junit.Test;
+import org.mockito.Mockito;
+import org.opendaylight.mdsal.binding.javav2.api.DataTreeCommitCohort;
+import org.opendaylight.mdsal.binding.javav2.dom.codec.api.BindingTreeCodec;
+import org.opendaylight.mdsal.binding.javav2.dom.codec.api.BindingTreeNodeCodec;
+import org.opendaylight.mdsal.binding.javav2.dom.codec.impl.BindingNormalizedNodeCodecRegistry;
+import org.opendaylight.mdsal.binding.javav2.dom.codec.impl.BindingToNormalizedNodeCodec;
+import org.opendaylight.mdsal.binding.javav2.dom.codec.modification.LazyDataTreeModification;
+import org.opendaylight.mdsal.binding.javav2.generator.impl.GeneratedClassLoadingStrategy;
+import org.opendaylight.mdsal.binding.javav2.spec.base.InstanceIdentifier;
+import org.opendaylight.mdsal.binding.javav2.spec.base.TreeArgument;
+import org.opendaylight.mdsal.binding.javav2.spec.base.TreeNode;
+import org.opendaylight.mdsal.common.api.LogicalDatastoreType;
+import org.opendaylight.mdsal.dom.api.DOMDataTreeCandidate;
+import org.opendaylight.mdsal.dom.api.DOMDataTreeIdentifier;
+import org.opendaylight.yangtools.yang.common.QName;
+import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
+import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifier;
+import org.opendaylight.yangtools.yang.data.api.schema.tree.DataTreeCandidateNode;
+
+public class BindingDOMDataTreeCommitCohortAdapterTest {
+
+    @SuppressWarnings({ "rawtypes", "unchecked" })
+    @Test
+    public void canCommitTest() throws Exception {
+        final DataTreeCommitCohort<?> cohort = mock(DataTreeCommitCohort.class);
+        final BindingNormalizedNodeCodecRegistry registry = mock(BindingNormalizedNodeCodecRegistry.class);
+        final BindingToNormalizedNodeCodec codec =
+                new BindingToNormalizedNodeCodec(
+                        (GeneratedClassLoadingStrategy) GeneratedClassLoadingStrategy.getTCCLClassLoadingStrategy(),
+                        registry);
+
+        final BindingDOMDataTreeCommitCohortAdapter adapter =
+                new BindingDOMDataTreeCommitCohortAdapter<>(codec, cohort);
+        assertNotNull(adapter);
+
+        final DOMDataTreeCandidate domDataTreeCandidate = mock(DOMDataTreeCandidate.class);
+        final DOMDataTreeIdentifier domDataTreeIdentifier =
+                new DOMDataTreeIdentifier(LogicalDatastoreType.OPERATIONAL, YangInstanceIdentifier.EMPTY);
+        doReturn(InstanceIdentifier.create(TreeNode.class)).when(registry).fromYangInstanceIdentifier(any());
+        final BindingTreeCodec bindingCodecTree = mock(BindingTreeCodec.class);
+        final BindingTreeNodeCodec bindingCodecTreeNode = mock(BindingTreeNodeCodec.class);
+        doReturn(bindingCodecTreeNode).when(bindingCodecTree).getSubtreeCodec(any(InstanceIdentifier.class));
+        doReturn(bindingCodecTree).when(registry).getCodecContext();
+        doReturn(domDataTreeIdentifier).when(domDataTreeCandidate).getRootPath();
+        final DataTreeCandidateNode dataTreeCandidateNode = mock(DataTreeCandidateNode.class);
+        final NodeIdentifier codeIdentifier = NodeIdentifier.create(QName.create("test", "2017-06-15", "ltest"));
+        doReturn(codeIdentifier).when(dataTreeCandidateNode)
+                .getIdentifier();
+        doReturn(mock(TreeArgument.class)).when(bindingCodecTreeNode).deserializePathArgument(codeIdentifier);
+        doReturn(dataTreeCandidateNode).when(domDataTreeCandidate).getRootNode();
+        assertNotNull(LazyDataTreeModification.create(codec, domDataTreeCandidate));
+
+        Mockito.doNothing().when(cohort).canCommit(any(), any(), any());
+        adapter.canCommit(new Object(), domDataTreeCandidate, null);
+        verify(cohort).canCommit(any(), any(), any());
+    }
+}
\ No newline at end of file
diff --git a/binding2/mdsal-binding2-dom-adapter/src/test/java/org/opendaylight/mdsal/binding/javav2/dom/adapter/impl/data/tree/BindingDOMDataTreeWriteCursorAdapterTest.java b/binding2/mdsal-binding2-dom-adapter/src/test/java/org/opendaylight/mdsal/binding/javav2/dom/adapter/impl/data/tree/BindingDOMDataTreeWriteCursorAdapterTest.java
new file mode 100644 (file)
index 0000000..6757b44
--- /dev/null
@@ -0,0 +1,88 @@
+/*
+ * Copyright (c) 2017 Pantheon Technologies s.r.o. 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.javav2.dom.adapter.impl.data.tree;
+
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+import static org.mockito.Matchers.any;
+import static org.mockito.Mockito.doNothing;
+import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.verify;
+
+import com.google.common.collect.ImmutableList;
+import java.lang.reflect.Field;
+import java.util.AbstractMap.SimpleEntry;
+import java.util.Deque;
+import org.junit.Test;
+import org.opendaylight.mdsal.binding.javav2.api.DataTreeIdentifier;
+import org.opendaylight.mdsal.binding.javav2.dom.codec.impl.BindingNormalizedNodeCodecRegistry;
+import org.opendaylight.mdsal.binding.javav2.dom.codec.impl.BindingToNormalizedNodeCodec;
+import org.opendaylight.mdsal.binding.javav2.generator.impl.GeneratedClassLoadingStrategy;
+import org.opendaylight.mdsal.binding.javav2.spec.base.InstanceIdentifier;
+import org.opendaylight.mdsal.binding.javav2.spec.base.Item;
+import org.opendaylight.mdsal.binding.javav2.spec.base.TreeArgument;
+import org.opendaylight.mdsal.binding.javav2.spec.base.TreeNode;
+import org.opendaylight.mdsal.common.api.LogicalDatastoreType;
+import org.opendaylight.mdsal.dom.api.DOMDataTreeWriteCursor;
+import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
+import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
+
+public class BindingDOMDataTreeWriteCursorAdapterTest {
+
+    @SuppressWarnings({ "unchecked", "rawtypes" })
+    @Test
+    public void basicTest() throws Exception {
+        final DataTreeIdentifier identifier =
+                DataTreeIdentifier.create(LogicalDatastoreType.OPERATIONAL,
+                        InstanceIdentifier.create(TreeNode.class));
+        final DOMDataTreeWriteCursor delegate = mock(DOMDataTreeWriteCursor.class);
+        final BindingNormalizedNodeCodecRegistry registry = mock(BindingNormalizedNodeCodecRegistry.class);
+        final BindingToNormalizedNodeCodec codec =
+                new BindingToNormalizedNodeCodec(
+                        (GeneratedClassLoadingStrategy) GeneratedClassLoadingStrategy.getTCCLClassLoadingStrategy(),
+                        registry);
+        final BindingDOMDataTreeWriteCursorAdapter adapter =
+                new BindingDOMDataTreeWriteCursorAdapter<>(identifier, delegate, codec);
+
+        final TreeArgument<?> pathArgument = new Item<>(TreeNode.class);
+        final TreeNode data = mock(TreeNode.class);
+
+        adapter.enter(pathArgument, pathArgument);
+        adapter.enter(ImmutableList.of(pathArgument));
+
+        doNothing().when(delegate).write(any(), any());
+        doNothing().when(delegate).merge(any(), any());
+        doNothing().when(delegate).delete(any());
+        doReturn(YangInstanceIdentifier.EMPTY).when(registry).toYangInstanceIdentifier(any());
+        doNothing().when(delegate).close();
+        final NormalizedNode normalizedNode = mock(NormalizedNode.class);
+
+        doReturn(new SimpleEntry<YangInstanceIdentifier,NormalizedNode<?,?>>(YangInstanceIdentifier.EMPTY,
+                normalizedNode)).when(registry).toNormalizedNode(any(), any());
+        adapter.write(pathArgument, data);
+        verify(delegate).write(any(), any());
+
+        adapter.merge(pathArgument, data);
+        verify(delegate).merge(any(), any());
+
+        adapter.delete(pathArgument);
+        verify(delegate).delete(any());
+
+        final Field stackField = BindingDOMDataTreeWriteCursorAdapter.class.getDeclaredField("stack");
+        stackField.setAccessible(true);
+        final Deque stack = (Deque) stackField.get(adapter);
+        assertTrue(stack.contains(pathArgument));
+
+        adapter.exit(stack.size());
+        assertFalse(stack.contains(pathArgument));
+
+        adapter.close();
+        verify(delegate).close();
+    }
+}
\ No newline at end of file