Fix various warnings
[netconf.git] / netconf / mdsal-netconf-connector / src / main / java / org / opendaylight / netconf / mdsal / connector / ops / EditOperationStrategyProvider.java
1 /*
2  * Copyright (c) 2015 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
9 package org.opendaylight.netconf.mdsal.connector.ops;
10
11 import java.util.ArrayList;
12 import java.util.Collections;
13 import java.util.Map;
14 import javax.annotation.Nullable;
15 import org.opendaylight.netconf.api.xml.XmlNetconfConstants;
16 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.netconf.base._1._0.rev110601.EditConfigInput;
17 import org.opendaylight.yangtools.yang.common.QName;
18 import org.opendaylight.yangtools.yang.data.api.ModifyAction;
19 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.AugmentationIdentifier;
20 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifier;
21 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifierWithPredicates;
22 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeWithValue;
23 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.PathArgument;
24 import org.opendaylight.yangtools.yang.data.api.schema.AugmentationNode;
25 import org.opendaylight.yangtools.yang.data.api.schema.ChoiceNode;
26 import org.opendaylight.yangtools.yang.data.api.schema.ContainerNode;
27 import org.opendaylight.yangtools.yang.data.api.schema.DataContainerNode;
28 import org.opendaylight.yangtools.yang.data.api.schema.LeafNode;
29 import org.opendaylight.yangtools.yang.data.api.schema.LeafSetEntryNode;
30 import org.opendaylight.yangtools.yang.data.api.schema.MapEntryNode;
31 import org.opendaylight.yangtools.yang.data.api.schema.MapNode;
32 import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
33 import org.opendaylight.yangtools.yang.data.api.schema.OrderedMapNode;
34 import org.opendaylight.yangtools.yang.data.api.schema.UnkeyedListEntryNode;
35 import org.opendaylight.yangtools.yang.data.api.schema.UnkeyedListNode;
36 import org.opendaylight.yangtools.yang.data.impl.schema.builder.api.AttributesBuilder;
37 import org.opendaylight.yangtools.yang.data.impl.schema.builder.api.NormalizedNodeBuilder;
38 import org.opendaylight.yangtools.yang.data.impl.schema.transform.base.parser.ExtensibleParser;
39 import org.opendaylight.yangtools.yang.data.impl.schema.transform.dom.parser.DomToNormalizedNodeParserFactory;
40
41 class EditOperationStrategyProvider extends DomToNormalizedNodeParserFactory.BuildingStrategyProvider {
42
43     private static final QName OPERATION_ATTRIBUTE = QName.create(EditConfigInput.QNAME.getNamespace(), null,
44             XmlNetconfConstants.OPERATION_ATTR_KEY);
45
46     private final DataTreeChangeTracker changeTracker;
47
48     EditOperationStrategyProvider(final DataTreeChangeTracker changeTracker) {
49         this.changeTracker = changeTracker;
50     }
51
52     @Override
53     protected ExtensibleParser.BuildingStrategy<NodeIdentifier, LeafNode<?>> forLeaf() {
54         return new NetconfOperationLeafStrategy(changeTracker);
55     }
56
57     @Override
58     protected ExtensibleParser.BuildingStrategy<NodeIdentifier, ContainerNode> forContainer() {
59         return new NetconfOperationContainerStrategy<>(changeTracker);
60     }
61
62     @Override
63     protected ExtensibleParser.BuildingStrategy<NodeIdentifier, MapNode> forMap() {
64         return new NetconfOperationCollectionStrategy<>(changeTracker);
65     }
66
67     @Override
68     protected ExtensibleParser.BuildingStrategy<NodeWithValue, LeafSetEntryNode<?>> forLeafSetEntry() {
69         return new NetconfOperationLeafSetEntryStrategy(changeTracker);
70     }
71
72     @Override
73     protected ExtensibleParser.BuildingStrategy<NodeIdentifierWithPredicates, MapEntryNode> forMapEntry() {
74         return new NetconfOperationContainerStrategy<>(changeTracker);
75     }
76
77     @Override
78     protected ExtensibleParser.BuildingStrategy<NodeIdentifier, OrderedMapNode> forOrderedList() {
79         return new NetconfOperationCollectionStrategy<>(changeTracker);
80     }
81
82     @Override
83     protected ExtensibleParser.BuildingStrategy<NodeIdentifier, UnkeyedListEntryNode> forUnkeyedListEntry() {
84         return new NetconfOperationContainerStrategy<>(changeTracker);
85     }
86
87     @Override
88     protected ExtensibleParser.BuildingStrategy<NodeIdentifier, UnkeyedListNode> forUnkeyedList() {
89         return new NetconfOperationCollectionStrategy<>(changeTracker);
90     }
91
92     @Override
93     protected ExtensibleParser.BuildingStrategy<NodeIdentifier, ChoiceNode> forChoice() {
94         return new NetconfOperationContainerStrategy<>(changeTracker);
95     }
96
97     @Override
98     public ExtensibleParser.BuildingStrategy<AugmentationIdentifier, AugmentationNode> forAugmentation() {
99         return new NetconfOperationContainerStrategy<>(changeTracker);
100     }
101
102     private static class NetconfOperationCollectionStrategy<N extends NormalizedNode<NodeIdentifier, ?>>
103             implements ExtensibleParser.BuildingStrategy<NodeIdentifier, N> {
104         private final DataTreeChangeTracker changeTracker;
105
106         NetconfOperationCollectionStrategy(final DataTreeChangeTracker changeTracker) {
107             this.changeTracker = changeTracker;
108         }
109
110         @Nullable
111         @Override
112         public N build(final NormalizedNodeBuilder<NodeIdentifier, ?, N> builder) {
113             changeTracker.popPath();
114             return builder.build();
115         }
116
117         @Override
118         public void prepareAttributes(
119                 final Map<QName, String> attributes,
120                 final NormalizedNodeBuilder<NodeIdentifier, ?, N> containerBuilder) {
121             changeTracker.pushPath(containerBuilder.build().getIdentifier());
122         }
123     }
124
125     public static final class NetconfOperationLeafStrategy
126             implements ExtensibleParser.BuildingStrategy<NodeIdentifier, LeafNode<?>> {
127
128         private final DataTreeChangeTracker dataTreeChangeTracker;
129
130         NetconfOperationLeafStrategy(final DataTreeChangeTracker dataTreeChangeTracker) {
131             this.dataTreeChangeTracker = dataTreeChangeTracker;
132         }
133
134         @Nullable
135         @Override
136         public LeafNode<?> build(
137                 final NormalizedNodeBuilder<NodeIdentifier, ?, LeafNode<?>> builder) {
138             LeafNode<?> node = builder.build();
139             String operation = (String) node.getAttributeValue(OPERATION_ATTRIBUTE);
140             if (operation == null) {
141                 return node;
142             }
143
144             if (builder instanceof AttributesBuilder<?>) {
145                 ((AttributesBuilder<?>) builder).withAttributes(Collections.<QName, String>emptyMap());
146             }
147
148             node = builder.build();
149
150             ModifyAction action = ModifyAction.fromXmlValue(operation);
151             if (dataTreeChangeTracker.getDeleteOperationTracker() > 0
152                     || dataTreeChangeTracker .getRemoveOperationTracker() > 0) {
153                 return node;
154             }
155
156             if (action.equals(dataTreeChangeTracker.peekAction())) {
157                 return node;
158             }
159
160             dataTreeChangeTracker.pushPath(node.getIdentifier());
161             dataTreeChangeTracker.addDataTreeChange(new DataTreeChangeTracker.DataTreeChange(node, action,
162                 new ArrayList<>(dataTreeChangeTracker.getCurrentPath())));
163             dataTreeChangeTracker.popPath();
164             return null;
165         }
166
167         @Override
168         public void prepareAttributes(
169                 final Map<QName, String> attributes,
170                 final NormalizedNodeBuilder<NodeIdentifier, ?, LeafNode<?>> containerBuilder) {
171             // Noop
172         }
173     }
174
175     public static final class NetconfOperationLeafSetEntryStrategy
176             implements ExtensibleParser.BuildingStrategy<NodeWithValue, LeafSetEntryNode<?>> {
177
178         private final DataTreeChangeTracker dataTreeChangeTracker;
179
180         NetconfOperationLeafSetEntryStrategy(final DataTreeChangeTracker dataTreeChangeTracker) {
181             this.dataTreeChangeTracker = dataTreeChangeTracker;
182         }
183
184         @Nullable
185         @Override
186         public LeafSetEntryNode<?> build(final NormalizedNodeBuilder<NodeWithValue, ?, LeafSetEntryNode<?>> builder) {
187             LeafSetEntryNode<?> node = builder.build();
188             String operation = (String) node.getAttributeValue(OPERATION_ATTRIBUTE);
189             if (operation == null) {
190                 return node;
191             }
192
193             if (builder instanceof AttributesBuilder<?>) {
194                 ((AttributesBuilder<?>) builder).withAttributes(Collections.<QName, String>emptyMap());
195             }
196
197             node = builder.build();
198
199             ModifyAction action = ModifyAction.fromXmlValue(operation);
200             if (dataTreeChangeTracker.getDeleteOperationTracker() > 0
201                     || dataTreeChangeTracker.getRemoveOperationTracker() > 0) {
202                 return node;
203             }
204
205             if (action.equals(dataTreeChangeTracker.peekAction())) {
206                 return node;
207             }
208
209             dataTreeChangeTracker.pushPath(node.getIdentifier());
210             dataTreeChangeTracker.addDataTreeChange(new DataTreeChangeTracker.DataTreeChange(node, action,
211                 new ArrayList<>(dataTreeChangeTracker.getCurrentPath())));
212             dataTreeChangeTracker.popPath();
213             return null;
214         }
215
216         @Override
217         public void prepareAttributes(
218                 final Map<QName, String> attributes,
219                 final NormalizedNodeBuilder<NodeWithValue, ?, LeafSetEntryNode<?>> containerBuilder) {
220         }
221     }
222
223     public static final class NetconfOperationContainerStrategy<P extends PathArgument, N
224             extends DataContainerNode<P>> implements ExtensibleParser.BuildingStrategy<P, N> {
225
226         private final DataTreeChangeTracker dataTreeChangeTracker;
227
228         NetconfOperationContainerStrategy(final DataTreeChangeTracker dataTreeChangeTracker) {
229             this.dataTreeChangeTracker = dataTreeChangeTracker;
230         }
231
232         @Nullable
233         @Override
234         public N build(final NormalizedNodeBuilder<P, ?, N> builder) {
235             if (builder instanceof AttributesBuilder<?>) {
236                 ((AttributesBuilder<?>) builder).withAttributes(Collections.<QName, String>emptyMap());
237             }
238
239             final N node = builder.build();
240             final ModifyAction currentAction = dataTreeChangeTracker.popAction();
241
242             //if we know that we are going to delete a parent node just complete the entire subtree
243             if (dataTreeChangeTracker.getDeleteOperationTracker() > 0
244                     || dataTreeChangeTracker.getRemoveOperationTracker() > 0) {
245                 dataTreeChangeTracker.popPath();
246                 return node;
247             }
248
249             if (currentAction.equals(dataTreeChangeTracker.peekAction())) {
250                 dataTreeChangeTracker.popPath();
251                 return node;
252             }
253
254             //if parent and current actions dont match create a DataTreeChange and add it to the change list
255             //dont add a new child to the parent node
256             dataTreeChangeTracker.addDataTreeChange(new DataTreeChangeTracker.DataTreeChange(node,
257                 currentAction, new ArrayList<>(dataTreeChangeTracker.getCurrentPath())));
258             dataTreeChangeTracker.popPath();
259             return null;
260         }
261
262         @Override
263         public void prepareAttributes(final Map<QName, String> attributes,
264                                       final NormalizedNodeBuilder<P, ?, N> containerBuilder) {
265             dataTreeChangeTracker.pushPath(containerBuilder.build().getIdentifier());
266             final String operation = attributes.get(OPERATION_ATTRIBUTE);
267             if (operation != null) {
268                 dataTreeChangeTracker.pushAction(ModifyAction.fromXmlValue(operation));
269             } else {
270                 dataTreeChangeTracker.pushAction(dataTreeChangeTracker.peekAction() != null
271                         ? dataTreeChangeTracker.peekAction() : dataTreeChangeTracker.getDefaultAction());
272             }
273         }
274     }
275 }