Fix checkstyle in mdsal-binding-dom-codec
[mdsal.git] / binding / mdsal-binding-dom-codec / src / main / java / org / opendaylight / mdsal / binding / dom / codec / impl / DataContainerCodecContext.java
1 /*
2  * Copyright (c) 2014 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.mdsal.binding.dom.codec.impl;
9
10 import com.google.common.base.Optional;
11 import com.google.common.collect.ImmutableCollection;
12 import com.google.common.collect.ImmutableSet;
13 import java.io.IOException;
14 import java.util.List;
15 import javax.annotation.Nonnull;
16 import javax.annotation.Nullable;
17 import org.opendaylight.mdsal.binding.dom.codec.api.BindingNormalizedNodeCachingCodec;
18 import org.opendaylight.yangtools.yang.binding.BindingStreamEventWriter;
19 import org.opendaylight.yangtools.yang.binding.DataObject;
20 import org.opendaylight.yangtools.yang.binding.DataObjectSerializer;
21 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier.PathArgument;
22 import org.opendaylight.yangtools.yang.common.QName;
23 import org.opendaylight.yangtools.yang.common.QNameModule;
24 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
25 import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
26 import org.opendaylight.yangtools.yang.data.api.schema.stream.NormalizedNodeStreamWriter;
27 import org.opendaylight.yangtools.yang.data.impl.schema.ImmutableNormalizedNodeStreamWriter;
28 import org.opendaylight.yangtools.yang.data.impl.schema.NormalizedNodeResult;
29
30 abstract class DataContainerCodecContext<D extends DataObject,T> extends NodeCodecContext<D>  {
31
32     private final DataContainerCodecPrototype<T> prototype;
33     private volatile DataObjectSerializer eventStreamSerializer;
34
35     protected DataContainerCodecContext(final DataContainerCodecPrototype<T> prototype) {
36         this.prototype = prototype;
37     }
38
39     @Override
40     public final T getSchema() {
41         return prototype.getSchema();
42     }
43
44     protected final QNameModule namespace() {
45         return prototype.getNamespace();
46     }
47
48     protected final CodecContextFactory factory() {
49         return prototype.getFactory();
50     }
51
52     @Override
53     protected YangInstanceIdentifier.PathArgument getDomPathArgument() {
54         return prototype.getYangArg();
55     }
56
57     /**
58      * Returns nested node context using supplied YANG Instance Identifier.
59      *
60      * @param arg Yang Instance Identifier Argument
61      * @return Context of child
62      * @throws IllegalArgumentException If supplied argument does not represent valid child.
63      */
64     @Override
65     public abstract NodeCodecContext<?> yangPathArgumentChild(YangInstanceIdentifier.PathArgument arg);
66
67     /**
68      * Returns nested node context using supplied Binding Instance Identifier
69      * and adds YANG instance identifiers to supplied list.
70      *
71      * @param arg Binding Instance Identifier Argument
72      * @return Context of child or null if supplied {@code arg} does not represent valid child.
73      * @throws IllegalArgumentException If supplied argument does not represent valid child.
74      */
75     @Override
76     @Nullable
77     public DataContainerCodecContext<?,?> bindingPathArgumentChild(final PathArgument arg,
78             final List<YangInstanceIdentifier.PathArgument> builder) {
79         final DataContainerCodecContext<?,?> child = streamChild(arg.getType());
80         if (child != null) {
81             if (builder != null) {
82                 child.addYangPathArgument(arg,builder);
83             }
84             return child;
85         }
86         throw new IllegalArgumentException("Supplied argument is not valid child");
87     }
88
89     /**
90      * Returns deserialized Binding Path Argument from YANG instance identifier.
91      */
92     protected PathArgument getBindingPathArgument(final YangInstanceIdentifier.PathArgument domArg) {
93         return bindingArg();
94     }
95
96     protected final PathArgument bindingArg() {
97         return prototype.getBindingArg();
98     }
99
100     @SuppressWarnings("unchecked")
101     @Override
102     public final Class<D> getBindingClass() {
103         return Class.class.cast(prototype.getBindingClass());
104     }
105
106     /**
107      * Returns child context as if it was walked by {@link BindingStreamEventWriter}. This means that to enter case, one
108      * must issue getChild(ChoiceClass).getChild(CaseClass).
109      *
110      * @param childClass child class
111      * @return Context of child node or null, if supplied class is not subtree child
112      * @throws IllegalArgumentException If supplied child class is not valid in specified context.
113      */
114     @Override
115     public abstract @Nullable <C extends DataObject> DataContainerCodecContext<C, ?> streamChild(Class<C> childClass);
116
117     /**
118      * Returns child context as if it was walked by {@link BindingStreamEventWriter}. This means that to enter case, one
119      * must issue getChild(ChoiceClass).getChild(CaseClass).
120      *
121      * @param childClass child class
122      * @return Context of child or Optional absent is supplied class is not applicable in context.
123      */
124     @Override
125     public abstract <C extends DataObject> Optional<DataContainerCodecContext<C,?>> possibleStreamChild(
126             Class<C> childClass);
127
128     @Override
129     public String toString() {
130         return getClass().getSimpleName() + " [" + prototype.getBindingClass() + "]";
131     }
132
133     @Override
134     public BindingNormalizedNodeCachingCodec<D> createCachingCodec(
135             final ImmutableCollection<Class<? extends DataObject>> cacheSpecifier) {
136         if (cacheSpecifier.isEmpty()) {
137             return new NonCachingCodec<>(this);
138         }
139         return new CachingNormalizedNodeCodec<>(this,ImmutableSet.copyOf(cacheSpecifier));
140     }
141
142     BindingStreamEventWriter createWriter(final NormalizedNodeStreamWriter domWriter) {
143         return BindingToNormalizedStreamWriter.create(this, domWriter);
144     }
145
146     @Nonnull
147     protected final <V> V childNonNull(@Nullable final V nullable, final YangInstanceIdentifier.PathArgument child,
148             final String message, final Object... args) {
149         if (nullable != null) {
150             return nullable;
151         }
152         MissingSchemaException.checkModulePresent(factory().getRuntimeContext().getSchemaContext(), child);
153         throw IncorrectNestingException.create(message, args);
154     }
155
156     @Nonnull
157     protected final <V> V childNonNull(@Nullable final V nullable, final QName child, final String message,
158             final Object... args) {
159         if (nullable != null) {
160             return nullable;
161         }
162         MissingSchemaException.checkModulePresent(factory().getRuntimeContext().getSchemaContext(), child);
163         throw IncorrectNestingException.create(message, args);
164     }
165
166     @Nonnull
167     protected final <V> V childNonNull(@Nullable final V nullable, final Class<?> childClass, final String message,
168             final Object... args) {
169         if (nullable != null) {
170             return nullable;
171         }
172         MissingSchemaForClassException.check(factory().getRuntimeContext(), childClass);
173         MissingClassInLoadingStrategyException.check(factory().getRuntimeContext().getStrategy(), childClass);
174         throw IncorrectNestingException.create(message, args);
175     }
176
177     DataObjectSerializer eventStreamSerializer() {
178         if (eventStreamSerializer == null) {
179             eventStreamSerializer = factory().getEventStreamSerializer(getBindingClass());
180         }
181         return eventStreamSerializer;
182     }
183
184     @Override
185     public NormalizedNode<?, ?> serialize(final D data) {
186         final NormalizedNodeResult result = new NormalizedNodeResult();
187         // We create DOM stream writer which produces normalized nodes
188         final NormalizedNodeStreamWriter domWriter = ImmutableNormalizedNodeStreamWriter.from(result);
189         writeAsNormalizedNode(data, domWriter);
190         return result.getResult();
191     }
192
193     @Override
194     public void writeAsNormalizedNode(final D data, final NormalizedNodeStreamWriter writer) {
195         try {
196             eventStreamSerializer().serialize(data, createWriter(writer));
197         } catch (final IOException e) {
198             throw new IllegalStateException("Failed to serialize Binding DTO",e);
199         }
200     }
201
202 }