Added getParent() method to DataSchemaNode and DataNodeContainer. Fixed Bugs.
[yangtools.git] / yang / yang-model-util / src / main / java / org / opendaylight / yangtools / yang / model / util / DataNodeIterator.java
1 /*
2  * Copyright (c) 2013 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.yangtools.yang.model.util;
9
10 import java.util.ArrayList;
11 import java.util.Iterator;
12 import java.util.List;
13 import java.util.Set;
14
15 import org.opendaylight.yangtools.yang.model.api.ChoiceCaseNode;
16 import org.opendaylight.yangtools.yang.model.api.ChoiceNode;
17 import org.opendaylight.yangtools.yang.model.api.ContainerSchemaNode;
18 import org.opendaylight.yangtools.yang.model.api.DataNodeContainer;
19 import org.opendaylight.yangtools.yang.model.api.DataSchemaNode;
20 import org.opendaylight.yangtools.yang.model.api.GroupingDefinition;
21 import org.opendaylight.yangtools.yang.model.api.ListSchemaNode;
22 import org.opendaylight.yangtools.yang.model.api.Module;
23 import org.opendaylight.yangtools.yang.model.api.NotificationDefinition;
24 import org.opendaylight.yangtools.yang.model.api.RpcDefinition;
25 import org.opendaylight.yangtools.yang.model.api.TypeDefinition;
26
27 public class DataNodeIterator implements Iterator<DataSchemaNode> {
28
29     private final DataNodeContainer container;
30     private final List<ListSchemaNode> allLists;
31     private final List<ContainerSchemaNode> allContainers;
32     private final List<ChoiceNode> allChoices;
33     private final List<DataSchemaNode> allChilds;
34     private final List<GroupingDefinition> allGroupings;
35     private final List<TypeDefinition<?>> allTypedefs;
36
37     public DataNodeIterator(final DataNodeContainer container) {
38         if (container == null) {
39             throw new IllegalArgumentException("Data Node Container MUST be specified and cannot be NULL!");
40         }
41
42         this.allContainers = new ArrayList<>();
43         this.allLists = new ArrayList<>();
44         this.allChilds = new ArrayList<>();
45         this.allChoices = new ArrayList<>();
46         this.allGroupings = new ArrayList<>();
47         this.allTypedefs = new ArrayList<>();
48
49         this.container = container;
50         traverse(this.container);
51     }
52
53     public List<ContainerSchemaNode> allContainers() {
54         return allContainers;
55     }
56
57     public List<ListSchemaNode> allLists() {
58         return allLists;
59     }
60
61     public List<ChoiceNode> allChoices() {
62         return allChoices;
63     }
64
65     public List<GroupingDefinition> allGroupings() {
66         return allGroupings;
67     }
68
69     public List<TypeDefinition<?>> allTypedefs() {
70         return allTypedefs;
71     }
72
73     private void traverse(final DataNodeContainer dataNode) {
74         if (dataNode == null) {
75             return;
76         }
77
78         final Set<DataSchemaNode> childNodes = dataNode.getChildNodes();
79         if (childNodes != null) {
80             for (DataSchemaNode childNode : childNodes) {
81                 if (childNode.isAugmenting()) {
82                     continue;
83                 }
84                 allChilds.add(childNode);
85                 if (childNode instanceof ContainerSchemaNode) {
86                     final ContainerSchemaNode containerNode = (ContainerSchemaNode) childNode;
87                     allContainers.add(containerNode);
88                     traverse(containerNode);
89                 } else if (childNode instanceof ListSchemaNode) {
90                     final ListSchemaNode list = (ListSchemaNode) childNode;
91                     allLists.add(list);
92                     traverse(list);
93                 } else if (childNode instanceof ChoiceNode) {
94                     final ChoiceNode choiceNode = (ChoiceNode) childNode;
95                     allChoices.add(choiceNode);
96                     final Set<ChoiceCaseNode> cases = choiceNode.getCases();
97                     if (cases != null) {
98                         for (final ChoiceCaseNode caseNode : cases) {
99                             traverse(caseNode);
100                         }
101                     }
102                 }
103             }
104         }
105
106         this.allTypedefs.addAll(dataNode.getTypeDefinitions());
107         traverseModule(dataNode);
108         traverseGroupings(dataNode);
109
110     }
111
112     private void traverseModule(DataNodeContainer dataNode) {
113         final Module module;
114         if (dataNode instanceof Module) {
115             module = (Module) dataNode;
116         } else {
117             return;
118         }
119
120         final Set<NotificationDefinition> notifications = module.getNotifications();
121         for (NotificationDefinition notificationDefinition : notifications) {
122             traverse(notificationDefinition);
123         }
124
125         final Set<RpcDefinition> rpcs = module.getRpcs();
126         for (RpcDefinition rpcDefinition : rpcs) {
127             this.allTypedefs.addAll(rpcDefinition.getTypeDefinitions());
128             ContainerSchemaNode input = rpcDefinition.getInput();
129             if (input != null) {
130                 traverse(input);
131             }
132             ContainerSchemaNode output = rpcDefinition.getInput();
133             if (input != null) {
134                 traverse(output);
135             }
136         }
137     }
138
139     private void traverseGroupings(DataNodeContainer dataNode) {
140         final Set<GroupingDefinition> groupings = dataNode.getGroupings();
141         if (groupings != null) {
142             for (GroupingDefinition grouping : groupings) {
143                 allGroupings.add(grouping);
144                 traverse(grouping);
145             }
146         }
147     }
148
149     @Override
150     public boolean hasNext() {
151         if (container.getChildNodes() != null) {
152             final Set<DataSchemaNode> childNodes = container.getChildNodes();
153
154             if ((childNodes != null) && !childNodes.isEmpty()) {
155                 return childNodes.iterator().hasNext();
156             }
157         }
158         return false;
159     }
160
161     @Override
162     public DataSchemaNode next() {
163         return allChilds.iterator().next();
164     }
165
166     @Override
167     public void remove() {
168         throw new UnsupportedOperationException();
169     }
170 }