Adjust to yangtools-2.0.0 changes
[mdsal.git] / binding2 / mdsal-binding2-dom-codec / src / main / java / org / opendaylight / mdsal / binding / javav2 / dom / codec / serialized / LazySerializedContainerNode.java
1 /*
2  * Copyright (c) 2017 Pantheon Technologies s.r.o. 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.javav2.dom.codec.serialized;
9
10 import java.util.Collection;
11 import java.util.Map;
12 import java.util.Optional;
13 import javax.annotation.Nonnull;
14 import org.opendaylight.mdsal.binding.javav2.dom.codec.impl.BindingNormalizedNodeCodecRegistry;
15 import org.opendaylight.mdsal.binding.javav2.spec.base.TreeNode;
16 import org.opendaylight.yangtools.yang.common.QName;
17 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifier;
18 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.PathArgument;
19 import org.opendaylight.yangtools.yang.data.api.schema.ContainerNode;
20 import org.opendaylight.yangtools.yang.data.api.schema.DataContainerChild;
21 import org.opendaylight.yangtools.yang.data.api.schema.LeafNode;
22 import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
23 import org.opendaylight.yangtools.yang.model.api.SchemaPath;
24
25 /**
26  * Serialize operation from binding to DOM.
27  */
28 public class LazySerializedContainerNode implements ContainerNode {
29
30     private final NodeIdentifier identifier;
31     private final TreeNode bindingData;
32
33     private BindingNormalizedNodeCodecRegistry registry;
34     private ContainerNode domData;
35
36     private LazySerializedContainerNode(final QName identifier, final TreeNode binding,
37             final BindingNormalizedNodeCodecRegistry registry) {
38         this.identifier = NodeIdentifier.create(identifier);
39         this.bindingData = binding;
40         this.registry = registry;
41         this.domData = null;
42     }
43
44     /**
45      * Prepare serializer of binding data with specific codec.
46      *
47      * @param operationName
48      *            - qname of operation
49      * @param data
50      *            - binding operation
51      * @param codec
52      *            - specifc codec for operation
53      * @return instance of lazy serialized container node
54      */
55     public static NormalizedNode<?, ?> create(final SchemaPath operationName, final TreeNode data,
56             final BindingNormalizedNodeCodecRegistry codec) {
57         return new LazySerializedContainerNode(operationName.getLastComponent(), data, codec);
58     }
59
60     /**
61      * Prepare serializer of binding data with specific codec and pre-cached serialized leaf holding routing
62      * information.
63      *
64      * @param operationName
65      *            - operation name
66      * @param data
67      *            - Binding data
68      * @param contextRef
69      *            - leaf context reference
70      * @param codec
71      *            - specific codec
72      * @return insntance of lazy serialized container node with pre-cached serialized leaf
73      */
74     public static NormalizedNode<?, ?> withContextRef(final SchemaPath operationName, final TreeNode data,
75             final LeafNode<?> contextRef, final BindingNormalizedNodeCodecRegistry codec) {
76         return new WithContextRef(operationName.getLastComponent(), data, contextRef, codec);
77     }
78
79     @Override
80     public Map<QName, String> getAttributes() {
81         return delegate().getAttributes();
82     }
83
84     private ContainerNode delegate() {
85         if (domData == null) {
86             domData = registry.toNormalizedNodeOperationData(bindingData);
87             registry = null;
88         }
89         return domData;
90     }
91
92     @Override
93     public final QName getNodeType() {
94         return identifier.getNodeType();
95     }
96
97     @Override
98     public final Collection<DataContainerChild<? extends PathArgument, ?>> getValue() {
99         return delegate().getValue();
100     }
101
102     @Nonnull
103     @Override
104     public final NodeIdentifier getIdentifier() {
105         return identifier;
106     }
107
108     @Override
109     public Optional<DataContainerChild<? extends PathArgument, ?>> getChild(final PathArgument child) {
110         return delegate().getChild(child);
111     }
112
113     @Override
114     public final Object getAttributeValue(final QName name) {
115         return delegate().getAttributeValue(name);
116     }
117
118     /**
119      * Get binding data.
120      *
121      * @return binding data.
122      */
123     public final TreeNode bindingData() {
124         return bindingData;
125     }
126
127     /**
128      * Lazy Serialized Node with pre-cached serialized leaf holding routing information.
129      *
130      */
131     private static final class WithContextRef extends LazySerializedContainerNode {
132
133         private final LeafNode<?> contextRef;
134
135         private WithContextRef(final QName identifier, final TreeNode binding, final LeafNode<?> contextRef,
136                 final BindingNormalizedNodeCodecRegistry registry) {
137             super(identifier, binding, registry);
138             this.contextRef = contextRef;
139         }
140
141         @Override
142         public Optional<DataContainerChild<? extends PathArgument, ?>> getChild(final PathArgument child) {
143             /*
144              * Use precached value of routing field and do not run full serialization if we are accessing it.
145              */
146             if (contextRef.getIdentifier().equals(child)) {
147                 return Optional.of(contextRef);
148             }
149             return super.getChild(child);
150         }
151     }
152
153 }