2 * Copyright (c) 2014 Cisco Systems, Inc. and others. All rights reserved.
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
8 package org.opendaylight.controller.sal.dom.broker.impl;
10 import static com.google.common.base.Preconditions.checkState;
12 import com.google.common.collect.Iterables;
15 import java.util.ArrayList;
16 import java.util.Arrays;
17 import java.util.Collection;
18 import java.util.Collections;
19 import java.util.HashMap;
20 import java.util.List;
22 import java.util.Map.Entry;
25 import org.opendaylight.controller.md.sal.common.impl.routing.AbstractDataReadRouter;
26 import org.opendaylight.yangtools.yang.common.QName;
27 import org.opendaylight.yangtools.yang.data.api.CompositeNode;
28 import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier;
29 import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier.NodeIdentifierWithPredicates;
30 import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier.PathArgument;
31 import org.opendaylight.yangtools.yang.data.api.Node;
32 import org.opendaylight.yangtools.yang.data.api.SimpleNode;
33 import org.opendaylight.yangtools.yang.data.impl.CompositeNodeTOImpl;
34 import org.slf4j.Logger;
35 import org.slf4j.LoggerFactory;
37 public class DataReaderRouter extends
38 AbstractDataReadRouter<InstanceIdentifier, CompositeNode> {
39 private final static Logger LOG = LoggerFactory
40 .getLogger(DataReaderRouter.class);
41 private final static URI NETCONF_NAMESPACE = URI
42 .create("urn:ietf:params:xml:ns:netconf:base:1.0");
43 private final static QName NETCONF_DATA = new QName(NETCONF_NAMESPACE,
47 protected CompositeNodeTOImpl merge(final InstanceIdentifier path,
48 final Iterable<CompositeNode> data) {
49 PathArgument pathArgument = Iterables.getLast(path.getPathArguments(), null);
51 QName name = (pathArgument == null ? null : pathArgument.getNodeType());
52 final ArrayList<Node<?>> nodes = new ArrayList<Node<?>>();
53 final HashMap<QName, SimpleNode<?>> keyNodes = new HashMap<QName, SimpleNode<?>>();
54 for (final CompositeNode dataBit : data) {
56 if (pathArgument != null && dataBit != null) {
58 final Map<QName, SimpleNode<?>> keyNodesLocal = getKeyNodes(
59 pathArgument, dataBit);
60 nodes.addAll(this.childrenWithout(dataBit,
61 keyNodesLocal.entrySet()));
62 } else if (dataBit != null) {
64 nodes.addAll(dataBit.getValue());
66 } catch (IllegalStateException e) {
67 LOG.error("BUG: Readed data for path {} was invalid", path, e);
77 if (pathArgument == null) {
78 return new CompositeNodeTOImpl(NETCONF_DATA, null, nodes);
80 final ArrayList<Node<?>> finalNodes = new ArrayList<Node<?>>(
81 nodes.size() + keyNodes.size());
82 finalNodes.addAll(keyNodes.values());
83 finalNodes.addAll(nodes);
84 return new CompositeNodeTOImpl(name, null, finalNodes);
87 protected Map<QName, SimpleNode<?>> _getKeyNodes(
88 final PathArgument argument, final CompositeNode node) {
89 return Collections.emptyMap();
92 protected Map<QName, SimpleNode<?>> _getKeyNodes(
93 final NodeIdentifierWithPredicates argument,
94 final CompositeNode node) {
95 final HashMap<QName, SimpleNode<?>> ret = new HashMap<QName, SimpleNode<?>>();
96 for (final Entry<QName, Object> keyValue : argument.getKeyValues()
98 final List<SimpleNode<?>> simpleNode = node
99 .getSimpleNodesByName(keyValue.getKey());
100 if (simpleNode != null && !simpleNode.isEmpty()) {
102 simpleNode.size() <= 1,
103 "Only one simple node for key $s is allowed in node $s",
104 keyValue.getKey(), node);
106 simpleNode.get(0).getValue().equals(keyValue.getValue()),
107 "Key node must equal to instance identifier value in node $s",
109 ret.put(keyValue.getKey(), simpleNode.get(0));
111 final List<CompositeNode> compositeNode = node
112 .getCompositesByName(keyValue.getKey());
113 checkState(compositeNode == null || compositeNode.isEmpty(),
114 "Key node must be Simple Node, not composite node.");
119 public Map<QName, SimpleNode<?>> getKeyNodes(
120 final InstanceIdentifier.PathArgument argument,
121 final CompositeNode node) {
122 if (argument instanceof InstanceIdentifier.NodeIdentifierWithPredicates) {
124 (InstanceIdentifier.NodeIdentifierWithPredicates) argument,
126 } else if (argument != null) {
127 return _getKeyNodes(argument, node);
129 throw new IllegalArgumentException("Unhandled parameter types: "
130 + Arrays.<Object> asList(argument, node).toString());
134 private Collection<? extends Node<?>> childrenWithout(
135 final CompositeNode node,
136 final Set<Entry<QName, SimpleNode<?>>> entries) {
137 if (entries.isEmpty()) {
138 return node.getValue();
140 final List<Node<?>> filteredNodes = new ArrayList<Node<?>>();
141 for (final Node<?> scannedNode : node.getValue()) {
142 if (!entries.contains(scannedNode.getNodeType())) {
143 filteredNodes.add(scannedNode);
146 return filteredNodes;