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 org.opendaylight.yangtools.yang.model.api.ContainerSchemaNode
13 import org.opendaylight.yangtools.yang.model.api.ListSchemaNode
14 import org.opendaylight.yangtools.sal.binding.model.api.MethodSignature
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
25 import java.util.WeakHashMap
27 import java.util.TreeSet
28 import com.google.common.base.Joiner
29 import org.opendaylight.yangtools.sal.binding.model.api.GeneratedTransferObject
30 import org.opendaylight.yangtools.sal.binding.model.api.Enumeration
31 import org.opendaylight.yangtools.yang.model.api.ChoiceCaseNode
32 import static org.opendaylight.controller.sal.binding.impl.util.ClassLoaderUtils.*;
33 import org.opendaylight.yangtools.yang.binding.BindingDeserializer
34 import org.opendaylight.yangtools.yang.binding.BindingSerializer
35 import org.opendaylight.yangtools.yang.binding.BindingCodec
36 import org.slf4j.LoggerFactory
38 class TransformerGenerator {
40 private static val log = LoggerFactory.getLogger(TransformerGenerator)
42 public static val STRING = Types.typeForClass(String);
43 public static val BOOLEAN = Types.typeForClass(Boolean);
44 public static val INTEGER = Types.typeForClass(Integer);
46 //public static val DECIMAL = Types.typeForClass(Decimal);
47 public static val LONG = Types.typeForClass(Long);
49 val ClassPool classPool
50 val extension JavassistUtils utils;
52 CtClass ctTransformator
57 var Map<Type, Type> typeDefinitions;
60 var Map<Type, GeneratedTypeBuilder> typeToDefinition
63 var Map<Type, SchemaNode> typeToSchemaNode
65 val Map<Class<?>, Class<?>> generatedClasses = new WeakHashMap();
67 public new(ClassPool pool) {
69 utils = new JavassistUtils(pool)
71 ctTransformator = BindingCodec.asCtClass;
72 ctQName = QName.asCtClass
75 def Class<? extends BindingCodec<Map<QName, Object>, Object>> transformerFor(Class<?> inputType) {
76 return withClassLoader(inputType.classLoader) [ |
77 val ret = generatedClasses.get(inputType);
79 return ret as Class<? extends BindingCodec<Map<QName,Object>, Object>>;
81 val ref = Types.typeForClass(inputType)
82 val node = typeToSchemaNode.get(ref)
83 val typeSpecBuilder = typeToDefinition.get(ref)
84 val typeSpec = typeSpecBuilder.toInstance();
85 val newret = generateTransformerFor(inputType, typeSpec, node)
86 generatedClasses.put(inputType, newret);
87 return newret as Class<? extends BindingCodec<Map<QName,Object>, Object>>;
91 def Class<?> keyTransformerFor(Class<?> inputType, GeneratedType type, ListSchemaNode schema) {
92 return withClassLoader(inputType.classLoader) [ |
93 val transformer = generatedClasses.get(inputType);
94 if (transformer != null) {
97 val newret = generateKeyTransformerFor(inputType, type, schema);
98 generatedClasses.put(inputType, newret);
99 return newret as Class<? extends BindingCodec<Map<QName,Object>, Object>>;
103 def Class<?> keyTransformer(GeneratedType type, ListSchemaNode node) {
104 val cls = loadClassWithTCCL(type.resolvedName + "Key");
105 keyTransformerFor(cls, type, node);
108 private def serializer(Type type) {
109 val cls = loadClassWithTCCL(type.resolvedName);
114 def Class<?> getValueSerializer(GeneratedTransferObject type) {
115 val cls = loadClassWithTCCL(type.resolvedName);
116 val transformer = generatedClasses.get(cls);
117 if (transformer !== null) {
120 val valueTransformer = generateValueTransformer(cls, type);
121 generatedClasses.put(cls, valueTransformer);
122 return valueTransformer;
125 private def generateKeyTransformerFor(Class<? extends Object> inputType, GeneratedType typeSpec, ListSchemaNode node) {
127 log.info("Generating DOM Codec for {} with {}",inputType,inputType.classLoader)
128 val properties = typeSpec.allProperties;
129 val ctCls = createClass(inputType.transformatorFqn) [
130 //staticField(Map,"AUGMENTATION_SERIALIZERS");
131 staticQNameField(node.QName);
132 implementsType(ctTransformator)
133 method(Object, "toDomStatic", QName, Object) [
134 modifiers = PUBLIC + FINAL + STATIC
142 method(Object, "fromDomStatic", QName, Object) [
143 modifiers = PUBLIC + FINAL + STATIC
149 «QName.name» _localQName = $1;
150 java.util.Map _compositeNode = (java.util.Map) $2;
151 «FOR key : node.keyDefinition»
152 «val propertyName = key.getterName»
153 «val keyDef = node.getDataChildByName(key)»
154 «val property = properties.get(propertyName)»
155 «deserializeProperty(keyDef, property.returnType, property)»;
157 «inputType.name» _value = new «inputType.name»(«node.keyDefinition.keyConstructorList»);
162 method(Object, "serialize", Object) [
164 return toDomStatic(QNAME,$1);
167 method(Object, "deserialize", Object) [
169 return fromDomStatic(QNAME,$1);
173 val ret = ctCls.toClass(inputType.classLoader, inputType.protectionDomain)
174 log.info("DOM Codec for {} was generated {}",inputType,ret)
175 return ret as Class<? extends BindingCodec<Map<QName,Object>, ?>>;
176 } catch (Exception e) {
177 log.error("Cannot compile DOM Codec for {}. Exception {}",inputType,e);
178 val exception = new IllegalStateException("Cannot compile Transformator for " + inputType);
179 exception.addSuppressed(e);
184 private def <D> Class<? extends BindingCodec<Map<QName, Object>, D>> generateTransformerFor(Class<D> inputType,
185 GeneratedType typeSpec, SchemaNode node) {
187 log.info("Generating DOM Codec for {} with {}",inputType,inputType.classLoader)
188 val ctCls = createClass(typeSpec.transformatorFqn) [
189 //staticField(Map,"AUGMENTATION_SERIALIZERS");
190 staticQNameField(inputType);
191 implementsType(ctTransformator)
192 method(Object, "toDomStatic", QName, Object) [
193 modifiers = PUBLIC + FINAL + STATIC
194 body = serializeBodyFacade(typeSpec, node)
196 method(Object, "serialize", Object) [
198 return toDomStatic(QNAME,$1);
201 method(Object, "fromDomStatic", QName, Object) [
202 modifiers = PUBLIC + FINAL + STATIC
203 body = deserializeBody(typeSpec, node)
205 method(Object, "deserialize", Object) [
207 return fromDomStatic(QNAME,$1);
212 val ret = ctCls.toClass(inputType.classLoader, inputType.protectionDomain)
213 return ret as Class<? extends BindingCodec<Map<QName,Object>, D>>;
214 } catch (Exception e) {
215 log.error("Cannot compile DOM Codec for {}. Exception {}",inputType,e);
216 val exception = new IllegalStateException("Cannot compile Transformator for " + inputType);
217 exception.addSuppressed(e);
222 private def keyConstructorList(List<QName> qnames) {
223 val names = new TreeSet<String>()
224 for (name : qnames) {
225 val fieldName = name.getterName;
226 names.add(fieldName);
228 return Joiner.on(",").join(names);
231 private def serializeBodyFacade(GeneratedType type, SchemaNode node) {
232 val ret = serializeBody(type, node);
236 private def String deserializeBody(GeneratedType type, SchemaNode node) {
237 val ret = deserializeBodyImpl(type, node);
241 private def deserializeKey(GeneratedType type, ListSchemaNode node) {
242 if (node.keyDefinition != null && !node.keyDefinition.empty) {
244 «type.resolvedName»Key getKey = («type.resolvedName»Key) «keyTransformer(type, node).canonicalName».fromDomStatic(_localQName,_compositeNode);
245 _builder.setKey(getKey);
250 private def dispatch String deserializeBodyImpl(GeneratedType type, SchemaNode node) '''
252 «QName.name» _localQName = «QName.name».create($1,QNAME.getLocalName());
257 java.util.Map _compositeNode = (java.util.Map) $2;
258 «type.builderName» _builder = new «type.builderName»();
260 return _builder.build();
264 private def dispatch String deserializeBodyImpl(GeneratedType type, ListSchemaNode node) '''
266 «QName.name» _localQName = «QName.name».create($1,QNAME.getLocalName());
270 java.util.Map _compositeNode = (java.util.Map) $2;
271 «type.builderName» _builder = new «type.builderName»();
272 «deserializeKey(type, node)»
273 «deserializeDataNodeContainerBody(type, node)»
274 return _builder.build();
278 private def dispatch String deserializeBodyImpl(GeneratedType type, ContainerSchemaNode node) '''
280 «QName.name» _localQName = «QName.name».create($1,QNAME.getLocalName());
284 java.util.Map _compositeNode = (java.util.Map) $2;
285 «type.builderName» _builder = new «type.builderName»();
286 «deserializeDataNodeContainerBody(type, node)»
287 return _builder.build();
291 private def dispatch String deserializeBodyImpl(GeneratedType type, ChoiceCaseNode node) '''
293 «QName.name» _localQName = «QName.name».create($1,QNAME.getLocalName());
297 java.util.Map _compositeNode = (java.util.Map) $2;
298 «type.builderName» _builder = new «type.builderName»();
299 «deserializeDataNodeContainerBody(type, node)»
300 return _builder.build();
304 private def deserializeDataNodeContainerBody(GeneratedType type, DataNodeContainer node) {
305 deserializeNodeContainerBodyImpl(type, type.allProperties, node);
308 private def deserializeNodeContainerBodyImpl(GeneratedType type, HashMap<String, MethodSignature> properties,
309 DataNodeContainer node) {
311 «FOR child : node.childNodes.filter[!augmenting]»
312 «val signature = properties.get(child.getterName)»
313 «deserializeProperty(child, signature.returnType, signature)»
314 _builder.«signature.name.toSetter»(«signature.name»);
320 private def dispatch CharSequence deserializeProperty(ListSchemaNode schema, ParameterizedType type,
321 MethodSignature property) '''
322 java.util.List _dom_«property.name» = _compositeNode.get(«QName.name».create(_localQName,"«schema.QName.
324 //System.out.println("«property.name»#deCode"+_dom_«property.name»);
325 java.util.List «property.name» = new java.util.ArrayList();
326 if(_dom_«property.name» != null) {
327 java.util.List _serialized = new java.util.ArrayList();
328 java.util.Iterator _iterator = _dom_«property.name».iterator();
329 boolean _hasNext = _iterator.hasNext();
331 Object _listItem = _iterator.next();
332 //System.out.println(" item" + _listItem);
333 Object _value = «type.actualTypeArguments.get(0).serializer.name».fromDomStatic(_localQName,_listItem);
334 //System.out.println(" value" + _value);
335 «property.name».add(_value);
336 _hasNext = _iterator.hasNext();
340 //System.out.println(" list" + «property.name»);
343 private def dispatch CharSequence deserializeProperty(LeafListSchemaNode schema, ParameterizedType type,
344 MethodSignature property) '''
345 java.util.List _dom_«property.name» = _compositeNode.get(«QName.name».create(_localQName,"«schema.QName.
347 java.util.List «property.name» = new java.util.ArrayList();
348 if(_dom_«property.name» != null) {
349 java.util.List _serialized = new java.util.ArrayList();
350 java.util.Iterator _iterator = _dom_«property.name».iterator();
351 boolean _hasNext = _iterator.hasNext();
353 Object _listItem = _iterator.next();
354 if(_listItem instanceof java.util.Map.Entry) {
355 Object _innerValue = ((java.util.Map.Entry) _listItem).getValue();
356 Object _value = «deserializeValue(type.actualTypeArguments.get(0), "_innerValue")»;
357 «property.name».add(_value);
359 _hasNext = _iterator.hasNext();
364 private def dispatch CharSequence deserializeProperty(LeafSchemaNode schema, Type type, MethodSignature property) '''
365 java.util.List _dom_«property.name»_list =
366 _compositeNode.get(«QName.name».create(_localQName,"«schema.QName.localName»"));
367 «type.resolvedName» «property.name» = null;
368 if(_dom_«property.name»_list != null && _dom_«property.name»_list.size() > 0) {
369 java.util.Map.Entry _dom_«property.name» = (java.util.Map.Entry) _dom_«property.name»_list.get(0);
370 Object _inner_value = _dom_«property.name».getValue();
371 «property.name» = «deserializeValue(type, "_inner_value")»;
375 private def dispatch CharSequence deserializeProperty(ContainerSchemaNode schema, Type type,
376 MethodSignature property) '''
377 java.util.List _dom_«property.name»_list =
378 _compositeNode.get(«QName.name».create(_localQName,"«schema.QName.localName»"));
379 «type.resolvedName» «property.name» = null;
380 if(_dom_«property.name»_list != null && _dom_«property.name»_list.size() > 0) {
382 java.util.Map _dom_«property.name» = (java.util.Map) _dom_«property.name»_list.get(0);
383 «type.resolvedName» «property.name» = «type.serializer.name».fromDomStatic(_localQName,_dom_«property.name»);
387 private def dispatch String deserializeValue(GeneratedTransferObject type, String domParameter) '''
388 («type.resolvedName») «type.valueSerializer.name».fromDomValue(«domParameter»);
391 private def dispatch Class<? extends BindingCodec<Map<QName, Object>, Object>> generateValueTransformer(
392 Class<?> inputType, GeneratedTransferObject typeSpec) {
395 val returnType = typeSpec.valueReturnType;
396 if (returnType == null) {
398 val ctCls = createDummyImplementation(inputType, typeSpec);
399 val ret = ctCls.toClass(inputType.classLoader, inputType.protectionDomain)
400 return ret as Class<? extends BindingCodec<Map<QName,Object>, Object>>;
402 val ctCls = createClass(typeSpec.transformatorFqn) [
403 //staticField(Map,"AUGMENTATION_SERIALIZERS");
404 implementsType(ctTransformator)
405 implementsType(BindingDeserializer.asCtClass)
406 method(Object, "toDomValue", Object) [
407 modifiers = PUBLIC + FINAL + STATIC
410 ////System.out.println("«inputType.simpleName»#toDomValue: "+$1);
415 «typeSpec.resolvedName» _encapsulatedValue = («typeSpec.resolvedName») $1;
416 //System.out.println("«inputType.simpleName»#toDomValue:Enc: "+_encapsulatedValue);
417 «returnType.resolvedName» _value = _encapsulatedValue.getValue();
418 //System.out.println("«inputType.simpleName»#toDomValue:DeEnc: "+_value);
423 method(Object, "serialize", Object) [
426 return toDomValue($1);
430 method(Object, "fromDomValue", Object) [
431 modifiers = PUBLIC + FINAL + STATIC
434 //System.out.println("«inputType.simpleName»#fromDomValue: "+$1);
439 «returnType.name» _simpleValue = «deserializeValue(returnType, "$1")»;
440 «typeSpec.resolvedName» _value = new «typeSpec.resolvedName»(_simpleValue);
445 method(Object, "deserialize", Object) [
447 return fromDomValue($1);
453 val ret = ctCls.toClass(inputType.classLoader, inputType.protectionDomain)
454 log.info("DOM Codec for {} was generated {}",inputType,ret)
455 return ret as Class<? extends BindingCodec<Map<QName,Object>, Object>>;
456 } catch (Exception e) {
457 log.error("Cannot compile DOM Codec for {}. Exception {}",inputType,e);
458 val exception = new IllegalStateException("Cannot compile Transformator for " + inputType);
459 exception.addSuppressed(e);
465 private def createDummyImplementation(Class<?> object, GeneratedTransferObject typeSpec) {
466 log.info("Generating Dummy DOM Codec for {} with {}",object,object.classLoader)
467 return createClass(typeSpec.transformatorFqn) [
468 //staticField(Map,"AUGMENTATION_SERIALIZERS");
469 implementsType(ctTransformator)
470 implementsType(BindingDeserializer.asCtClass)
471 method(Object, "toDomValue", Object) [
472 modifiers = PUBLIC + FINAL + STATIC
473 body = '''return null;'''
475 method(Object, "serialize", Object) [
478 return toDomValue($1);
482 method(Object, "fromDomValue", Object) [
483 modifiers = PUBLIC + FINAL + STATIC
484 body = '''return null;'''
486 method(Object, "deserialize", Object) [
488 return fromDomValue($1);
495 def Type getValueReturnType(GeneratedTransferObject object) {
496 for (prop : object.properties) {
497 if (prop.name == "value") {
498 return prop.returnType;
501 if (object.superType != null) {
502 return getValueReturnType(object.superType);
507 private def dispatch Class<? extends BindingCodec<Map<QName, Object>, Object>> generateValueTransformer(
508 Class<?> inputType, Enumeration typeSpec) {
510 log.info("Generating DOM Codec for {} with {}",inputType,inputType.classLoader)
511 val ctCls = createClass(typeSpec.transformatorFqn) [
512 //staticField(Map,"AUGMENTATION_SERIALIZERS");
513 implementsType(ctTransformator)
514 method(Object, "toDomValue", Object) [
515 modifiers = PUBLIC + FINAL + STATIC
520 «typeSpec.resolvedName» _value = («typeSpec.resolvedName») $1;
521 return _value.getValue();
524 method(Object, "serialize", Object) [
526 return toDomValue($1);
529 method(Object, "fromDomValue", Object) [
530 modifiers = PUBLIC + FINAL + STATIC
536 «typeSpec.resolvedName» _value = new «typeSpec.resolvedName»(null);
540 method(Object, "deserialize", Object) [
542 return fromDomValue($1);
547 val ret = ctCls.toClass(inputType.classLoader, inputType.protectionDomain)
548 log.info("DOM Codec for {} was generated {}",inputType,ret)
549 return ret as Class<? extends BindingCodec<Map<QName,Object>, Object>>;
550 } catch (Exception e) {
551 log.error("Cannot compile DOM Codec for {}. Exception {}",inputType,e);
552 val exception = new IllegalStateException("Cannot compile Transformator for " + inputType);
553 exception.addSuppressed(e);
559 private def dispatch String deserializeValue(Type type, String domParameter) '''(«type.resolvedName») «domParameter»'''
565 private def dispatch CharSequence deserializeProperty(DataSchemaNode container, Type type, MethodSignature property) '''
566 «type.resolvedName» «property.name» = null;
569 private def dispatch CharSequence deserializeProperty(DataSchemaNode container, GeneratedTypeBuilder type,
570 MethodSignature property) {
571 _deserializeProperty(container, type.toInstance, property)
574 public static def toSetter(String it) {
576 if (startsWith("is")) {
577 return "set" + substring(2);
578 } else if (startsWith("get")) {
579 return "set" + substring(3);
585 private def dispatch CharSequence deserializeProperty(DataSchemaNode container,GeneratedType type, MethodSignature property) '''
586 «property.returnType.resolvedName» «property.name» = value.«property.name»();
587 if(«property.name» != null) {
588 Object domValue = «type.serializer».toDomStatic(QNAME,«property.name»);
589 childNodes.add(domValue);
593 private def getBuilderName(GeneratedType type) '''«type.resolvedName»Builder'''
595 private def staticQNameField(CtClass it, Class node) {
596 val field = new CtField(ctQName, "QNAME", it);
597 field.modifiers = PUBLIC + FINAL + STATIC;
598 addField(field, '''«node.name».QNAME''')
601 private def staticQNameField(CtClass it, QName node) {
602 val field = new CtField(ctQName, "QNAME", it);
603 field.modifiers = PUBLIC + FINAL + STATIC;
604 addField(field, '''«QName.asCtClass.name».create("«node.namespace»","«node.formattedRevision»","«node.localName»")''')
607 private def dispatch String serializeBody(GeneratedType type, ListSchemaNode node) '''
609 «QName.name» resultName = «QName.name».create($1,QNAME.getLocalName());
610 java.util.List childNodes = new java.util.ArrayList();
611 «type.resolvedName» value = («type.resolvedName») $2;
612 «transformDataContainerBody(type.allProperties, node)»
613 return ($r) java.util.Collections.singletonMap(resultName,childNodes);
617 private def dispatch String serializeBody(GeneratedType type, ContainerSchemaNode node) '''
619 «QName.name» resultName = «QName.name».create($1,QNAME.getLocalName());
620 java.util.List childNodes = new java.util.ArrayList();
621 «type.resolvedName» value = («type.resolvedName») $2;
622 «transformDataContainerBody(type.allProperties, node)»
623 return ($r) java.util.Collections.singletonMap(resultName,childNodes);
627 private def transformDataContainerBody(Map<String, MethodSignature> properties, DataNodeContainer node) {
629 «FOR child : node.childNodes.filter[!augmenting]»
630 «val signature = properties.get(child.getterName)»
631 «serializeProperty(child, signature.returnType, signature)»
637 private static def String getGetterName(DataSchemaNode node) {
638 return "get" + BindingGeneratorUtil.parseToClassName(node.QName.localName);
641 private static def String getGetterName(QName node) {
642 return "get" + BindingGeneratorUtil.parseToClassName(node.localName);
645 private def dispatch CharSequence serializeProperty(ListSchemaNode schema, ParameterizedType type,
646 MethodSignature property) '''
647 «property.returnType.resolvedName» «property.name» = value.«property.name»();
648 if(«property.name» != null) {
649 java.util.Iterator _iterator = «property.name».iterator();
650 boolean _hasNext = _iterator.hasNext();
652 Object _listItem = _iterator.next();
653 Object _domValue = «type.actualTypeArguments.get(0).serializer.name».toDomStatic(QNAME,_listItem);
654 childNodes.add(_domValue);
655 _hasNext = _iterator.hasNext();
660 private def dispatch CharSequence serializeProperty(LeafSchemaNode schema, Type type, MethodSignature property) '''
661 «property.returnType.resolvedName» «property.name» = value.«property.name»();
663 if(«property.name» != null) {
664 «QName.name» _qname = «QName.name».create(resultName,"«schema.QName.localName»");
665 Object _propValue = «serializeValue(type, property.name)»;
666 if(_propValue != null) {
667 Object _domValue = java.util.Collections.singletonMap(_qname,_propValue);
668 childNodes.add(_domValue);
673 private def dispatch serializeValue(GeneratedTransferObject type, String parameter) '''«type.valueSerializer.name».toDomValue(«parameter»)'''
675 private def dispatch serializeValue(Type signature, String property) '''«property»'''
677 private def dispatch CharSequence serializeProperty(LeafListSchemaNode schema, Type type, MethodSignature property) '''
678 «property.returnType.resolvedName» «property.name» = value.«property.name»();
679 if(«property.name» != null) {
680 «QName.name» _qname = «QName.name».create(resultName,"«schema.QName.localName»");
681 java.util.Iterator _iterator = «property.name».iterator();
682 boolean _hasNext = _iterator.hasNext();
684 Object _listItem = _iterator.next();
685 Object _propValue = «property.name»;
686 Object _domValue = java.util.Collections.singletonMap(_qname,_propValue);
687 childNodes.add(_domValue);
688 _hasNext = _iterator.hasNext();
697 private def dispatch CharSequence serializeProperty(DataSchemaNode container, Type type, MethodSignature property) '''
698 «property.returnType.resolvedName» «property.name» = value.«property.name»();
699 if(«property.name» != null) {
700 Object domValue = «property.name»;
701 childNodes.add(domValue);
705 private def dispatch CharSequence serializeProperty(DataSchemaNode container, GeneratedTypeBuilder type,
706 MethodSignature property) {
707 serializeProperty(container, type.toInstance, property)
710 private def dispatch CharSequence serializeProperty(DataSchemaNode container, GeneratedType type,
711 MethodSignature property) '''
712 «property.returnType.resolvedName» «property.name» = value.«property.name»();
713 if(«property.name» != null) {
714 Object domValue = «type.serializer».toDomStatic(QNAME,«property.name»);
715 childNodes.add(domValue);
719 private def dispatch String serializeBody(GeneratedType type, SchemaNode node) '''
721 return ($r) java.util.Collections.singletonMap(this.QNAME,null);
725 private def transformatorFqn(GeneratedType typeSpec) {
726 return '''«typeSpec.resolvedName»$Broker$Codec$DOM'''
729 private def transformatorFqn(Class typeSpec) {
730 return '''«typeSpec.name»$Broker$Codec$DOM'''
733 private def HashMap<String, MethodSignature> getAllProperties(GeneratedType type) {
734 val ret = new HashMap<String, MethodSignature>();
735 type.collectAllProperties(ret);
739 private def dispatch void collectAllProperties(GeneratedType type, Map<String, MethodSignature> set) {
740 for (definition : type.methodDefinitions) {
741 set.put(definition.name, definition);
744 for (parent : type.implements) {
745 parent.collectAllProperties(set);
749 private def dispatch void collectAllProperties(Type type, Map<String, MethodSignature> set) {
750 // NOOP for generic type.
753 def String getResolvedName(Type type) {
754 return type.asCtClass.name;
757 def CtClass asCtClass(Type type) {
758 val name = type.fullyQualifiedName
759 val cls = loadClassWithTCCL(type.fullyQualifiedName)
760 return cls.asCtClass;
773 MethodSignature signature;
775 SchemaNode schemaNode;