1 package org.opendaylight.controller.sal.binding.dom.serializer.impl
3 import javassist.ClassPool
4 import org.opendaylight.yangtools.sal.binding.model.api.GeneratedType
5 import org.opendaylight.yangtools.yang.model.api.SchemaNode
6 import org.opendaylight.controller.sal.binding.codegen.util.JavassistUtils
7 import javassist.CtClass
9 import org.opendaylight.yangtools.yang.common.QName
10 import javassist.CtField
11 import static javassist.Modifier.*
12 import static org.opendaylight.controller.sal.binding.dom.serializer.impl.CodecMapping.*
13 import org.opendaylight.yangtools.yang.model.api.ContainerSchemaNode
14 import org.opendaylight.yangtools.yang.model.api.ListSchemaNode
15 import org.opendaylight.yangtools.yang.model.api.DataNodeContainer
16 import org.opendaylight.yangtools.sal.binding.model.api.Type
17 import org.opendaylight.yangtools.sal.binding.model.api.type.builder.GeneratedTypeBuilder
18 import org.opendaylight.yangtools.binding.generator.util.Types
19 import org.opendaylight.yangtools.sal.binding.model.api.ParameterizedType
20 import java.util.HashMap
21 import org.opendaylight.yangtools.yang.model.api.DataSchemaNode
22 import org.opendaylight.yangtools.binding.generator.util.BindingGeneratorUtil
23 import org.opendaylight.yangtools.yang.model.api.LeafSchemaNode
24 import org.opendaylight.yangtools.yang.model.api.LeafListSchemaNode
26 import java.util.TreeSet
27 import com.google.common.base.Joiner
28 import org.opendaylight.yangtools.sal.binding.model.api.GeneratedTransferObject
29 import org.opendaylight.yangtools.sal.binding.model.api.Enumeration
30 import org.opendaylight.yangtools.yang.model.api.ChoiceCaseNode
31 import static org.opendaylight.controller.sal.binding.impl.util.ClassLoaderUtils.*;
32 import org.opendaylight.yangtools.yang.binding.BindingDeserializer
33 import org.opendaylight.yangtools.yang.binding.BindingCodec
34 import org.slf4j.LoggerFactory
35 import org.opendaylight.controller.sal.binding.codegen.CodeGenerationException
36 import org.opendaylight.yangtools.yang.model.api.ChoiceNode
37 import java.security.ProtectionDomain
39 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier
40 import org.opendaylight.yangtools.sal.binding.model.api.GeneratedProperty
41 import java.util.Map.Entry
42 import java.util.AbstractMap.SimpleEntry
43 import org.opendaylight.yangtools.yang.binding.DataObject
44 import org.opendaylight.yangtools.yang.binding.Augmentation
45 import java.util.Iterator
46 import org.opendaylight.yangtools.yang.model.api.AugmentationSchema
47 import java.util.concurrent.ConcurrentHashMap
48 import static extension org.opendaylight.controller.sal.binding.impl.util.YangSchemaUtils.*;
49 import org.opendaylight.yangtools.binding.generator.util.ReferencedTypeImpl
50 import org.opendaylight.yangtools.yang.model.util.ExtendedType
51 import org.opendaylight.yangtools.yang.model.util.EnumerationType
52 import static com.google.common.base.Preconditions.*
53 import org.opendaylight.yangtools.yang.model.api.SchemaPath
54 import javassist.CtMethod
55 import javassist.CannotCompileException
56 import java.util.concurrent.locks.Lock
57 import java.util.concurrent.Callable
58 import org.opendaylight.controller.sal.binding.impl.util.ClassLoaderUtils
59 import org.opendaylight.yangtools.yang.model.api.TypeDefinition
60 import org.opendaylight.yangtools.yang.model.api.type.UnionTypeDefinition
61 import org.opendaylight.yangtools.yang.model.api.type.BitsTypeDefinition
62 import java.util.HashSet
63 import java.util.Collections
64 import org.opendaylight.yangtools.yang.model.api.type.BitsTypeDefinition.Bit
66 import org.opendaylight.controller.sal.binding.codegen.impl.XtendHelper
68 class TransformerGenerator {
70 private static val log = LoggerFactory.getLogger(TransformerGenerator)
72 public static val STRING = Types.typeForClass(String);
73 public static val BOOLEAN = Types.typeForClass(Boolean);
74 public static val INTEGER = Types.typeForClass(Integer);
75 public static val INSTANCE_IDENTIFIER = Types.typeForClass(InstanceIdentifier)
77 //public static val DECIMAL = Types.typeForClass(Decimal);
78 public static val LONG = Types.typeForClass(Long);
80 val ClassPool classPool
81 val extension JavassistUtils utils;
88 var File classFileCapturePath;
91 var Map<Type, Type> typeDefinitions = new ConcurrentHashMap();
94 var Map<Type, GeneratedTypeBuilder> typeToDefinition = new ConcurrentHashMap();
97 var Map<SchemaPath, GeneratedTypeBuilder> pathToType = new ConcurrentHashMap();
100 var Map<Type, SchemaNode> typeToSchemaNode = new ConcurrentHashMap();
103 var Map<Type, AugmentationSchema> typeToAugmentation = new ConcurrentHashMap();
106 var GeneratorListener listener;
108 public static val CLASS_TYPE = Types.typeForClass(Class);
110 public new(ClassPool pool) {
112 utils = new JavassistUtils(pool)
114 BINDING_CODEC = BindingCodec.asCtClass;
115 ctQName = QName.asCtClass
118 def Class<? extends BindingCodec<Map<QName, Object>, Object>> transformerFor(Class<?> inputType) {
119 return withClassLoaderAndLock(inputType.classLoader, lock) [ |
120 val ret = getGeneratedClass(inputType)
122 listener.onClassProcessed(inputType);
123 return ret as Class<? extends BindingCodec<Map<QName,Object>, Object>>;
125 val ref = Types.typeForClass(inputType)
126 val node = typeToSchemaNode.get(ref)
127 val typeSpecBuilder = typeToDefinition.get(ref)
128 checkState(typeSpecBuilder !== null, "Could not find typedefinition for %s", inputType.name);
129 val typeSpec = typeSpecBuilder.toInstance();
130 val newret = generateTransformerFor(inputType, typeSpec, node);
131 listener.onClassProcessed(inputType);
132 return newret as Class<? extends BindingCodec<Map<QName,Object>, Object>>;
136 def Class<? extends BindingCodec<Map<QName, Object>, Object>> transformerFor(Class<?> inputType, DataSchemaNode node) {
137 return withClassLoaderAndLock(inputType.classLoader, lock) [ |
138 val ret = getGeneratedClass(inputType)
140 listener.onClassProcessed(inputType);
141 return ret as Class<? extends BindingCodec<Map<QName,Object>, Object>>;
143 val ref = Types.typeForClass(inputType)
144 var typeSpecBuilder = typeToDefinition.get(ref)
145 if (typeSpecBuilder == null) {
146 typeSpecBuilder = pathToType.get(node.path);
148 checkState(typeSpecBuilder !== null, "Could not find TypeDefinition for %s, $s", inputType.name, node);
149 val typeSpec = typeSpecBuilder.toInstance();
150 val newret = generateTransformerFor(inputType, typeSpec, node);
151 listener.onClassProcessed(inputType);
152 return newret as Class<? extends BindingCodec<Map<QName,Object>, Object>>;
156 def Class<? extends BindingCodec<Map<QName, Object>, Object>> augmentationTransformerFor(Class<?> inputType) {
157 return withClassLoaderAndLock(inputType.classLoader, lock) [ |
158 val ret = getGeneratedClass(inputType)
160 return ret as Class<? extends BindingCodec<Map<QName,Object>, Object>>;
162 val ref = Types.typeForClass(inputType)
163 val node = typeToAugmentation.get(ref)
164 val typeSpecBuilder = typeToDefinition.get(ref)
165 val typeSpec = typeSpecBuilder.toInstance();
166 val newret = generateAugmentationTransformerFor(inputType, typeSpec, node);
167 listener.onClassProcessed(inputType);
168 return newret as Class<? extends BindingCodec<Map<QName,Object>, Object>>;
172 def Class<? extends BindingCodec<Object, Object>> caseCodecFor(Class<?> inputType, ChoiceCaseNode node) {
173 return withClassLoaderAndLock(inputType.classLoader, lock) [ |
174 val ret = getGeneratedClass(inputType)
176 return ret as Class<? extends BindingCodec<Object, Object>>;
178 val ref = Types.typeForClass(inputType)
179 val typeSpecBuilder = typeToDefinition.get(ref)
180 val typeSpec = typeSpecBuilder.toInstance();
181 val newret = generateCaseCodec(inputType, typeSpec, node);
182 return newret as Class<? extends BindingCodec<Object, Object>>;
186 def Class<? extends BindingCodec<Map<QName, Object>, Object>> keyTransformerForIdentifiable(Class<?> parentType) {
187 return withClassLoaderAndLock(parentType.classLoader, lock) [ |
188 val inputName = parentType.name + "Key";
189 val inputType = loadClassWithTCCL(inputName);
190 val ret = getGeneratedClass(inputType)
192 return ret as Class<? extends BindingCodec<Map<QName,Object>, Object>>;
194 val ref = Types.typeForClass(parentType)
195 val node = typeToSchemaNode.get(ref) as ListSchemaNode
196 val typeSpecBuilder = typeToDefinition.get(ref)
197 val typeSpec = typeSpecBuilder.identifierDefinition;
198 val newret = generateKeyTransformerFor(inputType, typeSpec, node);
199 return newret as Class<? extends BindingCodec<Map<QName,Object>, Object>>;
203 def getIdentifierDefinition(GeneratedTypeBuilder builder) {
204 val inst = builder.toInstance
205 val keyMethod = inst.methodDefinitions.findFirst[name == "getKey"]
206 return keyMethod.returnType as GeneratedTransferObject
209 def Class<? extends BindingCodec<Map<QName, Object>, Object>> keyTransformerForIdentifier(Class<?> inputType) {
210 return withClassLoaderAndLock(inputType.classLoader, lock) [ |
211 val ret = getGeneratedClass(inputType)
213 return ret as Class<? extends BindingCodec<Map<QName,Object>, Object>>;
215 val ref = Types.typeForClass(inputType)
216 val node = typeToSchemaNode.get(ref) as ListSchemaNode
217 val typeSpecBuilder = typeToDefinition.get(ref)
218 val typeSpec = typeSpecBuilder.toInstance();
219 val newret = generateKeyTransformerFor(inputType, typeSpec, node);
220 return newret as Class<? extends BindingCodec<Map<QName,Object>, Object>>;
224 private def Class<?> keyTransformerFor(Class<?> inputType, GeneratedType type, ListSchemaNode schema) {
225 return withClassLoaderAndLock(inputType.classLoader, lock) [ |
226 val transformer = getGeneratedClass(inputType)
227 if (transformer != null) {
230 val newret = generateKeyTransformerFor(inputType, type, schema);
231 return newret as Class<? extends BindingCodec<Map<QName,Object>, Object>>;
235 private def Class<?> getGeneratedClass(Class<? extends Object> cls) {
238 return loadClassWithTCCL(cls.codecClassName)
239 } catch (ClassNotFoundException e) {
244 private def Class<?> keyTransformer(GeneratedType type, ListSchemaNode node) {
245 val cls = loadClassWithTCCL(type.resolvedName + "Key");
246 keyTransformerFor(cls, type, node);
249 private def serializer(Type type, DataSchemaNode node) {
250 val cls = loadClassWithTCCL(type.resolvedName);
251 transformerFor(cls, node);
254 private def Class<?> valueSerializer(GeneratedTransferObject type, TypeDefinition<?> typeDefinition) {
255 val cls = loadClassWithTCCL(type.resolvedName);
256 val transformer = cls.generatedClass;
257 if (transformer !== null) {
260 var baseType = typeDefinition;
261 while (baseType.baseType != null) {
262 baseType = baseType.baseType;
264 val finalType = baseType;
265 return withClassLoaderAndLock(cls.classLoader, lock) [ |
266 val valueTransformer = generateValueTransformer(cls, type, finalType);
267 return valueTransformer;
271 private def Class<?> valueSerializer(Enumeration type, TypeDefinition<?> typeDefinition) {
272 val cls = loadClassWithTCCL(type.resolvedName);
273 val transformer = cls.generatedClass;
274 if (transformer !== null) {
278 return withClassLoaderAndLock(cls.classLoader, lock) [ |
279 val valueTransformer = generateValueTransformer(cls, type);
280 return valueTransformer;
284 private def generateKeyTransformerFor(Class<? extends Object> inputType, GeneratedType typeSpec, ListSchemaNode node) {
287 //log.info("Generating DOM Codec for {} with {}", inputType, inputType.classLoader)
288 val properties = typeSpec.allProperties;
289 val ctCls = createClass(inputType.codecClassName) [
290 //staticField(Map,"AUGMENTATION_SERIALIZERS");
291 staticField(it, INSTANCE_IDENTIFIER_CODEC, BindingCodec)
292 staticField(it, IDENTITYREF_CODEC, BindingCodec)
293 staticQNameField(node.QName);
294 implementsType(BINDING_CODEC)
295 method(Object, "toDomStatic", QName, Object) [
296 modifiers = PUBLIC + FINAL + STATIC
299 «QName.name» _resultName;
301 _resultName = «QName.name».create($1,QNAME.getLocalName());
305 java.util.List _childNodes = new java.util.ArrayList();
306 «inputType.resolvedName» value = («inputType.name») $2;
307 «FOR key : node.keyDefinition»
308 «val propertyName = key.getterName»
309 «val keyDef = node.getDataChildByName(key)»
310 «val property = properties.get(propertyName)»
311 «serializeProperty(keyDef, property, propertyName)»;
313 return ($r) java.util.Collections.singletonMap(_resultName,_childNodes);
317 method(Object, "fromDomStatic", QName, Object) [
318 modifiers = PUBLIC + FINAL + STATIC
324 «QName.name» _localQName = $1;
325 java.util.Map _compositeNode = (java.util.Map) $2;
326 boolean _is_empty = true;
327 «FOR key : node.keyDefinition»
328 «val propertyName = key.getterName»
329 «val keyDef = node.getDataChildByName(key)»
330 «val property = properties.get(propertyName)»
331 «deserializeProperty(keyDef, property, propertyName)»;
333 «inputType.resolvedName» _value = new «inputType.name»(«node.keyDefinition.
334 keyConstructorList»);
339 method(Object, "serialize", Object) [
342 java.util.Map.Entry _input = (java.util.Map.Entry) $1;
343 «QName.name» _localQName = («QName.name») _input.getKey();
344 «inputType.name» _keyValue = («inputType.name») _input.getValue();
345 return toDomStatic(_localQName,_keyValue);
349 method(Object, "deserialize", Object) [
351 return fromDomStatic(QNAME,$1);
355 val ret = ctCls.toClassImpl(inputType.classLoader, inputType.protectionDomain)
356 log.debug("DOM Codec for {} was generated {}", inputType, ret)
357 return ret as Class<? extends BindingCodec<Map<QName,Object>, ?>>;
358 } catch (Exception e) {
359 processException(inputType, e);
364 private def Class<? extends BindingCodec<Object, Object>> generateCaseCodec(Class<?> inputType, GeneratedType type,
365 ChoiceCaseNode node) {
368 //log.info("Generating DOM Codec for {} with {}, TCCL is: {}", inputType, inputType.classLoader,Thread.currentThread.contextClassLoader)
369 val ctCls = createClass(type.codecClassName) [
370 //staticField(Map,"AUGMENTATION_SERIALIZERS");
371 implementsType(BINDING_CODEC)
372 staticQNameField(node.QName);
373 staticField(it, INSTANCE_IDENTIFIER_CODEC, BindingCodec)
374 staticField(it, AUGMENTATION_CODEC, BindingCodec)
375 staticField(it, IDENTITYREF_CODEC, BindingCodec)
376 method(Object, "toDomStatic", QName, Object) [
377 modifiers = PUBLIC + FINAL + STATIC
380 «QName.name» _resultName = «QName.name».create($1,QNAME.getLocalName());
381 java.util.List _childNodes = new java.util.ArrayList();
382 «type.resolvedName» value = («type.resolvedName») $2;
383 «transformDataContainerBody(type, type.allProperties, node)»
384 return ($r) _childNodes;
388 method(Object, "serialize", Object) [
391 java.util.Map.Entry _input = (java.util.Map.Entry) $1;
392 «QName.name» _localName = QNAME;
393 if(_input.getKey() != null) {
394 _localName = («QName.name») _input.getKey();
396 return toDomStatic(_localName,_input.getValue());
400 method(Object, "fromDomStatic", QName, Object) [
401 modifiers = PUBLIC + FINAL + STATIC
402 bodyChecked = deserializeBody(type, node)
404 method(Object, "deserialize", Object) [
407 ////System.out.println("«type.name»#deserialize: " +$1);
408 java.util.Map.Entry _input = (java.util.Map.Entry) $1;
409 return fromDomStatic((«QName.name»)_input.getKey(),_input.getValue());
415 val ret = ctCls.toClassImpl(inputType.classLoader, inputType.protectionDomain) as Class<? extends BindingCodec<Object, Object>>
416 listener?.onDataContainerCodecCreated(inputType, ret);
417 log.debug("DOM Codec for {} was generated {}", inputType, ret)
419 } catch (Exception e) {
420 processException(inputType, e);
425 private def dispatch Class<? extends BindingCodec<Map<QName, Object>, Object>> generateTransformerFor(
426 Class<?> inputType, GeneratedType typeSpec, SchemaNode node) {
429 //log.info("Generating DOM Codec for {} with {}", inputType, inputType.classLoader)
430 val ctCls = createClass(typeSpec.codecClassName) [
431 //staticField(Map,"AUGMENTATION_SERIALIZERS");
432 staticQNameField(node.QName);
433 staticField(it, INSTANCE_IDENTIFIER_CODEC, BindingCodec)
434 staticField(it, IDENTITYREF_CODEC, BindingCodec)
435 staticField(it, AUGMENTATION_CODEC, BindingCodec)
436 implementsType(BINDING_CODEC)
437 method(Object, "toDomStatic", QName, Object) [
438 modifiers = PUBLIC + FINAL + STATIC
439 bodyChecked = serializeBodyFacade(typeSpec, node)
441 method(Object, "serialize", Object) [
444 java.util.Map.Entry _input = (java.util.Map.Entry) $1;
445 «QName.name» _localName = QNAME;
446 if(_input.getKey() != null) {
447 _localName = («QName.name») _input.getKey();
449 return toDomStatic(_localName,_input.getValue());
453 method(Object, "fromDomStatic", QName, Object) [
454 modifiers = PUBLIC + FINAL + STATIC
455 bodyChecked = deserializeBody(typeSpec, node)
457 method(Object, "deserialize", Object) [
459 return fromDomStatic(QNAME,$1);
464 val ret = ctCls.toClassImpl(inputType.classLoader, inputType.protectionDomain) as Class<? extends BindingCodec<Map<QName,Object>, Object>>
465 listener?.onDataContainerCodecCreated(inputType, ret);
466 log.debug("DOM Codec for {} was generated {}", inputType, ret)
468 } catch (Exception e) {
469 processException(inputType, e);
474 private def Class<? extends BindingCodec<Map<QName, Object>, Object>> generateAugmentationTransformerFor(
475 Class<?> inputType, GeneratedType type, AugmentationSchema node) {
478 //log.info("Generating DOM Codec for {} with {}", inputType, inputType.classLoader)
479 val properties = type.allProperties
480 val ctCls = createClass(type.codecClassName) [
481 //staticField(Map,"AUGMENTATION_SERIALIZERS");
482 staticQNameField(node.augmentationQName);
483 staticField(it, INSTANCE_IDENTIFIER_CODEC, BindingCodec)
484 staticField(it, AUGMENTATION_CODEC, BindingCodec)
485 staticField(it, IDENTITYREF_CODEC, BindingCodec)
486 implementsType(BINDING_CODEC)
487 method(Object, "toDomStatic", QName, Object) [
488 modifiers = PUBLIC + FINAL + STATIC
491 ////System.out.println("Qname " + $1);
492 ////System.out.println("Value " + $2);
493 «QName.name» _resultName = «QName.name».create(QNAME,QNAME.getLocalName());
494 java.util.List _childNodes = new java.util.ArrayList();
495 «type.resolvedName» value = («type.resolvedName») $2;
496 «FOR child : node.childNodes»
497 «var signature = properties.getFor(child)»
498 ////System.out.println("«signature.key»" + value.«signature.key»());
499 «serializeProperty(child, signature.value, signature.key)»
501 return ($r) _childNodes;
505 method(Object, "serialize", Object) [
508 java.util.Map.Entry _input = (java.util.Map.Entry) $1;
509 «QName.name» _localName = QNAME;
510 if(_input.getKey() != null) {
511 _localName = («QName.name») _input.getKey();
513 return toDomStatic(_localName,_input.getValue());
517 method(Object, "fromDomStatic", QName, Object) [
518 modifiers = PUBLIC + FINAL + STATIC
521 «QName.name» _localQName = QNAME;
526 java.util.Map _compositeNode = (java.util.Map) $2;
527 ////System.out.println(_localQName + " " + _compositeNode);
528 «type.builderName» _builder = new «type.builderName»();
529 boolean _is_empty = true;
530 «FOR child : node.childNodes»
531 «val signature = properties.getFor(child)»
532 «deserializeProperty(child, signature.value, signature.key)»
533 _builder.«signature.key.toSetter»(«signature.key»);
538 return _builder.build();
542 method(Object, "deserialize", Object) [
544 return fromDomStatic(QNAME,$1);
549 val ret = ctCls.toClassImpl(inputType.classLoader, inputType.protectionDomain) as Class<? extends BindingCodec<Map<QName,Object>, Object>>
550 listener?.onDataContainerCodecCreated(inputType, ret);
552 } catch (Exception e) {
553 processException(inputType, e);
558 private def dispatch Class<? extends BindingCodec<Map<QName, Object>, Object>> generateTransformerFor(
559 Class<?> inputType, GeneratedType typeSpec, ChoiceNode node) {
562 //log.info("Generating DOM Codec for {} with {}", inputType, inputType.classLoader)
563 val ctCls = createClass(typeSpec.codecClassName) [
564 //staticField(Map,"AUGMENTATION_SERIALIZERS");
565 //staticQNameField(inputType);
566 staticField(it, INSTANCE_IDENTIFIER_CODEC, BindingCodec)
567 staticField(it, IDENTITYREF_CODEC, BindingCodec)
568 staticField(it, CLASS_TO_CASE_MAP, Map)
569 staticField(it, COMPOSITE_TO_CASE, Map)
570 //staticField(it,QNAME_TO_CASE_MAP,BindingCodec)
571 implementsType(BINDING_CODEC)
572 method(List, "toDomStatic", QName, Object) [
573 modifiers = PUBLIC + FINAL + STATIC
579 «DataObject.name» _baValue = («DataObject.name») $2;
580 Class _baClass = _baValue.getImplementedInterface();
581 «BINDING_CODEC.name» _codec = «CLASS_TO_CASE_MAP».get(_baClass);
585 java.util.Map.Entry _input = new «SimpleEntry.name»($1,_baValue);
586 Object _ret = _codec.serialize(_input);
587 ////System.out.println("«typeSpec.name»#toDomStatic: " + _ret);
588 return («List.name») _ret;
592 method(Object, "serialize", Object) [
594 throw new «UnsupportedOperationException.name»("Direct invocation not supported.");
597 method(Object, "fromDomStatic", QName, Map) [
598 modifiers = PUBLIC + FINAL + STATIC
601 «BINDING_CODEC.name» _codec = («BINDING_CODEC.name») «COMPOSITE_TO_CASE».get($2);
603 return _codec.deserialize(new «SimpleEntry.name»($1,$2));
609 method(Object, "deserialize", Object) [
611 throw new «UnsupportedOperationException.name»("Direct invocation not supported.");
616 val rawRet = ctCls.toClassImpl(inputType.classLoader, inputType.protectionDomain)
617 val ret = rawRet as Class<? extends BindingCodec<Map<QName,Object>, Object>>;
618 listener?.onChoiceCodecCreated(inputType, ret, node);
619 log.debug("DOM Codec for {} was generated {}", inputType, ret)
621 } catch (Exception e) {
622 processException(inputType, e);
627 private def keyConstructorList(List<QName> qnames) {
628 val names = new TreeSet<String>()
629 for (name : qnames) {
630 val fieldName = name.getterName;
631 names.add(fieldName);
633 return Joiner.on(",").join(names);
636 private def serializeBodyFacade(GeneratedType type, SchemaNode node) {
637 val ret = serializeBody(type, node);
641 private def String deserializeBody(GeneratedType type, SchemaNode node) {
642 val ret = deserializeBodyImpl(type, node);
646 private def deserializeKey(GeneratedType type, ListSchemaNode node) {
647 if (node.keyDefinition != null && !node.keyDefinition.empty) {
649 «type.resolvedName»Key getKey = («type.resolvedName»Key) «keyTransformer(type, node).canonicalName».fromDomStatic(_localQName,_compositeNode);
650 _builder.setKey(getKey);
655 private def dispatch String deserializeBodyImpl(GeneratedType type, SchemaNode node) '''
657 «QName.name» _localQName = «QName.name».create($1,QNAME.getLocalName());
662 java.util.Map _compositeNode = (java.util.Map) $2;
663 «type.builderName» _builder = new «type.builderName»();
664 return _builder.build();
668 private def dispatch String deserializeBodyImpl(GeneratedType type, ListSchemaNode node) '''
670 «QName.name» _localQName = «QName.name».create($1,QNAME.getLocalName());
674 java.util.Map _compositeNode = (java.util.Map) $2;
675 «type.builderName» _builder = new «type.builderName»();
676 «deserializeKey(type, node)»
677 «deserializeDataNodeContainerBody(type, node)»
678 «deserializeAugmentations»
679 return _builder.build();
683 private def dispatch String deserializeBodyImpl(GeneratedType type, ContainerSchemaNode node) '''
685 «QName.name» _localQName = «QName.name».create($1,QNAME.getLocalName());
689 java.util.Map _compositeNode = (java.util.Map) $2;
690 «type.builderName» _builder = new «type.builderName»();
691 «deserializeDataNodeContainerBody(type, node)»
692 «deserializeAugmentations»
693 return _builder.build();
697 private def dispatch String deserializeBodyImpl(GeneratedType type, ChoiceCaseNode node) '''
699 «QName.name» _localQName = «QName.name».create($1,QNAME.getLocalName());
704 java.util.Map _compositeNode = (java.util.Map) $2;
705 ////System.out.println(_localQName + " " + _compositeNode);
706 «type.builderName» _builder = new «type.builderName»();
707 «deserializeDataNodeContainerBody(type, node)»
708 «deserializeAugmentations»
709 return _builder.build();
713 private def deserializeDataNodeContainerBody(GeneratedType type, DataNodeContainer node) {
714 deserializeNodeContainerBodyImpl(type, type.allProperties, node);
717 private def deserializeNodeContainerBodyImpl(GeneratedType type, HashMap<String, Type> properties,
718 DataNodeContainer node) {
720 boolean _is_empty = true;
721 «FOR child : node.childNodes»
722 «val signature = properties.getFor(child)»
723 «IF signature !== null»
724 «deserializeProperty(child, signature.value, signature.key)»
725 _builder.«signature.key.toSetter»(«signature.key»);
732 def deserializeAugmentations() '''
733 java.util.Map _augmentation = (java.util.Map) «AUGMENTATION_CODEC».deserialize(_compositeNode);
734 if(_augmentation != null) {
735 «Iterator.name» _entries = _augmentation.entrySet().iterator();
736 while(_entries.hasNext()) {
737 java.util.Map.Entry _entry = (java.util.Map.Entry) _entries.next();
738 ////System.out.println("Aug. key:" + _entry.getKey());
739 Class _type = (Class) _entry.getKey();
740 «Augmentation.resolvedName» _value = («Augmentation.name») _entry.getValue();
742 _builder.addAugmentation(_type,_value);
748 private def dispatch CharSequence deserializeProperty(ListSchemaNode schema, ParameterizedType type,
749 String propertyName) '''
750 java.util.List _dom_«propertyName» = _compositeNode.get(«QName.name».create(_localQName,"«schema.QName.
752 ////System.out.println("«propertyName»#deCode"+_dom_«propertyName»);
753 java.util.List «propertyName» = new java.util.ArrayList();
754 if(_dom_«propertyName» != null) {
755 java.util.List _serialized = new java.util.ArrayList();
756 java.util.Iterator _iterator = _dom_«propertyName».iterator();
757 boolean _hasNext = _iterator.hasNext();
759 Object _listItem = _iterator.next();
761 ////System.out.println(" item" + _listItem);
762 Object _value = «type.actualTypeArguments.get(0).serializer(schema).resolvedName».fromDomStatic(_localQName,_listItem);
763 ////System.out.println(" value" + _value);
764 «propertyName».add(_value);
765 _hasNext = _iterator.hasNext();
769 ////System.out.println(" list" + «propertyName»);
772 private def dispatch CharSequence deserializeProperty(LeafListSchemaNode schema, ParameterizedType type,
773 String propertyName) '''
774 java.util.List _dom_«propertyName» = _compositeNode.get(«QName.name».create(_localQName,"«schema.QName.
776 java.util.List «propertyName» = new java.util.ArrayList();
777 if(_dom_«propertyName» != null) {
778 java.util.List _serialized = new java.util.ArrayList();
779 java.util.Iterator _iterator = _dom_«propertyName».iterator();
780 boolean _hasNext = _iterator.hasNext();
783 Object _listItem = _iterator.next();
784 if(_listItem instanceof java.util.Map.Entry) {
785 Object _innerValue = ((java.util.Map.Entry) _listItem).getValue();
786 Object _value = «deserializeValue(type.actualTypeArguments.get(0), "_innerValue", schema.type)»;
787 «propertyName».add(_value);
789 _hasNext = _iterator.hasNext();
794 private def dispatch CharSequence deserializeProperty(LeafSchemaNode schema, Type type, String propertyName) '''
795 java.util.List _dom_«propertyName»_list =
796 _compositeNode.get(«QName.name».create(_localQName,"«schema.QName.localName»"));
797 «type.resolvedName» «propertyName» = null;
798 if(_dom_«propertyName»_list != null && _dom_«propertyName»_list.size() > 0) {
800 java.util.Map.Entry _dom_«propertyName» = (java.util.Map.Entry) _dom_«propertyName»_list.get(0);
801 Object _inner_value = _dom_«propertyName».getValue();
802 «propertyName» = «deserializeValue(type, "_inner_value", schema.type)»;
806 private def dispatch CharSequence deserializeProperty(ContainerSchemaNode schema, Type type,
807 String propertyName) '''
808 java.util.List _dom_«propertyName»_list =
809 _compositeNode.get(«QName.name».create(_localQName,"«schema.QName.localName»"));
810 «type.resolvedName» «propertyName» = null;
811 if(_dom_«propertyName»_list != null && _dom_«propertyName»_list.size() > 0) {
813 java.util.Map _dom_«propertyName» = (java.util.Map) _dom_«propertyName»_list.get(0);
814 «propertyName» = «type.serializer(schema).resolvedName».fromDomStatic(_localQName,_dom_«propertyName»);
818 private def dispatch CharSequence deserializeProperty(ChoiceNode schema, Type type, String propertyName) '''
819 «type.resolvedName» «propertyName» = «type.serializer(schema).resolvedName».fromDomStatic(_localQName,_compositeNode);
820 if(«propertyName» != null) {
825 private def dispatch String deserializeValue(GeneratedTransferObject type, String domParameter,
826 TypeDefinition<?> typeDefinition) '''
827 («type.resolvedName») «type.valueSerializer(typeDefinition).resolvedName».fromDomValue(«domParameter»)
830 private def dispatch String deserializeValue(Enumeration type, String domParameter, TypeDefinition<?> typeDefinition) '''
831 («type.resolvedName») «type.valueSerializer(typeDefinition).resolvedName».fromDomValue(«domParameter»)
834 private def dispatch Class<? extends BindingCodec<Map<QName, Object>, Object>> generateValueTransformer(
835 Class<?> inputType, GeneratedTransferObject typeSpec, TypeDefinition<?> typeDef) {
838 val returnType = typeSpec.valueReturnType;
839 if (returnType == null) {
840 val ctCls = createDummyImplementation(inputType, typeSpec);
841 val ret = ctCls.toClassImpl(inputType.classLoader, inputType.protectionDomain)
842 return ret as Class<? extends BindingCodec<Map<QName,Object>, Object>>;
845 val ctCls = createClass(typeSpec.codecClassName) [
846 //staticField(Map,"AUGMENTATION_SERIALIZERS");
847 if (inputType.isYangBindingAvailable) {
848 implementsType(BINDING_CODEC)
849 staticField(it, INSTANCE_IDENTIFIER_CODEC, BindingCodec)
850 staticField(it, IDENTITYREF_CODEC, BindingCodec)
851 implementsType(BindingDeserializer.asCtClass)
853 method(Object, "toDomValue", Object) [
854 modifiers = PUBLIC + FINAL + STATIC
855 val ctSpec = typeSpec.asCtClass;
858 ////System.out.println("«inputType.simpleName»#toDomValue: "+$1);
863 «typeSpec.resolvedName» _encapsulatedValue = («typeSpec.resolvedName») $1;
864 ////System.out.println("«inputType.simpleName»#toDomValue:Enc: "+_encapsulatedValue);
865 «returnType.resolvedName» _value = _encapsulatedValue.getValue();
866 ////System.out.println("«inputType.simpleName»#toDomValue:DeEnc: "+_value);
867 Object _domValue = «serializeValue(returnType, "_value", null)»;
872 method(Object, "serialize", Object) [
875 return toDomValue($1);
879 method(Object, "fromDomValue", Object) [
880 modifiers = PUBLIC + FINAL + STATIC
883 ////System.out.println("«inputType.simpleName»#fromDomValue: "+$1);
888 «returnType.resolvedName» _simpleValue = «deserializeValue(returnType, "$1", null)»;
889 «typeSpec.resolvedName» _value = new «typeSpec.resolvedName»(_simpleValue);
894 method(Object, "deserialize", Object) [
896 return fromDomValue($1);
902 val ret = ctCls.toClassImpl(inputType.classLoader, inputType.protectionDomain)
903 log.debug("DOM Codec for {} was generated {}", inputType, ret)
904 return ret as Class<? extends BindingCodec<Map<QName,Object>, Object>>;
905 } catch (Exception e) {
906 log.error("Cannot compile DOM Codec for {}", inputType, e);
907 val exception = new CodeGenerationException("Cannot compile Transformator for " + inputType);
908 exception.addSuppressed(e);
913 private def dispatch Class<? extends BindingCodec<Map<QName, Object>, Object>> generateValueTransformer(
914 Class<?> inputType, GeneratedTransferObject typeSpec, UnionTypeDefinition typeDef) {
916 val ctCls = createClass(typeSpec.codecClassName) [
917 val properties = typeSpec.allProperties;
918 val getterToTypeDefinition = XtendHelper.getTypes(typeDef).toMap[type | type.QName.getterName];
919 //staticField(Map,"AUGMENTATION_SERIALIZERS");
920 if (inputType.isYangBindingAvailable) {
921 implementsType(BINDING_CODEC)
922 staticField(it, INSTANCE_IDENTIFIER_CODEC, BindingCodec)
923 staticField(it, IDENTITYREF_CODEC, BindingCodec)
924 implementsType(BindingDeserializer.asCtClass)
926 method(Object, "toDomValue", Object) [
927 modifiers = PUBLIC + FINAL + STATIC
928 val ctSpec = inputType.asCtClass;
932 ////System.out.println("«inputType.simpleName»#toDomValue: "+$1);
937 «typeSpec.resolvedName» _value = («typeSpec.resolvedName») $1;
938 «FOR property : properties.entrySet»
939 «IF property.key != "getValue"»
940 «property.value.resolvedName» «property.key» = («property.value.resolvedName») _value.«property.
942 if(«property.key» != null) {
943 return «serializeValue(property.value, property.key, getterToTypeDefinition.get(property.key))»;
952 method(Object, "serialize", Object) [
955 return toDomValue($1);
959 method(Object, "fromDomValue", Object) [
960 modifiers = PUBLIC + FINAL + STATIC
963 ////System.out.println("«inputType.simpleName»#fromDomValue: "+$1);
968 if($1 instanceof String) {
969 String _simpleValue = (String) $1;
970 return new «typeSpec.resolvedName»(_simpleValue.toCharArray());
976 method(Object, "deserialize", Object) [
978 return fromDomValue($1);
984 val ret = ctCls.toClassImpl(inputType.classLoader, inputType.protectionDomain)
985 log.debug("DOM Codec for {} was generated {}", inputType, ret)
986 return ret as Class<? extends BindingCodec<Map<QName,Object>, Object>>;
987 } catch (Exception e) {
988 log.error("Cannot compile DOM Codec for {}", inputType, e);
989 val exception = new CodeGenerationException("Cannot compile Transformator for " + inputType);
990 exception.addSuppressed(e);
996 private def dispatch Class<? extends BindingCodec<Map<QName, Object>, Object>> generateValueTransformer(
997 Class<?> inputType, GeneratedTransferObject typeSpec, BitsTypeDefinition typeDef) {
999 val ctCls = createClass(typeSpec.codecClassName) [
1000 //staticField(Map,"AUGMENTATION_SERIALIZERS");
1001 if (inputType.isYangBindingAvailable) {
1002 implementsType(BINDING_CODEC)
1003 staticField(it, INSTANCE_IDENTIFIER_CODEC, BindingCodec)
1004 staticField(it, IDENTITYREF_CODEC, BindingCodec)
1005 implementsType(BindingDeserializer.asCtClass)
1007 method(Object, "toDomValue", Object) [
1008 modifiers = PUBLIC + FINAL + STATIC
1009 val ctSpec = typeSpec.asCtClass;
1012 ////System.out.println("«inputType.simpleName»#toDomValue: "+$1);
1017 «typeSpec.resolvedName» _encapsulatedValue = («typeSpec.resolvedName») $1;
1018 «HashSet.resolvedName» _value = new «HashSet.resolvedName»();
1019 //System.out.println("«inputType.simpleName»#toDomValue:Enc: "+_encapsulatedValue);
1021 «FOR bit : typeDef.bits»
1022 «val getter = bit.getterName()»
1023 if(Boolean.TRUE.equals(_encapsulatedValue.«getter»())) {
1024 _value.add("«bit.name»");
1027 «Set.resolvedName» _domValue = «Collections.resolvedName».unmodifiableSet(_value);
1028 //System.out.println("«inputType.simpleName»#toDomValue:DeEnc: "+_domValue);
1034 method(Object, "serialize", Object) [
1037 return toDomValue($1);
1041 method(Object, "fromDomValue", Object) [
1042 modifiers = PUBLIC + FINAL + STATIC
1043 val sortedBits = typeDef.bits.sort[o1, o2|o1.propertyName.compareTo(o2.propertyName)]
1046 //System.out.println("«inputType.simpleName»#fromDomValue: "+$1);
1051 «Set.resolvedName» _domValue = («Set.resolvedName») $1;
1052 «FOR bit : sortedBits»
1053 Boolean «bit.propertyName» = Boolean.valueOf(_domValue.contains("«bit.name»"));
1056 return new «inputType.resolvedName»(«FOR bit : sortedBits SEPARATOR ","»«bit.propertyName»«ENDFOR»);
1060 method(Object, "deserialize", Object) [
1062 return fromDomValue($1);
1068 val ret = ctCls.toClassImpl(inputType.classLoader, inputType.protectionDomain)
1069 log.debug("DOM Codec for {} was generated {}", inputType, ret)
1070 return ret as Class<? extends BindingCodec<Map<QName,Object>, Object>>;
1071 } catch (Exception e) {
1072 log.error("Cannot compile DOM Codec for {}", inputType, e);
1073 val exception = new CodeGenerationException("Cannot compile Transformator for " + inputType);
1074 exception.addSuppressed(e);
1079 def String getPropertyName(Bit bit) {
1080 '''_«BindingGeneratorUtil.parseToValidParamName(bit.name)»'''
1083 def String getterName(Bit bit) {
1085 val paramName = BindingGeneratorUtil.parseToValidParamName(bit.name);
1086 return '''is«paramName.toFirstUpper»''';
1089 def boolean isYangBindingAvailable(Class<?> class1) {
1091 val bindingCodecClass = class1.classLoader.loadClass(BINDING_CODEC.name);
1092 return bindingCodecClass !== null;
1093 } catch (ClassNotFoundException e) {
1098 private def createDummyImplementation(Class<?> object, GeneratedTransferObject typeSpec) {
1099 log.info("Generating Dummy DOM Codec for {} with {}", object, object.classLoader)
1100 return createClass(typeSpec.codecClassName) [
1101 if (object.isYangBindingAvailable) {
1102 implementsType(BINDING_CODEC)
1103 staticField(it, INSTANCE_IDENTIFIER_CODEC, BindingCodec)
1104 staticField(it, IDENTITYREF_CODEC, BindingCodec)
1105 implementsType(BindingDeserializer.asCtClass)
1107 //implementsType(BindingDeserializer.asCtClass)
1108 method(Object, "toDomValue", Object) [
1109 modifiers = PUBLIC + FINAL + STATIC
1114 return $1.toString();
1118 method(Object, "serialize", Object) [
1121 return toDomValue($1);
1125 method(Object, "fromDomValue", Object) [
1126 modifiers = PUBLIC + FINAL + STATIC
1127 bodyChecked = '''return null;'''
1129 method(Object, "deserialize", Object) [
1131 return fromDomValue($1);
1138 private def Type getValueReturnType(GeneratedTransferObject object) {
1139 for (prop : object.properties) {
1140 if (prop.name == "value") {
1141 return prop.returnType;
1144 if (object.superType != null) {
1145 return getValueReturnType(object.superType);
1150 private def Class<?> generateValueTransformer(Class<?> inputType, Enumeration typeSpec) {
1152 val typeRef = new ReferencedTypeImpl(typeSpec.packageName, typeSpec.name);
1153 val schema = typeToSchemaNode.get(typeRef) as ExtendedType;
1154 val enumSchema = schema.baseType as EnumerationType;
1156 //log.info("Generating DOM Codec for {} with {}", inputType, inputType.classLoader)
1157 val ctCls = createClass(typeSpec.codecClassName) [
1158 //staticField(Map,"AUGMENTATION_SERIALIZERS");
1159 //implementsType(BINDING_CODEC)
1160 method(Object, "toDomValue", Object) [
1161 modifiers = PUBLIC + FINAL + STATIC
1166 «typeSpec.resolvedName» _value = («typeSpec.resolvedName») $1;
1167 «FOR en : enumSchema.values»
1168 if(«typeSpec.resolvedName».«BindingGeneratorUtil.parseToClassName(en.name)».equals(_value)) {
1176 method(Object, "serialize", Object) [
1178 return toDomValue($1);
1181 method(Object, "fromDomValue", Object) [
1182 modifiers = PUBLIC + FINAL + STATIC
1188 String _value = (String) $1;
1189 «FOR en : enumSchema.values»
1190 if("«en.name»".equals(_value)) {
1191 return «typeSpec.resolvedName».«BindingGeneratorUtil.parseToClassName(en.name)»;
1198 method(Object, "deserialize", Object) [
1200 return fromDomValue($1);
1205 val ret = ctCls.toClassImpl(inputType.classLoader, inputType.protectionDomain)
1206 log.debug("DOM Codec for {} was generated {}", inputType, ret)
1208 } catch (CodeGenerationException e) {
1209 throw new CodeGenerationException("Cannot compile Transformator for " + inputType, e);
1210 } catch (Exception e) {
1211 log.error("Cannot compile DOM Codec for {}", inputType, e);
1212 val exception = new CodeGenerationException("Cannot compile Transformator for " + inputType);
1213 exception.addSuppressed(e);
1219 def Class<?> toClassImpl(CtClass newClass, ClassLoader loader, ProtectionDomain domain) {
1220 val cls = newClass.toClass(loader, domain);
1221 if (classFileCapturePath !== null) {
1222 newClass.writeFile(classFileCapturePath.absolutePath);
1224 listener?.onCodecCreated(cls);
1228 def debugWriteClass(CtClass class1) {
1229 val path = class1.name.replace(".", "/") + ".class"
1231 val captureFile = new File(classFileCapturePath, path);
1232 captureFile.createNewFile
1236 private def dispatch String deserializeValue(Type type, String domParameter, TypeDefinition<?> typeDef) {
1237 if (INSTANCE_IDENTIFIER.equals(type)) {
1238 return '''(«InstanceIdentifier.name») «INSTANCE_IDENTIFIER_CODEC».deserialize(«domParameter»)'''
1239 } else if (CLASS_TYPE.equals(type)) {
1240 return '''(«Class.name») «IDENTITYREF_CODEC».deserialize(«domParameter»)'''
1242 return '''(«type.resolvedName») «domParameter»'''
1250 private def dispatch CharSequence deserializeProperty(DataSchemaNode container, Type type, String propertyName) '''
1251 «type.resolvedName» «propertyName» = null;
1254 private def dispatch CharSequence deserializeProperty(DataSchemaNode container, GeneratedTypeBuilder type,
1255 String propertyName) {
1256 _deserializeProperty(container, type.toInstance, propertyName)
1259 public static def toSetter(String it) {
1261 if (startsWith("is")) {
1262 return "set" + substring(2);
1263 } else if (startsWith("get")) {
1264 return "set" + substring(3);
1270 private def dispatch CharSequence deserializeProperty(DataSchemaNode container,GeneratedType type, String propertyName) '''
1271 «type.resolvedName» «propertyName» = value.«propertyName»();
1272 if(«propertyName» != null) {
1273 Object domValue = «type.serializer».toDomStatic(QNAME,«propertyName»);
1274 _childNodes.add(domValue);
1278 private def getBuilderName(GeneratedType type) '''«type.resolvedName»Builder'''
1280 private def staticQNameField(CtClass it, QName node) {
1281 val field = new CtField(ctQName, "QNAME", it);
1282 field.modifiers = PUBLIC + FINAL + STATIC;
1284 '''«QName.asCtClass.name».create("«node.namespace»","«node.formattedRevision»","«node.localName»")''')
1287 private def dispatch String serializeBody(GeneratedType type, ListSchemaNode node) '''
1289 «QName.name» _resultName = «QName.name».create($1,QNAME.getLocalName());
1290 java.util.List _childNodes = new java.util.ArrayList();
1291 «type.resolvedName» value = («type.resolvedName») $2;
1292 «transformDataContainerBody(type, type.allProperties, node)»
1293 «serializeAugmentations»
1294 return ($r) java.util.Collections.singletonMap(_resultName,_childNodes);
1298 private def dispatch String serializeBody(GeneratedType type, ContainerSchemaNode node) '''
1300 «QName.name» _resultName = «QName.name».create($1,QNAME.getLocalName());
1301 java.util.List _childNodes = new java.util.ArrayList();
1302 «type.resolvedName» value = («type.resolvedName») $2;
1303 «transformDataContainerBody(type, type.allProperties, node)»
1304 «serializeAugmentations»
1305 return ($r) java.util.Collections.singletonMap(_resultName,_childNodes);
1309 private def dispatch String serializeBody(GeneratedType type, ChoiceCaseNode node) '''
1311 «QName.name» _resultName = «QName.name».create($1,QNAME.getLocalName());
1312 java.util.List _childNodes = new java.util.ArrayList();
1313 «type.resolvedName» value = («type.resolvedName») $2;
1314 «transformDataContainerBody(type, type.allProperties, node)»
1315 «serializeAugmentations»
1316 return ($r) java.util.Collections.singletonMap(_resultName,_childNodes);
1320 private def dispatch String serializeBody(GeneratedType type, SchemaNode node) '''
1322 «QName.name» _resultName = «QName.name».create($1,QNAME.getLocalName());
1323 java.util.List _childNodes = new java.util.ArrayList();
1324 «type.resolvedName» value = («type.resolvedName») $2;
1325 return ($r) java.util.Collections.singletonMap(_resultName,_childNodes);
1329 private def transformDataContainerBody(Type type, Map<String, Type> properties, DataNodeContainer node) {
1331 «FOR child : node.childNodes»
1332 «val signature = properties.getFor(child)»
1333 «IF signature !== null»
1334 ////System.out.println("«type.name»#«signature.key»" + value.«signature.key»());
1335 «serializeProperty(child, signature.value, signature.key)»
1342 private def serializeAugmentations() '''
1343 java.util.List _augmentations = (java.util.List) «AUGMENTATION_CODEC».serialize(value);
1344 if(_augmentations != null) {
1345 _childNodes.addAll(_augmentations);
1349 def Entry<String, Type> getFor(Map<String, Type> map, DataSchemaNode node) {
1350 var sig = map.get(node.getterName);
1352 return new SimpleEntry(node.getterName, sig);
1354 sig = map.get(node.booleanGetterName);
1356 return new SimpleEntry(node.booleanGetterName, map.get(node.booleanGetterName));
1361 private static def String getBooleanGetterName(DataSchemaNode node) {
1362 return "is" + BindingGeneratorUtil.parseToClassName(node.QName.localName);
1365 private static def String getGetterName(DataSchemaNode node) {
1366 return "get" + BindingGeneratorUtil.parseToClassName(node.QName.localName);
1369 private static def String getGetterName(QName node) {
1370 return "get" + BindingGeneratorUtil.parseToClassName(node.localName);
1373 private def dispatch CharSequence serializeProperty(ListSchemaNode schema, ParameterizedType type,
1374 String propertyName) '''
1375 «type.resolvedName» «propertyName» = value.«propertyName»();
1376 ////System.out.println("«propertyName»:" + «propertyName»);
1377 if(«propertyName» != null) {
1378 java.util.Iterator _iterator = «propertyName».iterator();
1379 boolean _hasNext = _iterator.hasNext();
1381 Object _listItem = _iterator.next();
1382 Object _domValue = «type.actualTypeArguments.get(0).serializer(schema).resolvedName».toDomStatic(_resultName,_listItem);
1383 _childNodes.add(_domValue);
1384 _hasNext = _iterator.hasNext();
1389 private def dispatch CharSequence serializeProperty(LeafSchemaNode schema, Type type, String propertyName) '''
1390 «type.resolvedName» «propertyName» = value.«propertyName»();
1392 if(«propertyName» != null) {
1393 «QName.name» _qname = «QName.name».create(_resultName,"«schema.QName.localName»");
1394 Object _propValue = «serializeValue(type, propertyName, schema.type)»;
1395 if(_propValue != null) {
1396 Object _domValue = java.util.Collections.singletonMap(_qname,_propValue);
1397 _childNodes.add(_domValue);
1402 private def dispatch serializeValue(GeneratedTransferObject type, String parameter, TypeDefinition<?> typeDefinition) {
1403 '''«type.valueSerializer(typeDefinition).resolvedName».toDomValue(«parameter»)'''
1406 private def dispatch serializeValue(Enumeration type, String parameter, TypeDefinition<?> typeDefinition) {
1407 '''«type.valueSerializer(typeDefinition).resolvedName».toDomValue(«parameter»)'''
1410 private def dispatch serializeValue(Type signature, String property, TypeDefinition<?> typeDefinition) {
1411 if (INSTANCE_IDENTIFIER == signature) {
1412 return '''«INSTANCE_IDENTIFIER_CODEC».serialize(«property»)'''
1413 } else if (CLASS_TYPE.equals(signature)) {
1414 return '''(«QName.resolvedName») «IDENTITYREF_CODEC».serialize(«property»)'''
1416 if ("char[]" == signature.name) {
1417 return '''new String(«property»)''';
1419 return '''«property»''';
1422 private def dispatch CharSequence serializeProperty(LeafListSchemaNode schema, ParameterizedType type,
1423 String propertyName) '''
1424 «type.resolvedName» «propertyName» = value.«propertyName»();
1425 if(«propertyName» != null) {
1426 «QName.name» _qname = «QName.name».create(_resultName,"«schema.QName.localName»");
1427 java.util.Iterator _iterator = «propertyName».iterator();
1428 boolean _hasNext = _iterator.hasNext();
1430 Object _listItem = _iterator.next();
1431 Object _propValue = «serializeValue(type.actualTypeArguments.get(0), "_listItem", schema.type)»;
1432 Object _domValue = java.util.Collections.singletonMap(_qname,_propValue);
1433 _childNodes.add(_domValue);
1434 _hasNext = _iterator.hasNext();
1439 private def dispatch CharSequence serializeProperty(ChoiceNode container, GeneratedType type,
1440 String propertyName) '''
1441 «type.resolvedName» «propertyName» = value.«propertyName»();
1442 if(«propertyName» != null) {
1443 java.util.List domValue = «type.serializer(container).resolvedName».toDomStatic(_resultName,«propertyName»);
1444 _childNodes.addAll(domValue);
1452 private def dispatch CharSequence serializeProperty(DataSchemaNode container, Type type, String propertyName) '''
1453 «type.resolvedName» «propertyName» = value.«propertyName»();
1454 if(«propertyName» != null) {
1455 Object domValue = «propertyName»;
1456 _childNodes.add(domValue);
1460 private def dispatch CharSequence serializeProperty(DataSchemaNode container, GeneratedTypeBuilder type,
1461 String propertyName) {
1462 serializeProperty(container, type.toInstance, propertyName)
1465 private def dispatch CharSequence serializeProperty(DataSchemaNode container, GeneratedType type,
1466 String propertyName) '''
1467 «type.resolvedName» «propertyName» = value.«propertyName»();
1468 if(«propertyName» != null) {
1469 Object domValue = «type.serializer(container).resolvedName».toDomStatic(_resultName,«propertyName»);
1470 _childNodes.add(domValue);
1474 private def codecClassName(GeneratedType typeSpec) {
1475 return '''«typeSpec.resolvedName»$Broker$Codec$DOM'''
1478 private def codecClassName(Class<?> typeSpec) {
1479 return '''«typeSpec.name»$Broker$Codec$DOM'''
1482 private def HashMap<String, Type> getAllProperties(GeneratedType type) {
1483 val ret = new HashMap<String, Type>();
1484 type.collectAllProperties(ret);
1488 private def dispatch void collectAllProperties(GeneratedType type, Map<String, Type> set) {
1489 for (definition : type.methodDefinitions) {
1490 set.put(definition.name, definition.returnType);
1492 for (property : type.properties) {
1493 set.put(property.getterName, property.returnType);
1495 for (parent : type.implements) {
1496 parent.collectAllProperties(set);
1500 def String getGetterName(GeneratedProperty property) {
1501 return "get" + property.name.toFirstUpper
1504 private def dispatch void collectAllProperties(Type type, Map<String, Type> set) {
1505 // NOOP for generic type.
1508 def String getResolvedName(Type type) {
1509 return type.asCtClass.name;
1512 def String getResolvedName(Class<?> type) {
1513 return type.asCtClass.name;
1516 def CtClass asCtClass(Type type) {
1517 val cls = loadClassWithTCCL(type.fullyQualifiedName)
1518 return cls.asCtClass;
1521 private def dispatch processException(Class<?> inputType, CodeGenerationException e) {
1522 log.error("Cannot compile DOM Codec for {}. One of it's prerequisites was not generated.", inputType);
1526 private def dispatch processException(Class<?> inputType, Exception e) {
1527 log.error("Cannot compile DOM Codec for {}", inputType, e);
1528 val exception = new CodeGenerationException("Cannot compile Transformator for " + inputType, e);
1532 private def setBodyChecked(CtMethod method, String body) {
1534 method.setBody(body);
1535 } catch (CannotCompileException e) {
1536 log.error("Cannot compile method: {}#{} {}, Reason: {} Body: {}", method.declaringClass, method.name,
1537 method.signature, e.message, body)
1542 private def <V> V withClassLoaderAndLock(ClassLoader cls, Lock lock, Callable<V> function) throws Exception {
1543 appendClassLoaderIfMissing(cls);
1544 ClassLoaderUtils.withClassLoaderAndLock(cls, lock, function);
1550 class PropertyPair {
1559 SchemaNode schemaNode;