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 javassist.ClassPool
11 import org.opendaylight.yangtools.sal.binding.model.api.GeneratedType
12 import org.opendaylight.yangtools.yang.model.api.SchemaNode
13 import org.opendaylight.yangtools.sal.binding.generator.util.JavassistUtils
14 import javassist.CtClass
16 import org.opendaylight.yangtools.yang.common.QName
17 import javassist.CtField
18 import static javassist.Modifier.*
19 import static org.opendaylight.yangtools.sal.binding.generator.impl.CodecMapping.*
20 import org.opendaylight.yangtools.yang.model.api.ContainerSchemaNode
21 import org.opendaylight.yangtools.yang.model.api.ListSchemaNode
22 import org.opendaylight.yangtools.yang.model.api.DataNodeContainer
23 import org.opendaylight.yangtools.sal.binding.model.api.Type
24 import org.opendaylight.yangtools.sal.binding.model.api.type.builder.GeneratedTypeBuilder
25 import org.opendaylight.yangtools.binding.generator.util.Types
26 import org.opendaylight.yangtools.sal.binding.model.api.ParameterizedType
27 import java.util.HashMap
28 import org.opendaylight.yangtools.yang.model.api.DataSchemaNode
29 import org.opendaylight.yangtools.binding.generator.util.BindingGeneratorUtil
30 import org.opendaylight.yangtools.yang.model.api.LeafSchemaNode
31 import org.opendaylight.yangtools.yang.model.api.LeafListSchemaNode
33 import java.util.TreeSet
34 import com.google.common.base.Joiner
35 import org.opendaylight.yangtools.sal.binding.model.api.GeneratedTransferObject
36 import org.opendaylight.yangtools.sal.binding.model.api.Enumeration
37 import org.opendaylight.yangtools.yang.model.api.ChoiceCaseNode
38 import static org.opendaylight.yangtools.sal.binding.generator.util.ClassLoaderUtils.*;
39 import org.opendaylight.yangtools.yang.binding.BindingDeserializer
40 import org.opendaylight.yangtools.yang.binding.BindingCodec
41 import org.slf4j.LoggerFactory
42 import org.opendaylight.yangtools.sal.binding.generator.util.CodeGenerationException
43 import org.opendaylight.yangtools.yang.model.api.ChoiceNode
44 import java.security.ProtectionDomain
46 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier
47 import org.opendaylight.yangtools.sal.binding.model.api.GeneratedProperty
48 import java.util.Map.Entry
49 import java.util.AbstractMap.SimpleEntry
50 import org.opendaylight.yangtools.yang.binding.DataObject
51 import org.opendaylight.yangtools.yang.binding.Augmentation
52 import java.util.Iterator
53 import org.opendaylight.yangtools.yang.model.api.AugmentationSchema
54 import java.util.concurrent.ConcurrentHashMap
55 import static extension org.opendaylight.yangtools.sal.binding.generator.util.YangSchemaUtils.*;
56 import org.opendaylight.yangtools.binding.generator.util.ReferencedTypeImpl
57 import org.opendaylight.yangtools.yang.model.util.ExtendedType
58 import org.opendaylight.yangtools.yang.model.util.EnumerationType
59 import static com.google.common.base.Preconditions.*
60 import org.opendaylight.yangtools.yang.model.api.SchemaPath
61 import javassist.CtMethod
62 import javassist.CannotCompileException
63 import java.util.concurrent.locks.Lock
64 import java.util.concurrent.Callable
65 import org.opendaylight.yangtools.sal.binding.generator.util.ClassLoaderUtils
66 import org.opendaylight.yangtools.yang.model.api.TypeDefinition
67 import org.opendaylight.yangtools.yang.model.api.type.UnionTypeDefinition
68 import org.opendaylight.yangtools.yang.model.api.type.BitsTypeDefinition
69 import java.util.HashSet
70 import java.util.Collections
71 import org.opendaylight.yangtools.yang.model.api.type.BitsTypeDefinition.Bit
73 import org.opendaylight.yangtools.sal.binding.generator.util.XtendHelper
74 import org.opendaylight.yangtools.yang.model.api.NotificationDefinition
76 class TransformerGenerator {
78 private static val log = LoggerFactory.getLogger(TransformerGenerator)
80 public static val STRING = Types.typeForClass(String);
81 public static val BOOLEAN = Types.typeForClass(Boolean);
82 public static val INTEGER = Types.typeForClass(Integer);
83 public static val INSTANCE_IDENTIFIER = Types.typeForClass(InstanceIdentifier)
85 //public static val DECIMAL = Types.typeForClass(Decimal);
86 public static val LONG = Types.typeForClass(Long);
88 val ClassPool classPool
89 val extension JavassistUtils utils;
96 var File classFileCapturePath;
99 var Map<Type, Type> typeDefinitions = new ConcurrentHashMap();
102 var Map<Type, GeneratedTypeBuilder> typeToDefinition = new ConcurrentHashMap();
105 var Map<SchemaPath, GeneratedTypeBuilder> pathToType = new ConcurrentHashMap();
108 var Map<Type, SchemaNode> typeToSchemaNode = new ConcurrentHashMap();
111 var Map<Type, AugmentationSchema> typeToAugmentation = new ConcurrentHashMap();
114 var GeneratorListener listener;
116 public static val CLASS_TYPE = Types.typeForClass(Class);
118 public new(ClassPool pool) {
120 utils = new JavassistUtils(pool)
122 BINDING_CODEC = BindingCodec.asCtClass;
123 ctQName = QName.asCtClass
126 def Class<? extends BindingCodec<Map<QName, Object>, Object>> transformerFor(Class<?> inputType) {
127 return withClassLoaderAndLock(inputType.classLoader, lock) [ |
128 val ret = getGeneratedClass(inputType)
130 listener.onClassProcessed(inputType);
131 return ret as Class<? extends BindingCodec<Map<QName,Object>, Object>>;
133 val ref = Types.typeForClass(inputType)
134 val node = typeToSchemaNode.get(ref)
135 val typeSpecBuilder = typeToDefinition.get(ref)
136 checkState(typeSpecBuilder !== null, "Could not find typedefinition for %s", inputType.name);
137 val typeSpec = typeSpecBuilder.toInstance();
138 val newret = generateTransformerFor(inputType, typeSpec, node);
139 listener.onClassProcessed(inputType);
140 return newret as Class<? extends BindingCodec<Map<QName,Object>, Object>>;
144 def Class<? extends BindingCodec<Map<QName, Object>, Object>> transformerFor(Class<?> inputType, DataSchemaNode node) {
145 return withClassLoaderAndLock(inputType.classLoader, lock) [ |
146 val ret = getGeneratedClass(inputType)
148 listener.onClassProcessed(inputType);
149 return ret as Class<? extends BindingCodec<Map<QName,Object>, Object>>;
151 val ref = Types.typeForClass(inputType)
152 var typeSpecBuilder = typeToDefinition.get(ref)
153 if (typeSpecBuilder == null) {
154 typeSpecBuilder = pathToType.get(node.path);
156 var schemaNode = typeToSchemaNode.get(ref);
157 if(schemaNode === null) {
160 checkState(typeSpecBuilder !== null, "Could not find TypeDefinition for %s, $s", inputType.name, node);
161 val typeSpec = typeSpecBuilder.toInstance();
162 val newret = generateTransformerFor(inputType, typeSpec, schemaNode);
163 listener.onClassProcessed(inputType);
164 return newret as Class<? extends BindingCodec<Map<QName,Object>, Object>>;
168 def Class<? extends BindingCodec<Map<QName, Object>, Object>> augmentationTransformerFor(Class<?> inputType) {
169 return withClassLoaderAndLock(inputType.classLoader, lock) [ |
170 val ret = getGeneratedClass(inputType)
172 return ret as Class<? extends BindingCodec<Map<QName,Object>, Object>>;
174 val ref = Types.typeForClass(inputType)
175 val node = typeToAugmentation.get(ref)
176 val typeSpecBuilder = typeToDefinition.get(ref)
177 val typeSpec = typeSpecBuilder.toInstance();
178 val newret = generateAugmentationTransformerFor(inputType, typeSpec, node);
179 listener.onClassProcessed(inputType);
180 return newret as Class<? extends BindingCodec<Map<QName,Object>, Object>>;
184 def Class<? extends BindingCodec<Object, Object>> caseCodecFor(Class<?> inputType, ChoiceCaseNode node) {
185 return withClassLoaderAndLock(inputType.classLoader, lock) [ |
186 val ret = getGeneratedClass(inputType)
188 return ret as Class<? extends BindingCodec<Object, Object>>;
190 val ref = Types.typeForClass(inputType)
191 val typeSpecBuilder = typeToDefinition.get(ref)
192 val typeSpec = typeSpecBuilder.toInstance();
193 val newret = generateCaseCodec(inputType, typeSpec, node);
194 return newret as Class<? extends BindingCodec<Object, Object>>;
198 def Class<? extends BindingCodec<Map<QName, Object>, Object>> keyTransformerForIdentifiable(Class<?> parentType) {
199 return withClassLoaderAndLock(parentType.classLoader, lock) [ |
200 val inputName = parentType.name + "Key";
201 val inputType = loadClassWithTCCL(inputName);
202 val ret = getGeneratedClass(inputType)
204 return ret as Class<? extends BindingCodec<Map<QName,Object>, Object>>;
206 val ref = Types.typeForClass(parentType)
207 val node = typeToSchemaNode.get(ref) as ListSchemaNode
208 val typeSpecBuilder = typeToDefinition.get(ref)
209 val typeSpec = typeSpecBuilder.identifierDefinition;
210 val newret = generateKeyTransformerFor(inputType, typeSpec, node);
211 return newret as Class<? extends BindingCodec<Map<QName,Object>, Object>>;
215 def getIdentifierDefinition(GeneratedTypeBuilder builder) {
216 val inst = builder.toInstance
217 val keyMethod = inst.methodDefinitions.findFirst[name == "getKey"]
218 return keyMethod.returnType as GeneratedTransferObject
221 def Class<? extends BindingCodec<Map<QName, Object>, Object>> keyTransformerForIdentifier(Class<?> inputType) {
222 return withClassLoaderAndLock(inputType.classLoader, lock) [ |
223 val ret = getGeneratedClass(inputType)
225 return ret as Class<? extends BindingCodec<Map<QName,Object>, Object>>;
227 val ref = Types.typeForClass(inputType)
228 val node = typeToSchemaNode.get(ref) as ListSchemaNode
229 val typeSpecBuilder = typeToDefinition.get(ref)
230 val typeSpec = typeSpecBuilder.toInstance();
231 val newret = generateKeyTransformerFor(inputType, typeSpec, node);
232 return newret as Class<? extends BindingCodec<Map<QName,Object>, Object>>;
236 private def Class<?> keyTransformerFor(Class<?> inputType, GeneratedType type, ListSchemaNode schema) {
237 return withClassLoaderAndLock(inputType.classLoader, lock) [ |
238 val transformer = getGeneratedClass(inputType)
239 if (transformer != null) {
242 val newret = generateKeyTransformerFor(inputType, type, schema);
243 return newret as Class<? extends BindingCodec<Map<QName,Object>, Object>>;
247 private def Class<?> getGeneratedClass(Class<? extends Object> cls) {
250 return loadClassWithTCCL(cls.codecClassName)
251 } catch (ClassNotFoundException e) {
256 private def Class<?> keyTransformer(GeneratedType type, ListSchemaNode node) {
257 val cls = loadClassWithTCCL(type.resolvedName + "Key");
258 keyTransformerFor(cls, type, node);
261 private def serializer(Type type, DataSchemaNode node) {
262 val cls = loadClassWithTCCL(type.resolvedName);
263 transformerFor(cls, node);
266 private def Class<?> valueSerializer(GeneratedTransferObject type, TypeDefinition<?> typeDefinition) {
267 val cls = loadClassWithTCCL(type.resolvedName);
268 val transformer = cls.generatedClass;
269 if (transformer !== null) {
272 var baseType = typeDefinition;
273 while (baseType.baseType != null) {
274 baseType = baseType.baseType;
276 val finalType = baseType;
277 return withClassLoaderAndLock(cls.classLoader, lock) [ |
278 val valueTransformer = generateValueTransformer(cls, type, finalType);
279 return valueTransformer;
283 private def Class<?> valueSerializer(Enumeration type, TypeDefinition<?> typeDefinition) {
284 val cls = loadClassWithTCCL(type.resolvedName);
285 val transformer = cls.generatedClass;
286 if (transformer !== null) {
290 return withClassLoaderAndLock(cls.classLoader, lock) [ |
291 val valueTransformer = generateValueTransformer(cls, type);
292 return valueTransformer;
296 private def generateKeyTransformerFor(Class<? extends Object> inputType, GeneratedType typeSpec, ListSchemaNode node) {
299 //log.info("Generating DOM Codec for {} with {}", inputType, inputType.classLoader)
300 val properties = typeSpec.allProperties;
301 val ctCls = createClass(inputType.codecClassName) [
302 //staticField(Map,"AUGMENTATION_SERIALIZERS");
303 staticField(it, INSTANCE_IDENTIFIER_CODEC, BindingCodec)
304 staticField(it, IDENTITYREF_CODEC, BindingCodec)
305 staticQNameField(node.QName);
306 implementsType(BINDING_CODEC)
307 method(Object, "toDomStatic", QName, Object) [
308 modifiers = PUBLIC + FINAL + STATIC
311 «QName.name» _resultName;
313 _resultName = «QName.name».create($1,QNAME.getLocalName());
317 java.util.List _childNodes = new java.util.ArrayList();
318 «inputType.resolvedName» value = («inputType.name») $2;
319 «FOR key : node.keyDefinition»
320 «val propertyName = key.getterName»
321 «val keyDef = node.getDataChildByName(key)»
322 «val property = properties.get(propertyName)»
323 «serializeProperty(keyDef, property, propertyName)»;
325 return ($r) java.util.Collections.singletonMap(_resultName,_childNodes);
329 method(Object, "fromDomStatic", QName, Object) [
330 modifiers = PUBLIC + FINAL + STATIC
336 «QName.name» _localQName = $1;
337 java.util.Map _compositeNode = (java.util.Map) $2;
338 boolean _is_empty = true;
339 «FOR key : node.keyDefinition»
340 «val propertyName = key.getterName»
341 «val keyDef = node.getDataChildByName(key)»
342 «val property = properties.get(propertyName)»
343 «deserializeProperty(keyDef, property, propertyName)»;
345 «inputType.resolvedName» _value = new «inputType.name»(«node.keyDefinition.
346 keyConstructorList»);
351 method(Object, "serialize", Object) [
354 java.util.Map.Entry _input = (java.util.Map.Entry) $1;
355 «QName.name» _localQName = («QName.name») _input.getKey();
356 «inputType.name» _keyValue = («inputType.name») _input.getValue();
357 return toDomStatic(_localQName,_keyValue);
361 method(Object, "deserialize", Object) [
364 «QName.name» _qname = QNAME;
365 if($1 instanceof java.util.Map.Entry) {
366 _qname = («QName.name») ((java.util.Map.Entry) $1).getKey();
368 return fromDomStatic(_qname,$1);
373 val ret = ctCls.toClassImpl(inputType.classLoader, inputType.protectionDomain)
374 log.debug("DOM Codec for {} was generated {}", inputType, ret)
375 return ret as Class<? extends BindingCodec<Map<QName,Object>, ?>>;
376 } catch (Exception e) {
377 processException(inputType, e);
382 private def Class<? extends BindingCodec<Object, Object>> generateCaseCodec(Class<?> inputType, GeneratedType type,
383 ChoiceCaseNode node) {
386 //log.info("Generating DOM Codec for {} with {}, TCCL is: {}", inputType, inputType.classLoader,Thread.currentThread.contextClassLoader)
387 val ctCls = createClass(type.codecClassName) [
388 //staticField(Map,"AUGMENTATION_SERIALIZERS");
389 implementsType(BINDING_CODEC)
390 staticQNameField(node.QName);
391 staticField(it, INSTANCE_IDENTIFIER_CODEC, BindingCodec)
392 staticField(it, AUGMENTATION_CODEC, BindingCodec)
393 staticField(it, IDENTITYREF_CODEC, BindingCodec)
394 method(Object, "toDomStatic", QName, Object) [
395 modifiers = PUBLIC + FINAL + STATIC
398 «QName.name» _resultName = «QName.name».create($1,QNAME.getLocalName());
399 java.util.List _childNodes = new java.util.ArrayList();
400 «type.resolvedName» value = («type.resolvedName») $2;
401 «transformDataContainerBody(type, type.allProperties, node)»
402 return ($r) _childNodes;
406 method(Object, "serialize", Object) [
409 java.util.Map.Entry _input = (java.util.Map.Entry) $1;
410 «QName.name» _localName = QNAME;
411 if(_input.getKey() != null) {
412 _localName = («QName.name») _input.getKey();
414 return toDomStatic(_localName,_input.getValue());
418 method(Object, "fromDomStatic", QName, Object) [
419 modifiers = PUBLIC + FINAL + STATIC
420 bodyChecked = deserializeBody(type, node)
422 method(Object, "deserialize", Object) [
425 //System.out.println("«type.name»#deserialize: " +$1);
426 java.util.Map.Entry _input = (java.util.Map.Entry) $1;
427 return fromDomStatic((«QName.name»)_input.getKey(),_input.getValue());
433 val ret = ctCls.toClassImpl(inputType.classLoader, inputType.protectionDomain) as Class<? extends BindingCodec<Object, Object>>
434 listener?.onDataContainerCodecCreated(inputType, ret);
435 log.debug("DOM Codec for {} was generated {}", inputType, ret)
437 } catch (Exception e) {
438 processException(inputType, e);
443 private def dispatch Class<? extends BindingCodec<Map<QName, Object>, Object>> generateTransformerFor(
444 Class<?> inputType, GeneratedType typeSpec, SchemaNode node) {
447 //log.info("Generating DOM Codec for {} with {}", inputType, inputType.classLoader)
448 val ctCls = createClass(typeSpec.codecClassName) [
449 //staticField(Map,"AUGMENTATION_SERIALIZERS");
450 staticQNameField(node.QName);
451 staticField(it, INSTANCE_IDENTIFIER_CODEC, BindingCodec)
452 staticField(it, IDENTITYREF_CODEC, BindingCodec)
453 staticField(it, AUGMENTATION_CODEC, BindingCodec)
454 implementsType(BINDING_CODEC)
455 method(Object, "toDomStatic", QName, Object) [
456 modifiers = PUBLIC + FINAL + STATIC
457 bodyChecked = serializeBodyFacade(typeSpec, node)
459 method(Object, "serialize", Object) [
462 java.util.Map.Entry _input = (java.util.Map.Entry) $1;
463 «QName.name» _localName = QNAME;
464 if(_input.getKey() != null) {
465 _localName = («QName.name») _input.getKey();
467 return toDomStatic(_localName,_input.getValue());
471 method(Object, "fromDomStatic", QName, Object) [
472 modifiers = PUBLIC + FINAL + STATIC
473 bodyChecked = deserializeBody(typeSpec, node)
475 method(Object, "deserialize", Object) [
478 «QName.name» _qname = QNAME;
479 if($1 instanceof java.util.Map.Entry) {
480 _qname = («QName.name») ((java.util.Map.Entry) $1).getKey();
482 return fromDomStatic(_qname,$1);
488 val ret = ctCls.toClassImpl(inputType.classLoader, inputType.protectionDomain) as Class<? extends BindingCodec<Map<QName,Object>, Object>>
489 listener?.onDataContainerCodecCreated(inputType, ret);
490 log.debug("DOM Codec for {} was generated {}", inputType, ret)
492 } catch (Exception e) {
493 processException(inputType, e);
498 private def Class<? extends BindingCodec<Map<QName, Object>, Object>> generateAugmentationTransformerFor(
499 Class<?> inputType, GeneratedType type, AugmentationSchema node) {
502 //log.info("Generating DOM Codec for {} with {}", inputType, inputType.classLoader)
503 val properties = type.allProperties
504 val ctCls = createClass(type.codecClassName) [
505 //staticField(Map,"AUGMENTATION_SERIALIZERS");
506 staticQNameField(node.augmentationQName);
507 staticField(it, INSTANCE_IDENTIFIER_CODEC, BindingCodec)
508 staticField(it, AUGMENTATION_CODEC, BindingCodec)
509 staticField(it, IDENTITYREF_CODEC, BindingCodec)
510 implementsType(BINDING_CODEC)
511 method(Object, "toDomStatic", QName, Object) [
512 modifiers = PUBLIC + FINAL + STATIC
515 ////System.out.println("Qname " + $1);
516 ////System.out.println("Value " + $2);
517 «QName.name» _resultName = «QName.name».create(QNAME,QNAME.getLocalName());
518 java.util.List _childNodes = new java.util.ArrayList();
519 «type.resolvedName» value = («type.resolvedName») $2;
520 «FOR child : node.childNodes»
521 «var signature = properties.getFor(child)»
522 ////System.out.println("«signature.key»" + value.«signature.key»());
523 «serializeProperty(child, signature.value, signature.key)»
525 return ($r) _childNodes;
529 method(Object, "serialize", Object) [
532 java.util.Map.Entry _input = (java.util.Map.Entry) $1;
533 «QName.name» _localName = QNAME;
534 if(_input.getKey() != null) {
535 _localName = («QName.name») _input.getKey();
537 return toDomStatic(_localName,_input.getValue());
541 method(Object, "fromDomStatic", QName, Object) [
542 modifiers = PUBLIC + FINAL + STATIC
545 «QName.name» _localQName = QNAME;
550 java.util.Map _compositeNode = (java.util.Map) $2;
551 //System.out.println(_localQName + " " + _compositeNode);
552 «type.builderName» _builder = new «type.builderName»();
553 boolean _is_empty = true;
554 «FOR child : node.childNodes»
555 «val signature = properties.getFor(child)»
556 «deserializeProperty(child, signature.value, signature.key)»
557 _builder.«signature.key.toSetter»(«signature.key»);
562 return _builder.build();
566 method(Object, "deserialize", Object) [
568 return fromDomStatic(QNAME,$1);
573 val ret = ctCls.toClassImpl(inputType.classLoader, inputType.protectionDomain) as Class<? extends BindingCodec<Map<QName,Object>, Object>>
574 listener?.onDataContainerCodecCreated(inputType, ret);
576 } catch (Exception e) {
577 processException(inputType, e);
582 private def dispatch Class<? extends BindingCodec<Map<QName, Object>, Object>> generateTransformerFor(
583 Class<?> inputType, GeneratedType typeSpec, ChoiceNode node) {
586 //log.info("Generating DOM Codec for {} with {}", inputType, inputType.classLoader)
587 val ctCls = createClass(typeSpec.codecClassName) [
588 //staticField(Map,"AUGMENTATION_SERIALIZERS");
589 //staticQNameField(inputType);
590 staticField(it, INSTANCE_IDENTIFIER_CODEC, BindingCodec)
591 staticField(it, IDENTITYREF_CODEC, BindingCodec)
592 staticField(it, CLASS_TO_CASE_MAP, Map)
593 staticField(it, COMPOSITE_TO_CASE, Map)
594 //staticField(it,QNAME_TO_CASE_MAP,BindingCodec)
595 implementsType(BINDING_CODEC)
596 method(List, "toDomStatic", QName, Object) [
597 modifiers = PUBLIC + FINAL + STATIC
603 «DataObject.name» _baValue = («DataObject.name») $2;
604 Class _baClass = _baValue.getImplementedInterface();
605 «BINDING_CODEC.name» _codec = «CLASS_TO_CASE_MAP».get(_baClass);
609 java.util.Map.Entry _input = new «SimpleEntry.name»($1,_baValue);
610 Object _ret = _codec.serialize(_input);
611 ////System.out.println("«typeSpec.name»#toDomStatic: " + _ret);
612 return («List.name») _ret;
616 method(Object, "serialize", Object) [
618 throw new «UnsupportedOperationException.name»("Direct invocation not supported.");
621 method(Object, "fromDomStatic", QName, Map) [
622 modifiers = PUBLIC + FINAL + STATIC
625 «BINDING_CODEC.name» _codec = («BINDING_CODEC.name») «COMPOSITE_TO_CASE».get($2);
627 return _codec.deserialize(new «SimpleEntry.name»($1,$2));
633 method(Object, "deserialize", Object) [
635 throw new «UnsupportedOperationException.name»("Direct invocation not supported.");
640 val rawRet = ctCls.toClassImpl(inputType.classLoader, inputType.protectionDomain)
641 val ret = rawRet as Class<? extends BindingCodec<Map<QName,Object>, Object>>;
642 listener?.onChoiceCodecCreated(inputType, ret, node);
643 log.debug("DOM Codec for {} was generated {}", inputType, ret)
645 } catch (Exception e) {
646 processException(inputType, e);
651 private def keyConstructorList(List<QName> qnames) {
652 val names = new TreeSet<String>()
653 for (name : qnames) {
654 val fieldName = name.getterName;
655 names.add(fieldName);
657 return Joiner.on(",").join(names);
660 private def serializeBodyFacade(GeneratedType type, SchemaNode node) {
661 val ret = serializeBody(type, node);
665 private def String deserializeBody(GeneratedType type, SchemaNode node) {
666 val ret = deserializeBodyImpl(type, node);
670 private def deserializeKey(GeneratedType type, ListSchemaNode node) {
671 if (node.keyDefinition != null && !node.keyDefinition.empty) {
673 «type.resolvedName»Key getKey = («type.resolvedName»Key) «keyTransformer(type, node).canonicalName».fromDomStatic(_localQName,_compositeNode);
674 _builder.setKey(getKey);
679 private def String deserializeBodyWithAugmentations(GeneratedType type, DataNodeContainer node) '''
681 «QName.name» _localQName = «QName.name».create($1,QNAME.getLocalName());
685 java.util.Map _compositeNode = (java.util.Map) $2;
686 //System.out.println(_localQName + " " + _compositeNode);
687 «type.builderName» _builder = new «type.builderName»();
688 «deserializeDataNodeContainerBody(type, node)»
689 «deserializeAugmentations»
690 return _builder.build();
694 private def dispatch String deserializeBodyImpl(GeneratedType type, SchemaNode node) '''
696 «QName.name» _localQName = «QName.name».create($1,QNAME.getLocalName());
701 java.util.Map _compositeNode = (java.util.Map) $2;
702 «type.builderName» _builder = new «type.builderName»();
703 return _builder.build();
707 private def dispatch String deserializeBodyImpl(GeneratedType type, ListSchemaNode node) '''
709 «QName.name» _localQName = «QName.name».create($1,QNAME.getLocalName());
713 java.util.Map _compositeNode = (java.util.Map) $2;
714 //System.out.println(_localQName + " " + _compositeNode);
715 «type.builderName» _builder = new «type.builderName»();
716 «deserializeKey(type, node)»
717 «deserializeDataNodeContainerBody(type, node)»
718 «deserializeAugmentations»
719 return _builder.build();
723 private def dispatch String deserializeBodyImpl(GeneratedType type, ContainerSchemaNode node) {
724 return deserializeBodyWithAugmentations(type,node);
727 private def dispatch String deserializeBodyImpl(GeneratedType type, NotificationDefinition node) {
728 return deserializeBodyWithAugmentations(type,node);
731 private def dispatch String deserializeBodyImpl(GeneratedType type, ChoiceCaseNode node) {
732 return deserializeBodyWithAugmentations(type,node);
735 private def deserializeDataNodeContainerBody(GeneratedType type, DataNodeContainer node) {
736 deserializeNodeContainerBodyImpl(type, type.allProperties, node);
739 private def deserializeNodeContainerBodyImpl(GeneratedType type, HashMap<String, Type> properties,
740 DataNodeContainer node) {
742 boolean _is_empty = true;
743 «FOR child : node.childNodes»
744 «val signature = properties.getFor(child)»
745 «IF signature !== null»
746 «deserializeProperty(child, signature.value, signature.key)»
747 _builder.«signature.key.toSetter»(«signature.key»);
754 def deserializeAugmentations() '''
755 java.util.Map _augmentation = (java.util.Map) «AUGMENTATION_CODEC».deserialize(_compositeNode);
756 if(_augmentation != null) {
757 «Iterator.name» _entries = _augmentation.entrySet().iterator();
758 while(_entries.hasNext()) {
759 java.util.Map.Entry _entry = (java.util.Map.Entry) _entries.next();
760 ////System.out.println("Aug. key:" + _entry.getKey());
761 Class _type = (Class) _entry.getKey();
762 «Augmentation.resolvedName» _value = («Augmentation.name») _entry.getValue();
764 _builder.addAugmentation(_type,_value);
770 private def dispatch CharSequence deserializeProperty(ListSchemaNode schema, ParameterizedType type,
771 String propertyName) '''
772 java.util.List _dom_«propertyName» = _compositeNode.get(«QName.name».create(_localQName,"«schema.QName.
774 ////System.out.println("«propertyName»#deCode"+_dom_«propertyName»);
775 java.util.List «propertyName» = new java.util.ArrayList();
776 if(_dom_«propertyName» != null) {
777 java.util.List _serialized = new java.util.ArrayList();
778 java.util.Iterator _iterator = _dom_«propertyName».iterator();
779 boolean _hasNext = _iterator.hasNext();
781 Object _listItem = _iterator.next();
783 ////System.out.println(" item" + _listItem);
784 Object _value = «type.actualTypeArguments.get(0).serializer(schema).resolvedName».fromDomStatic(_localQName,_listItem);
785 ////System.out.println(" value" + _value);
786 «propertyName».add(_value);
787 _hasNext = _iterator.hasNext();
791 ////System.out.println(" list" + «propertyName»);
794 private def dispatch CharSequence deserializeProperty(LeafListSchemaNode schema, ParameterizedType type,
795 String propertyName) '''
796 java.util.List _dom_«propertyName» = _compositeNode.get(«QName.name».create(_localQName,"«schema.QName.
798 java.util.List «propertyName» = new java.util.ArrayList();
799 if(_dom_«propertyName» != null) {
800 java.util.List _serialized = new java.util.ArrayList();
801 java.util.Iterator _iterator = _dom_«propertyName».iterator();
802 boolean _hasNext = _iterator.hasNext();
805 Object _listItem = _iterator.next();
806 if(_listItem instanceof java.util.Map.Entry) {
807 Object _innerValue = ((java.util.Map.Entry) _listItem).getValue();
808 Object _value = «deserializeValue(type.actualTypeArguments.get(0), "_innerValue", schema.type)»;
809 «propertyName».add(_value);
811 _hasNext = _iterator.hasNext();
816 private def dispatch CharSequence deserializeProperty(LeafSchemaNode schema, Type type, String propertyName) '''
817 java.util.List _dom_«propertyName»_list =
818 _compositeNode.get(«QName.name».create(_localQName,"«schema.QName.localName»"));
819 «type.resolvedName» «propertyName» = null;
820 if(_dom_«propertyName»_list != null && _dom_«propertyName»_list.size() > 0) {
822 java.util.Map.Entry _dom_«propertyName» = (java.util.Map.Entry) _dom_«propertyName»_list.get(0);
823 Object _inner_value = _dom_«propertyName».getValue();
824 «propertyName» = «deserializeValue(type, "_inner_value", schema.type)»;
828 private def dispatch CharSequence deserializeProperty(ContainerSchemaNode schema, Type type,
829 String propertyName) '''
830 java.util.List _dom_«propertyName»_list =
831 _compositeNode.get(«QName.name».create(_localQName,"«schema.QName.localName»"));
832 «type.resolvedName» «propertyName» = null;
833 if(_dom_«propertyName»_list != null && _dom_«propertyName»_list.size() > 0) {
835 java.util.Map _dom_«propertyName» = (java.util.Map) _dom_«propertyName»_list.get(0);
836 «propertyName» = «type.serializer(schema).resolvedName».fromDomStatic(_localQName,_dom_«propertyName»);
840 private def dispatch CharSequence deserializeProperty(ChoiceNode schema, Type type, String propertyName) '''
841 «type.resolvedName» «propertyName» = «type.serializer(schema).resolvedName».fromDomStatic(_localQName,_compositeNode);
842 if(«propertyName» != null) {
847 private def dispatch String deserializeValue(GeneratedTransferObject type, String domParameter,
848 TypeDefinition<?> typeDefinition) '''
849 («type.resolvedName») «type.valueSerializer(typeDefinition).resolvedName».fromDomValue(«domParameter»)
852 private def dispatch String deserializeValue(Enumeration type, String domParameter, TypeDefinition<?> typeDefinition) '''
853 («type.resolvedName») «type.valueSerializer(typeDefinition).resolvedName».fromDomValue(«domParameter»)
856 private def dispatch Class<? extends BindingCodec<Map<QName, Object>, Object>> generateValueTransformer(
857 Class<?> inputType, GeneratedTransferObject typeSpec, TypeDefinition<?> typeDef) {
860 val returnType = typeSpec.valueReturnType;
861 if (returnType == null) {
862 val ctCls = createDummyImplementation(inputType, typeSpec);
863 val ret = ctCls.toClassImpl(inputType.classLoader, inputType.protectionDomain)
864 return ret as Class<? extends BindingCodec<Map<QName,Object>, Object>>;
867 val ctCls = createClass(typeSpec.codecClassName) [
868 //staticField(Map,"AUGMENTATION_SERIALIZERS");
869 if (inputType.isYangBindingAvailable) {
870 implementsType(BINDING_CODEC)
871 staticField(it, INSTANCE_IDENTIFIER_CODEC, BindingCodec)
872 staticField(it, IDENTITYREF_CODEC, BindingCodec)
873 implementsType(BindingDeserializer.asCtClass)
875 method(Object, "toDomValue", Object) [
876 modifiers = PUBLIC + FINAL + STATIC
877 val ctSpec = typeSpec.asCtClass;
880 ////System.out.println("«inputType.simpleName»#toDomValue: "+$1);
885 «typeSpec.resolvedName» _encapsulatedValue = («typeSpec.resolvedName») $1;
886 ////System.out.println("«inputType.simpleName»#toDomValue:Enc: "+_encapsulatedValue);
887 «returnType.resolvedName» _value = _encapsulatedValue.getValue();
888 ////System.out.println("«inputType.simpleName»#toDomValue:DeEnc: "+_value);
889 Object _domValue = «serializeValue(returnType, "_value", null)»;
894 method(Object, "serialize", Object) [
897 return toDomValue($1);
901 method(Object, "fromDomValue", Object) [
902 modifiers = PUBLIC + FINAL + STATIC
905 ////System.out.println("«inputType.simpleName»#fromDomValue: "+$1);
910 «returnType.resolvedName» _simpleValue = «deserializeValue(returnType, "$1", null)»;
911 «typeSpec.resolvedName» _value = new «typeSpec.resolvedName»(_simpleValue);
916 method(Object, "deserialize", Object) [
918 return fromDomValue($1);
924 val ret = ctCls.toClassImpl(inputType.classLoader, inputType.protectionDomain)
925 log.debug("DOM Codec for {} was generated {}", inputType, ret)
926 return ret as Class<? extends BindingCodec<Map<QName,Object>, Object>>;
927 } catch (Exception e) {
928 log.error("Cannot compile DOM Codec for {}", inputType, e);
929 val exception = new CodeGenerationException("Cannot compile Transformator for " + inputType);
930 exception.addSuppressed(e);
935 private def dispatch Class<? extends BindingCodec<Map<QName, Object>, Object>> generateValueTransformer(
936 Class<?> inputType, GeneratedTransferObject typeSpec, UnionTypeDefinition typeDef) {
938 val ctCls = createClass(typeSpec.codecClassName) [
939 val properties = typeSpec.allProperties;
940 val getterToTypeDefinition = XtendHelper.getTypes(typeDef).toMap[type | type.QName.getterName];
941 //staticField(Map,"AUGMENTATION_SERIALIZERS");
942 if (inputType.isYangBindingAvailable) {
943 implementsType(BINDING_CODEC)
944 staticField(it, INSTANCE_IDENTIFIER_CODEC, BindingCodec)
945 staticField(it, IDENTITYREF_CODEC, BindingCodec)
946 implementsType(BindingDeserializer.asCtClass)
948 method(Object, "toDomValue", Object) [
949 modifiers = PUBLIC + FINAL + STATIC
950 val ctSpec = inputType.asCtClass;
954 ////System.out.println("«inputType.simpleName»#toDomValue: "+$1);
959 «typeSpec.resolvedName» _value = («typeSpec.resolvedName») $1;
960 «FOR property : properties.entrySet»
961 «IF property.key != "getValue"»
962 «property.value.resolvedName» «property.key» = («property.value.resolvedName») _value.«property.
964 if(«property.key» != null) {
965 return «serializeValue(property.value, property.key, getterToTypeDefinition.get(property.key))»;
974 method(Object, "serialize", Object) [
977 return toDomValue($1);
981 method(Object, "fromDomValue", Object) [
982 modifiers = PUBLIC + FINAL + STATIC
985 ////System.out.println("«inputType.simpleName»#fromDomValue: "+$1);
990 if($1 instanceof String) {
991 String _simpleValue = (String) $1;
992 return new «typeSpec.resolvedName»(_simpleValue.toCharArray());
998 method(Object, "deserialize", Object) [
1000 return fromDomValue($1);
1006 val ret = ctCls.toClassImpl(inputType.classLoader, inputType.protectionDomain)
1007 log.debug("DOM Codec for {} was generated {}", inputType, ret)
1008 return ret as Class<? extends BindingCodec<Map<QName,Object>, Object>>;
1009 } catch (Exception e) {
1010 log.error("Cannot compile DOM Codec for {}", inputType, e);
1011 val exception = new CodeGenerationException("Cannot compile Transformator for " + inputType);
1012 exception.addSuppressed(e);
1018 private def dispatch Class<? extends BindingCodec<Map<QName, Object>, Object>> generateValueTransformer(
1019 Class<?> inputType, GeneratedTransferObject typeSpec, BitsTypeDefinition typeDef) {
1021 val ctCls = createClass(typeSpec.codecClassName) [
1022 //staticField(Map,"AUGMENTATION_SERIALIZERS");
1023 if (inputType.isYangBindingAvailable) {
1024 implementsType(BINDING_CODEC)
1025 staticField(it, INSTANCE_IDENTIFIER_CODEC, BindingCodec)
1026 staticField(it, IDENTITYREF_CODEC, BindingCodec)
1027 implementsType(BindingDeserializer.asCtClass)
1029 method(Object, "toDomValue", Object) [
1030 modifiers = PUBLIC + FINAL + STATIC
1031 val ctSpec = typeSpec.asCtClass;
1034 ////System.out.println("«inputType.simpleName»#toDomValue: "+$1);
1039 «typeSpec.resolvedName» _encapsulatedValue = («typeSpec.resolvedName») $1;
1040 «HashSet.resolvedName» _value = new «HashSet.resolvedName»();
1041 //System.out.println("«inputType.simpleName»#toDomValue:Enc: "+_encapsulatedValue);
1043 «FOR bit : typeDef.bits»
1044 «val getter = bit.getterName()»
1045 if(Boolean.TRUE.equals(_encapsulatedValue.«getter»())) {
1046 _value.add("«bit.name»");
1049 «Set.resolvedName» _domValue = «Collections.resolvedName».unmodifiableSet(_value);
1050 //System.out.println("«inputType.simpleName»#toDomValue:DeEnc: "+_domValue);
1056 method(Object, "serialize", Object) [
1059 return toDomValue($1);
1063 method(Object, "fromDomValue", Object) [
1064 modifiers = PUBLIC + FINAL + STATIC
1065 val sortedBits = typeDef.bits.sort[o1, o2|o1.propertyName.compareTo(o2.propertyName)]
1068 //System.out.println("«inputType.simpleName»#fromDomValue: "+$1);
1073 «Set.resolvedName» _domValue = («Set.resolvedName») $1;
1074 «FOR bit : sortedBits»
1075 Boolean «bit.propertyName» = Boolean.valueOf(_domValue.contains("«bit.name»"));
1078 return new «inputType.resolvedName»(«FOR bit : sortedBits SEPARATOR ","»«bit.propertyName»«ENDFOR»);
1082 method(Object, "deserialize", Object) [
1084 return fromDomValue($1);
1090 val ret = ctCls.toClassImpl(inputType.classLoader, inputType.protectionDomain)
1091 log.debug("DOM Codec for {} was generated {}", inputType, ret)
1092 return ret as Class<? extends BindingCodec<Map<QName,Object>, Object>>;
1093 } catch (Exception e) {
1094 log.error("Cannot compile DOM Codec for {}", inputType, e);
1095 val exception = new CodeGenerationException("Cannot compile Transformator for " + inputType);
1096 exception.addSuppressed(e);
1101 def String getPropertyName(Bit bit) {
1102 '''_«BindingGeneratorUtil.parseToValidParamName(bit.name)»'''
1105 def String getterName(Bit bit) {
1107 val paramName = BindingGeneratorUtil.parseToValidParamName(bit.name);
1108 return '''is«paramName.toFirstUpper»''';
1111 def boolean isYangBindingAvailable(Class<?> class1) {
1113 val bindingCodecClass = class1.classLoader.loadClass(BINDING_CODEC.name);
1114 return bindingCodecClass !== null;
1115 } catch (ClassNotFoundException e) {
1120 private def createDummyImplementation(Class<?> object, GeneratedTransferObject typeSpec) {
1121 log.trace("Generating Dummy DOM Codec for {} with {}", object, object.classLoader)
1122 return createClass(typeSpec.codecClassName) [
1123 if (object.isYangBindingAvailable) {
1124 implementsType(BINDING_CODEC)
1125 staticField(it, INSTANCE_IDENTIFIER_CODEC, BindingCodec)
1126 staticField(it, IDENTITYREF_CODEC, BindingCodec)
1127 implementsType(BindingDeserializer.asCtClass)
1129 //implementsType(BindingDeserializer.asCtClass)
1130 method(Object, "toDomValue", Object) [
1131 modifiers = PUBLIC + FINAL + STATIC
1136 return $1.toString();
1140 method(Object, "serialize", Object) [
1143 return toDomValue($1);
1147 method(Object, "fromDomValue", Object) [
1148 modifiers = PUBLIC + FINAL + STATIC
1149 bodyChecked = '''return null;'''
1151 method(Object, "deserialize", Object) [
1153 return fromDomValue($1);
1160 private def Type getValueReturnType(GeneratedTransferObject object) {
1161 for (prop : object.properties) {
1162 if (prop.name == "value") {
1163 return prop.returnType;
1166 if (object.superType != null) {
1167 return getValueReturnType(object.superType);
1172 private def Class<?> generateValueTransformer(Class<?> inputType, Enumeration typeSpec) {
1174 val typeRef = new ReferencedTypeImpl(typeSpec.packageName, typeSpec.name);
1175 val schema = typeToSchemaNode.get(typeRef) as ExtendedType;
1176 val enumSchema = schema.baseType as EnumerationType;
1178 //log.info("Generating DOM Codec for {} with {}", inputType, inputType.classLoader)
1179 val ctCls = createClass(typeSpec.codecClassName) [
1180 //staticField(Map,"AUGMENTATION_SERIALIZERS");
1181 //implementsType(BINDING_CODEC)
1182 method(Object, "toDomValue", Object) [
1183 modifiers = PUBLIC + FINAL + STATIC
1188 «typeSpec.resolvedName» _value = («typeSpec.resolvedName») $1;
1189 «FOR en : enumSchema.values»
1190 if(«typeSpec.resolvedName».«BindingGeneratorUtil.parseToClassName(en.name)».equals(_value)) {
1198 method(Object, "serialize", Object) [
1200 return toDomValue($1);
1203 method(Object, "fromDomValue", Object) [
1204 modifiers = PUBLIC + FINAL + STATIC
1210 String _value = (String) $1;
1211 «FOR en : enumSchema.values»
1212 if("«en.name»".equals(_value)) {
1213 return «typeSpec.resolvedName».«BindingGeneratorUtil.parseToClassName(en.name)»;
1220 method(Object, "deserialize", Object) [
1222 return fromDomValue($1);
1227 val ret = ctCls.toClassImpl(inputType.classLoader, inputType.protectionDomain)
1228 log.debug("DOM Codec for {} was generated {}", inputType, ret)
1230 } catch (CodeGenerationException e) {
1231 throw new CodeGenerationException("Cannot compile Transformator for " + inputType, e);
1232 } catch (Exception e) {
1233 log.error("Cannot compile DOM Codec for {}", inputType, e);
1234 val exception = new CodeGenerationException("Cannot compile Transformator for " + inputType);
1235 exception.addSuppressed(e);
1241 def Class<?> toClassImpl(CtClass newClass, ClassLoader loader, ProtectionDomain domain) {
1242 val cls = newClass.toClass(loader, domain);
1243 if (classFileCapturePath !== null) {
1244 newClass.writeFile(classFileCapturePath.absolutePath);
1246 listener?.onCodecCreated(cls);
1250 def debugWriteClass(CtClass class1) {
1251 val path = class1.name.replace(".", "/") + ".class"
1253 val captureFile = new File(classFileCapturePath, path);
1254 captureFile.createNewFile
1258 private def dispatch String deserializeValue(Type type, String domParameter, TypeDefinition<?> typeDef) {
1259 if (INSTANCE_IDENTIFIER.equals(type)) {
1260 return '''(«InstanceIdentifier.name») «INSTANCE_IDENTIFIER_CODEC».deserialize(«domParameter»)'''
1261 } else if (CLASS_TYPE.equals(type)) {
1262 return '''(«Class.name») «IDENTITYREF_CODEC».deserialize(«domParameter»)'''
1264 return '''(«type.resolvedName») «domParameter»'''
1272 private def dispatch CharSequence deserializeProperty(DataSchemaNode container, Type type, String propertyName) '''
1273 «type.resolvedName» «propertyName» = null;
1276 private def dispatch CharSequence deserializeProperty(DataSchemaNode container, GeneratedTypeBuilder type,
1277 String propertyName) {
1278 _deserializeProperty(container, type.toInstance, propertyName)
1281 public static def toSetter(String it) {
1283 if (startsWith("is")) {
1284 return "set" + substring(2);
1285 } else if (startsWith("get")) {
1286 return "set" + substring(3);
1292 private def dispatch CharSequence deserializeProperty(DataSchemaNode container,GeneratedType type, String propertyName) '''
1293 «type.resolvedName» «propertyName» = value.«propertyName»();
1294 if(«propertyName» != null) {
1295 Object domValue = «type.serializer».toDomStatic(QNAME,«propertyName»);
1296 _childNodes.add(domValue);
1300 private def getBuilderName(GeneratedType type) '''«type.resolvedName»Builder'''
1302 private def staticQNameField(CtClass it, QName node) {
1303 val field = new CtField(ctQName, "QNAME", it);
1304 field.modifiers = PUBLIC + FINAL + STATIC;
1306 '''«QName.asCtClass.name».create("«node.namespace»","«node.formattedRevision»","«node.localName»")''')
1309 private def String serializeBodyImpl(GeneratedType type, DataNodeContainer nodeContainer) '''
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, nodeContainer)»
1315 «serializeAugmentations»
1316 return ($r) java.util.Collections.singletonMap(_resultName,_childNodes);
1320 private def dispatch String serializeBody(GeneratedType type, ListSchemaNode node) {
1321 return serializeBodyImpl(type,node);
1324 private def dispatch String serializeBody(GeneratedType type, NotificationDefinition node) {
1325 return serializeBodyImpl(type,node);
1328 private def dispatch String serializeBody(GeneratedType type, ContainerSchemaNode node) {
1329 return serializeBodyImpl(type,node);
1332 private def dispatch String serializeBody(GeneratedType type, ChoiceCaseNode node){
1333 return serializeBodyImpl(type,node);
1336 private def dispatch String serializeBody(GeneratedType type, SchemaNode node) '''
1338 «QName.name» _resultName = «QName.name».create($1,QNAME.getLocalName());
1339 java.util.List _childNodes = new java.util.ArrayList();
1340 «type.resolvedName» value = («type.resolvedName») $2;
1341 return ($r) java.util.Collections.singletonMap(_resultName,_childNodes);
1345 private def transformDataContainerBody(Type type, Map<String, Type> properties, DataNodeContainer node) {
1347 «FOR child : node.childNodes»
1348 «val signature = properties.getFor(child)»
1349 «IF signature !== null»
1350 ////System.out.println("«type.name»#«signature.key»" + value.«signature.key»());
1351 «serializeProperty(child, signature.value, signature.key)»
1358 private def serializeAugmentations() '''
1359 java.util.List _augmentations = (java.util.List) «AUGMENTATION_CODEC».serialize(value);
1360 if(_augmentations != null) {
1361 _childNodes.addAll(_augmentations);
1365 def Entry<String, Type> getFor(Map<String, Type> map, DataSchemaNode node) {
1366 var sig = map.get(node.getterName);
1368 return new SimpleEntry(node.getterName, sig);
1370 sig = map.get(node.booleanGetterName);
1372 return new SimpleEntry(node.booleanGetterName, map.get(node.booleanGetterName));
1377 private static def String getBooleanGetterName(DataSchemaNode node) {
1378 return "is" + BindingGeneratorUtil.parseToClassName(node.QName.localName);
1381 private static def String getGetterName(DataSchemaNode node) {
1382 return "get" + BindingGeneratorUtil.parseToClassName(node.QName.localName);
1385 private static def String getGetterName(QName node) {
1386 return "get" + BindingGeneratorUtil.parseToClassName(node.localName);
1389 private def dispatch CharSequence serializeProperty(ListSchemaNode schema, ParameterizedType type,
1390 String propertyName) '''
1391 «type.resolvedName» «propertyName» = value.«propertyName»();
1392 ////System.out.println("«propertyName»:" + «propertyName»);
1393 if(«propertyName» != null) {
1394 java.util.Iterator _iterator = «propertyName».iterator();
1395 boolean _hasNext = _iterator.hasNext();
1397 Object _listItem = _iterator.next();
1398 Object _domValue = «type.actualTypeArguments.get(0).serializer(schema).resolvedName».toDomStatic(_resultName,_listItem);
1399 _childNodes.add(_domValue);
1400 _hasNext = _iterator.hasNext();
1405 private def dispatch CharSequence serializeProperty(LeafSchemaNode schema, Type type, String propertyName) '''
1406 «type.resolvedName» «propertyName» = value.«propertyName»();
1408 if(«propertyName» != null) {
1409 «QName.name» _qname = «QName.name».create(_resultName,"«schema.QName.localName»");
1410 Object _propValue = «serializeValue(type, propertyName, schema.type)»;
1411 if(_propValue != null) {
1412 Object _domValue = java.util.Collections.singletonMap(_qname,_propValue);
1413 _childNodes.add(_domValue);
1418 private def dispatch serializeValue(GeneratedTransferObject type, String parameter, TypeDefinition<?> typeDefinition) {
1419 '''«type.valueSerializer(typeDefinition).resolvedName».toDomValue(«parameter»)'''
1422 private def dispatch serializeValue(Enumeration type, String parameter, TypeDefinition<?> typeDefinition) {
1423 '''«type.valueSerializer(typeDefinition).resolvedName».toDomValue(«parameter»)'''
1426 private def dispatch serializeValue(Type signature, String property, TypeDefinition<?> typeDefinition) {
1427 if (INSTANCE_IDENTIFIER == signature) {
1428 return '''«INSTANCE_IDENTIFIER_CODEC».serialize(«property»)'''
1429 } else if (CLASS_TYPE.equals(signature)) {
1430 return '''(«QName.resolvedName») «IDENTITYREF_CODEC».serialize(«property»)'''
1432 if ("char[]" == signature.name) {
1433 return '''new String(«property»)''';
1435 return '''«property»''';
1438 private def dispatch CharSequence serializeProperty(LeafListSchemaNode schema, ParameterizedType type,
1439 String propertyName) '''
1440 «type.resolvedName» «propertyName» = value.«propertyName»();
1441 if(«propertyName» != null) {
1442 «QName.name» _qname = «QName.name».create(_resultName,"«schema.QName.localName»");
1443 java.util.Iterator _iterator = «propertyName».iterator();
1444 boolean _hasNext = _iterator.hasNext();
1446 Object _listItem = _iterator.next();
1447 Object _propValue = «serializeValue(type.actualTypeArguments.get(0), "_listItem", schema.type)»;
1448 Object _domValue = java.util.Collections.singletonMap(_qname,_propValue);
1449 _childNodes.add(_domValue);
1450 _hasNext = _iterator.hasNext();
1455 private def dispatch CharSequence serializeProperty(ChoiceNode container, GeneratedType type,
1456 String propertyName) '''
1457 «type.resolvedName» «propertyName» = value.«propertyName»();
1458 if(«propertyName» != null) {
1459 java.util.List domValue = «type.serializer(container).resolvedName».toDomStatic(_resultName,«propertyName»);
1460 _childNodes.addAll(domValue);
1468 private def dispatch CharSequence serializeProperty(DataSchemaNode container, Type type, String propertyName) '''
1469 «type.resolvedName» «propertyName» = value.«propertyName»();
1470 if(«propertyName» != null) {
1471 Object domValue = «propertyName»;
1472 _childNodes.add(domValue);
1476 private def dispatch CharSequence serializeProperty(DataSchemaNode container, GeneratedTypeBuilder type,
1477 String propertyName) {
1478 serializeProperty(container, type.toInstance, propertyName)
1481 private def dispatch CharSequence serializeProperty(DataSchemaNode container, GeneratedType type,
1482 String propertyName) '''
1483 «type.resolvedName» «propertyName» = value.«propertyName»();
1484 if(«propertyName» != null) {
1485 Object domValue = «type.serializer(container).resolvedName».toDomStatic(_resultName,«propertyName»);
1486 _childNodes.add(domValue);
1490 private def codecClassName(GeneratedType typeSpec) {
1491 return '''«typeSpec.resolvedName»$Broker$Codec$DOM'''
1494 private def codecClassName(Class<?> typeSpec) {
1495 return '''«typeSpec.name»$Broker$Codec$DOM'''
1498 private def HashMap<String, Type> getAllProperties(GeneratedType type) {
1499 val ret = new HashMap<String, Type>();
1500 type.collectAllProperties(ret);
1504 private def dispatch void collectAllProperties(GeneratedType type, Map<String, Type> set) {
1505 for (definition : type.methodDefinitions) {
1506 set.put(definition.name, definition.returnType);
1508 for (property : type.properties) {
1509 set.put(property.getterName, property.returnType);
1511 for (parent : type.implements) {
1512 parent.collectAllProperties(set);
1516 def String getGetterName(GeneratedProperty property) {
1517 return "get" + property.name.toFirstUpper
1520 private def dispatch void collectAllProperties(Type type, Map<String, Type> set) {
1521 // NOOP for generic type.
1524 def String getResolvedName(Type type) {
1525 return type.asCtClass.name;
1528 def String getResolvedName(Class<?> type) {
1529 return type.asCtClass.name;
1532 def CtClass asCtClass(Type type) {
1533 val cls = loadClassWithTCCL(type.fullyQualifiedName)
1534 return cls.asCtClass;
1537 private def dispatch processException(Class<?> inputType, CodeGenerationException e) {
1538 log.error("Cannot compile DOM Codec for {}. One of it's prerequisites was not generated.", inputType);
1542 private def dispatch processException(Class<?> inputType, Exception e) {
1543 log.error("Cannot compile DOM Codec for {}", inputType, e);
1544 val exception = new CodeGenerationException("Cannot compile Transformator for " + inputType, e);
1548 private def setBodyChecked(CtMethod method, String body) {
1550 method.setBody(body);
1551 } catch (CannotCompileException e) {
1552 log.error("Cannot compile method: {}#{} {}, Reason: {} Body: {}", method.declaringClass, method.name,
1553 method.signature, e.message, body)
1558 private def <V> V withClassLoaderAndLock(ClassLoader cls, Lock lock, Callable<V> function) throws Exception {
1559 appendClassLoaderIfMissing(cls);
1560 ClassLoaderUtils.withClassLoaderAndLock(cls, lock, function);
1566 class PropertyPair {
1575 SchemaNode schemaNode;