Merge "Yang Changes to include list<actions> to PacketOut - Added list<actions> and...
[controller.git] / opendaylight / md-sal / sal-dom-broker / src / main / java / org / opendaylight / controller / sal / dom / broker / impl / DataReaderRouter.xtend
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.controller.sal.dom.broker.impl
9
10 import org.opendaylight.controller.md.sal.common.impl.routing.AbstractDataReadRouter
11 import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier
12 import org.opendaylight.yangtools.yang.data.api.CompositeNode
13 import org.opendaylight.controller.md.sal.common.api.data.DataReader
14 import org.opendaylight.yangtools.yang.common.QName
15 import java.net.URI
16 import java.util.List
17 import org.opendaylight.yangtools.yang.data.api.Node
18 import java.util.ArrayList
19 import org.opendaylight.yangtools.yang.data.impl.SimpleNodeTOImpl
20 import java.util.Map
21 import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier.PathArgument
22 import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier.NodeIdentifier
23 import org.opendaylight.yangtools.yang.data.api.SimpleNode
24 import java.util.Collections
25 import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier.NodeIdentifierWithPredicates
26 import java.util.HashMap
27 import static com.google.common.base.Preconditions.*;
28 import java.util.Collection
29 import java.util.Set
30 import java.util.Map.Entry
31 import org.slf4j.LoggerFactory
32 import org.opendaylight.yangtools.yang.data.impl.CompositeNodeTOImpl
33
34 class DataReaderRouter extends AbstractDataReadRouter<InstanceIdentifier, CompositeNode> {
35     private static val LOG = LoggerFactory.getLogger(DataReaderRouter);
36     private static val NETCONF_NAMESPACE = URI.create("urn:ietf:params:xml:ns:netconf:base:1.0")
37     private static val NETCONF_DATA = new QName(NETCONF_NAMESPACE,"data");
38
39     override protected merge(InstanceIdentifier path, Iterable<CompositeNode> data) {
40         val pathArgument = path.path.last;
41         var empty = true;
42         var name = pathArgument?.nodeType;
43         val nodes = new ArrayList<Node<?>>();
44         val keyNodes = new HashMap<QName, SimpleNode<?>>();
45         val iterator = data.iterator;
46         for(dataBit : data) {
47             try {
48                 if(pathArgument != null && dataBit != null) {
49                     empty = false;
50                     val keyNodesLocal = getKeyNodes(pathArgument,dataBit);
51                     nodes.addAll(dataBit.childrenWithout(keyNodesLocal.entrySet));
52                 } else if (dataBit != null) {
53                     empty = false;
54                     nodes.addAll(dataBit.children)
55                 }
56             }   catch (IllegalStateException e) {
57                 LOG.error("BUG: Readed data for path {} was invalid",path,e);
58             }
59         }
60         if(empty) {
61             return null;
62         }
63         /**
64          * Reading from Root
65          * 
66          */
67         if(pathArgument == null) {
68             return new CompositeNodeTOImpl(NETCONF_DATA,null,nodes);
69         }
70         val finalNodes = new ArrayList<Node<?>>();
71         finalNodes.addAll(keyNodes.values);
72         finalNodes.addAll(nodes);
73         return new CompositeNodeTOImpl(name,null,finalNodes);
74     }
75     
76     
77     
78     dispatch def Map<QName, SimpleNode<?>> getKeyNodes(PathArgument argument, CompositeNode node) {
79         return Collections.emptyMap();
80     }
81     
82     dispatch def getKeyNodes(NodeIdentifierWithPredicates argument, CompositeNode node) {
83         val ret = new HashMap<QName, SimpleNode<?>>();
84         for (keyValue : argument.keyValues.entrySet) {
85             val simpleNode = node.getSimpleNodesByName(keyValue.key);
86             if(simpleNode !== null && !simpleNode.empty) {
87                 checkState(simpleNode.size <= 1,"Only one simple node for key $s is allowed in node $s",keyValue.key,node);
88                 checkState(simpleNode.get(0).value == keyValue.value,"Key node must equal to instance identifier value in node $s",node);
89                 ret.put(keyValue.key,simpleNode.get(0));
90             }
91             val compositeNode = node.getCompositesByName(keyValue.key);
92             checkState(compositeNode === null || compositeNode.empty,"Key node must be Simple Node, not composite node.");
93         }
94         return ret;
95     }
96     
97     def Collection<? extends Node<?>> childrenWithout(CompositeNode node, Set<Entry<QName, SimpleNode<?>>> entries) {
98         if(entries.empty) {
99             return node.children;
100         }
101         val filteredNodes = new ArrayList<Node<?>>();
102         for(scannedNode : node.children) {
103             if(!entries.contains(scannedNode.nodeType)) {
104                 filteredNodes.add(scannedNode);
105             }
106         }
107         return filteredNodes;
108     }
109     
110 }