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