Switch to Objects.requireNonNull
[mdsal.git] / binding2 / mdsal-binding2-dom-codec / src / main / java / org / opendaylight / mdsal / binding / javav2 / dom / codec / generator / spi / source / AbstractTreeNodeSerializerSource.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.generator.spi.source;
9
10 import static java.util.Objects.requireNonNull;
11
12 import com.google.common.annotations.Beta;
13 import org.opendaylight.mdsal.binding.javav2.dom.codec.generator.spi.generator.AbstractGenerator;
14 import org.opendaylight.mdsal.binding.javav2.dom.codec.generator.spi.generator.AbstractStreamWriterGenerator;
15 import org.opendaylight.mdsal.binding.javav2.generator.api.ClassLoadingStrategy;
16 import org.opendaylight.mdsal.binding.javav2.generator.impl.GeneratedClassLoadingStrategy;
17 import org.opendaylight.mdsal.binding.javav2.model.api.Type;
18 import org.opendaylight.mdsal.binding.javav2.spec.base.Instantiable;
19 import org.opendaylight.mdsal.binding.javav2.spec.base.TreeNode;
20 import org.opendaylight.mdsal.binding.javav2.spec.runtime.BindingStreamEventWriter;
21 import org.opendaylight.mdsal.binding.javav2.spec.runtime.TreeNodeSerializerRegistry;
22
23 @Beta
24 public abstract class AbstractTreeNodeSerializerSource extends AbstractSource {
25
26     private static final ClassLoadingStrategy STRATEGY = GeneratedClassLoadingStrategy.getTCCLClassLoadingStrategy();
27
28     static final String SERIALIZER = "_serializer";
29     static final String STREAM = "_stream";
30     static final String ITERATOR = "_iterator";
31     static final String CURRENT = "_current";
32     static final String REGISTRY = "_registry";
33
34     private final AbstractGenerator generator;
35
36     /**
37      * Set up generator.
38      *
39      * @param generator
40      *            -parent generator
41      */
42     AbstractTreeNodeSerializerSource(final AbstractGenerator generator) {
43         this.generator = requireNonNull(generator);
44     }
45
46     @SuppressWarnings("unchecked")
47     Class<? extends Instantiable<?>> loadClass(final Type childType) {
48         try {
49             return (Class<? extends Instantiable<?>>) STRATEGY.loadClass(childType);
50         } catch (final ClassNotFoundException e) {
51             throw new IllegalStateException("Could not load referenced class ", e);
52         }
53     }
54
55     /**
56      * Returns body of static serialize method.
57      *
58      * <ul>
59      * <li>{@link TreeNodeSerializerRegistry} - registry of serializers
60      * <li>{@link TreeNode} - node to be serialized
61      * <li>{@link BindingStreamEventWriter} - writer to which events should be
62      * serialized
63      * </ul>
64      *
65      * @return valid javassist code describing static serialization body
66      */
67     public abstract CharSequence getSerializerBody();
68
69     /**
70      * Invoking leafNode method of stream with arguments local name and value.
71      *
72      * @param localName
73      *            - argument for invoking leafNode
74      * @param value
75      *            - argument for invoking leafNode
76      * @return invoking leafNode method as String
77      */
78     static final CharSequence leafNode(final String localName, final CharSequence value) {
79         return invoke(STREAM, "leafNode", escape(localName), value);
80     }
81
82     /**
83      * Invoking startLeafSet method of stream with arguments local name and
84      * expected.
85      *
86      * @param localName
87      *            - argument for invoking startLeafSet
88      * @param expected
89      *            - argument for invoking startLeafSet
90      * @return invoking startLeafSet method as String
91      */
92     static final CharSequence startLeafSet(final String localName, final CharSequence expected) {
93         return invoke(STREAM, "startLeafSet", escape(localName), expected);
94     }
95
96     /**
97      * Invoking startOrderedLeafSet method of stream with arguments localname
98      * and expected.
99      *
100      * @param localName
101      *            - argument for invoking startOrderedLeafSet
102      * @param expected
103      *            - argument for invoking startOrderedLeafSet
104      * @return invoking startOrderedLeafSet method as String
105      */
106     static final CharSequence startOrderedLeafSet(final String localName, final CharSequence expected) {
107         return invoke(STREAM, "startOrderedLeafSet", escape(localName), expected);
108     }
109
110     /**
111      * Bound local name by quotes.
112      *
113      * @param localName
114      *            - to be bounded
115      * @return bounded local name
116      */
117     static final CharSequence escape(final String localName) {
118         return '"' + localName + '"';
119     }
120
121     /**
122      * Invoking leafSetEntryNode method of stream with argument value.
123      *
124      * @param value
125      *            - argument for invoking leafSetEntryNode
126      * @return invoking leafSetEntryNode method as String
127      */
128     static final CharSequence leafSetEntryNode(final CharSequence value) {
129         return invoke(STREAM, "leafSetEntryNode", value);
130     }
131
132     /**
133      * Invoking startContainerNode method of stream with arguments type and
134      * expected.
135      *
136      * @param type
137      *            - argument for invoking startContainerNode
138      * @param expected
139      *            - argument for invoking startContainerNode
140      * @return invoking startContainerNode method as String
141      */
142     public static final CharSequence startContainerNode(final CharSequence type, final CharSequence expected) {
143         return invoke(STREAM, "startContainerNode", type, expected);
144     }
145
146     /**
147      * Invoking startUnkeyedList method of stream with arguments type and
148      * expected.
149      *
150      * @param type
151      *            - argument for invoking startUnkeyedList
152      * @param expected
153      *            - argument for invoking startUnkeyedList
154      * @return invoking startUnkeyedList method as String
155      */
156     static final CharSequence startUnkeyedList(final CharSequence type, final CharSequence expected) {
157         return invoke(STREAM, "startUnkeyedList", type, expected);
158     }
159
160     /**
161      * Invoking startUnkeyedListItem of stream with argument expected.
162      *
163      * @param expected
164      *            - argument for invoking startUnkeyedListItem
165      * @return invoking startUnkeyedListItem method as String
166      */
167     protected static final CharSequence startUnkeyedListItem(final CharSequence expected) {
168         return invoke(STREAM, "startUnkeyedListItem", expected);
169     }
170
171     /**
172      * Invoking startMapNode method of stream with arguments type and expected.
173      *
174      * @param type
175      *            - argument for invoking startMapNode
176      * @param expected
177      *            - argument for invoking startMapNode
178      * @return invoking startMapNode method as String
179      */
180     static final CharSequence startMapNode(final CharSequence type, final CharSequence expected) {
181         return invoke(STREAM, "startMapNode", type, expected);
182     }
183
184     /**
185      * Invoking startOrderedMapNode method of stream with arguments type and
186      * expected.
187      *
188      * @param type
189      *            - argument for invoking startOrderedMapNode
190      * @param expected
191      *            - argument for invoking startOrderedMapNode
192      * @return invoking startOrderedMapNode method as String
193      */
194     static final CharSequence startOrderedMapNode(final CharSequence type, final CharSequence expected) {
195         return invoke(STREAM, "startOrderedMapNode", type, expected);
196     }
197
198     /**
199      * Invoking startMapEntryNode method of stream with arguments key and
200      * expected.
201      *
202      * @param key
203      *            - argument for invoking startMapEntryNode
204      * @param expected
205      *            - argument for invoking startMapEntryNode
206      * @return invoking startMapEntryNode method as String
207      */
208     protected static final CharSequence startMapEntryNode(final CharSequence key, final CharSequence expected) {
209         return invoke(STREAM, "startMapEntryNode", key, expected);
210     }
211
212     /**
213      * Invoking startAugmentationNode of stream with argument key.
214      *
215      * @param key
216      *            - argument for invoking startAugmentationNode
217      * @return invoking startAugmentationNode method as String
218      */
219     protected static final CharSequence startAugmentationNode(final CharSequence key) {
220         return invoke(STREAM, "startAugmentationNode", key);
221     }
222
223     /**
224      * Invoking startChoiceNode method of stream with arguments localname and
225      * expected.
226      *
227      * @param localName
228      *            - argument for invoking startChoiceNode
229      * @param expected
230      *            - argument for invoking startChoiceNode
231      * @return invoking startChoiceNode method as String
232      */
233     static final CharSequence startChoiceNode(final CharSequence localName, final CharSequence expected) {
234         return invoke(STREAM, "startChoiceNode", localName, expected);
235     }
236
237     /**
238      * Invoking startCaseNode method of stream with arguments localname and
239      * expected.
240      *
241      * @param localName
242      *            - argument for invoking startCaseNode
243      * @param expected
244      *            - argument for invoking startCaseNode
245      * @return invoking startCaseNode method as String
246      */
247     protected static final CharSequence startCaseNode(final CharSequence localName, final CharSequence expected) {
248         return invoke(STREAM, "startCase", localName, expected);
249     }
250
251     /**
252      * Invoking anyxmlNode method of stream with arguments name and
253      * value.
254      *
255      * @param name
256      *            - argument for invoking anyxmlNode
257      * @param value
258      *            - argument for invoking anyxmlNode
259      * @return invoking anyxmlNode method as String
260      */
261     static final CharSequence anyxmlNode(final String name, final String value)
262             throws IllegalArgumentException {
263         return invoke(STREAM, "anyxmlNode", escape(name), value);
264     }
265
266     /**
267      * Invoking anydataNode method of stream with arguments name and
268      * value.
269      *
270      * @param name
271      *            - argument for invoking anydataNode
272      * @param value
273      *            - argument for invoking anydataNode
274      * @return invoking anydataNode method as String
275      */
276     static final CharSequence anydataNode(final String name, final String value)
277             throws IllegalArgumentException {
278         return invoke(STREAM, "anydataNode", escape(name), name);
279     }
280
281     /**
282      * Invoking endNode method of stream without any arguments.
283      *
284      * @return invoking andNode method as String
285      */
286     static final CharSequence endNode() {
287         return invoke(STREAM, "endNode");
288     }
289
290     /**
291      * Prepare loop through iterable object with specific body.
292      *
293      * @param iterable
294      *            - name of iterable object
295      * @param valueType
296      *            - type of iterate objects
297      * @param body
298      *            - specific body of loop
299      * @return loop through iterable object as String
300      */
301     static final CharSequence forEach(final String iterable, final Type valueType, final CharSequence body) {
302         return forEach(iterable, ITERATOR, valueType.getFullyQualifiedName(), CURRENT, body);
303     }
304
305     /**
306      * Returns class reference for type.
307      *
308      * @param type
309      *            - type for referencing class
310      * @return referenced class of type
311      */
312     protected static final CharSequence classReference(final Type type) {
313         return type.getFullyQualifiedName() + ".class";
314     }
315
316     /**
317      * After getting class of childType from class loader, prepare invoking of
318      * serialize() method from instance of reached class of childType with
319      * arguments {@link #REGISTRY}, name and {@link #STREAM}.
320      *
321      * @param childType
322      *            - type of child for getting class from classloader
323      * @param name
324      *            - argument for invoking serialize method of instance childType
325      *            class
326      * @return invoking serialize method with specific arguments as String
327      */
328     final CharSequence staticInvokeEmitter(final Type childType, final String name) {
329         final Class<?> cls;
330         try {
331             cls = STRATEGY.loadClass(childType);
332         } catch (final ClassNotFoundException e) {
333             throw new IllegalStateException("Failed to invoke emitter", e);
334         }
335
336         final String className = this.generator.loadSerializerFor(cls) + ".getInstance()";
337         return invoke(className, AbstractStreamWriterGenerator.SERIALIZE_METHOD_NAME, REGISTRY, name, STREAM);
338     }
339 }
340