Fix checkstyle in mdsal-binding2-dom-codec
[mdsal.git] / binding2 / mdsal-binding2-dom-codec / src / main / java / org / opendaylight / mdsal / binding / javav2 / dom / codec / impl / serializer / CachingNormalizedNodeSerializer.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.impl.serializer;
9
10 import com.google.common.annotations.Beta;
11 import com.google.common.base.Throwables;
12 import java.io.IOException;
13 import org.opendaylight.mdsal.binding.javav2.dom.codec.impl.cache.AbstractBindingNormalizedNodeCacheHolder;
14 import org.opendaylight.mdsal.binding.javav2.dom.codec.impl.cache.BindingNormalizedNodeCache;
15 import org.opendaylight.mdsal.binding.javav2.dom.codec.impl.context.base.DataContainerCodecContext;
16 import org.opendaylight.mdsal.binding.javav2.spec.base.TreeNode;
17 import org.opendaylight.mdsal.binding.javav2.spec.runtime.BindingSerializer;
18 import org.opendaylight.mdsal.binding.javav2.spec.runtime.BindingStreamEventWriter;
19 import org.opendaylight.mdsal.binding.javav2.spec.runtime.TreeNodeSerializer;
20 import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
21 import org.opendaylight.yangtools.yang.data.impl.schema.NormalizedNodeResult;
22
23 /**
24  * Serializer of Binding objects to Normalized Node which uses
25  * {@link BindingNormalizedNodeCache} to cache already serialized values.
26  *
27  * <p>
28  * This serializer implements {@link BindingStreamEventWriter} along with
29  * {@link BindingSerializer}.
30  *
31  * {@link BindingSerializer} interface is used by generated implementations of
32  * {@link TreeNodeSerializer} to provide Binding object for inspection and to
33  * prevent streaming of already serialized object.
34  */
35 @Beta
36 public final class CachingNormalizedNodeSerializer extends ForwardingBindingStreamEventWriter
37         implements BindingSerializer<Object, TreeNode> {
38
39     private final NormalizedNodeResult domResult;
40     private final NormalizedNodeWithAddChildWriter domWriter;
41     private final BindingToNormalizedStreamWriter delegate;
42     private final AbstractBindingNormalizedNodeCacheHolder cacheHolder;
43
44     private CachingNormalizedNodeSerializer(final AbstractBindingNormalizedNodeCacheHolder cacheHolder,
45             final DataContainerCodecContext<?, ?> subtreeRoot) {
46         this.cacheHolder = cacheHolder;
47         this.domResult = new NormalizedNodeResult();
48         this.domWriter = new NormalizedNodeWithAddChildWriter(domResult);
49         this.delegate = BindingToNormalizedStreamWriter.create(subtreeRoot, domWriter);
50     }
51
52     @Override
53     protected BindingStreamEventWriter delegate() {
54         return delegate;
55     }
56
57     private NormalizedNode<?, ?> build() {
58         return domResult.getResult();
59     }
60
61     /**
62      * Serializes input if it is cached, returns null otherwise.
63      *
64      * <p>
65      * If input is cached it uses
66      * {@link NormalizedNodeWithAddChildWriter#addChild(NormalizedNode)} to
67      * provide already serialized value to underlying NormalizedNodeWriter in
68      * order to reuse value instead of creating new one using Normalized Node
69      * stream APIs.
70      *
71      * <p>
72      * Note that this optional is serialization of child node invoked from
73      * {@link TreeNodeSerializer}, which may opt-out from streaming of data when
74      * non-null result is returned.
75      */
76     @Override
77     public NormalizedNode<?, ?> serialize(final TreeNode input) {
78         final BindingNormalizedNodeCache cachingSerializer = getCacheSerializer(input.getClass());
79         if (cachingSerializer != null) {
80             final NormalizedNode<?, ?> domData = cachingSerializer.get(input);
81             domWriter.addChild(domData);
82             return domData;
83         }
84         return null;
85     }
86
87     /**
88      * Serializes supplied data using stream writer with child cache enabled or
89      * using cache directly if cache is avalaible also for supplied Codec node.
90      *
91      * @param cacheHolder
92      *            - Binding to Normalized Node Cache holder
93      * @param subtreeRoot
94      *            - codec Node for provided data object
95      * @param data
96      *            - data to be serialized
97      * @return Normalized Node representation of data
98      */
99     public static NormalizedNode<?, ?> serialize(final AbstractBindingNormalizedNodeCacheHolder cacheHolder,
100             final DataContainerCodecContext<?, ?> subtreeRoot, final TreeNode data) {
101         final BindingNormalizedNodeCache cache = cacheHolder.getCachingSerializer(subtreeRoot);
102         if (cache != null) {
103             return cache.get(data);
104         }
105         return serializeUsingStreamWriter(cacheHolder, subtreeRoot, data);
106     }
107
108     @SuppressWarnings({ "rawtypes", "unchecked" })
109     private BindingNormalizedNodeCache getCacheSerializer(final Class type) {
110         if (cacheHolder.isCached(type)) {
111             final DataContainerCodecContext<?, ?> currentCtx = (DataContainerCodecContext<?, ?>) delegate.current();
112             if (type.equals(currentCtx.getBindingClass())) {
113                 return cacheHolder.getCachingSerializer(currentCtx);
114             }
115             return cacheHolder.getCachingSerializer(currentCtx.streamChild(type));
116         }
117         return null;
118     }
119
120     /**
121      * Serializes supplied data using stream writer with child cache enabled.
122      *
123      * @param cacheHolder
124      *            - binding to Normalized Node Cache holder
125      * @param subtreeRoot
126      *            - codec Node for provided data object
127      * @param data
128      *            - data to be serialized
129      * @return Normalized Node representation of data
130      */
131     public static NormalizedNode<?, ?> serializeUsingStreamWriter(
132             final AbstractBindingNormalizedNodeCacheHolder cacheHolder,
133             final DataContainerCodecContext<?, ?> subtreeRoot, final TreeNode data) {
134         final CachingNormalizedNodeSerializer writer = new CachingNormalizedNodeSerializer(cacheHolder, subtreeRoot);
135         try {
136             subtreeRoot.eventStreamSerializer().serialize(data, writer);
137             return writer.build();
138         } catch (final IOException e) {
139             throw Throwables.propagate(e);
140         }
141     }
142 }