Remove OSGiBindingAdapterFactory
[mdsal.git] / binding / mdsal-binding-dom-adapter / src / main / java / org / opendaylight / mdsal / binding / dom / adapter / AbstractForwardedTransaction.java
1 /*
2  * Copyright (c) 2014 Cisco Systems, Inc. and others.  All rights reserved.
3  *
4  * This program and the accompanying materials are made available under the
5  * terms of the Eclipse Public License v1.0 which accompanies this distribution,
6  * and is available at http://www.eclipse.org/legal/epl-v10.html
7  */
8 package org.opendaylight.mdsal.binding.dom.adapter;
9
10 import static com.google.common.base.Preconditions.checkArgument;
11 import static com.google.common.base.Preconditions.checkState;
12 import static java.util.Objects.requireNonNull;
13
14 import com.google.common.util.concurrent.FluentFuture;
15 import com.google.common.util.concurrent.MoreExecutors;
16 import java.util.Optional;
17 import org.eclipse.jdt.annotation.NonNull;
18 import org.opendaylight.mdsal.binding.api.query.QueryExpression;
19 import org.opendaylight.mdsal.binding.api.query.QueryResult;
20 import org.opendaylight.mdsal.binding.dom.adapter.query.DefaultQuery;
21 import org.opendaylight.mdsal.common.api.LogicalDatastoreType;
22 import org.opendaylight.mdsal.dom.api.DOMDataTreeQueryOperations;
23 import org.opendaylight.mdsal.dom.api.DOMDataTreeReadOperations;
24 import org.opendaylight.mdsal.dom.api.DOMDataTreeTransaction;
25 import org.opendaylight.mdsal.dom.api.query.DOMQuery;
26 import org.opendaylight.mdsal.dom.api.query.DOMQueryResult;
27 import org.opendaylight.mdsal.dom.spi.query.DOMQueryEvaluator;
28 import org.opendaylight.yangtools.concepts.Delegator;
29 import org.opendaylight.yangtools.concepts.Identifiable;
30 import org.opendaylight.yangtools.yang.binding.DataObject;
31 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
32 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
33 import org.slf4j.Logger;
34 import org.slf4j.LoggerFactory;
35
36 abstract class AbstractForwardedTransaction<T extends DOMDataTreeTransaction> implements Delegator<T>,
37         Identifiable<Object> {
38     private static final Logger LOG = LoggerFactory.getLogger(AbstractForwardedTransaction.class);
39
40     private final @NonNull AdapterContext adapterContext;
41     private final @NonNull T delegate;
42
43     AbstractForwardedTransaction(final AdapterContext adapterContext, final T delegateTx) {
44         this.adapterContext = requireNonNull(adapterContext, "Codec must not be null");
45         this.delegate = requireNonNull(delegateTx, "Delegate must not be null");
46     }
47
48     @Override
49     public final Object getIdentifier() {
50         return delegate.getIdentifier();
51     }
52
53     @Override
54     public final T getDelegate() {
55         return delegate;
56     }
57
58     protected final <S extends DOMDataTreeTransaction> S getDelegateChecked(final Class<S> txType) {
59         checkState(txType.isInstance(delegate));
60         return txType.cast(delegate);
61     }
62
63     protected final AdapterContext adapterContext() {
64         return adapterContext;
65     }
66
67     protected final <D extends DataObject> @NonNull FluentFuture<Optional<D>> doRead(
68             final DOMDataTreeReadOperations readOps, final LogicalDatastoreType store,
69             final InstanceIdentifier<D> path) {
70         checkArgument(!path.isWildcarded(), "Invalid read of wildcarded path %s", path);
71
72         final CurrentAdapterSerializer codec = adapterContext.currentSerializer();
73         final YangInstanceIdentifier domPath = codec.toYangInstanceIdentifier(path);
74
75         return readOps.read(store, domPath)
76                 .transform(optData -> optData.map(domData -> (D) codec.fromNormalizedNode(domPath, domData).getValue()),
77                     MoreExecutors.directExecutor());
78     }
79
80     protected final @NonNull FluentFuture<Boolean> doExists(final DOMDataTreeReadOperations readOps,
81             final LogicalDatastoreType store, final InstanceIdentifier<?> path) {
82         checkArgument(!path.isWildcarded(), "Invalid exists of wildcarded path %s", path);
83         return readOps.exists(store, adapterContext.currentSerializer().toYangInstanceIdentifier(path));
84     }
85
86     protected final <T extends @NonNull DataObject> @NonNull FluentFuture<QueryResult<T>> doExecute(
87             final DOMDataTreeReadOperations readOps, final @NonNull LogicalDatastoreType store,
88             final @NonNull QueryExpression<T> query) {
89         checkArgument(query instanceof DefaultQuery, "Unsupported query type %s", query);
90         final DefaultQuery<T> defaultQuery = (DefaultQuery<T>) query;
91
92         final FluentFuture<DOMQueryResult> domResult = readOps instanceof DOMDataTreeQueryOperations
93             ? ((DOMDataTreeQueryOperations) readOps).execute(store, defaultQuery.asDOMQuery())
94                 : fallbackExecute(readOps, store, defaultQuery.asDOMQuery());
95
96         return domResult.transform(defaultQuery::toQueryResult, MoreExecutors.directExecutor());
97     }
98
99     private static FluentFuture<DOMQueryResult> fallbackExecute(final @NonNull DOMDataTreeReadOperations readOps,
100             final @NonNull LogicalDatastoreType store, final @NonNull DOMQuery domQuery) {
101         LOG.trace("Fallback evaluation of {} on {}", domQuery, readOps);
102         return readOps.read(store, domQuery.getRoot())
103             .transform(
104                 node -> node.map(data -> DOMQueryEvaluator.evaluateOn(domQuery, data)).orElse(DOMQueryResult.of()),
105                 // TODO: execute on a dedicated thread pool
106                 MoreExecutors.directExecutor());
107     }
108 }