2 * Copyright (c) 2014 Cisco Systems, Inc. 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.yangtools.sal.binding.generator.impl
10 import com.google.common.base.Joiner
12 import java.security.ProtectionDomain
13 import java.util.AbstractMap.SimpleEntry
14 import java.util.Collection
15 import java.util.Collections
16 import java.util.HashMap
17 import java.util.HashSet
18 import java.util.Iterator
21 import java.util.Map.Entry
23 import java.util.TreeSet
24 import javassist.CannotCompileException
25 import javassist.ClassPool
26 import javassist.CtClass
27 import javassist.CtField
28 import javassist.CtMethod
29 import org.opendaylight.yangtools.binding.generator.util.BindingGeneratorUtil
30 import org.opendaylight.yangtools.binding.generator.util.ReferencedTypeImpl
31 import org.opendaylight.yangtools.binding.generator.util.Types
32 import org.opendaylight.yangtools.sal.binding.generator.util.ClassLoaderUtils
33 import org.opendaylight.yangtools.sal.binding.generator.util.CodeGenerationException
34 import org.opendaylight.yangtools.sal.binding.generator.util.XtendHelper
35 import org.opendaylight.yangtools.sal.binding.model.api.Enumeration
36 import org.opendaylight.yangtools.sal.binding.model.api.GeneratedProperty
37 import org.opendaylight.yangtools.sal.binding.model.api.GeneratedTransferObject
38 import org.opendaylight.yangtools.sal.binding.model.api.GeneratedType
39 import org.opendaylight.yangtools.sal.binding.model.api.ParameterizedType
40 import org.opendaylight.yangtools.sal.binding.model.api.Type
41 import org.opendaylight.yangtools.sal.binding.model.api.type.builder.GeneratedTypeBuilder
42 import org.opendaylight.yangtools.yang.binding.Augmentation
43 import org.opendaylight.yangtools.yang.binding.BindingCodec
44 import org.opendaylight.yangtools.yang.binding.BindingDeserializer
45 import org.opendaylight.yangtools.yang.binding.BindingMapping
46 import org.opendaylight.yangtools.yang.binding.DataObject
47 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier
48 import org.opendaylight.yangtools.yang.common.QName
49 import org.opendaylight.yangtools.yang.model.api.AugmentationSchema
50 import org.opendaylight.yangtools.yang.model.api.ChoiceCaseNode
51 import org.opendaylight.yangtools.yang.model.api.ChoiceNode
52 import org.opendaylight.yangtools.yang.model.api.ContainerSchemaNode
53 import org.opendaylight.yangtools.yang.model.api.DataNodeContainer
54 import org.opendaylight.yangtools.yang.model.api.DataSchemaNode
55 import org.opendaylight.yangtools.yang.model.api.LeafListSchemaNode
56 import org.opendaylight.yangtools.yang.model.api.LeafSchemaNode
57 import org.opendaylight.yangtools.yang.model.api.ListSchemaNode
58 import org.opendaylight.yangtools.yang.model.api.NotificationDefinition
59 import org.opendaylight.yangtools.yang.model.api.SchemaNode
60 import org.opendaylight.yangtools.yang.model.api.TypeDefinition
61 import org.opendaylight.yangtools.yang.model.api.type.BitsTypeDefinition
62 import org.opendaylight.yangtools.yang.model.api.type.BitsTypeDefinition.Bit
63 import org.opendaylight.yangtools.yang.model.api.type.EmptyTypeDefinition
64 import org.opendaylight.yangtools.yang.model.api.type.UnionTypeDefinition
65 import org.opendaylight.yangtools.yang.model.util.EnumerationType
66 import org.opendaylight.yangtools.yang.model.util.ExtendedType
67 import org.slf4j.LoggerFactory
69 import static com.google.common.base.Preconditions.*
70 import static javassist.Modifier.*
71 import static org.opendaylight.yangtools.sal.binding.generator.impl.CodecMapping.*
73 import static extension org.opendaylight.yangtools.sal.binding.generator.util.YangSchemaUtils.*
75 class TransformerGenerator extends AbstractTransformerGenerator {
76 private static val LOG = LoggerFactory.getLogger(TransformerGenerator)
78 public static val STRING = Types.typeForClass(String);
79 public static val BOOLEAN = Types.typeForClass(Boolean);
80 public static val INTEGER = Types.typeForClass(Integer);
81 public static val INSTANCE_IDENTIFIER = Types.typeForClass(InstanceIdentifier);
82 //public static val DECIMAL = Types.typeForClass(Decimal);
83 public static val LONG = Types.typeForClass(Long);
84 public static val CLASS_TYPE = Types.typeForClass(Class);
87 var File classFileCapturePath;
89 val CtClass BINDING_CODEC
92 public new(TypeResolver typeResolver, ClassPool pool) {
93 super(typeResolver, pool)
95 BINDING_CODEC = BindingCodec.asCtClass;
96 ctQName = QName.asCtClass
99 override transformerForImpl(Class inputType) {
100 return runOnClassLoader(inputType.classLoader) [ |
101 val ret = getGeneratedClass(inputType)
103 listener.onClassProcessed(inputType);
104 return ret as Class<? extends BindingCodec<Map<QName,Object>, Object>>;
106 val ref = Types.typeForClass(inputType)
107 val node = getSchemaNode(ref)
108 createMapping(inputType, node, null)
109 val typeSpecBuilder = getDefinition(ref)
110 checkState(typeSpecBuilder !== null, "Could not find typedefinition for %s", inputType.name);
111 val typeSpec = typeSpecBuilder.toInstance();
112 val newret = generateTransformerFor(inputType, typeSpec, node);
113 listener.onClassProcessed(inputType);
114 return newret as Class<? extends BindingCodec<Map<QName,Object>, Object>>;
118 def Class<? extends BindingCodec<Map<QName, Object>, Object>> transformerFor(Class<?> inputType, DataSchemaNode node) {
119 return runOnClassLoader(inputType.classLoader) [ |
120 createMapping(inputType, node, null)
121 val ret = getGeneratedClass(inputType)
123 listener.onClassProcessed(inputType);
124 return ret as Class<? extends BindingCodec<Map<QName,Object>, Object>>;
126 val ref = Types.typeForClass(inputType)
127 var typeSpecBuilder = getDefinition(ref)
128 if (typeSpecBuilder == null) {
129 typeSpecBuilder = getTypeBuilder(node.path);
132 checkState(typeSpecBuilder !== null, "Could not find TypeDefinition for %s, $s", inputType.name, node);
133 val typeSpec = typeSpecBuilder.toInstance();
134 val newret = generateTransformerFor(inputType, typeSpec, node);
135 listener.onClassProcessed(inputType);
136 return newret as Class<? extends BindingCodec<Map<QName,Object>, Object>>;
140 override augmentationTransformerForImpl(Class inputType) {
141 return runOnClassLoader(inputType.classLoader) [ |
143 val ret = getGeneratedClass(inputType)
145 return ret as Class<? extends BindingCodec<Map<QName,Object>, Object>>;
147 val ref = Types.typeForClass(inputType)
148 val node = getAugmentation(ref)
149 val typeSpecBuilder = getDefinition(ref)
150 val typeSpec = typeSpecBuilder.toInstance();
151 //mappingForNodes(node.childNodes, typeSpec.allProperties, bindingId)
152 val newret = generateAugmentationTransformerFor(inputType, typeSpec, node);
153 listener.onClassProcessed(inputType);
154 return newret as Class<? extends BindingCodec<Map<QName,Object>, Object>>;
158 override caseCodecForImpl(Class inputType, ChoiceCaseNode node) {
159 return runOnClassLoader(inputType.classLoader) [ |
160 createMapping(inputType, node, null)
161 val ret = getGeneratedClass(inputType)
163 return ret as Class<? extends BindingCodec<Object, Object>>;
165 val ref = Types.typeForClass(inputType)
166 val typeSpecBuilder = getDefinition(ref)
167 val typeSpec = typeSpecBuilder.toInstance();
168 val newret = generateCaseCodec(inputType, typeSpec, node);
169 return newret as Class<? extends BindingCodec<Object, Object>>;
173 override keyTransformerForIdentifiableImpl(Class parentType) {
174 return runOnClassLoader(parentType.classLoader) [ |
175 val inputName = parentType.name + "Key";
176 val inputType = loadClass(inputName);
177 val ret = getGeneratedClass(inputType)
179 return ret as Class<? extends BindingCodec<Map<QName,Object>, Object>>;
181 val ref = Types.typeForClass(parentType)
182 val node = getSchemaNode(ref) as ListSchemaNode
183 val typeSpecBuilder = getDefinition(ref)
184 val typeSpec = typeSpecBuilder.identifierDefinition;
185 val newret = generateKeyTransformerFor(inputType, typeSpec, node);
186 return newret as Class<? extends BindingCodec<Map<QName,Object>, Object>>;
190 private def void createMapping(Class<?> inputType, SchemaNode node, InstanceIdentifier<?> parentId) {
191 var ClassLoader cl = inputType.classLoader
193 cl = Thread.currentThread.contextClassLoader
195 ClassLoaderUtils.withClassLoader(cl,
197 if (!(node instanceof DataNodeContainer)) {
200 var InstanceIdentifier<?> bindingId = getBindingIdentifierByPath(node.path)
201 if (bindingId != null) {
204 val ref = Types.typeForClass(inputType)
205 var typeSpecBuilder = getDefinition(ref)
206 if (typeSpecBuilder == null) {
207 typeSpecBuilder = getTypeBuilder(node.path);
209 checkState(typeSpecBuilder !== null, "Could not find type definition for %s, $s", inputType.name, node);
210 val typeSpec = typeSpecBuilder.toInstance();
211 var InstanceIdentifier<?> parent
212 if (parentId == null) {
213 bindingId = InstanceIdentifier.create(inputType as Class)
215 putPathToBindingIdentifier(node.path, bindingId)
217 parent = putPathToBindingIdentifier(node.path, parentId, inputType)
219 val Map<String, Type> properties = typeSpec.allProperties
220 if (node instanceof DataNodeContainer) {
221 mappingForNodes((node as DataNodeContainer).childNodes, properties, parent)
222 } else if (node instanceof ChoiceNode) {
223 mappingForNodes((node as ChoiceNode).cases, properties, parent)
229 private def void mappingForNodes(Collection<? extends DataSchemaNode> childNodes, Map<String, Type> properties,
230 InstanceIdentifier<?> parent) {
231 for (DataSchemaNode child : childNodes) {
232 val signature = properties.getFor(child)
233 if (signature != null) {
234 val Type childType = signature.value
235 var Class<?> childTypeClass = null;
236 if (child instanceof ListSchemaNode && childType instanceof ParameterizedType) {
237 childTypeClass = loadClass((childType as ParameterizedType).actualTypeArguments.get(0))
239 childTypeClass = loadClass(childType)
241 createMapping(childTypeClass, child, parent)
246 def getIdentifierDefinition(GeneratedTypeBuilder builder) {
247 val inst = builder.toInstance
248 val keyMethod = inst.methodDefinitions.findFirst[name == "getKey"]
249 return keyMethod.returnType as GeneratedTransferObject
252 override keyTransformerForIdentifierImpl(Class inputType) {
253 return runOnClassLoader(inputType.classLoader) [ |
254 val ret = getGeneratedClass(inputType)
256 return ret as Class<? extends BindingCodec<Map<QName,Object>, Object>>;
258 val ref = Types.typeForClass(inputType)
259 val node = getSchemaNode(ref) as ListSchemaNode
260 val typeSpecBuilder = getDefinition(ref)
261 val typeSpec = typeSpecBuilder.toInstance();
262 val newret = generateKeyTransformerFor(inputType, typeSpec, node);
263 return newret as Class<? extends BindingCodec<Map<QName,Object>, Object>>;
267 private def Class<?> keyTransformerFor(Class<?> inputType, GeneratedType type, ListSchemaNode schema) {
268 return runOnClassLoader(inputType.classLoader) [ |
269 val transformer = getGeneratedClass(inputType)
270 if (transformer != null) {
273 val newret = generateKeyTransformerFor(inputType, type, schema);
274 return newret as Class<? extends BindingCodec<Map<QName,Object>, Object>>;
278 private def Class<?> getGeneratedClass(Class<? extends Object> cls) {
281 return loadClass(cls.codecClassName)
282 } catch (ClassNotFoundException e) {
287 private def Class<?> keyTransformer(GeneratedType type, ListSchemaNode node) {
288 val cls = loadClass(type.resolvedName + "Key");
289 keyTransformerFor(cls, type, node);
292 private def serializer(Type type, DataSchemaNode node) {
293 val cls = loadClass(type.resolvedName);
294 transformerFor(cls, node);
297 private def Class<?> valueSerializer(GeneratedTransferObject type, TypeDefinition<?> typeDefinition) {
298 val cls = loadClass(type.resolvedName);
299 val transformer = cls.generatedClass;
300 if (transformer !== null) {
303 var baseType = typeDefinition;
304 while (baseType.baseType != null) {
305 baseType = baseType.baseType;
307 val finalType = baseType;
308 return runOnClassLoader(cls.classLoader) [ |
309 val valueTransformer = generateValueTransformer(cls, type, finalType);
310 return valueTransformer;
314 private def Class<?> valueSerializer(Enumeration type, TypeDefinition<?> typeDefinition) {
315 val cls = loadClass(type.resolvedName);
316 val transformer = cls.generatedClass;
317 if (transformer !== null) {
321 return runOnClassLoader(cls.classLoader) [ |
322 val valueTransformer = generateValueTransformer(cls, type, typeDefinition);
323 return valueTransformer;
327 private def generateKeyTransformerFor(Class<? extends Object> inputType, GeneratedType typeSpec, ListSchemaNode node) {
330 //log.info("Generating DOM Codec for {} with {}", inputType, inputType.classLoader)
331 val properties = typeSpec.allProperties;
332 val ctCls = createClass(inputType.codecClassName) [
333 //staticField(Map,"AUGMENTATION_SERIALIZERS");
334 staticField(it, INSTANCE_IDENTIFIER_CODEC, BindingCodec)
335 staticField(it, IDENTITYREF_CODEC, BindingCodec)
336 staticQNameField(node.QName);
337 implementsType(BINDING_CODEC)
338 method(Object, "toDomStatic", #[QName, Object]) [
339 modifiers = PUBLIC + FINAL + STATIC
342 «QName.name» _resultName;
344 _resultName = «QName.name».create($1,QNAME.getLocalName());
348 java.util.List _childNodes = new java.util.ArrayList();
349 «inputType.resolvedName» value = («inputType.name») $2;
350 «FOR key : node.keyDefinition»
351 «val propertyName = key.getterName»
352 «val keyDef = node.getDataChildByName(key)»
353 «val property = properties.get(propertyName)»
354 «serializeProperty(keyDef, property, propertyName)»;
356 return ($r) java.util.Collections.singletonMap(_resultName,_childNodes);
360 method(Object, "fromDomStatic", #[QName, Object]) [
361 modifiers = PUBLIC + FINAL + STATIC
367 «QName.name» _localQName = $1;
368 java.util.Map _compositeNode = (java.util.Map) $2;
369 boolean _is_empty = true;
370 «FOR key : node.keyDefinition»
371 «val propertyName = key.getterName»
372 «val keyDef = node.getDataChildByName(key)»
373 «val property = properties.get(propertyName)»
374 «deserializeProperty(keyDef, property, propertyName)»;
376 «inputType.resolvedName» _value = new «inputType.name»(«node.keyDefinition.
377 keyConstructorList»);
382 method(Object, "serialize", Object) [
385 java.util.Map.Entry _input = (java.util.Map.Entry) $1;
386 «QName.name» _localQName = («QName.name») _input.getKey();
387 «inputType.name» _keyValue = («inputType.name») _input.getValue();
388 return toDomStatic(_localQName,_keyValue);
392 method(Object, "deserialize", Object) [
395 «QName.name» _qname = QNAME;
396 if($1 instanceof java.util.Map.Entry) {
397 _qname = («QName.name») ((java.util.Map.Entry) $1).getKey();
399 return fromDomStatic(_qname,$1);
404 val ret = ctCls.toClassImpl(inputType.classLoader, inputType.protectionDomain)
405 LOG.debug("DOM Codec for {} was generated {}", inputType, ret)
406 return ret as Class<? extends BindingCodec<Map<QName,Object>, ?>>;
407 } catch (Exception e) {
408 processException(inputType, e);
413 private def Class<? extends BindingCodec<Object, Object>> generateCaseCodec(Class<?> inputType, GeneratedType type,
414 ChoiceCaseNode node) {
416 //log.info("Generating DOM Codec for {} with {}, TCCL is: {}", inputType, inputType.classLoader,Thread.currentThread.contextClassLoader)
417 val ctCls = createClass(type.codecClassName) [
418 //staticField(Map,"AUGMENTATION_SERIALIZERS");
419 implementsType(BINDING_CODEC)
420 staticQNameField(node.QName);
421 staticField(it, INSTANCE_IDENTIFIER_CODEC, BindingCodec)
422 staticField(it, AUGMENTATION_CODEC, BindingCodec)
423 staticField(it, IDENTITYREF_CODEC, BindingCodec)
424 method(Object, "toDomStatic", #[QName, Object]) [
425 modifiers = PUBLIC + FINAL + STATIC
428 «QName.name» _resultName = «QName.name».create($1,QNAME.getLocalName());
429 java.util.List _childNodes = new java.util.ArrayList();
430 «type.resolvedName» value = («type.resolvedName») $2;
431 «transformDataContainerBody(type, type.allProperties, node)»
432 return ($r) _childNodes;
436 method(Object, "serialize", Object) [
439 java.util.Map.Entry _input = (java.util.Map.Entry) $1;
440 «QName.name» _localName = QNAME;
441 if(_input.getKey() != null) {
442 _localName = («QName.name») _input.getKey();
444 return toDomStatic(_localName,_input.getValue());
448 method(Object, "fromDomStatic", #[QName, Object, InstanceIdentifier]) [
449 modifiers = PUBLIC + FINAL + STATIC
450 bodyChecked = deserializeBody(type, node, getBindingIdentifierByPath(node.path))
452 method(Object, "deserialize", #[Object, InstanceIdentifier]) [
455 //System.out.println("«type.name»#deserialize: " +$1);
456 java.util.Map.Entry _input = (java.util.Map.Entry) $1;
457 return fromDomStatic((«QName.name»)_input.getKey(),_input.getValue(),$2);
463 val ret = ctCls.toClassImpl(inputType.classLoader, inputType.protectionDomain) as Class<? extends BindingCodec<Object, Object>>
464 listener?.onDataContainerCodecCreated(inputType, ret);
465 LOG.debug("DOM Codec for {} was generated {}", inputType, ret)
467 } catch (Exception e) {
468 processException(inputType, e);
473 private def dispatch Class<? extends BindingCodec<Map<QName, Object>, Object>> generateTransformerFor(
474 Class<?> inputType, GeneratedType typeSpec, SchemaNode node) {
477 //log.info("Generating DOM Codec for {} with {}", inputType, inputType.classLoader)
478 val ctCls = createClass(typeSpec.codecClassName) [
479 //staticField(Map,"AUGMENTATION_SERIALIZERS");
480 staticQNameField(node.QName);
481 staticField(it, INSTANCE_IDENTIFIER_CODEC, BindingCodec)
482 staticField(it, IDENTITYREF_CODEC, BindingCodec)
483 staticField(it, AUGMENTATION_CODEC, BindingCodec)
484 implementsType(BINDING_CODEC)
486 method(Object, "toDomStatic", #[QName, Object]) [
487 modifiers = PUBLIC + FINAL + STATIC
488 bodyChecked = serializeBodyFacade(typeSpec, node)
490 method(Object, "serialize", Object) [
493 java.util.Map.Entry _input = (java.util.Map.Entry) $1;
494 «QName.name» _localName = QNAME;
495 if(_input.getKey() != null) {
496 _localName = («QName.name») _input.getKey();
498 return toDomStatic(_localName,_input.getValue());
503 method(Object, "fromDomStatic", #[QName, Object, InstanceIdentifier]) [
504 modifiers = PUBLIC + FINAL + STATIC
505 bodyChecked = deserializeBody(typeSpec, node, getBindingIdentifierByPath(node.path))
508 method(Object, "deserialize", #[Object, InstanceIdentifier]) [
511 «QName.name» _qname = QNAME;
512 if($1 instanceof java.util.Map.Entry) {
513 _qname = («QName.name») ((java.util.Map.Entry) $1).getKey();
515 return fromDomStatic(_qname,$1,$2);
521 val ret = ctCls.toClassImpl(inputType.classLoader, inputType.protectionDomain) as Class<? extends BindingCodec<Map<QName,Object>, Object>>
522 listener?.onDataContainerCodecCreated(inputType, ret);
523 LOG.debug("DOM Codec for {} was generated {}", inputType, ret)
525 } catch (Exception e) {
526 processException(inputType, e);
531 private def Class<? extends BindingCodec<Map<QName, Object>, Object>> generateAugmentationTransformerFor(
532 Class<?> inputType, GeneratedType type, AugmentationSchema node) {
535 //log.info("Generating DOM Codec for {} with {}", inputType, inputType.classLoader)
536 val properties = type.allProperties
537 val ctCls = createClass(type.codecClassName) [
538 //staticField(Map,"AUGMENTATION_SERIALIZERS");
539 staticQNameField(node.augmentationQName);
540 staticField(it, INSTANCE_IDENTIFIER_CODEC, BindingCodec)
541 staticField(it, AUGMENTATION_CODEC, BindingCodec)
542 staticField(it, IDENTITYREF_CODEC, BindingCodec)
543 implementsType(BINDING_CODEC)
545 method(Object, "toDomStatic", #[QName, Object]) [
546 modifiers = PUBLIC + FINAL + STATIC
549 ////System.out.println("Qname " + $1);
550 ////System.out.println("Value " + $2);
551 «QName.name» _resultName = «QName.name».create(QNAME,QNAME.getLocalName());
552 java.util.List _childNodes = new java.util.ArrayList();
553 «type.resolvedName» value = («type.resolvedName») $2;
554 «FOR child : node.childNodes»
555 «var signature = properties.getFor(child)»
556 ////System.out.println("«signature.key»" + value.«signature.key»());
557 «serializeProperty(child, signature.value, signature.key)»
559 return ($r) _childNodes;
563 method(Object, "serialize", Object) [
566 java.util.Map.Entry _input = (java.util.Map.Entry) $1;
567 «QName.name» _localName = QNAME;
568 if(_input.getKey() != null) {
569 _localName = («QName.name») _input.getKey();
571 return toDomStatic(_localName,_input.getValue());
576 method(Object, "fromDomStatic", #[QName, Object, InstanceIdentifier]) [
577 modifiers = PUBLIC + FINAL + STATIC
580 «QName.name» _localQName = QNAME;
585 java.util.Map _compositeNode = (java.util.Map) $2;
586 //System.out.println(_localQName + " " + _compositeNode);
587 «type.builderName» _builder = new «type.builderName»();
588 boolean _is_empty = true;
589 «FOR child : node.childNodes»
590 «val signature = properties.getFor(child)»
591 «deserializeProperty(child, signature.value, signature.key)»
592 _builder.«signature.key.toSetter»(«signature.key»);
597 return _builder.build();
602 method(Object, "deserialize", #[Object, InstanceIdentifier]) [
604 return fromDomStatic(QNAME,$1,$2);
609 val ret = ctCls.toClassImpl(inputType.classLoader, inputType.protectionDomain) as Class<? extends BindingCodec<Map<QName,Object>, Object>>
610 listener?.onDataContainerCodecCreated(inputType, ret);
612 } catch (Exception e) {
613 processException(inputType, e);
618 private def dispatch Class<? extends BindingCodec<Map<QName, Object>, Object>> generateTransformerFor(
619 Class<?> inputType, GeneratedType typeSpec, ChoiceNode node) {
622 //log.info("Generating DOM Codec for {} with {}", inputType, inputType.classLoader)
623 val ctCls = createClass(typeSpec.codecClassName) [
624 //staticField(Map,"AUGMENTATION_SERIALIZERS");
625 //staticQNameField(inputType);
626 staticField(it, INSTANCE_IDENTIFIER_CODEC, BindingCodec)
627 staticField(it, IDENTITYREF_CODEC, BindingCodec)
628 staticField(it, DISPATCH_CODEC, BindingCodec)
629 //staticField(it,QNAME_TO_CASE_MAP,BindingCodec)
630 implementsType(BINDING_CODEC)
631 method(List, "toDomStatic", #[QName, Object]) [
632 modifiers = PUBLIC + FINAL + STATIC
638 if («DISPATCH_CODEC» == null) {
639 throw new «IllegalStateException.name»("Implementation of codec was not initialized.");
641 java.util.Map.Entry _input = new «SimpleEntry.name»($1,$2);
642 Object _ret = «DISPATCH_CODEC».serialize(_input);
643 ////System.out.println("«typeSpec.name»#toDomStatic: " + _ret);
644 return («List.name») _ret;
648 method(Object, "serialize", Object) [
650 throw new «UnsupportedOperationException.name»("Direct invocation not supported.");
653 method(Object, "fromDomStatic", #[QName, Map, InstanceIdentifier]) [
654 modifiers = PUBLIC + FINAL + STATIC
657 if («DISPATCH_CODEC» == null) {
658 throw new «IllegalStateException.name»("Implementation of codec was not initialized.");
660 return «DISPATCH_CODEC».deserialize($2,$3);
664 method(Object, "deserialize", #[Object, InstanceIdentifier]) [
666 throw new «UnsupportedOperationException.name»("Direct invocation not supported.");
671 val rawRet = ctCls.toClassImpl(inputType.classLoader, inputType.protectionDomain)
672 val ret = rawRet as Class<? extends BindingCodec<Map<QName,Object>, Object>>;
673 listener?.onChoiceCodecCreated(inputType, ret, node);
674 LOG.debug("DOM Codec for {} was generated {}", inputType, ret)
676 } catch (Exception e) {
677 processException(inputType, e);
682 private def keyConstructorList(List<QName> qnames) {
683 val names = new TreeSet<String>()
684 for (name : qnames) {
685 val fieldName = name.getterName;
686 names.add(fieldName);
688 return Joiner.on(",").join(names);
691 private def serializeBodyFacade(GeneratedType type, SchemaNode node) {
692 val ret = serializeBody(type, node);
696 private def String deserializeBody(GeneratedType type, SchemaNode node, InstanceIdentifier<?> bindingId) {
697 val ret = deserializeBodyImpl(type, node, bindingId);
701 private def deserializeKey(GeneratedType type, ListSchemaNode node) {
702 if (node.keyDefinition != null && !node.keyDefinition.empty) {
704 «type.resolvedName»Key getKey = («type.resolvedName»Key) «keyTransformer(type, node).canonicalName».fromDomStatic(_localQName,_compositeNode);
705 _builder.setKey(getKey);
710 private def String deserializeBodyWithAugmentations(GeneratedType type, DataNodeContainer node, InstanceIdentifier<?> bindingId) '''
712 «QName.name» _localQName = «QName.name».create($1,QNAME.getLocalName());
716 java.util.Map _compositeNode = (java.util.Map) $2;
717 //System.out.println(_localQName + " " + _compositeNode);
718 «type.builderName» _builder = new «type.builderName»();
719 «deserializeDataNodeContainerBody(type, node, bindingId)»
720 «type.deserializeAugmentations»
721 return _builder.build();
725 private def dispatch String deserializeBodyImpl(GeneratedType type, SchemaNode node, InstanceIdentifier<?> bindingId) '''
727 «QName.name» _localQName = «QName.name».create($1,QNAME.getLocalName());
732 java.util.Map _compositeNode = (java.util.Map) $2;
733 «type.builderName» _builder = new «type.builderName»();
734 return _builder.build();
738 private def dispatch String deserializeBodyImpl(GeneratedType type, ListSchemaNode node, InstanceIdentifier<?> bindingId) '''
740 «QName.name» _localQName = «QName.name».create($1,QNAME.getLocalName());
744 java.util.Map _compositeNode = (java.util.Map) $2;
745 //System.out.println(_localQName + " " + _compositeNode);
746 «type.builderName» _builder = new «type.builderName»();
747 «deserializeKey(type, node)»
748 «deserializeDataNodeContainerBody(type, node, bindingId)»
749 «type.deserializeAugmentations»
750 return _builder.build();
754 private def dispatch String deserializeBodyImpl(GeneratedType type, ContainerSchemaNode node, InstanceIdentifier<?> bindingId) {
755 return deserializeBodyWithAugmentations(type, node, bindingId);
758 private def dispatch String deserializeBodyImpl(GeneratedType type, NotificationDefinition node, InstanceIdentifier<?> bindingId) {
759 return deserializeBodyWithAugmentations(type, node, bindingId);
762 private def dispatch String deserializeBodyImpl(GeneratedType type, ChoiceCaseNode node, InstanceIdentifier<?> bindingId) {
763 return deserializeBodyWithAugmentations(type, node, bindingId);
766 private def deserializeDataNodeContainerBody(GeneratedType type, DataNodeContainer node, InstanceIdentifier<?> bindingId) {
767 deserializeNodeContainerBodyImpl(type, type.allProperties, node, bindingId);
770 private def deserializeNodeContainerBodyImpl(GeneratedType type, HashMap<String, Type> properties,
771 DataNodeContainer node, InstanceIdentifier<?> bindingId) {
773 boolean _is_empty = true;
774 «FOR child : node.childNodes»
775 «val signature = properties.getFor(child)»
776 «IF signature !== null»
777 «deserializeProperty(child, signature.value, signature.key)»
778 _builder.«signature.key.toSetter»(«signature.key»);
785 def deserializeAugmentations(GeneratedType type) '''
786 «InstanceIdentifier.resolvedName» iid = $3.builder().child(«type.resolvedName».class).build();
787 java.util.Map _augmentation = (java.util.Map) «AUGMENTATION_CODEC».deserialize(_compositeNode,$3);
788 if(_augmentation != null) {
789 «Iterator.name» _entries = _augmentation.entrySet().iterator();
790 while(_entries.hasNext()) {
791 java.util.Map.Entry _entry = (java.util.Map.Entry) _entries.next();
792 ////System.out.println("Aug. key:" + _entry.getKey());
793 Class _type = (Class) _entry.getKey();
794 «Augmentation.resolvedName» _value = («Augmentation.name») _entry.getValue();
796 _builder.addAugmentation(_type,_value);
802 private def dispatch CharSequence deserializeProperty(ListSchemaNode schema, ParameterizedType type,
803 String propertyName) '''
804 java.util.List _dom_«propertyName» = _compositeNode.get(«QName.name».create(_localQName,"«schema.QName.
806 ////System.out.println("«propertyName»#deCode"+_dom_«propertyName»);
807 java.util.List «propertyName» = new java.util.ArrayList();
808 if(_dom_«propertyName» != null) {
809 java.util.List _serialized = new java.util.ArrayList();
810 java.util.Iterator _iterator = _dom_«propertyName».iterator();
811 boolean _hasNext = _iterator.hasNext();
813 Object _listItem = _iterator.next();
815 ////System.out.println(" item" + _listItem);
816 «val param = type.actualTypeArguments.get(0)»
817 «InstanceIdentifier.resolvedName» iid = $3.builder().child(«param.resolvedName».class).build();
818 Object _value = «type.actualTypeArguments.get(0).serializer(schema).resolvedName».fromDomStatic(_localQName,_listItem,iid);
819 ////System.out.println(" value" + _value);
820 «propertyName».add(_value);
821 _hasNext = _iterator.hasNext();
825 ////System.out.println(" list" + «propertyName»);
828 private def dispatch CharSequence deserializeProperty(LeafListSchemaNode schema, ParameterizedType type,
829 String propertyName) '''
830 java.util.List _dom_«propertyName» = _compositeNode.get(«QName.name».create(_localQName,"«schema.QName.
832 java.util.List «propertyName» = new java.util.ArrayList();
833 if(_dom_«propertyName» != null) {
834 java.util.List _serialized = new java.util.ArrayList();
835 java.util.Iterator _iterator = _dom_«propertyName».iterator();
836 boolean _hasNext = _iterator.hasNext();
839 Object _listItem = _iterator.next();
840 if(_listItem instanceof java.util.Map.Entry) {
841 Object _innerValue = ((java.util.Map.Entry) _listItem).getValue();
842 Object _value = «deserializeValue(type.actualTypeArguments.get(0), "_innerValue", schema.type)»;
843 «propertyName».add(_value);
845 _hasNext = _iterator.hasNext();
850 private def dispatch CharSequence deserializeProperty(LeafSchemaNode schema, Type type, String propertyName) '''
851 java.util.List _dom_«propertyName»_list =
852 _compositeNode.get(«QName.name».create(_localQName,"«schema.QName.localName»"));
853 «type.resolvedName» «propertyName» = null;
854 if(_dom_«propertyName»_list != null && _dom_«propertyName»_list.size() > 0) {
856 java.util.Map.Entry _dom_«propertyName» = (java.util.Map.Entry) _dom_«propertyName»_list.get(0);
857 Object _inner_value = _dom_«propertyName».getValue();
858 «propertyName» = «deserializeValue(type, "_inner_value", schema.type)»;
862 private def dispatch CharSequence deserializeProperty(ContainerSchemaNode schema, Type type,
863 String propertyName) '''
864 java.util.List _dom_«propertyName»_list =
865 _compositeNode.get(«QName.name».create(_localQName,"«schema.QName.localName»"));
866 «type.resolvedName» «propertyName» = null;
867 if(_dom_«propertyName»_list != null && _dom_«propertyName»_list.size() > 0) {
869 java.util.Map _dom_«propertyName» = (java.util.Map) _dom_«propertyName»_list.get(0);
870 «InstanceIdentifier.resolvedName» iid = $3.builder().child(«type.resolvedName».class).build();
871 «propertyName» = «type.serializer(schema).resolvedName».fromDomStatic(_localQName,_dom_«propertyName»,iid);
875 private def dispatch CharSequence deserializeProperty(ChoiceNode schema, Type type, String propertyName) '''
876 «type.resolvedName» «propertyName» = «type.serializer(schema).resolvedName».fromDomStatic(_localQName,_compositeNode,$3);
877 if(«propertyName» != null) {
882 private def dispatch String deserializeValue(GeneratedTransferObject type, String domParameter,
883 TypeDefinition<?> typeDefinition) '''
884 («type.resolvedName») «type.valueSerializer(typeDefinition).resolvedName».fromDomValue(«domParameter»)
887 private def dispatch String deserializeValue(Enumeration type, String domParameter, TypeDefinition<?> typeDefinition) '''
888 («type.resolvedName») «type.valueSerializer(typeDefinition).resolvedName».fromDomValue(«domParameter»)
891 private def dispatch String deserializeValue(Type type, String domParameter, TypeDefinition<?> typeDef) {
892 if (INSTANCE_IDENTIFIER.equals(type)) {
893 return '''(«InstanceIdentifier.name») «INSTANCE_IDENTIFIER_CODEC».deserialize(«domParameter»)'''
894 } else if (CLASS_TYPE.equals(type)) {
895 return '''(«Class.name») «IDENTITYREF_CODEC».deserialize(«domParameter»)'''
896 } else if (typeDef!=null && typeDef instanceof EmptyTypeDefinition) {
897 if(domParameter == null) {
898 return ''' Boolean.FALSE '''
900 return ''' Boolean.TRUE '''
903 return '''(«type.resolvedName») «domParameter»'''
906 private def dispatch Class<? extends BindingCodec<Map<QName, Object>, Object>> generateValueTransformer(
907 Class<?> inputType, GeneratedTransferObject typeSpec, TypeDefinition<?> typeDef) {
910 val returnType = typeSpec.valueReturnType;
911 if (returnType == null) {
912 val ctCls = createDummyImplementation(inputType, typeSpec);
913 val ret = ctCls.toClassImpl(inputType.classLoader, inputType.protectionDomain)
914 return ret as Class<? extends BindingCodec<Map<QName,Object>, Object>>;
917 val ctCls = createClass(typeSpec.codecClassName) [
918 //staticField(Map,"AUGMENTATION_SERIALIZERS");
919 if (inputType.isYangBindingAvailable) {
920 implementsType(BINDING_CODEC)
921 staticField(it, INSTANCE_IDENTIFIER_CODEC, BindingCodec)
922 staticField(it, IDENTITYREF_CODEC, BindingCodec)
923 implementsType(BindingDeserializer.asCtClass)
925 method(Object, "toDomValue", Object) [
926 modifiers = PUBLIC + FINAL + STATIC
927 val ctSpec = typeSpec.asCtClass;
930 ////System.out.println("«inputType.simpleName»#toDomValue: "+$1);
935 «typeSpec.resolvedName» _encapsulatedValue = («typeSpec.resolvedName») $1;
936 ////System.out.println("«inputType.simpleName»#toDomValue:Enc: "+_encapsulatedValue);
937 «returnType.resolvedName» _value = _encapsulatedValue.getValue();
938 ////System.out.println("«inputType.simpleName»#toDomValue:DeEnc: "+_value);
939 Object _domValue = «serializeValue(returnType, "_value", null)»;
944 method(Object, "serialize", Object) [
947 return toDomValue($1);
951 method(Object, "fromDomValue", Object) [
952 modifiers = PUBLIC + FINAL + STATIC
955 ////System.out.println("«inputType.simpleName»#fromDomValue: "+$1);
960 «returnType.resolvedName» _simpleValue = «deserializeValue(returnType, "$1", null)»;
961 «typeSpec.resolvedName» _value = new «typeSpec.resolvedName»(_simpleValue);
966 method(Object, "deserialize", Object) [
968 return fromDomValue($1);
974 val ret = ctCls.toClassImpl(inputType.classLoader, inputType.protectionDomain)
975 LOG.debug("DOM Codec for {} was generated {}", inputType, ret)
976 return ret as Class<? extends BindingCodec<Map<QName,Object>, Object>>;
977 } catch (Exception e) {
978 LOG.error("Cannot compile DOM Codec for {}", inputType, e);
979 val exception = new CodeGenerationException("Cannot compile Transformator for " + inputType);
980 exception.addSuppressed(e);
985 private def dispatch Class<? extends BindingCodec<Map<QName, Object>, Object>> generateValueTransformer(
986 Class<?> inputType, GeneratedTransferObject typeSpec, UnionTypeDefinition typeDef) {
988 val ctCls = createClass(typeSpec.codecClassName) [
989 val properties = typeSpec.allProperties;
990 val getterToTypeDefinition = XtendHelper.getTypes(typeDef).toMap[type|type.QName.getterName];
991 //staticField(Map,"AUGMENTATION_SERIALIZERS");
992 if (inputType.isYangBindingAvailable) {
993 implementsType(BINDING_CODEC)
994 staticField(it, INSTANCE_IDENTIFIER_CODEC, BindingCodec)
995 staticField(it, IDENTITYREF_CODEC, BindingCodec)
996 implementsType(BindingDeserializer.asCtClass)
998 method(Object, "toDomValue", Object) [
999 modifiers = PUBLIC + FINAL + STATIC
1000 val ctSpec = inputType.asCtClass;
1003 ////System.out.println("«inputType.simpleName»#toDomValue: "+$1);
1008 «typeSpec.resolvedName» _value = («typeSpec.resolvedName») $1;
1009 «FOR property : properties.entrySet»
1010 «IF property.key != "getValue"»
1011 «property.value.resolvedName» «property.key» = («property.value.resolvedName») _value.«property.
1013 if(«property.key» != null) {
1014 return «serializeValue(property.value, property.key,
1015 getterToTypeDefinition.get(property.key))»;
1024 method(Object, "serialize", Object) [
1027 return toDomValue($1);
1031 method(Object, "fromDomValue", Object) [
1032 modifiers = PUBLIC + FINAL + STATIC
1035 ////System.out.println("«inputType.simpleName»#fromDomValue: "+$1);
1040 if($1 instanceof String) {
1041 String _simpleValue = (String) $1;
1042 return new «typeSpec.resolvedName»(_simpleValue.toCharArray());
1048 method(Object, "deserialize", Object) [
1050 return fromDomValue($1);
1056 val ret = ctCls.toClassImpl(inputType.classLoader, inputType.protectionDomain)
1057 LOG.debug("DOM Codec for {} was generated {}", inputType, ret)
1058 return ret as Class<? extends BindingCodec<Map<QName,Object>, Object>>;
1059 } catch (Exception e) {
1060 LOG.error("Cannot compile DOM Codec for {}", inputType, e);
1061 val exception = new CodeGenerationException("Cannot compile Transformator for " + inputType);
1062 exception.addSuppressed(e);
1067 private def dispatch Class<? extends BindingCodec<Map<QName, Object>, Object>> generateValueTransformer(
1068 Class<?> inputType, GeneratedTransferObject typeSpec, BitsTypeDefinition typeDef) {
1070 val ctCls = createClass(typeSpec.codecClassName) [
1071 //staticField(Map,"AUGMENTATION_SERIALIZERS");
1072 if (inputType.isYangBindingAvailable) {
1073 implementsType(BINDING_CODEC)
1074 staticField(it, INSTANCE_IDENTIFIER_CODEC, BindingCodec)
1075 staticField(it, IDENTITYREF_CODEC, BindingCodec)
1076 implementsType(BindingDeserializer.asCtClass)
1078 method(Object, "toDomValue", Object) [
1079 modifiers = PUBLIC + FINAL + STATIC
1080 val ctSpec = typeSpec.asCtClass;
1083 ////System.out.println("«inputType.simpleName»#toDomValue: "+$1);
1088 «typeSpec.resolvedName» _encapsulatedValue = («typeSpec.resolvedName») $1;
1089 «HashSet.resolvedName» _value = new «HashSet.resolvedName»();
1090 //System.out.println("«inputType.simpleName»#toDomValue:Enc: "+_encapsulatedValue);
1092 «FOR bit : typeDef.bits»
1093 «val getter = bit.getterName()»
1094 if(Boolean.TRUE.equals(_encapsulatedValue.«getter»())) {
1095 _value.add("«bit.name»");
1098 «Set.resolvedName» _domValue = «Collections.resolvedName».unmodifiableSet(_value);
1099 //System.out.println("«inputType.simpleName»#toDomValue:DeEnc: "+_domValue);
1105 method(Object, "serialize", Object) [
1108 return toDomValue($1);
1112 method(Object, "fromDomValue", Object) [
1113 modifiers = PUBLIC + FINAL + STATIC
1114 val sortedBits = typeDef.bits.sort[o1, o2|o1.propertyName.compareTo(o2.propertyName)]
1117 //System.out.println("«inputType.simpleName»#fromDomValue: "+$1);
1122 «Set.resolvedName» _domValue = («Set.resolvedName») $1;
1123 «FOR bit : sortedBits»
1124 Boolean «bit.propertyName» = Boolean.valueOf(_domValue.contains("«bit.name»"));
1127 return new «inputType.resolvedName»(«FOR bit : sortedBits SEPARATOR ","»«bit.propertyName»«ENDFOR»);
1131 method(Object, "deserialize", Object) [
1133 return fromDomValue($1);
1139 val ret = ctCls.toClassImpl(inputType.classLoader, inputType.protectionDomain)
1140 LOG.debug("DOM Codec for {} was generated {}", inputType, ret)
1141 return ret as Class<? extends BindingCodec<Map<QName,Object>, Object>>;
1142 } catch (Exception e) {
1143 LOG.error("Cannot compile DOM Codec for {}", inputType, e);
1144 val exception = new CodeGenerationException("Cannot compile Transformator for " + inputType);
1145 exception.addSuppressed(e);
1150 def String getPropertyName(Bit bit) {
1151 '''_«BindingGeneratorUtil.parseToValidParamName(bit.name)»'''
1154 def String getterName(Bit bit) {
1156 val paramName = BindingGeneratorUtil.parseToValidParamName(bit.name);
1157 return '''is«paramName.toFirstUpper»''';
1160 def boolean isYangBindingAvailable(Class<?> class1) {
1162 val bindingCodecClass = class1.classLoader.loadClass(BINDING_CODEC.name);
1163 return bindingCodecClass !== null;
1164 } catch (ClassNotFoundException e) {
1169 private def createDummyImplementation(Class<?> object, GeneratedTransferObject typeSpec) {
1170 LOG.trace("Generating Dummy DOM Codec for {} with {}", object, object.classLoader)
1171 return createClass(typeSpec.codecClassName) [
1172 if (object.isYangBindingAvailable) {
1173 implementsType(BINDING_CODEC)
1174 staticField(it, INSTANCE_IDENTIFIER_CODEC, BindingCodec)
1175 staticField(it, IDENTITYREF_CODEC, BindingCodec)
1176 implementsType(BindingDeserializer.asCtClass)
1178 //implementsType(BindingDeserializer.asCtClass)
1179 method(Object, "toDomValue", Object) [
1180 modifiers = PUBLIC + FINAL + STATIC
1185 return $1.toString();
1189 method(Object, "serialize", Object) [
1192 return toDomValue($1);
1196 method(Object, "fromDomValue", Object) [
1197 modifiers = PUBLIC + FINAL + STATIC
1198 bodyChecked = '''return null;'''
1200 method(Object, "deserialize", Object) [
1202 return fromDomValue($1);
1209 private def Type getValueReturnType(GeneratedTransferObject object) {
1210 for (prop : object.properties) {
1211 if (prop.name == "value") {
1212 return prop.returnType;
1215 if (object.superType != null) {
1216 return getValueReturnType(object.superType);
1221 private def dispatch Class<?> generateValueTransformer(Class<?> inputType, Enumeration typeSpec, TypeDefinition<?> type) {
1222 var EnumerationType enumSchemaType
1223 if (type instanceof EnumerationType) {
1224 enumSchemaType = type as EnumerationType
1226 val typeRef = new ReferencedTypeImpl(typeSpec.packageName, typeSpec.name);
1227 val schema = getSchemaNode(typeRef) as ExtendedType;
1228 enumSchemaType = schema.baseType as EnumerationType;
1230 val enumSchema = enumSchemaType;
1232 //log.info("Generating DOM Codec for {} with {}", inputType, inputType.classLoader)
1233 val ctCls = createClass(typeSpec.codecClassName) [
1234 //staticField(Map,"AUGMENTATION_SERIALIZERS");
1235 //implementsType(BINDING_CODEC)
1236 method(Object, "toDomValue", Object) [
1237 modifiers = PUBLIC + FINAL + STATIC
1242 «typeSpec.resolvedName» _value = («typeSpec.resolvedName») $1;
1243 «FOR en : enumSchema.values»
1244 if(«typeSpec.resolvedName».«BindingMapping.getClassName(en.name)».equals(_value)) {
1252 method(Object, "serialize", Object) [
1254 return toDomValue($1);
1257 method(Object, "fromDomValue", Object) [
1258 modifiers = PUBLIC + FINAL + STATIC
1264 String _value = (String) $1;
1265 «FOR en : enumSchema.values»
1266 if("«en.name»".equals(_value)) {
1267 return «typeSpec.resolvedName».«BindingMapping.getClassName(en.name)»;
1274 method(Object, "deserialize", Object) [
1276 return fromDomValue($1);
1281 val ret = ctCls.toClassImpl(inputType.classLoader, inputType.protectionDomain)
1282 LOG.debug("DOM Codec for {} was generated {}", inputType, ret)
1284 } catch (CodeGenerationException e) {
1285 throw new CodeGenerationException("Cannot compile Transformator for " + inputType, e);
1286 } catch (Exception e) {
1287 LOG.error("Cannot compile DOM Codec for {}", inputType, e);
1288 val exception = new CodeGenerationException("Cannot compile Transformator for " + inputType);
1289 exception.addSuppressed(e);
1295 def Class<?> toClassImpl(CtClass newClass, ClassLoader loader, ProtectionDomain domain) {
1296 val cls = newClass.toClass(loader, domain);
1297 if (classFileCapturePath !== null) {
1298 newClass.writeFile(classFileCapturePath.absolutePath);
1300 listener?.onCodecCreated(cls);
1304 def debugWriteClass(CtClass class1) {
1305 val path = class1.name.replace(".", "/") + ".class"
1307 val captureFile = new File(classFileCapturePath, path);
1308 captureFile.createNewFile
1316 private def dispatch CharSequence deserializeProperty(DataSchemaNode container, Type type, String propertyName) '''
1317 «type.resolvedName» «propertyName» = null;
1320 private def dispatch CharSequence deserializeProperty(DataSchemaNode container, GeneratedTypeBuilder type,
1321 String propertyName) {
1322 _deserializeProperty(container, type.toInstance, propertyName)
1325 static def toSetter(String it) {
1327 if (startsWith("is")) {
1328 return "set" + substring(2);
1329 } else if (startsWith("get")) {
1330 return "set" + substring(3);
1336 private def dispatch CharSequence deserializeProperty(DataSchemaNode container,GeneratedType type, String propertyName) '''
1337 «type.resolvedName» «propertyName» = value.«propertyName»();
1338 if(«propertyName» != null) {
1339 Object domValue = «type.serializer».toDomStatic(QNAME,«propertyName»);
1340 _childNodes.add(domValue);
1344 private def getBuilderName(GeneratedType type) '''«type.resolvedName»Builder'''
1346 private def staticQNameField(CtClass it, QName node) {
1347 val field = new CtField(ctQName, "QNAME", it);
1348 field.modifiers = PUBLIC + FINAL + STATIC;
1350 '''«QName.asCtClass.name».create("«node.namespace»","«node.formattedRevision»","«node.localName»")''')
1353 private def String serializeBodyImpl(GeneratedType type, DataNodeContainer nodeContainer) '''
1355 «QName.name» _resultName = «QName.name».create($1,QNAME.getLocalName());
1356 java.util.List _childNodes = new java.util.ArrayList();
1357 «type.resolvedName» value = («type.resolvedName») $2;
1358 «transformDataContainerBody(type, type.allProperties, nodeContainer)»
1359 «serializeAugmentations»
1360 return ($r) java.util.Collections.singletonMap(_resultName,_childNodes);
1364 private def dispatch String serializeBody(GeneratedType type, ListSchemaNode node) {
1365 return serializeBodyImpl(type, node);
1368 private def dispatch String serializeBody(GeneratedType type, NotificationDefinition node) {
1369 return serializeBodyImpl(type, node);
1372 private def dispatch String serializeBody(GeneratedType type, ContainerSchemaNode node) {
1373 return serializeBodyImpl(type, node);
1376 private def dispatch String serializeBody(GeneratedType type, ChoiceCaseNode node) {
1377 return serializeBodyImpl(type, node);
1380 private def dispatch String serializeBody(GeneratedType type, SchemaNode node) '''
1382 «QName.name» _resultName = «QName.name».create($1,QNAME.getLocalName());
1383 java.util.List _childNodes = new java.util.ArrayList();
1384 «type.resolvedName» value = («type.resolvedName») $2;
1385 return ($r) java.util.Collections.singletonMap(_resultName,_childNodes);
1389 private def transformDataContainerBody(Type type, Map<String, Type> properties, DataNodeContainer node) {
1391 «FOR child : node.childNodes»
1392 «val signature = properties.getFor(child)»
1393 «IF signature !== null»
1394 ////System.out.println("«type.name»#«signature.key»" + value.«signature.key»());
1395 «serializeProperty(child, signature.value, signature.key)»
1402 private static def serializeAugmentations() '''
1403 java.util.List _augmentations = (java.util.List) «AUGMENTATION_CODEC».serialize(value);
1404 if(_augmentations != null) {
1405 _childNodes.addAll(_augmentations);
1409 private static def Entry<String, Type> getFor(Map<String, Type> map, DataSchemaNode node) {
1410 var sig = map.get(node.getterName);
1412 return new SimpleEntry(node.getterName, sig);
1414 sig = map.get(node.booleanGetterName);
1416 return new SimpleEntry(node.booleanGetterName, map.get(node.booleanGetterName));
1421 private static def String getBooleanGetterName(DataSchemaNode node) {
1422 return "is" + BindingMapping.getPropertyName(node.QName.localName).toFirstUpper;
1425 private static def String getGetterName(DataSchemaNode node) {
1426 return "get" + BindingMapping.getPropertyName(node.QName.localName).toFirstUpper;
1429 private static def String getGetterName(QName node) {
1430 return "get" + BindingMapping.getPropertyName(node.localName).toFirstUpper;
1433 private def dispatch CharSequence serializeProperty(ListSchemaNode schema, ParameterizedType type,
1434 String propertyName) '''
1435 «type.resolvedName» «propertyName» = value.«propertyName»();
1436 ////System.out.println("«propertyName»:" + «propertyName»);
1437 if(«propertyName» != null) {
1438 java.util.Iterator _iterator = «propertyName».iterator();
1439 boolean _hasNext = _iterator.hasNext();
1441 Object _listItem = _iterator.next();
1442 Object _domValue = «type.actualTypeArguments.get(0).serializer(schema).resolvedName».toDomStatic(_resultName,_listItem);
1443 _childNodes.add(_domValue);
1444 _hasNext = _iterator.hasNext();
1449 private def dispatch CharSequence serializeProperty(LeafSchemaNode schema, Type type, String propertyName) '''
1450 «type.resolvedName» «propertyName» = value.«propertyName»();
1452 if(«propertyName» != null) {
1453 «QName.name» _qname = «QName.name».create(_resultName,"«schema.QName.localName»");
1454 Object _propValue = «serializeValue(type, propertyName, schema.type)»;
1455 if(_propValue != null) {
1456 Object _domValue = java.util.Collections.singletonMap(_qname,_propValue);
1457 _childNodes.add(_domValue);
1462 private def dispatch serializeValue(GeneratedTransferObject type, String parameter, TypeDefinition<?> typeDefinition) {
1463 '''«type.valueSerializer(typeDefinition).resolvedName».toDomValue(«parameter»)'''
1466 private def dispatch serializeValue(Enumeration type, String parameter, TypeDefinition<?> typeDefinition) {
1467 '''«type.valueSerializer(typeDefinition).resolvedName».toDomValue(«parameter»)'''
1470 private def dispatch serializeValue(Type type, String parameter, EmptyTypeDefinition typeDefinition) {
1471 '''(«parameter».booleanValue() ? "" : null)'''
1474 private def dispatch serializeValue(Type signature, String property, TypeDefinition<?> typeDefinition) {
1475 serializeValue(signature,property)
1478 private def dispatch serializeValue(Type signature, String property, Void typeDefinition) {
1479 serializeValue(signature,property)
1482 private def dispatch serializeValue(Type signature, String property) {
1483 if (INSTANCE_IDENTIFIER == signature) {
1484 return '''«INSTANCE_IDENTIFIER_CODEC».serialize(«property»)'''
1485 } else if (CLASS_TYPE.equals(signature)) {
1486 return '''(«QName.resolvedName») «IDENTITYREF_CODEC».serialize(«property»)'''
1488 if ("char[]" == signature.name) {
1489 return '''new String(«property»)''';
1491 return '''«property»''';
1494 private def dispatch CharSequence serializeProperty(LeafListSchemaNode schema, ParameterizedType type,
1495 String propertyName) '''
1496 «type.resolvedName» «propertyName» = value.«propertyName»();
1497 if(«propertyName» != null) {
1498 «QName.name» _qname = «QName.name».create(_resultName,"«schema.QName.localName»");
1499 java.util.Iterator _iterator = «propertyName».iterator();
1500 boolean _hasNext = _iterator.hasNext();
1502 Object _listItem = _iterator.next();
1503 Object _propValue = «serializeValue(type.actualTypeArguments.get(0), "_listItem", schema.type)»;
1504 Object _domValue = java.util.Collections.singletonMap(_qname,_propValue);
1505 _childNodes.add(_domValue);
1506 _hasNext = _iterator.hasNext();
1511 private def dispatch CharSequence serializeProperty(ChoiceNode container, GeneratedType type,
1512 String propertyName) '''
1513 «type.resolvedName» «propertyName» = value.«propertyName»();
1514 if(«propertyName» != null) {
1515 java.util.List domValue = «type.serializer(container).resolvedName».toDomStatic(_resultName,«propertyName»);
1516 _childNodes.addAll(domValue);
1524 private def dispatch CharSequence serializeProperty(DataSchemaNode container, Type type, String propertyName) '''
1525 «type.resolvedName» «propertyName» = value.«propertyName»();
1526 if(«propertyName» != null) {
1527 Object domValue = «propertyName»;
1528 _childNodes.add(domValue);
1532 private def dispatch CharSequence serializeProperty(DataSchemaNode container, GeneratedTypeBuilder type,
1533 String propertyName) {
1534 serializeProperty(container, type.toInstance, propertyName)
1537 private def dispatch CharSequence serializeProperty(DataSchemaNode container, GeneratedType type,
1538 String propertyName) '''
1539 «type.resolvedName» «propertyName» = value.«propertyName»();
1540 if(«propertyName» != null) {
1541 Object domValue = «type.serializer(container).resolvedName».toDomStatic(_resultName,«propertyName»);
1542 _childNodes.add(domValue);
1546 private def codecClassName(GeneratedType typeSpec) {
1547 return '''«typeSpec.resolvedName»$Broker$Codec$DOM'''
1550 private def codecClassName(Class<?> typeSpec) {
1551 return '''«typeSpec.name»$Broker$Codec$DOM'''
1554 private def HashMap<String, Type> getAllProperties(GeneratedType type) {
1555 val ret = new HashMap<String, Type>();
1556 type.collectAllProperties(ret);
1560 private def dispatch void collectAllProperties(GeneratedType type, Map<String, Type> set) {
1561 for (definition : type.methodDefinitions) {
1562 set.put(definition.name, definition.returnType);
1564 for (property : type.properties) {
1565 set.put(property.getterName, property.returnType);
1567 for (parent : type.implements) {
1568 parent.collectAllProperties(set);
1572 def String getGetterName(GeneratedProperty property) {
1573 return "get" + property.name.toFirstUpper
1576 private def dispatch void collectAllProperties(Type type, Map<String, Type> set) {
1577 // NOOP for generic type.
1580 def String getResolvedName(Type type) {
1581 return type.asCtClass.name;
1584 def String getResolvedName(Class<?> type) {
1585 return type.asCtClass.name;
1588 def CtClass asCtClass(Type type) {
1589 val cls = loadClass(type.fullyQualifiedName)
1590 return cls.asCtClass;
1593 private def dispatch processException(Class<?> inputType, CodeGenerationException e) {
1594 LOG.error("Cannot compile DOM Codec for {}. One of it's prerequisites was not generated.", inputType);
1598 private def dispatch processException(Class<?> inputType, Exception e) {
1599 LOG.error("Cannot compile DOM Codec for {}", inputType, e);
1600 val exception = new CodeGenerationException("Cannot compile Transformator for " + inputType, e);
1604 private def setBodyChecked(CtMethod method, String body) {
1606 method.setBody(body);
1607 } catch (CannotCompileException e) {
1608 LOG.error("Cannot compile method: {}#{} {}, Reason: {} Body: {}", method.declaringClass, method.name,
1609 method.signature, e.message, body)
1616 class PropertyPair {
1625 SchemaNode schemaNode;