2 * Copyright (c) 2017 Pantheon Technologies s.r.o. and others. All rights reserved.
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
8 package org.opendaylight.mdsal.binding.javav2.dom.codec.impl.serializer;
10 import com.google.common.annotations.Beta;
11 import com.google.common.base.Preconditions;
12 import com.google.common.base.Throwables;
13 import java.io.IOException;
14 import org.opendaylight.mdsal.binding.javav2.dom.codec.impl.cache.AbstractBindingNormalizedNodeCacheHolder;
15 import org.opendaylight.mdsal.binding.javav2.dom.codec.impl.cache.BindingNormalizedNodeCache;
16 import org.opendaylight.mdsal.binding.javav2.dom.codec.impl.context.base.DataContainerCodecContext;
17 import org.opendaylight.mdsal.binding.javav2.spec.base.Instantiable;
18 import org.opendaylight.mdsal.binding.javav2.spec.base.TreeNode;
19 import org.opendaylight.mdsal.binding.javav2.spec.runtime.BindingSerializer;
20 import org.opendaylight.mdsal.binding.javav2.spec.runtime.BindingStreamEventWriter;
21 import org.opendaylight.mdsal.binding.javav2.spec.runtime.TreeNodeSerializer;
22 import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
23 import org.opendaylight.yangtools.yang.data.impl.schema.NormalizedNodeResult;
26 * Serializer of Binding objects to Normalized Node which uses
27 * {@link BindingNormalizedNodeCache} to cache already serialized values.
30 * This serializer implements {@link BindingStreamEventWriter} along with
31 * {@link BindingSerializer}.
33 * {@link BindingSerializer} interface is used by generated implementations of
34 * {@link TreeNodeSerializer} to provide Binding object for inspection and to
35 * prevent streaming of already serialized object.
38 public final class CachingNormalizedNodeSerializer extends ForwardingBindingStreamEventWriter
39 implements BindingSerializer<Object, TreeNode> {
41 private final NormalizedNodeResult domResult;
42 private final NormalizedNodeWithAddChildWriter domWriter;
43 private final BindingToNormalizedStreamWriter delegate;
44 private final AbstractBindingNormalizedNodeCacheHolder cacheHolder;
46 private CachingNormalizedNodeSerializer(final AbstractBindingNormalizedNodeCacheHolder cacheHolder,
47 final DataContainerCodecContext<?, ?> subtreeRoot) {
48 this.cacheHolder = cacheHolder;
49 this.domResult = new NormalizedNodeResult();
50 this.domWriter = new NormalizedNodeWithAddChildWriter(domResult);
51 this.delegate = BindingToNormalizedStreamWriter.create(subtreeRoot, domWriter);
55 protected BindingStreamEventWriter delegate() {
59 private NormalizedNode<?, ?> build() {
60 return domResult.getResult();
64 * Serializes input if it is cached, returns null otherwise.
67 * If input is cached it uses
68 * {@link NormalizedNodeWithAddChildWriter#addChild(NormalizedNode)} to
69 * provide already serialized value to underlying NormalizedNodeWriter in
70 * order to reuse value instead of creating new one using Normalized Node
74 * Note that this optional is serialization of child node invoked from
75 * {@link TreeNodeSerializer}, which may opt-out from streaming of data when
76 * non-null result is returned.
79 public NormalizedNode<?, ?> serialize(final TreeNode input) {
80 // Binding data input MUST be an instance of Instantiable too.
81 Preconditions.checkArgument(input instanceof Instantiable, "Input %s is not instantiable", input);
83 final BindingNormalizedNodeCache cachingSerializer =
84 getCacheSerializer(((Instantiable<?>) input).implementedInterface());
85 if (cachingSerializer != null) {
86 final NormalizedNode<?, ?> domData = cachingSerializer.get(input);
87 domWriter.addChild(domData);
94 * Serializes supplied data using stream writer with child cache enabled or
95 * using cache directly if cache is avalaible also for supplied Codec node.
98 * - Binding to Normalized Node Cache holder
100 * - codec Node for provided data object
102 * - data to be serialized
103 * @return Normalized Node representation of data
105 public static NormalizedNode<?, ?> serialize(final AbstractBindingNormalizedNodeCacheHolder cacheHolder,
106 final DataContainerCodecContext<?, ?> subtreeRoot, final TreeNode data) {
107 final BindingNormalizedNodeCache cache = cacheHolder.getCachingSerializer(subtreeRoot);
109 return cache.get(data);
111 return serializeUsingStreamWriter(cacheHolder, subtreeRoot, data);
114 @SuppressWarnings({ "rawtypes", "unchecked" })
115 private BindingNormalizedNodeCache getCacheSerializer(final Class type) {
116 if (cacheHolder.isCached(type)) {
117 final DataContainerCodecContext<?, ?> currentCtx = (DataContainerCodecContext<?, ?>) delegate.current();
118 if (type.equals(currentCtx.getBindingClass())) {
119 return cacheHolder.getCachingSerializer(currentCtx);
121 return cacheHolder.getCachingSerializer(currentCtx.streamChild(type));
127 * Serializes supplied data using stream writer with child cache enabled.
130 * - binding to Normalized Node Cache holder
132 * - codec Node for provided data object
134 * - data to be serialized
135 * @return Normalized Node representation of data
137 public static NormalizedNode<?, ?> serializeUsingStreamWriter(
138 final AbstractBindingNormalizedNodeCacheHolder cacheHolder,
139 final DataContainerCodecContext<?, ?> subtreeRoot, final TreeNode data) {
140 final CachingNormalizedNodeSerializer writer = new CachingNormalizedNodeSerializer(cacheHolder, subtreeRoot);
142 subtreeRoot.eventStreamSerializer().serialize(data, writer);
143 return writer.build();
144 } catch (final IOException e) {
145 throw Throwables.propagate(e);