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
75 class TransformerGenerator {
77 private static val log = LoggerFactory.getLogger(TransformerGenerator)
79 public static val STRING = Types.typeForClass(String);
80 public static val BOOLEAN = Types.typeForClass(Boolean);
81 public static val INTEGER = Types.typeForClass(Integer);
82 public static val INSTANCE_IDENTIFIER = Types.typeForClass(InstanceIdentifier)
84 //public static val DECIMAL = Types.typeForClass(Decimal);
85 public static val LONG = Types.typeForClass(Long);
87 val ClassPool classPool
88 val extension JavassistUtils utils;
95 var File classFileCapturePath;
98 var Map<Type, Type> typeDefinitions = new ConcurrentHashMap();
101 var Map<Type, GeneratedTypeBuilder> typeToDefinition = new ConcurrentHashMap();
104 var Map<SchemaPath, GeneratedTypeBuilder> pathToType = new ConcurrentHashMap();
107 var Map<Type, SchemaNode> typeToSchemaNode = new ConcurrentHashMap();
110 var Map<Type, AugmentationSchema> typeToAugmentation = new ConcurrentHashMap();
113 var GeneratorListener listener;
115 public static val CLASS_TYPE = Types.typeForClass(Class);
117 public new(ClassPool pool) {
119 utils = new JavassistUtils(pool)
121 BINDING_CODEC = BindingCodec.asCtClass;
122 ctQName = QName.asCtClass
125 def Class<? extends BindingCodec<Map<QName, Object>, Object>> transformerFor(Class<?> inputType) {
126 return withClassLoaderAndLock(inputType.classLoader, lock) [ |
127 val ret = getGeneratedClass(inputType)
129 listener.onClassProcessed(inputType);
130 return ret as Class<? extends BindingCodec<Map<QName,Object>, Object>>;
132 val ref = Types.typeForClass(inputType)
133 val node = typeToSchemaNode.get(ref)
134 val typeSpecBuilder = typeToDefinition.get(ref)
135 checkState(typeSpecBuilder !== null, "Could not find typedefinition for %s", inputType.name);
136 val typeSpec = typeSpecBuilder.toInstance();
137 val newret = generateTransformerFor(inputType, typeSpec, node);
138 listener.onClassProcessed(inputType);
139 return newret as Class<? extends BindingCodec<Map<QName,Object>, Object>>;
143 def Class<? extends BindingCodec<Map<QName, Object>, Object>> transformerFor(Class<?> inputType, DataSchemaNode node) {
144 return withClassLoaderAndLock(inputType.classLoader, lock) [ |
145 val ret = getGeneratedClass(inputType)
147 listener.onClassProcessed(inputType);
148 return ret as Class<? extends BindingCodec<Map<QName,Object>, Object>>;
150 val ref = Types.typeForClass(inputType)
151 var typeSpecBuilder = typeToDefinition.get(ref)
152 if (typeSpecBuilder == null) {
153 typeSpecBuilder = pathToType.get(node.path);
155 var schemaNode = typeToSchemaNode.get(ref);
156 if(schemaNode === null) {
159 checkState(typeSpecBuilder !== null, "Could not find TypeDefinition for %s, $s", inputType.name, node);
160 val typeSpec = typeSpecBuilder.toInstance();
161 val newret = generateTransformerFor(inputType, typeSpec, schemaNode);
162 listener.onClassProcessed(inputType);
163 return newret as Class<? extends BindingCodec<Map<QName,Object>, Object>>;
167 def Class<? extends BindingCodec<Map<QName, Object>, Object>> augmentationTransformerFor(Class<?> inputType) {
168 return withClassLoaderAndLock(inputType.classLoader, lock) [ |
169 val ret = getGeneratedClass(inputType)
171 return ret as Class<? extends BindingCodec<Map<QName,Object>, Object>>;
173 val ref = Types.typeForClass(inputType)
174 val node = typeToAugmentation.get(ref)
175 val typeSpecBuilder = typeToDefinition.get(ref)
176 val typeSpec = typeSpecBuilder.toInstance();
177 val newret = generateAugmentationTransformerFor(inputType, typeSpec, node);
178 listener.onClassProcessed(inputType);
179 return newret as Class<? extends BindingCodec<Map<QName,Object>, Object>>;
183 def Class<? extends BindingCodec<Object, Object>> caseCodecFor(Class<?> inputType, ChoiceCaseNode node) {
184 return withClassLoaderAndLock(inputType.classLoader, lock) [ |
185 val ret = getGeneratedClass(inputType)
187 return ret as Class<? extends BindingCodec<Object, Object>>;
189 val ref = Types.typeForClass(inputType)
190 val typeSpecBuilder = typeToDefinition.get(ref)
191 val typeSpec = typeSpecBuilder.toInstance();
192 val newret = generateCaseCodec(inputType, typeSpec, node);
193 return newret as Class<? extends BindingCodec<Object, Object>>;
197 def Class<? extends BindingCodec<Map<QName, Object>, Object>> keyTransformerForIdentifiable(Class<?> parentType) {
198 return withClassLoaderAndLock(parentType.classLoader, lock) [ |
199 val inputName = parentType.name + "Key";
200 val inputType = loadClassWithTCCL(inputName);
201 val ret = getGeneratedClass(inputType)
203 return ret as Class<? extends BindingCodec<Map<QName,Object>, Object>>;
205 val ref = Types.typeForClass(parentType)
206 val node = typeToSchemaNode.get(ref) as ListSchemaNode
207 val typeSpecBuilder = typeToDefinition.get(ref)
208 val typeSpec = typeSpecBuilder.identifierDefinition;
209 val newret = generateKeyTransformerFor(inputType, typeSpec, node);
210 return newret as Class<? extends BindingCodec<Map<QName,Object>, Object>>;
214 def getIdentifierDefinition(GeneratedTypeBuilder builder) {
215 val inst = builder.toInstance
216 val keyMethod = inst.methodDefinitions.findFirst[name == "getKey"]
217 return keyMethod.returnType as GeneratedTransferObject
220 def Class<? extends BindingCodec<Map<QName, Object>, Object>> keyTransformerForIdentifier(Class<?> inputType) {
221 return withClassLoaderAndLock(inputType.classLoader, lock) [ |
222 val ret = getGeneratedClass(inputType)
224 return ret as Class<? extends BindingCodec<Map<QName,Object>, Object>>;
226 val ref = Types.typeForClass(inputType)
227 val node = typeToSchemaNode.get(ref) as ListSchemaNode
228 val typeSpecBuilder = typeToDefinition.get(ref)
229 val typeSpec = typeSpecBuilder.toInstance();
230 val newret = generateKeyTransformerFor(inputType, typeSpec, node);
231 return newret as Class<? extends BindingCodec<Map<QName,Object>, Object>>;
235 private def Class<?> keyTransformerFor(Class<?> inputType, GeneratedType type, ListSchemaNode schema) {
236 return withClassLoaderAndLock(inputType.classLoader, lock) [ |
237 val transformer = getGeneratedClass(inputType)
238 if (transformer != null) {
241 val newret = generateKeyTransformerFor(inputType, type, schema);
242 return newret as Class<? extends BindingCodec<Map<QName,Object>, Object>>;
246 private def Class<?> getGeneratedClass(Class<? extends Object> cls) {
249 return loadClassWithTCCL(cls.codecClassName)
250 } catch (ClassNotFoundException e) {
255 private def Class<?> keyTransformer(GeneratedType type, ListSchemaNode node) {
256 val cls = loadClassWithTCCL(type.resolvedName + "Key");
257 keyTransformerFor(cls, type, node);
260 private def serializer(Type type, DataSchemaNode node) {
261 val cls = loadClassWithTCCL(type.resolvedName);
262 transformerFor(cls, node);
265 private def Class<?> valueSerializer(GeneratedTransferObject type, TypeDefinition<?> typeDefinition) {
266 val cls = loadClassWithTCCL(type.resolvedName);
267 val transformer = cls.generatedClass;
268 if (transformer !== null) {
271 var baseType = typeDefinition;
272 while (baseType.baseType != null) {
273 baseType = baseType.baseType;
275 val finalType = baseType;
276 return withClassLoaderAndLock(cls.classLoader, lock) [ |
277 val valueTransformer = generateValueTransformer(cls, type, finalType);
278 return valueTransformer;
282 private def Class<?> valueSerializer(Enumeration type, TypeDefinition<?> typeDefinition) {
283 val cls = loadClassWithTCCL(type.resolvedName);
284 val transformer = cls.generatedClass;
285 if (transformer !== null) {
289 return withClassLoaderAndLock(cls.classLoader, lock) [ |
290 val valueTransformer = generateValueTransformer(cls, type);
291 return valueTransformer;
295 private def generateKeyTransformerFor(Class<? extends Object> inputType, GeneratedType typeSpec, ListSchemaNode node) {
298 //log.info("Generating DOM Codec for {} with {}", inputType, inputType.classLoader)
299 val properties = typeSpec.allProperties;
300 val ctCls = createClass(inputType.codecClassName) [
301 //staticField(Map,"AUGMENTATION_SERIALIZERS");
302 staticField(it, INSTANCE_IDENTIFIER_CODEC, BindingCodec)
303 staticField(it, IDENTITYREF_CODEC, BindingCodec)
304 staticQNameField(node.QName);
305 implementsType(BINDING_CODEC)
306 method(Object, "toDomStatic", QName, Object) [
307 modifiers = PUBLIC + FINAL + STATIC
310 «QName.name» _resultName;
312 _resultName = «QName.name».create($1,QNAME.getLocalName());
316 java.util.List _childNodes = new java.util.ArrayList();
317 «inputType.resolvedName» value = («inputType.name») $2;
318 «FOR key : node.keyDefinition»
319 «val propertyName = key.getterName»
320 «val keyDef = node.getDataChildByName(key)»
321 «val property = properties.get(propertyName)»
322 «serializeProperty(keyDef, property, propertyName)»;
324 return ($r) java.util.Collections.singletonMap(_resultName,_childNodes);
328 method(Object, "fromDomStatic", QName, Object) [
329 modifiers = PUBLIC + FINAL + STATIC
335 «QName.name» _localQName = $1;
336 java.util.Map _compositeNode = (java.util.Map) $2;
337 boolean _is_empty = true;
338 «FOR key : node.keyDefinition»
339 «val propertyName = key.getterName»
340 «val keyDef = node.getDataChildByName(key)»
341 «val property = properties.get(propertyName)»
342 «deserializeProperty(keyDef, property, propertyName)»;
344 «inputType.resolvedName» _value = new «inputType.name»(«node.keyDefinition.
345 keyConstructorList»);
350 method(Object, "serialize", Object) [
353 java.util.Map.Entry _input = (java.util.Map.Entry) $1;
354 «QName.name» _localQName = («QName.name») _input.getKey();
355 «inputType.name» _keyValue = («inputType.name») _input.getValue();
356 return toDomStatic(_localQName,_keyValue);
360 method(Object, "deserialize", Object) [
363 «QName.name» _qname = QNAME;
364 if($1 instanceof java.util.Map.Entry) {
365 _qname = («QName.name») ((java.util.Map.Entry) $1).getKey();
367 return fromDomStatic(_qname,$1);
372 val ret = ctCls.toClassImpl(inputType.classLoader, inputType.protectionDomain)
373 log.debug("DOM Codec for {} was generated {}", inputType, ret)
374 return ret as Class<? extends BindingCodec<Map<QName,Object>, ?>>;
375 } catch (Exception e) {
376 processException(inputType, e);
381 private def Class<? extends BindingCodec<Object, Object>> generateCaseCodec(Class<?> inputType, GeneratedType type,
382 ChoiceCaseNode node) {
385 //log.info("Generating DOM Codec for {} with {}, TCCL is: {}", inputType, inputType.classLoader,Thread.currentThread.contextClassLoader)
386 val ctCls = createClass(type.codecClassName) [
387 //staticField(Map,"AUGMENTATION_SERIALIZERS");
388 implementsType(BINDING_CODEC)
389 staticQNameField(node.QName);
390 staticField(it, INSTANCE_IDENTIFIER_CODEC, BindingCodec)
391 staticField(it, AUGMENTATION_CODEC, BindingCodec)
392 staticField(it, IDENTITYREF_CODEC, BindingCodec)
393 method(Object, "toDomStatic", QName, Object) [
394 modifiers = PUBLIC + FINAL + STATIC
397 «QName.name» _resultName = «QName.name».create($1,QNAME.getLocalName());
398 java.util.List _childNodes = new java.util.ArrayList();
399 «type.resolvedName» value = («type.resolvedName») $2;
400 «transformDataContainerBody(type, type.allProperties, node)»
401 return ($r) _childNodes;
405 method(Object, "serialize", Object) [
408 java.util.Map.Entry _input = (java.util.Map.Entry) $1;
409 «QName.name» _localName = QNAME;
410 if(_input.getKey() != null) {
411 _localName = («QName.name») _input.getKey();
413 return toDomStatic(_localName,_input.getValue());
417 method(Object, "fromDomStatic", QName, Object) [
418 modifiers = PUBLIC + FINAL + STATIC
419 bodyChecked = deserializeBody(type, node)
421 method(Object, "deserialize", Object) [
424 //System.out.println("«type.name»#deserialize: " +$1);
425 java.util.Map.Entry _input = (java.util.Map.Entry) $1;
426 return fromDomStatic((«QName.name»)_input.getKey(),_input.getValue());
432 val ret = ctCls.toClassImpl(inputType.classLoader, inputType.protectionDomain) as Class<? extends BindingCodec<Object, Object>>
433 listener?.onDataContainerCodecCreated(inputType, ret);
434 log.debug("DOM Codec for {} was generated {}", inputType, ret)
436 } catch (Exception e) {
437 processException(inputType, e);
442 private def dispatch Class<? extends BindingCodec<Map<QName, Object>, Object>> generateTransformerFor(
443 Class<?> inputType, GeneratedType typeSpec, SchemaNode node) {
446 //log.info("Generating DOM Codec for {} with {}", inputType, inputType.classLoader)
447 val ctCls = createClass(typeSpec.codecClassName) [
448 //staticField(Map,"AUGMENTATION_SERIALIZERS");
449 staticQNameField(node.QName);
450 staticField(it, INSTANCE_IDENTIFIER_CODEC, BindingCodec)
451 staticField(it, IDENTITYREF_CODEC, BindingCodec)
452 staticField(it, AUGMENTATION_CODEC, BindingCodec)
453 implementsType(BINDING_CODEC)
454 method(Object, "toDomStatic", QName, Object) [
455 modifiers = PUBLIC + FINAL + STATIC
456 bodyChecked = serializeBodyFacade(typeSpec, node)
458 method(Object, "serialize", Object) [
461 java.util.Map.Entry _input = (java.util.Map.Entry) $1;
462 «QName.name» _localName = QNAME;
463 if(_input.getKey() != null) {
464 _localName = («QName.name») _input.getKey();
466 return toDomStatic(_localName,_input.getValue());
470 method(Object, "fromDomStatic", QName, Object) [
471 modifiers = PUBLIC + FINAL + STATIC
472 bodyChecked = deserializeBody(typeSpec, node)
474 method(Object, "deserialize", Object) [
477 «QName.name» _qname = QNAME;
478 if($1 instanceof java.util.Map.Entry) {
479 _qname = («QName.name») ((java.util.Map.Entry) $1).getKey();
481 return fromDomStatic(_qname,$1);
487 val ret = ctCls.toClassImpl(inputType.classLoader, inputType.protectionDomain) as Class<? extends BindingCodec<Map<QName,Object>, Object>>
488 listener?.onDataContainerCodecCreated(inputType, ret);
489 log.debug("DOM Codec for {} was generated {}", inputType, ret)
491 } catch (Exception e) {
492 processException(inputType, e);
497 private def Class<? extends BindingCodec<Map<QName, Object>, Object>> generateAugmentationTransformerFor(
498 Class<?> inputType, GeneratedType type, AugmentationSchema node) {
501 //log.info("Generating DOM Codec for {} with {}", inputType, inputType.classLoader)
502 val properties = type.allProperties
503 val ctCls = createClass(type.codecClassName) [
504 //staticField(Map,"AUGMENTATION_SERIALIZERS");
505 staticQNameField(node.augmentationQName);
506 staticField(it, INSTANCE_IDENTIFIER_CODEC, BindingCodec)
507 staticField(it, AUGMENTATION_CODEC, BindingCodec)
508 staticField(it, IDENTITYREF_CODEC, BindingCodec)
509 implementsType(BINDING_CODEC)
510 method(Object, "toDomStatic", QName, Object) [
511 modifiers = PUBLIC + FINAL + STATIC
514 ////System.out.println("Qname " + $1);
515 ////System.out.println("Value " + $2);
516 «QName.name» _resultName = «QName.name».create(QNAME,QNAME.getLocalName());
517 java.util.List _childNodes = new java.util.ArrayList();
518 «type.resolvedName» value = («type.resolvedName») $2;
519 «FOR child : node.childNodes»
520 «var signature = properties.getFor(child)»
521 ////System.out.println("«signature.key»" + value.«signature.key»());
522 «serializeProperty(child, signature.value, signature.key)»
524 return ($r) _childNodes;
528 method(Object, "serialize", Object) [
531 java.util.Map.Entry _input = (java.util.Map.Entry) $1;
532 «QName.name» _localName = QNAME;
533 if(_input.getKey() != null) {
534 _localName = («QName.name») _input.getKey();
536 return toDomStatic(_localName,_input.getValue());
540 method(Object, "fromDomStatic", QName, Object) [
541 modifiers = PUBLIC + FINAL + STATIC
544 «QName.name» _localQName = QNAME;
549 java.util.Map _compositeNode = (java.util.Map) $2;
550 //System.out.println(_localQName + " " + _compositeNode);
551 «type.builderName» _builder = new «type.builderName»();
552 boolean _is_empty = true;
553 «FOR child : node.childNodes»
554 «val signature = properties.getFor(child)»
555 «deserializeProperty(child, signature.value, signature.key)»
556 _builder.«signature.key.toSetter»(«signature.key»);
561 return _builder.build();
565 method(Object, "deserialize", Object) [
567 return fromDomStatic(QNAME,$1);
572 val ret = ctCls.toClassImpl(inputType.classLoader, inputType.protectionDomain) as Class<? extends BindingCodec<Map<QName,Object>, Object>>
573 listener?.onDataContainerCodecCreated(inputType, ret);
575 } catch (Exception e) {
576 processException(inputType, e);
581 private def dispatch Class<? extends BindingCodec<Map<QName, Object>, Object>> generateTransformerFor(
582 Class<?> inputType, GeneratedType typeSpec, ChoiceNode node) {
585 //log.info("Generating DOM Codec for {} with {}", inputType, inputType.classLoader)
586 val ctCls = createClass(typeSpec.codecClassName) [
587 //staticField(Map,"AUGMENTATION_SERIALIZERS");
588 //staticQNameField(inputType);
589 staticField(it, INSTANCE_IDENTIFIER_CODEC, BindingCodec)
590 staticField(it, IDENTITYREF_CODEC, BindingCodec)
591 staticField(it, CLASS_TO_CASE_MAP, Map)
592 staticField(it, COMPOSITE_TO_CASE, Map)
593 //staticField(it,QNAME_TO_CASE_MAP,BindingCodec)
594 implementsType(BINDING_CODEC)
595 method(List, "toDomStatic", QName, Object) [
596 modifiers = PUBLIC + FINAL + STATIC
602 «DataObject.name» _baValue = («DataObject.name») $2;
603 Class _baClass = _baValue.getImplementedInterface();
604 «BINDING_CODEC.name» _codec = «CLASS_TO_CASE_MAP».get(_baClass);
608 java.util.Map.Entry _input = new «SimpleEntry.name»($1,_baValue);
609 Object _ret = _codec.serialize(_input);
610 ////System.out.println("«typeSpec.name»#toDomStatic: " + _ret);
611 return («List.name») _ret;
615 method(Object, "serialize", Object) [
617 throw new «UnsupportedOperationException.name»("Direct invocation not supported.");
620 method(Object, "fromDomStatic", QName, Map) [
621 modifiers = PUBLIC + FINAL + STATIC
624 «BINDING_CODEC.name» _codec = («BINDING_CODEC.name») «COMPOSITE_TO_CASE».get($2);
626 return _codec.deserialize(new «SimpleEntry.name»($1,$2));
632 method(Object, "deserialize", Object) [
634 throw new «UnsupportedOperationException.name»("Direct invocation not supported.");
639 val rawRet = ctCls.toClassImpl(inputType.classLoader, inputType.protectionDomain)
640 val ret = rawRet as Class<? extends BindingCodec<Map<QName,Object>, Object>>;
641 listener?.onChoiceCodecCreated(inputType, ret, node);
642 log.debug("DOM Codec for {} was generated {}", inputType, ret)
644 } catch (Exception e) {
645 processException(inputType, e);
650 private def keyConstructorList(List<QName> qnames) {
651 val names = new TreeSet<String>()
652 for (name : qnames) {
653 val fieldName = name.getterName;
654 names.add(fieldName);
656 return Joiner.on(",").join(names);
659 private def serializeBodyFacade(GeneratedType type, SchemaNode node) {
660 val ret = serializeBody(type, node);
664 private def String deserializeBody(GeneratedType type, SchemaNode node) {
665 val ret = deserializeBodyImpl(type, node);
669 private def deserializeKey(GeneratedType type, ListSchemaNode node) {
670 if (node.keyDefinition != null && !node.keyDefinition.empty) {
672 «type.resolvedName»Key getKey = («type.resolvedName»Key) «keyTransformer(type, node).canonicalName».fromDomStatic(_localQName,_compositeNode);
673 _builder.setKey(getKey);
678 private def dispatch String deserializeBodyImpl(GeneratedType type, SchemaNode node) '''
680 «QName.name» _localQName = «QName.name».create($1,QNAME.getLocalName());
685 java.util.Map _compositeNode = (java.util.Map) $2;
686 «type.builderName» _builder = new «type.builderName»();
687 return _builder.build();
691 private def dispatch String deserializeBodyImpl(GeneratedType type, ListSchemaNode node) '''
693 «QName.name» _localQName = «QName.name».create($1,QNAME.getLocalName());
697 java.util.Map _compositeNode = (java.util.Map) $2;
698 //System.out.println(_localQName + " " + _compositeNode);
699 «type.builderName» _builder = new «type.builderName»();
700 «deserializeKey(type, node)»
701 «deserializeDataNodeContainerBody(type, node)»
702 «deserializeAugmentations»
703 return _builder.build();
707 private def dispatch String deserializeBodyImpl(GeneratedType type, ContainerSchemaNode 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 «deserializeDataNodeContainerBody(type, node)»
717 «deserializeAugmentations»
718 return _builder.build();
722 private def dispatch String deserializeBodyImpl(GeneratedType type, ChoiceCaseNode node) '''
724 «QName.name» _localQName = «QName.name».create($1,QNAME.getLocalName());
729 java.util.Map _compositeNode = (java.util.Map) $2;
730 //System.out.println(_localQName + " " + _compositeNode);
731 «type.builderName» _builder = new «type.builderName»();
732 «deserializeDataNodeContainerBody(type, node)»
733 «deserializeAugmentations»
734 return _builder.build();
738 private def deserializeDataNodeContainerBody(GeneratedType type, DataNodeContainer node) {
739 deserializeNodeContainerBodyImpl(type, type.allProperties, node);
742 private def deserializeNodeContainerBodyImpl(GeneratedType type, HashMap<String, Type> properties,
743 DataNodeContainer node) {
745 boolean _is_empty = true;
746 «FOR child : node.childNodes»
747 «val signature = properties.getFor(child)»
748 «IF signature !== null»
749 «deserializeProperty(child, signature.value, signature.key)»
750 _builder.«signature.key.toSetter»(«signature.key»);
757 def deserializeAugmentations() '''
758 java.util.Map _augmentation = (java.util.Map) «AUGMENTATION_CODEC».deserialize(_compositeNode);
759 if(_augmentation != null) {
760 «Iterator.name» _entries = _augmentation.entrySet().iterator();
761 while(_entries.hasNext()) {
762 java.util.Map.Entry _entry = (java.util.Map.Entry) _entries.next();
763 ////System.out.println("Aug. key:" + _entry.getKey());
764 Class _type = (Class) _entry.getKey();
765 «Augmentation.resolvedName» _value = («Augmentation.name») _entry.getValue();
767 _builder.addAugmentation(_type,_value);
773 private def dispatch CharSequence deserializeProperty(ListSchemaNode schema, ParameterizedType type,
774 String propertyName) '''
775 java.util.List _dom_«propertyName» = _compositeNode.get(«QName.name».create(_localQName,"«schema.QName.
777 ////System.out.println("«propertyName»#deCode"+_dom_«propertyName»);
778 java.util.List «propertyName» = new java.util.ArrayList();
779 if(_dom_«propertyName» != null) {
780 java.util.List _serialized = new java.util.ArrayList();
781 java.util.Iterator _iterator = _dom_«propertyName».iterator();
782 boolean _hasNext = _iterator.hasNext();
784 Object _listItem = _iterator.next();
786 ////System.out.println(" item" + _listItem);
787 Object _value = «type.actualTypeArguments.get(0).serializer(schema).resolvedName».fromDomStatic(_localQName,_listItem);
788 ////System.out.println(" value" + _value);
789 «propertyName».add(_value);
790 _hasNext = _iterator.hasNext();
794 ////System.out.println(" list" + «propertyName»);
797 private def dispatch CharSequence deserializeProperty(LeafListSchemaNode schema, ParameterizedType type,
798 String propertyName) '''
799 java.util.List _dom_«propertyName» = _compositeNode.get(«QName.name».create(_localQName,"«schema.QName.
801 java.util.List «propertyName» = new java.util.ArrayList();
802 if(_dom_«propertyName» != null) {
803 java.util.List _serialized = new java.util.ArrayList();
804 java.util.Iterator _iterator = _dom_«propertyName».iterator();
805 boolean _hasNext = _iterator.hasNext();
808 Object _listItem = _iterator.next();
809 if(_listItem instanceof java.util.Map.Entry) {
810 Object _innerValue = ((java.util.Map.Entry) _listItem).getValue();
811 Object _value = «deserializeValue(type.actualTypeArguments.get(0), "_innerValue", schema.type)»;
812 «propertyName».add(_value);
814 _hasNext = _iterator.hasNext();
819 private def dispatch CharSequence deserializeProperty(LeafSchemaNode schema, Type type, String propertyName) '''
820 java.util.List _dom_«propertyName»_list =
821 _compositeNode.get(«QName.name».create(_localQName,"«schema.QName.localName»"));
822 «type.resolvedName» «propertyName» = null;
823 if(_dom_«propertyName»_list != null && _dom_«propertyName»_list.size() > 0) {
825 java.util.Map.Entry _dom_«propertyName» = (java.util.Map.Entry) _dom_«propertyName»_list.get(0);
826 Object _inner_value = _dom_«propertyName».getValue();
827 «propertyName» = «deserializeValue(type, "_inner_value", schema.type)»;
831 private def dispatch CharSequence deserializeProperty(ContainerSchemaNode schema, Type type,
832 String propertyName) '''
833 java.util.List _dom_«propertyName»_list =
834 _compositeNode.get(«QName.name».create(_localQName,"«schema.QName.localName»"));
835 «type.resolvedName» «propertyName» = null;
836 if(_dom_«propertyName»_list != null && _dom_«propertyName»_list.size() > 0) {
838 java.util.Map _dom_«propertyName» = (java.util.Map) _dom_«propertyName»_list.get(0);
839 «propertyName» = «type.serializer(schema).resolvedName».fromDomStatic(_localQName,_dom_«propertyName»);
843 private def dispatch CharSequence deserializeProperty(ChoiceNode schema, Type type, String propertyName) '''
844 «type.resolvedName» «propertyName» = «type.serializer(schema).resolvedName».fromDomStatic(_localQName,_compositeNode);
845 if(«propertyName» != null) {
850 private def dispatch String deserializeValue(GeneratedTransferObject type, String domParameter,
851 TypeDefinition<?> typeDefinition) '''
852 («type.resolvedName») «type.valueSerializer(typeDefinition).resolvedName».fromDomValue(«domParameter»)
855 private def dispatch String deserializeValue(Enumeration type, String domParameter, TypeDefinition<?> typeDefinition) '''
856 («type.resolvedName») «type.valueSerializer(typeDefinition).resolvedName».fromDomValue(«domParameter»)
859 private def dispatch Class<? extends BindingCodec<Map<QName, Object>, Object>> generateValueTransformer(
860 Class<?> inputType, GeneratedTransferObject typeSpec, TypeDefinition<?> typeDef) {
863 val returnType = typeSpec.valueReturnType;
864 if (returnType == null) {
865 val ctCls = createDummyImplementation(inputType, typeSpec);
866 val ret = ctCls.toClassImpl(inputType.classLoader, inputType.protectionDomain)
867 return ret as Class<? extends BindingCodec<Map<QName,Object>, Object>>;
870 val ctCls = createClass(typeSpec.codecClassName) [
871 //staticField(Map,"AUGMENTATION_SERIALIZERS");
872 if (inputType.isYangBindingAvailable) {
873 implementsType(BINDING_CODEC)
874 staticField(it, INSTANCE_IDENTIFIER_CODEC, BindingCodec)
875 staticField(it, IDENTITYREF_CODEC, BindingCodec)
876 implementsType(BindingDeserializer.asCtClass)
878 method(Object, "toDomValue", Object) [
879 modifiers = PUBLIC + FINAL + STATIC
880 val ctSpec = typeSpec.asCtClass;
883 ////System.out.println("«inputType.simpleName»#toDomValue: "+$1);
888 «typeSpec.resolvedName» _encapsulatedValue = («typeSpec.resolvedName») $1;
889 ////System.out.println("«inputType.simpleName»#toDomValue:Enc: "+_encapsulatedValue);
890 «returnType.resolvedName» _value = _encapsulatedValue.getValue();
891 ////System.out.println("«inputType.simpleName»#toDomValue:DeEnc: "+_value);
892 Object _domValue = «serializeValue(returnType, "_value", null)»;
897 method(Object, "serialize", Object) [
900 return toDomValue($1);
904 method(Object, "fromDomValue", Object) [
905 modifiers = PUBLIC + FINAL + STATIC
908 ////System.out.println("«inputType.simpleName»#fromDomValue: "+$1);
913 «returnType.resolvedName» _simpleValue = «deserializeValue(returnType, "$1", null)»;
914 «typeSpec.resolvedName» _value = new «typeSpec.resolvedName»(_simpleValue);
919 method(Object, "deserialize", Object) [
921 return fromDomValue($1);
927 val ret = ctCls.toClassImpl(inputType.classLoader, inputType.protectionDomain)
928 log.debug("DOM Codec for {} was generated {}", inputType, ret)
929 return ret as Class<? extends BindingCodec<Map<QName,Object>, Object>>;
930 } catch (Exception e) {
931 log.error("Cannot compile DOM Codec for {}", inputType, e);
932 val exception = new CodeGenerationException("Cannot compile Transformator for " + inputType);
933 exception.addSuppressed(e);
938 private def dispatch Class<? extends BindingCodec<Map<QName, Object>, Object>> generateValueTransformer(
939 Class<?> inputType, GeneratedTransferObject typeSpec, UnionTypeDefinition typeDef) {
941 val ctCls = createClass(typeSpec.codecClassName) [
942 val properties = typeSpec.allProperties;
943 val getterToTypeDefinition = XtendHelper.getTypes(typeDef).toMap[type | type.QName.getterName];
944 //staticField(Map,"AUGMENTATION_SERIALIZERS");
945 if (inputType.isYangBindingAvailable) {
946 implementsType(BINDING_CODEC)
947 staticField(it, INSTANCE_IDENTIFIER_CODEC, BindingCodec)
948 staticField(it, IDENTITYREF_CODEC, BindingCodec)
949 implementsType(BindingDeserializer.asCtClass)
951 method(Object, "toDomValue", Object) [
952 modifiers = PUBLIC + FINAL + STATIC
953 val ctSpec = inputType.asCtClass;
957 ////System.out.println("«inputType.simpleName»#toDomValue: "+$1);
962 «typeSpec.resolvedName» _value = («typeSpec.resolvedName») $1;
963 «FOR property : properties.entrySet»
964 «IF property.key != "getValue"»
965 «property.value.resolvedName» «property.key» = («property.value.resolvedName») _value.«property.
967 if(«property.key» != null) {
968 return «serializeValue(property.value, property.key, getterToTypeDefinition.get(property.key))»;
977 method(Object, "serialize", Object) [
980 return toDomValue($1);
984 method(Object, "fromDomValue", Object) [
985 modifiers = PUBLIC + FINAL + STATIC
988 ////System.out.println("«inputType.simpleName»#fromDomValue: "+$1);
993 if($1 instanceof String) {
994 String _simpleValue = (String) $1;
995 return new «typeSpec.resolvedName»(_simpleValue.toCharArray());
1001 method(Object, "deserialize", Object) [
1003 return fromDomValue($1);
1009 val ret = ctCls.toClassImpl(inputType.classLoader, inputType.protectionDomain)
1010 log.debug("DOM Codec for {} was generated {}", inputType, ret)
1011 return ret as Class<? extends BindingCodec<Map<QName,Object>, Object>>;
1012 } catch (Exception e) {
1013 log.error("Cannot compile DOM Codec for {}", inputType, e);
1014 val exception = new CodeGenerationException("Cannot compile Transformator for " + inputType);
1015 exception.addSuppressed(e);
1021 private def dispatch Class<? extends BindingCodec<Map<QName, Object>, Object>> generateValueTransformer(
1022 Class<?> inputType, GeneratedTransferObject typeSpec, BitsTypeDefinition typeDef) {
1024 val ctCls = createClass(typeSpec.codecClassName) [
1025 //staticField(Map,"AUGMENTATION_SERIALIZERS");
1026 if (inputType.isYangBindingAvailable) {
1027 implementsType(BINDING_CODEC)
1028 staticField(it, INSTANCE_IDENTIFIER_CODEC, BindingCodec)
1029 staticField(it, IDENTITYREF_CODEC, BindingCodec)
1030 implementsType(BindingDeserializer.asCtClass)
1032 method(Object, "toDomValue", Object) [
1033 modifiers = PUBLIC + FINAL + STATIC
1034 val ctSpec = typeSpec.asCtClass;
1037 ////System.out.println("«inputType.simpleName»#toDomValue: "+$1);
1042 «typeSpec.resolvedName» _encapsulatedValue = («typeSpec.resolvedName») $1;
1043 «HashSet.resolvedName» _value = new «HashSet.resolvedName»();
1044 //System.out.println("«inputType.simpleName»#toDomValue:Enc: "+_encapsulatedValue);
1046 «FOR bit : typeDef.bits»
1047 «val getter = bit.getterName()»
1048 if(Boolean.TRUE.equals(_encapsulatedValue.«getter»())) {
1049 _value.add("«bit.name»");
1052 «Set.resolvedName» _domValue = «Collections.resolvedName».unmodifiableSet(_value);
1053 //System.out.println("«inputType.simpleName»#toDomValue:DeEnc: "+_domValue);
1059 method(Object, "serialize", Object) [
1062 return toDomValue($1);
1066 method(Object, "fromDomValue", Object) [
1067 modifiers = PUBLIC + FINAL + STATIC
1068 val sortedBits = typeDef.bits.sort[o1, o2|o1.propertyName.compareTo(o2.propertyName)]
1071 //System.out.println("«inputType.simpleName»#fromDomValue: "+$1);
1076 «Set.resolvedName» _domValue = («Set.resolvedName») $1;
1077 «FOR bit : sortedBits»
1078 Boolean «bit.propertyName» = Boolean.valueOf(_domValue.contains("«bit.name»"));
1081 return new «inputType.resolvedName»(«FOR bit : sortedBits SEPARATOR ","»«bit.propertyName»«ENDFOR»);
1085 method(Object, "deserialize", Object) [
1087 return fromDomValue($1);
1093 val ret = ctCls.toClassImpl(inputType.classLoader, inputType.protectionDomain)
1094 log.debug("DOM Codec for {} was generated {}", inputType, ret)
1095 return ret as Class<? extends BindingCodec<Map<QName,Object>, Object>>;
1096 } catch (Exception e) {
1097 log.error("Cannot compile DOM Codec for {}", inputType, e);
1098 val exception = new CodeGenerationException("Cannot compile Transformator for " + inputType);
1099 exception.addSuppressed(e);
1104 def String getPropertyName(Bit bit) {
1105 '''_«BindingGeneratorUtil.parseToValidParamName(bit.name)»'''
1108 def String getterName(Bit bit) {
1110 val paramName = BindingGeneratorUtil.parseToValidParamName(bit.name);
1111 return '''is«paramName.toFirstUpper»''';
1114 def boolean isYangBindingAvailable(Class<?> class1) {
1116 val bindingCodecClass = class1.classLoader.loadClass(BINDING_CODEC.name);
1117 return bindingCodecClass !== null;
1118 } catch (ClassNotFoundException e) {
1123 private def createDummyImplementation(Class<?> object, GeneratedTransferObject typeSpec) {
1124 log.trace("Generating Dummy DOM Codec for {} with {}", object, object.classLoader)
1125 return createClass(typeSpec.codecClassName) [
1126 if (object.isYangBindingAvailable) {
1127 implementsType(BINDING_CODEC)
1128 staticField(it, INSTANCE_IDENTIFIER_CODEC, BindingCodec)
1129 staticField(it, IDENTITYREF_CODEC, BindingCodec)
1130 implementsType(BindingDeserializer.asCtClass)
1132 //implementsType(BindingDeserializer.asCtClass)
1133 method(Object, "toDomValue", Object) [
1134 modifiers = PUBLIC + FINAL + STATIC
1139 return $1.toString();
1143 method(Object, "serialize", Object) [
1146 return toDomValue($1);
1150 method(Object, "fromDomValue", Object) [
1151 modifiers = PUBLIC + FINAL + STATIC
1152 bodyChecked = '''return null;'''
1154 method(Object, "deserialize", Object) [
1156 return fromDomValue($1);
1163 private def Type getValueReturnType(GeneratedTransferObject object) {
1164 for (prop : object.properties) {
1165 if (prop.name == "value") {
1166 return prop.returnType;
1169 if (object.superType != null) {
1170 return getValueReturnType(object.superType);
1175 private def Class<?> generateValueTransformer(Class<?> inputType, Enumeration typeSpec) {
1177 val typeRef = new ReferencedTypeImpl(typeSpec.packageName, typeSpec.name);
1178 val schema = typeToSchemaNode.get(typeRef) as ExtendedType;
1179 val enumSchema = schema.baseType as EnumerationType;
1181 //log.info("Generating DOM Codec for {} with {}", inputType, inputType.classLoader)
1182 val ctCls = createClass(typeSpec.codecClassName) [
1183 //staticField(Map,"AUGMENTATION_SERIALIZERS");
1184 //implementsType(BINDING_CODEC)
1185 method(Object, "toDomValue", Object) [
1186 modifiers = PUBLIC + FINAL + STATIC
1191 «typeSpec.resolvedName» _value = («typeSpec.resolvedName») $1;
1192 «FOR en : enumSchema.values»
1193 if(«typeSpec.resolvedName».«BindingGeneratorUtil.parseToClassName(en.name)».equals(_value)) {
1201 method(Object, "serialize", Object) [
1203 return toDomValue($1);
1206 method(Object, "fromDomValue", Object) [
1207 modifiers = PUBLIC + FINAL + STATIC
1213 String _value = (String) $1;
1214 «FOR en : enumSchema.values»
1215 if("«en.name»".equals(_value)) {
1216 return «typeSpec.resolvedName».«BindingGeneratorUtil.parseToClassName(en.name)»;
1223 method(Object, "deserialize", Object) [
1225 return fromDomValue($1);
1230 val ret = ctCls.toClassImpl(inputType.classLoader, inputType.protectionDomain)
1231 log.debug("DOM Codec for {} was generated {}", inputType, ret)
1233 } catch (CodeGenerationException e) {
1234 throw new CodeGenerationException("Cannot compile Transformator for " + inputType, e);
1235 } catch (Exception e) {
1236 log.error("Cannot compile DOM Codec for {}", inputType, e);
1237 val exception = new CodeGenerationException("Cannot compile Transformator for " + inputType);
1238 exception.addSuppressed(e);
1244 def Class<?> toClassImpl(CtClass newClass, ClassLoader loader, ProtectionDomain domain) {
1245 val cls = newClass.toClass(loader, domain);
1246 if (classFileCapturePath !== null) {
1247 newClass.writeFile(classFileCapturePath.absolutePath);
1249 listener?.onCodecCreated(cls);
1253 def debugWriteClass(CtClass class1) {
1254 val path = class1.name.replace(".", "/") + ".class"
1256 val captureFile = new File(classFileCapturePath, path);
1257 captureFile.createNewFile
1261 private def dispatch String deserializeValue(Type type, String domParameter, TypeDefinition<?> typeDef) {
1262 if (INSTANCE_IDENTIFIER.equals(type)) {
1263 return '''(«InstanceIdentifier.name») «INSTANCE_IDENTIFIER_CODEC».deserialize(«domParameter»)'''
1264 } else if (CLASS_TYPE.equals(type)) {
1265 return '''(«Class.name») «IDENTITYREF_CODEC».deserialize(«domParameter»)'''
1267 return '''(«type.resolvedName») «domParameter»'''
1275 private def dispatch CharSequence deserializeProperty(DataSchemaNode container, Type type, String propertyName) '''
1276 «type.resolvedName» «propertyName» = null;
1279 private def dispatch CharSequence deserializeProperty(DataSchemaNode container, GeneratedTypeBuilder type,
1280 String propertyName) {
1281 _deserializeProperty(container, type.toInstance, propertyName)
1284 public static def toSetter(String it) {
1286 if (startsWith("is")) {
1287 return "set" + substring(2);
1288 } else if (startsWith("get")) {
1289 return "set" + substring(3);
1295 private def dispatch CharSequence deserializeProperty(DataSchemaNode container,GeneratedType type, String propertyName) '''
1296 «type.resolvedName» «propertyName» = value.«propertyName»();
1297 if(«propertyName» != null) {
1298 Object domValue = «type.serializer».toDomStatic(QNAME,«propertyName»);
1299 _childNodes.add(domValue);
1303 private def getBuilderName(GeneratedType type) '''«type.resolvedName»Builder'''
1305 private def staticQNameField(CtClass it, QName node) {
1306 val field = new CtField(ctQName, "QNAME", it);
1307 field.modifiers = PUBLIC + FINAL + STATIC;
1309 '''«QName.asCtClass.name».create("«node.namespace»","«node.formattedRevision»","«node.localName»")''')
1312 private def dispatch String serializeBody(GeneratedType type, ListSchemaNode node) '''
1314 «QName.name» _resultName = «QName.name».create($1,QNAME.getLocalName());
1315 java.util.List _childNodes = new java.util.ArrayList();
1316 «type.resolvedName» value = («type.resolvedName») $2;
1317 «transformDataContainerBody(type, type.allProperties, node)»
1318 «serializeAugmentations»
1319 return ($r) java.util.Collections.singletonMap(_resultName,_childNodes);
1323 private def dispatch String serializeBody(GeneratedType type, ContainerSchemaNode node) '''
1325 «QName.name» _resultName = «QName.name».create($1,QNAME.getLocalName());
1326 java.util.List _childNodes = new java.util.ArrayList();
1327 «type.resolvedName» value = («type.resolvedName») $2;
1328 «transformDataContainerBody(type, type.allProperties, node)»
1329 «serializeAugmentations»
1330 return ($r) java.util.Collections.singletonMap(_resultName,_childNodes);
1334 private def dispatch String serializeBody(GeneratedType type, ChoiceCaseNode node) '''
1336 «QName.name» _resultName = «QName.name».create($1,QNAME.getLocalName());
1337 java.util.List _childNodes = new java.util.ArrayList();
1338 «type.resolvedName» value = («type.resolvedName») $2;
1339 «transformDataContainerBody(type, type.allProperties, node)»
1340 «serializeAugmentations»
1341 return ($r) java.util.Collections.singletonMap(_resultName,_childNodes);
1345 private def dispatch String serializeBody(GeneratedType type, SchemaNode node) '''
1347 «QName.name» _resultName = «QName.name».create($1,QNAME.getLocalName());
1348 java.util.List _childNodes = new java.util.ArrayList();
1349 «type.resolvedName» value = («type.resolvedName») $2;
1350 return ($r) java.util.Collections.singletonMap(_resultName,_childNodes);
1354 private def transformDataContainerBody(Type type, Map<String, Type> properties, DataNodeContainer node) {
1356 «FOR child : node.childNodes»
1357 «val signature = properties.getFor(child)»
1358 «IF signature !== null»
1359 ////System.out.println("«type.name»#«signature.key»" + value.«signature.key»());
1360 «serializeProperty(child, signature.value, signature.key)»
1367 private def serializeAugmentations() '''
1368 java.util.List _augmentations = (java.util.List) «AUGMENTATION_CODEC».serialize(value);
1369 if(_augmentations != null) {
1370 _childNodes.addAll(_augmentations);
1374 def Entry<String, Type> getFor(Map<String, Type> map, DataSchemaNode node) {
1375 var sig = map.get(node.getterName);
1377 return new SimpleEntry(node.getterName, sig);
1379 sig = map.get(node.booleanGetterName);
1381 return new SimpleEntry(node.booleanGetterName, map.get(node.booleanGetterName));
1386 private static def String getBooleanGetterName(DataSchemaNode node) {
1387 return "is" + BindingGeneratorUtil.parseToClassName(node.QName.localName);
1390 private static def String getGetterName(DataSchemaNode node) {
1391 return "get" + BindingGeneratorUtil.parseToClassName(node.QName.localName);
1394 private static def String getGetterName(QName node) {
1395 return "get" + BindingGeneratorUtil.parseToClassName(node.localName);
1398 private def dispatch CharSequence serializeProperty(ListSchemaNode schema, ParameterizedType type,
1399 String propertyName) '''
1400 «type.resolvedName» «propertyName» = value.«propertyName»();
1401 ////System.out.println("«propertyName»:" + «propertyName»);
1402 if(«propertyName» != null) {
1403 java.util.Iterator _iterator = «propertyName».iterator();
1404 boolean _hasNext = _iterator.hasNext();
1406 Object _listItem = _iterator.next();
1407 Object _domValue = «type.actualTypeArguments.get(0).serializer(schema).resolvedName».toDomStatic(_resultName,_listItem);
1408 _childNodes.add(_domValue);
1409 _hasNext = _iterator.hasNext();
1414 private def dispatch CharSequence serializeProperty(LeafSchemaNode schema, Type type, String propertyName) '''
1415 «type.resolvedName» «propertyName» = value.«propertyName»();
1417 if(«propertyName» != null) {
1418 «QName.name» _qname = «QName.name».create(_resultName,"«schema.QName.localName»");
1419 Object _propValue = «serializeValue(type, propertyName, schema.type)»;
1420 if(_propValue != null) {
1421 Object _domValue = java.util.Collections.singletonMap(_qname,_propValue);
1422 _childNodes.add(_domValue);
1427 private def dispatch serializeValue(GeneratedTransferObject type, String parameter, TypeDefinition<?> typeDefinition) {
1428 '''«type.valueSerializer(typeDefinition).resolvedName».toDomValue(«parameter»)'''
1431 private def dispatch serializeValue(Enumeration type, String parameter, TypeDefinition<?> typeDefinition) {
1432 '''«type.valueSerializer(typeDefinition).resolvedName».toDomValue(«parameter»)'''
1435 private def dispatch serializeValue(Type signature, String property, TypeDefinition<?> typeDefinition) {
1436 if (INSTANCE_IDENTIFIER == signature) {
1437 return '''«INSTANCE_IDENTIFIER_CODEC».serialize(«property»)'''
1438 } else if (CLASS_TYPE.equals(signature)) {
1439 return '''(«QName.resolvedName») «IDENTITYREF_CODEC».serialize(«property»)'''
1441 if ("char[]" == signature.name) {
1442 return '''new String(«property»)''';
1444 return '''«property»''';
1447 private def dispatch CharSequence serializeProperty(LeafListSchemaNode schema, ParameterizedType type,
1448 String propertyName) '''
1449 «type.resolvedName» «propertyName» = value.«propertyName»();
1450 if(«propertyName» != null) {
1451 «QName.name» _qname = «QName.name».create(_resultName,"«schema.QName.localName»");
1452 java.util.Iterator _iterator = «propertyName».iterator();
1453 boolean _hasNext = _iterator.hasNext();
1455 Object _listItem = _iterator.next();
1456 Object _propValue = «serializeValue(type.actualTypeArguments.get(0), "_listItem", schema.type)»;
1457 Object _domValue = java.util.Collections.singletonMap(_qname,_propValue);
1458 _childNodes.add(_domValue);
1459 _hasNext = _iterator.hasNext();
1464 private def dispatch CharSequence serializeProperty(ChoiceNode container, GeneratedType type,
1465 String propertyName) '''
1466 «type.resolvedName» «propertyName» = value.«propertyName»();
1467 if(«propertyName» != null) {
1468 java.util.List domValue = «type.serializer(container).resolvedName».toDomStatic(_resultName,«propertyName»);
1469 _childNodes.addAll(domValue);
1477 private def dispatch CharSequence serializeProperty(DataSchemaNode container, Type type, String propertyName) '''
1478 «type.resolvedName» «propertyName» = value.«propertyName»();
1479 if(«propertyName» != null) {
1480 Object domValue = «propertyName»;
1481 _childNodes.add(domValue);
1485 private def dispatch CharSequence serializeProperty(DataSchemaNode container, GeneratedTypeBuilder type,
1486 String propertyName) {
1487 serializeProperty(container, type.toInstance, propertyName)
1490 private def dispatch CharSequence serializeProperty(DataSchemaNode container, GeneratedType type,
1491 String propertyName) '''
1492 «type.resolvedName» «propertyName» = value.«propertyName»();
1493 if(«propertyName» != null) {
1494 Object domValue = «type.serializer(container).resolvedName».toDomStatic(_resultName,«propertyName»);
1495 _childNodes.add(domValue);
1499 private def codecClassName(GeneratedType typeSpec) {
1500 return '''«typeSpec.resolvedName»$Broker$Codec$DOM'''
1503 private def codecClassName(Class<?> typeSpec) {
1504 return '''«typeSpec.name»$Broker$Codec$DOM'''
1507 private def HashMap<String, Type> getAllProperties(GeneratedType type) {
1508 val ret = new HashMap<String, Type>();
1509 type.collectAllProperties(ret);
1513 private def dispatch void collectAllProperties(GeneratedType type, Map<String, Type> set) {
1514 for (definition : type.methodDefinitions) {
1515 set.put(definition.name, definition.returnType);
1517 for (property : type.properties) {
1518 set.put(property.getterName, property.returnType);
1520 for (parent : type.implements) {
1521 parent.collectAllProperties(set);
1525 def String getGetterName(GeneratedProperty property) {
1526 return "get" + property.name.toFirstUpper
1529 private def dispatch void collectAllProperties(Type type, Map<String, Type> set) {
1530 // NOOP for generic type.
1533 def String getResolvedName(Type type) {
1534 return type.asCtClass.name;
1537 def String getResolvedName(Class<?> type) {
1538 return type.asCtClass.name;
1541 def CtClass asCtClass(Type type) {
1542 val cls = loadClassWithTCCL(type.fullyQualifiedName)
1543 return cls.asCtClass;
1546 private def dispatch processException(Class<?> inputType, CodeGenerationException e) {
1547 log.error("Cannot compile DOM Codec for {}. One of it's prerequisites was not generated.", inputType);
1551 private def dispatch processException(Class<?> inputType, Exception e) {
1552 log.error("Cannot compile DOM Codec for {}", inputType, e);
1553 val exception = new CodeGenerationException("Cannot compile Transformator for " + inputType, e);
1557 private def setBodyChecked(CtMethod method, String body) {
1559 method.setBody(body);
1560 } catch (CannotCompileException e) {
1561 log.error("Cannot compile method: {}#{} {}, Reason: {} Body: {}", method.declaringClass, method.name,
1562 method.signature, e.message, body)
1567 private def <V> V withClassLoaderAndLock(ClassLoader cls, Lock lock, Callable<V> function) throws Exception {
1568 appendClassLoaderIfMissing(cls);
1569 ClassLoaderUtils.withClassLoaderAndLock(cls, lock, function);
1575 class PropertyPair {
1584 SchemaNode schemaNode;