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
75 import org.opendaylight.yangtools.yang.binding.BindingMapping
77 class TransformerGenerator {
79 private static val log = LoggerFactory.getLogger(TransformerGenerator)
81 public static val STRING = Types.typeForClass(String);
82 public static val BOOLEAN = Types.typeForClass(Boolean);
83 public static val INTEGER = Types.typeForClass(Integer);
84 public static val INSTANCE_IDENTIFIER = Types.typeForClass(InstanceIdentifier)
86 //public static val DECIMAL = Types.typeForClass(Decimal);
87 public static val LONG = Types.typeForClass(Long);
89 val ClassPool classPool
90 val extension JavassistUtils utils;
97 var File classFileCapturePath;
100 var Map<Type, Type> typeDefinitions = new ConcurrentHashMap();
103 var Map<Type, GeneratedTypeBuilder> typeToDefinition = new ConcurrentHashMap();
106 var Map<SchemaPath, GeneratedTypeBuilder> pathToType = new ConcurrentHashMap();
109 var Map<Type, SchemaNode> typeToSchemaNode = new ConcurrentHashMap();
112 var Map<Type, AugmentationSchema> typeToAugmentation = new ConcurrentHashMap();
115 var GeneratorListener listener;
118 var extension GeneratedClassLoadingStrategy classLoadingStrategy
120 public static val CLASS_TYPE = Types.typeForClass(Class);
122 public new(ClassPool pool) {
124 utils = new JavassistUtils(pool)
126 BINDING_CODEC = BindingCodec.asCtClass;
127 ctQName = QName.asCtClass
129 classLoadingStrategy = GeneratedClassLoadingStrategy.TCCLClassLoadingStrategy;
132 def Class<? extends BindingCodec<Map<QName, Object>, Object>> transformerFor(Class<?> inputType) {
133 return withClassLoaderAndLock(inputType.classLoader, lock) [ |
134 val ret = getGeneratedClass(inputType)
136 listener.onClassProcessed(inputType);
137 return ret as Class<? extends BindingCodec<Map<QName,Object>, Object>>;
139 val ref = Types.typeForClass(inputType)
140 val node = typeToSchemaNode.get(ref)
141 val typeSpecBuilder = typeToDefinition.get(ref)
142 checkState(typeSpecBuilder !== null, "Could not find typedefinition for %s", inputType.name);
143 val typeSpec = typeSpecBuilder.toInstance();
144 val newret = generateTransformerFor(inputType, typeSpec, node);
145 listener.onClassProcessed(inputType);
146 return newret as Class<? extends BindingCodec<Map<QName,Object>, Object>>;
150 def Class<? extends BindingCodec<Map<QName, Object>, Object>> transformerFor(Class<?> inputType, DataSchemaNode node) {
151 return withClassLoaderAndLock(inputType.classLoader, lock) [ |
152 val ret = getGeneratedClass(inputType)
154 listener.onClassProcessed(inputType);
155 return ret as Class<? extends BindingCodec<Map<QName,Object>, Object>>;
157 val ref = Types.typeForClass(inputType)
158 var typeSpecBuilder = typeToDefinition.get(ref)
159 if (typeSpecBuilder == null) {
160 typeSpecBuilder = pathToType.get(node.path);
162 var schemaNode = typeToSchemaNode.get(ref);
163 if (schemaNode === null) {
166 checkState(typeSpecBuilder !== null, "Could not find TypeDefinition for %s, $s", inputType.name, node);
167 val typeSpec = typeSpecBuilder.toInstance();
168 val newret = generateTransformerFor(inputType, typeSpec, schemaNode);
169 listener.onClassProcessed(inputType);
170 return newret as Class<? extends BindingCodec<Map<QName,Object>, Object>>;
174 def Class<? extends BindingCodec<Map<QName, Object>, Object>> augmentationTransformerFor(Class<?> inputType) {
175 return withClassLoaderAndLock(inputType.classLoader, lock) [ |
176 val ret = getGeneratedClass(inputType)
178 return ret as Class<? extends BindingCodec<Map<QName,Object>, Object>>;
180 val ref = Types.typeForClass(inputType)
181 val node = typeToAugmentation.get(ref)
182 val typeSpecBuilder = typeToDefinition.get(ref)
183 val typeSpec = typeSpecBuilder.toInstance();
184 val newret = generateAugmentationTransformerFor(inputType, typeSpec, node);
185 listener.onClassProcessed(inputType);
186 return newret as Class<? extends BindingCodec<Map<QName,Object>, Object>>;
190 def Class<? extends BindingCodec<Object, Object>> caseCodecFor(Class<?> inputType, ChoiceCaseNode node) {
191 return withClassLoaderAndLock(inputType.classLoader, lock) [ |
192 val ret = getGeneratedClass(inputType)
194 return ret as Class<? extends BindingCodec<Object, Object>>;
196 val ref = Types.typeForClass(inputType)
197 val typeSpecBuilder = typeToDefinition.get(ref)
198 val typeSpec = typeSpecBuilder.toInstance();
199 val newret = generateCaseCodec(inputType, typeSpec, node);
200 return newret as Class<? extends BindingCodec<Object, Object>>;
204 def Class<? extends BindingCodec<Map<QName, Object>, Object>> keyTransformerForIdentifiable(Class<?> parentType) {
205 return withClassLoaderAndLock(parentType.classLoader, lock) [ |
206 val inputName = parentType.name + "Key";
207 val inputType = loadClass(inputName);
208 val ret = getGeneratedClass(inputType)
210 return ret as Class<? extends BindingCodec<Map<QName,Object>, Object>>;
212 val ref = Types.typeForClass(parentType)
213 val node = typeToSchemaNode.get(ref) as ListSchemaNode
214 val typeSpecBuilder = typeToDefinition.get(ref)
215 val typeSpec = typeSpecBuilder.identifierDefinition;
216 val newret = generateKeyTransformerFor(inputType, typeSpec, node);
217 return newret as Class<? extends BindingCodec<Map<QName,Object>, Object>>;
221 def getIdentifierDefinition(GeneratedTypeBuilder builder) {
222 val inst = builder.toInstance
223 val keyMethod = inst.methodDefinitions.findFirst[name == "getKey"]
224 return keyMethod.returnType as GeneratedTransferObject
227 def Class<? extends BindingCodec<Map<QName, Object>, Object>> keyTransformerForIdentifier(Class<?> inputType) {
228 return withClassLoaderAndLock(inputType.classLoader, lock) [ |
229 val ret = getGeneratedClass(inputType)
231 return ret as Class<? extends BindingCodec<Map<QName,Object>, Object>>;
233 val ref = Types.typeForClass(inputType)
234 val node = typeToSchemaNode.get(ref) as ListSchemaNode
235 val typeSpecBuilder = typeToDefinition.get(ref)
236 val typeSpec = typeSpecBuilder.toInstance();
237 val newret = generateKeyTransformerFor(inputType, typeSpec, node);
238 return newret as Class<? extends BindingCodec<Map<QName,Object>, Object>>;
242 private def Class<?> keyTransformerFor(Class<?> inputType, GeneratedType type, ListSchemaNode schema) {
243 return withClassLoaderAndLock(inputType.classLoader, lock) [ |
244 val transformer = getGeneratedClass(inputType)
245 if (transformer != null) {
248 val newret = generateKeyTransformerFor(inputType, type, schema);
249 return newret as Class<? extends BindingCodec<Map<QName,Object>, Object>>;
253 private def Class<?> getGeneratedClass(Class<? extends Object> cls) {
256 return loadClass(cls.codecClassName)
257 } catch (ClassNotFoundException e) {
262 private def Class<?> keyTransformer(GeneratedType type, ListSchemaNode node) {
263 val cls = loadClass(type.resolvedName + "Key");
264 keyTransformerFor(cls, type, node);
267 private def serializer(Type type, DataSchemaNode node) {
268 val cls = loadClass(type.resolvedName);
269 transformerFor(cls, node);
272 private def Class<?> valueSerializer(GeneratedTransferObject type, TypeDefinition<?> typeDefinition) {
273 val cls = loadClass(type.resolvedName);
274 val transformer = cls.generatedClass;
275 if (transformer !== null) {
278 var baseType = typeDefinition;
279 while (baseType.baseType != null) {
280 baseType = baseType.baseType;
282 val finalType = baseType;
283 return withClassLoaderAndLock(cls.classLoader, lock) [ |
284 val valueTransformer = generateValueTransformer(cls, type, finalType);
285 return valueTransformer;
289 private def Class<?> valueSerializer(Enumeration type, TypeDefinition<?> typeDefinition) {
290 val cls = loadClass(type.resolvedName);
291 val transformer = cls.generatedClass;
292 if (transformer !== null) {
296 return withClassLoaderAndLock(cls.classLoader, lock) [ |
297 val valueTransformer = generateValueTransformer(cls, type);
298 return valueTransformer;
302 private def generateKeyTransformerFor(Class<? extends Object> inputType, GeneratedType typeSpec, ListSchemaNode node) {
305 //log.info("Generating DOM Codec for {} with {}", inputType, inputType.classLoader)
306 val properties = typeSpec.allProperties;
307 val ctCls = createClass(inputType.codecClassName) [
308 //staticField(Map,"AUGMENTATION_SERIALIZERS");
309 staticField(it, INSTANCE_IDENTIFIER_CODEC, BindingCodec)
310 staticField(it, IDENTITYREF_CODEC, BindingCodec)
311 staticQNameField(node.QName);
312 implementsType(BINDING_CODEC)
313 method(Object, "toDomStatic", QName, Object) [
314 modifiers = PUBLIC + FINAL + STATIC
317 «QName.name» _resultName;
319 _resultName = «QName.name».create($1,QNAME.getLocalName());
323 java.util.List _childNodes = new java.util.ArrayList();
324 «inputType.resolvedName» value = («inputType.name») $2;
325 «FOR key : node.keyDefinition»
326 «val propertyName = key.getterName»
327 «val keyDef = node.getDataChildByName(key)»
328 «val property = properties.get(propertyName)»
329 «serializeProperty(keyDef, property, propertyName)»;
331 return ($r) java.util.Collections.singletonMap(_resultName,_childNodes);
335 method(Object, "fromDomStatic", QName, Object) [
336 modifiers = PUBLIC + FINAL + STATIC
342 «QName.name» _localQName = $1;
343 java.util.Map _compositeNode = (java.util.Map) $2;
344 boolean _is_empty = true;
345 «FOR key : node.keyDefinition»
346 «val propertyName = key.getterName»
347 «val keyDef = node.getDataChildByName(key)»
348 «val property = properties.get(propertyName)»
349 «deserializeProperty(keyDef, property, propertyName)»;
351 «inputType.resolvedName» _value = new «inputType.name»(«node.keyDefinition.
352 keyConstructorList»);
357 method(Object, "serialize", Object) [
360 java.util.Map.Entry _input = (java.util.Map.Entry) $1;
361 «QName.name» _localQName = («QName.name») _input.getKey();
362 «inputType.name» _keyValue = («inputType.name») _input.getValue();
363 return toDomStatic(_localQName,_keyValue);
367 method(Object, "deserialize", Object) [
370 «QName.name» _qname = QNAME;
371 if($1 instanceof java.util.Map.Entry) {
372 _qname = («QName.name») ((java.util.Map.Entry) $1).getKey();
374 return fromDomStatic(_qname,$1);
379 val ret = ctCls.toClassImpl(inputType.classLoader, inputType.protectionDomain)
380 log.debug("DOM Codec for {} was generated {}", inputType, ret)
381 return ret as Class<? extends BindingCodec<Map<QName,Object>, ?>>;
382 } catch (Exception e) {
383 processException(inputType, e);
388 private def Class<? extends BindingCodec<Object, Object>> generateCaseCodec(Class<?> inputType, GeneratedType type,
389 ChoiceCaseNode node) {
392 //log.info("Generating DOM Codec for {} with {}, TCCL is: {}", inputType, inputType.classLoader,Thread.currentThread.contextClassLoader)
393 val ctCls = createClass(type.codecClassName) [
394 //staticField(Map,"AUGMENTATION_SERIALIZERS");
395 implementsType(BINDING_CODEC)
396 staticQNameField(node.QName);
397 staticField(it, INSTANCE_IDENTIFIER_CODEC, BindingCodec)
398 staticField(it, AUGMENTATION_CODEC, BindingCodec)
399 staticField(it, IDENTITYREF_CODEC, BindingCodec)
400 method(Object, "toDomStatic", QName, Object) [
401 modifiers = PUBLIC + FINAL + STATIC
404 «QName.name» _resultName = «QName.name».create($1,QNAME.getLocalName());
405 java.util.List _childNodes = new java.util.ArrayList();
406 «type.resolvedName» value = («type.resolvedName») $2;
407 «transformDataContainerBody(type, type.allProperties, node)»
408 return ($r) _childNodes;
412 method(Object, "serialize", Object) [
415 java.util.Map.Entry _input = (java.util.Map.Entry) $1;
416 «QName.name» _localName = QNAME;
417 if(_input.getKey() != null) {
418 _localName = («QName.name») _input.getKey();
420 return toDomStatic(_localName,_input.getValue());
424 method(Object, "fromDomStatic", QName, Object) [
425 modifiers = PUBLIC + FINAL + STATIC
426 bodyChecked = deserializeBody(type, node)
428 method(Object, "deserialize", Object) [
431 //System.out.println("«type.name»#deserialize: " +$1);
432 java.util.Map.Entry _input = (java.util.Map.Entry) $1;
433 return fromDomStatic((«QName.name»)_input.getKey(),_input.getValue());
439 val ret = ctCls.toClassImpl(inputType.classLoader, inputType.protectionDomain) as Class<? extends BindingCodec<Object, Object>>
440 listener?.onDataContainerCodecCreated(inputType, ret);
441 log.debug("DOM Codec for {} was generated {}", inputType, ret)
443 } catch (Exception e) {
444 processException(inputType, e);
449 private def dispatch Class<? extends BindingCodec<Map<QName, Object>, Object>> generateTransformerFor(
450 Class<?> inputType, GeneratedType typeSpec, SchemaNode node) {
453 //log.info("Generating DOM Codec for {} with {}", inputType, inputType.classLoader)
454 val ctCls = createClass(typeSpec.codecClassName) [
455 //staticField(Map,"AUGMENTATION_SERIALIZERS");
456 staticQNameField(node.QName);
457 staticField(it, INSTANCE_IDENTIFIER_CODEC, BindingCodec)
458 staticField(it, IDENTITYREF_CODEC, BindingCodec)
459 staticField(it, AUGMENTATION_CODEC, BindingCodec)
460 implementsType(BINDING_CODEC)
461 method(Object, "toDomStatic", QName, Object) [
462 modifiers = PUBLIC + FINAL + STATIC
463 bodyChecked = serializeBodyFacade(typeSpec, node)
465 method(Object, "serialize", Object) [
468 java.util.Map.Entry _input = (java.util.Map.Entry) $1;
469 «QName.name» _localName = QNAME;
470 if(_input.getKey() != null) {
471 _localName = («QName.name») _input.getKey();
473 return toDomStatic(_localName,_input.getValue());
477 method(Object, "fromDomStatic", QName, Object) [
478 modifiers = PUBLIC + FINAL + STATIC
479 bodyChecked = deserializeBody(typeSpec, node)
481 method(Object, "deserialize", Object) [
484 «QName.name» _qname = QNAME;
485 if($1 instanceof java.util.Map.Entry) {
486 _qname = («QName.name») ((java.util.Map.Entry) $1).getKey();
488 return fromDomStatic(_qname,$1);
494 val ret = ctCls.toClassImpl(inputType.classLoader, inputType.protectionDomain) as Class<? extends BindingCodec<Map<QName,Object>, Object>>
495 listener?.onDataContainerCodecCreated(inputType, ret);
496 log.debug("DOM Codec for {} was generated {}", inputType, ret)
498 } catch (Exception e) {
499 processException(inputType, e);
504 private def Class<? extends BindingCodec<Map<QName, Object>, Object>> generateAugmentationTransformerFor(
505 Class<?> inputType, GeneratedType type, AugmentationSchema node) {
508 //log.info("Generating DOM Codec for {} with {}", inputType, inputType.classLoader)
509 val properties = type.allProperties
510 val ctCls = createClass(type.codecClassName) [
511 //staticField(Map,"AUGMENTATION_SERIALIZERS");
512 staticQNameField(node.augmentationQName);
513 staticField(it, INSTANCE_IDENTIFIER_CODEC, BindingCodec)
514 staticField(it, AUGMENTATION_CODEC, BindingCodec)
515 staticField(it, IDENTITYREF_CODEC, BindingCodec)
516 implementsType(BINDING_CODEC)
517 method(Object, "toDomStatic", QName, Object) [
518 modifiers = PUBLIC + FINAL + STATIC
521 ////System.out.println("Qname " + $1);
522 ////System.out.println("Value " + $2);
523 «QName.name» _resultName = «QName.name».create(QNAME,QNAME.getLocalName());
524 java.util.List _childNodes = new java.util.ArrayList();
525 «type.resolvedName» value = («type.resolvedName») $2;
526 «FOR child : node.childNodes»
527 «var signature = properties.getFor(child)»
528 ////System.out.println("«signature.key»" + value.«signature.key»());
529 «serializeProperty(child, signature.value, signature.key)»
531 return ($r) _childNodes;
535 method(Object, "serialize", Object) [
538 java.util.Map.Entry _input = (java.util.Map.Entry) $1;
539 «QName.name» _localName = QNAME;
540 if(_input.getKey() != null) {
541 _localName = («QName.name») _input.getKey();
543 return toDomStatic(_localName,_input.getValue());
547 method(Object, "fromDomStatic", QName, Object) [
548 modifiers = PUBLIC + FINAL + STATIC
551 «QName.name» _localQName = QNAME;
556 java.util.Map _compositeNode = (java.util.Map) $2;
557 //System.out.println(_localQName + " " + _compositeNode);
558 «type.builderName» _builder = new «type.builderName»();
559 boolean _is_empty = true;
560 «FOR child : node.childNodes»
561 «val signature = properties.getFor(child)»
562 «deserializeProperty(child, signature.value, signature.key)»
563 _builder.«signature.key.toSetter»(«signature.key»);
568 return _builder.build();
572 method(Object, "deserialize", Object) [
574 return fromDomStatic(QNAME,$1);
579 val ret = ctCls.toClassImpl(inputType.classLoader, inputType.protectionDomain) as Class<? extends BindingCodec<Map<QName,Object>, Object>>
580 listener?.onDataContainerCodecCreated(inputType, ret);
582 } catch (Exception e) {
583 processException(inputType, e);
588 private def dispatch Class<? extends BindingCodec<Map<QName, Object>, Object>> generateTransformerFor(
589 Class<?> inputType, GeneratedType typeSpec, ChoiceNode node) {
592 //log.info("Generating DOM Codec for {} with {}", inputType, inputType.classLoader)
593 val ctCls = createClass(typeSpec.codecClassName) [
594 //staticField(Map,"AUGMENTATION_SERIALIZERS");
595 //staticQNameField(inputType);
596 staticField(it, INSTANCE_IDENTIFIER_CODEC, BindingCodec)
597 staticField(it, IDENTITYREF_CODEC, BindingCodec)
598 staticField(it, CLASS_TO_CASE_MAP, Map)
599 staticField(it, COMPOSITE_TO_CASE, Map)
600 //staticField(it,QNAME_TO_CASE_MAP,BindingCodec)
601 implementsType(BINDING_CODEC)
602 method(List, "toDomStatic", QName, Object) [
603 modifiers = PUBLIC + FINAL + STATIC
609 «DataObject.name» _baValue = («DataObject.name») $2;
610 Class _baClass = _baValue.getImplementedInterface();
611 «BINDING_CODEC.name» _codec = «CLASS_TO_CASE_MAP».get(_baClass);
615 java.util.Map.Entry _input = new «SimpleEntry.name»($1,_baValue);
616 Object _ret = _codec.serialize(_input);
617 ////System.out.println("«typeSpec.name»#toDomStatic: " + _ret);
618 return («List.name») _ret;
622 method(Object, "serialize", Object) [
624 throw new «UnsupportedOperationException.name»("Direct invocation not supported.");
627 method(Object, "fromDomStatic", QName, Map) [
628 modifiers = PUBLIC + FINAL + STATIC
631 «BINDING_CODEC.name» _codec = («BINDING_CODEC.name») «COMPOSITE_TO_CASE».get($2);
633 return _codec.deserialize(new «SimpleEntry.name»($1,$2));
639 method(Object, "deserialize", Object) [
641 throw new «UnsupportedOperationException.name»("Direct invocation not supported.");
646 val rawRet = ctCls.toClassImpl(inputType.classLoader, inputType.protectionDomain)
647 val ret = rawRet as Class<? extends BindingCodec<Map<QName,Object>, Object>>;
648 listener?.onChoiceCodecCreated(inputType, ret, node);
649 log.debug("DOM Codec for {} was generated {}", inputType, ret)
651 } catch (Exception e) {
652 processException(inputType, e);
657 private def keyConstructorList(List<QName> qnames) {
658 val names = new TreeSet<String>()
659 for (name : qnames) {
660 val fieldName = name.getterName;
661 names.add(fieldName);
663 return Joiner.on(",").join(names);
666 private def serializeBodyFacade(GeneratedType type, SchemaNode node) {
667 val ret = serializeBody(type, node);
671 private def String deserializeBody(GeneratedType type, SchemaNode node) {
672 val ret = deserializeBodyImpl(type, node);
676 private def deserializeKey(GeneratedType type, ListSchemaNode node) {
677 if (node.keyDefinition != null && !node.keyDefinition.empty) {
679 «type.resolvedName»Key getKey = («type.resolvedName»Key) «keyTransformer(type, node).canonicalName».fromDomStatic(_localQName,_compositeNode);
680 _builder.setKey(getKey);
685 private def String deserializeBodyWithAugmentations(GeneratedType type, DataNodeContainer node) '''
687 «QName.name» _localQName = «QName.name».create($1,QNAME.getLocalName());
691 java.util.Map _compositeNode = (java.util.Map) $2;
692 //System.out.println(_localQName + " " + _compositeNode);
693 «type.builderName» _builder = new «type.builderName»();
694 «deserializeDataNodeContainerBody(type, node)»
695 «deserializeAugmentations»
696 return _builder.build();
700 private def dispatch String deserializeBodyImpl(GeneratedType type, SchemaNode node) '''
702 «QName.name» _localQName = «QName.name».create($1,QNAME.getLocalName());
707 java.util.Map _compositeNode = (java.util.Map) $2;
708 «type.builderName» _builder = new «type.builderName»();
709 return _builder.build();
713 private def dispatch String deserializeBodyImpl(GeneratedType type, ListSchemaNode node) '''
715 «QName.name» _localQName = «QName.name».create($1,QNAME.getLocalName());
719 java.util.Map _compositeNode = (java.util.Map) $2;
720 //System.out.println(_localQName + " " + _compositeNode);
721 «type.builderName» _builder = new «type.builderName»();
722 «deserializeKey(type, node)»
723 «deserializeDataNodeContainerBody(type, node)»
724 «deserializeAugmentations»
725 return _builder.build();
729 private def dispatch String deserializeBodyImpl(GeneratedType type, ContainerSchemaNode node) {
730 return deserializeBodyWithAugmentations(type, node);
733 private def dispatch String deserializeBodyImpl(GeneratedType type, NotificationDefinition node) {
734 return deserializeBodyWithAugmentations(type, node);
737 private def dispatch String deserializeBodyImpl(GeneratedType type, ChoiceCaseNode node) {
738 return deserializeBodyWithAugmentations(type, node);
741 private def deserializeDataNodeContainerBody(GeneratedType type, DataNodeContainer node) {
742 deserializeNodeContainerBodyImpl(type, type.allProperties, node);
745 private def deserializeNodeContainerBodyImpl(GeneratedType type, HashMap<String, Type> properties,
746 DataNodeContainer node) {
748 boolean _is_empty = true;
749 «FOR child : node.childNodes»
750 «val signature = properties.getFor(child)»
751 «IF signature !== null»
752 «deserializeProperty(child, signature.value, signature.key)»
753 _builder.«signature.key.toSetter»(«signature.key»);
760 def deserializeAugmentations() '''
761 java.util.Map _augmentation = (java.util.Map) «AUGMENTATION_CODEC».deserialize(_compositeNode);
762 if(_augmentation != null) {
763 «Iterator.name» _entries = _augmentation.entrySet().iterator();
764 while(_entries.hasNext()) {
765 java.util.Map.Entry _entry = (java.util.Map.Entry) _entries.next();
766 ////System.out.println("Aug. key:" + _entry.getKey());
767 Class _type = (Class) _entry.getKey();
768 «Augmentation.resolvedName» _value = («Augmentation.name») _entry.getValue();
770 _builder.addAugmentation(_type,_value);
776 private def dispatch CharSequence deserializeProperty(ListSchemaNode schema, ParameterizedType type,
777 String propertyName) '''
778 java.util.List _dom_«propertyName» = _compositeNode.get(«QName.name».create(_localQName,"«schema.QName.
780 ////System.out.println("«propertyName»#deCode"+_dom_«propertyName»);
781 java.util.List «propertyName» = new java.util.ArrayList();
782 if(_dom_«propertyName» != null) {
783 java.util.List _serialized = new java.util.ArrayList();
784 java.util.Iterator _iterator = _dom_«propertyName».iterator();
785 boolean _hasNext = _iterator.hasNext();
787 Object _listItem = _iterator.next();
789 ////System.out.println(" item" + _listItem);
790 Object _value = «type.actualTypeArguments.get(0).serializer(schema).resolvedName».fromDomStatic(_localQName,_listItem);
791 ////System.out.println(" value" + _value);
792 «propertyName».add(_value);
793 _hasNext = _iterator.hasNext();
797 ////System.out.println(" list" + «propertyName»);
800 private def dispatch CharSequence deserializeProperty(LeafListSchemaNode schema, ParameterizedType type,
801 String propertyName) '''
802 java.util.List _dom_«propertyName» = _compositeNode.get(«QName.name».create(_localQName,"«schema.QName.
804 java.util.List «propertyName» = new java.util.ArrayList();
805 if(_dom_«propertyName» != null) {
806 java.util.List _serialized = new java.util.ArrayList();
807 java.util.Iterator _iterator = _dom_«propertyName».iterator();
808 boolean _hasNext = _iterator.hasNext();
811 Object _listItem = _iterator.next();
812 if(_listItem instanceof java.util.Map.Entry) {
813 Object _innerValue = ((java.util.Map.Entry) _listItem).getValue();
814 Object _value = «deserializeValue(type.actualTypeArguments.get(0), "_innerValue", schema.type)»;
815 «propertyName».add(_value);
817 _hasNext = _iterator.hasNext();
822 private def dispatch CharSequence deserializeProperty(LeafSchemaNode schema, Type type, String propertyName) '''
823 java.util.List _dom_«propertyName»_list =
824 _compositeNode.get(«QName.name».create(_localQName,"«schema.QName.localName»"));
825 «type.resolvedName» «propertyName» = null;
826 if(_dom_«propertyName»_list != null && _dom_«propertyName»_list.size() > 0) {
828 java.util.Map.Entry _dom_«propertyName» = (java.util.Map.Entry) _dom_«propertyName»_list.get(0);
829 Object _inner_value = _dom_«propertyName».getValue();
830 «propertyName» = «deserializeValue(type, "_inner_value", schema.type)»;
834 private def dispatch CharSequence deserializeProperty(ContainerSchemaNode schema, Type type,
835 String propertyName) '''
836 java.util.List _dom_«propertyName»_list =
837 _compositeNode.get(«QName.name».create(_localQName,"«schema.QName.localName»"));
838 «type.resolvedName» «propertyName» = null;
839 if(_dom_«propertyName»_list != null && _dom_«propertyName»_list.size() > 0) {
841 java.util.Map _dom_«propertyName» = (java.util.Map) _dom_«propertyName»_list.get(0);
842 «propertyName» = «type.serializer(schema).resolvedName».fromDomStatic(_localQName,_dom_«propertyName»);
846 private def dispatch CharSequence deserializeProperty(ChoiceNode schema, Type type, String propertyName) '''
847 «type.resolvedName» «propertyName» = «type.serializer(schema).resolvedName».fromDomStatic(_localQName,_compositeNode);
848 if(«propertyName» != null) {
853 private def dispatch String deserializeValue(GeneratedTransferObject type, String domParameter,
854 TypeDefinition<?> typeDefinition) '''
855 («type.resolvedName») «type.valueSerializer(typeDefinition).resolvedName».fromDomValue(«domParameter»)
858 private def dispatch String deserializeValue(Enumeration type, String domParameter, TypeDefinition<?> typeDefinition) '''
859 («type.resolvedName») «type.valueSerializer(typeDefinition).resolvedName».fromDomValue(«domParameter»)
862 private def dispatch Class<? extends BindingCodec<Map<QName, Object>, Object>> generateValueTransformer(
863 Class<?> inputType, GeneratedTransferObject typeSpec, TypeDefinition<?> typeDef) {
866 val returnType = typeSpec.valueReturnType;
867 if (returnType == null) {
868 val ctCls = createDummyImplementation(inputType, typeSpec);
869 val ret = ctCls.toClassImpl(inputType.classLoader, inputType.protectionDomain)
870 return ret as Class<? extends BindingCodec<Map<QName,Object>, Object>>;
873 val ctCls = createClass(typeSpec.codecClassName) [
874 //staticField(Map,"AUGMENTATION_SERIALIZERS");
875 if (inputType.isYangBindingAvailable) {
876 implementsType(BINDING_CODEC)
877 staticField(it, INSTANCE_IDENTIFIER_CODEC, BindingCodec)
878 staticField(it, IDENTITYREF_CODEC, BindingCodec)
879 implementsType(BindingDeserializer.asCtClass)
881 method(Object, "toDomValue", Object) [
882 modifiers = PUBLIC + FINAL + STATIC
883 val ctSpec = typeSpec.asCtClass;
886 ////System.out.println("«inputType.simpleName»#toDomValue: "+$1);
891 «typeSpec.resolvedName» _encapsulatedValue = («typeSpec.resolvedName») $1;
892 ////System.out.println("«inputType.simpleName»#toDomValue:Enc: "+_encapsulatedValue);
893 «returnType.resolvedName» _value = _encapsulatedValue.getValue();
894 ////System.out.println("«inputType.simpleName»#toDomValue:DeEnc: "+_value);
895 Object _domValue = «serializeValue(returnType, "_value", null)»;
900 method(Object, "serialize", Object) [
903 return toDomValue($1);
907 method(Object, "fromDomValue", Object) [
908 modifiers = PUBLIC + FINAL + STATIC
911 ////System.out.println("«inputType.simpleName»#fromDomValue: "+$1);
916 «returnType.resolvedName» _simpleValue = «deserializeValue(returnType, "$1", null)»;
917 «typeSpec.resolvedName» _value = new «typeSpec.resolvedName»(_simpleValue);
922 method(Object, "deserialize", Object) [
924 return fromDomValue($1);
930 val ret = ctCls.toClassImpl(inputType.classLoader, inputType.protectionDomain)
931 log.debug("DOM Codec for {} was generated {}", inputType, ret)
932 return ret as Class<? extends BindingCodec<Map<QName,Object>, Object>>;
933 } catch (Exception e) {
934 log.error("Cannot compile DOM Codec for {}", inputType, e);
935 val exception = new CodeGenerationException("Cannot compile Transformator for " + inputType);
936 exception.addSuppressed(e);
941 private def dispatch Class<? extends BindingCodec<Map<QName, Object>, Object>> generateValueTransformer(
942 Class<?> inputType, GeneratedTransferObject typeSpec, UnionTypeDefinition typeDef) {
944 val ctCls = createClass(typeSpec.codecClassName) [
945 val properties = typeSpec.allProperties;
946 val getterToTypeDefinition = XtendHelper.getTypes(typeDef).toMap[type|type.QName.getterName];
947 //staticField(Map,"AUGMENTATION_SERIALIZERS");
948 if (inputType.isYangBindingAvailable) {
949 implementsType(BINDING_CODEC)
950 staticField(it, INSTANCE_IDENTIFIER_CODEC, BindingCodec)
951 staticField(it, IDENTITYREF_CODEC, BindingCodec)
952 implementsType(BindingDeserializer.asCtClass)
954 method(Object, "toDomValue", Object) [
955 modifiers = PUBLIC + FINAL + STATIC
956 val ctSpec = inputType.asCtClass;
959 ////System.out.println("«inputType.simpleName»#toDomValue: "+$1);
964 «typeSpec.resolvedName» _value = («typeSpec.resolvedName») $1;
965 «FOR property : properties.entrySet»
966 «IF property.key != "getValue"»
967 «property.value.resolvedName» «property.key» = («property.value.resolvedName») _value.«property.
969 if(«property.key» != null) {
970 return «serializeValue(property.value, property.key,
971 getterToTypeDefinition.get(property.key))»;
980 method(Object, "serialize", Object) [
983 return toDomValue($1);
987 method(Object, "fromDomValue", Object) [
988 modifiers = PUBLIC + FINAL + STATIC
991 ////System.out.println("«inputType.simpleName»#fromDomValue: "+$1);
996 if($1 instanceof String) {
997 String _simpleValue = (String) $1;
998 return new «typeSpec.resolvedName»(_simpleValue.toCharArray());
1004 method(Object, "deserialize", Object) [
1006 return fromDomValue($1);
1012 val ret = ctCls.toClassImpl(inputType.classLoader, inputType.protectionDomain)
1013 log.debug("DOM Codec for {} was generated {}", inputType, ret)
1014 return ret as Class<? extends BindingCodec<Map<QName,Object>, Object>>;
1015 } catch (Exception e) {
1016 log.error("Cannot compile DOM Codec for {}", inputType, e);
1017 val exception = new CodeGenerationException("Cannot compile Transformator for " + inputType);
1018 exception.addSuppressed(e);
1023 private def dispatch Class<? extends BindingCodec<Map<QName, Object>, Object>> generateValueTransformer(
1024 Class<?> inputType, GeneratedTransferObject typeSpec, BitsTypeDefinition typeDef) {
1026 val ctCls = createClass(typeSpec.codecClassName) [
1027 //staticField(Map,"AUGMENTATION_SERIALIZERS");
1028 if (inputType.isYangBindingAvailable) {
1029 implementsType(BINDING_CODEC)
1030 staticField(it, INSTANCE_IDENTIFIER_CODEC, BindingCodec)
1031 staticField(it, IDENTITYREF_CODEC, BindingCodec)
1032 implementsType(BindingDeserializer.asCtClass)
1034 method(Object, "toDomValue", Object) [
1035 modifiers = PUBLIC + FINAL + STATIC
1036 val ctSpec = typeSpec.asCtClass;
1039 ////System.out.println("«inputType.simpleName»#toDomValue: "+$1);
1044 «typeSpec.resolvedName» _encapsulatedValue = («typeSpec.resolvedName») $1;
1045 «HashSet.resolvedName» _value = new «HashSet.resolvedName»();
1046 //System.out.println("«inputType.simpleName»#toDomValue:Enc: "+_encapsulatedValue);
1048 «FOR bit : typeDef.bits»
1049 «val getter = bit.getterName()»
1050 if(Boolean.TRUE.equals(_encapsulatedValue.«getter»())) {
1051 _value.add("«bit.name»");
1054 «Set.resolvedName» _domValue = «Collections.resolvedName».unmodifiableSet(_value);
1055 //System.out.println("«inputType.simpleName»#toDomValue:DeEnc: "+_domValue);
1061 method(Object, "serialize", Object) [
1064 return toDomValue($1);
1068 method(Object, "fromDomValue", Object) [
1069 modifiers = PUBLIC + FINAL + STATIC
1070 val sortedBits = typeDef.bits.sort[o1, o2|o1.propertyName.compareTo(o2.propertyName)]
1073 //System.out.println("«inputType.simpleName»#fromDomValue: "+$1);
1078 «Set.resolvedName» _domValue = («Set.resolvedName») $1;
1079 «FOR bit : sortedBits»
1080 Boolean «bit.propertyName» = Boolean.valueOf(_domValue.contains("«bit.name»"));
1083 return new «inputType.resolvedName»(«FOR bit : sortedBits SEPARATOR ","»«bit.propertyName»«ENDFOR»);
1087 method(Object, "deserialize", Object) [
1089 return fromDomValue($1);
1095 val ret = ctCls.toClassImpl(inputType.classLoader, inputType.protectionDomain)
1096 log.debug("DOM Codec for {} was generated {}", inputType, ret)
1097 return ret as Class<? extends BindingCodec<Map<QName,Object>, Object>>;
1098 } catch (Exception e) {
1099 log.error("Cannot compile DOM Codec for {}", inputType, e);
1100 val exception = new CodeGenerationException("Cannot compile Transformator for " + inputType);
1101 exception.addSuppressed(e);
1106 def String getPropertyName(Bit bit) {
1107 '''_«BindingGeneratorUtil.parseToValidParamName(bit.name)»'''
1110 def String getterName(Bit bit) {
1112 val paramName = BindingGeneratorUtil.parseToValidParamName(bit.name);
1113 return '''is«paramName.toFirstUpper»''';
1116 def boolean isYangBindingAvailable(Class<?> class1) {
1118 val bindingCodecClass = class1.classLoader.loadClass(BINDING_CODEC.name);
1119 return bindingCodecClass !== null;
1120 } catch (ClassNotFoundException e) {
1125 private def createDummyImplementation(Class<?> object, GeneratedTransferObject typeSpec) {
1126 log.trace("Generating Dummy DOM Codec for {} with {}", object, object.classLoader)
1127 return createClass(typeSpec.codecClassName) [
1128 if (object.isYangBindingAvailable) {
1129 implementsType(BINDING_CODEC)
1130 staticField(it, INSTANCE_IDENTIFIER_CODEC, BindingCodec)
1131 staticField(it, IDENTITYREF_CODEC, BindingCodec)
1132 implementsType(BindingDeserializer.asCtClass)
1134 //implementsType(BindingDeserializer.asCtClass)
1135 method(Object, "toDomValue", Object) [
1136 modifiers = PUBLIC + FINAL + STATIC
1141 return $1.toString();
1145 method(Object, "serialize", Object) [
1148 return toDomValue($1);
1152 method(Object, "fromDomValue", Object) [
1153 modifiers = PUBLIC + FINAL + STATIC
1154 bodyChecked = '''return null;'''
1156 method(Object, "deserialize", Object) [
1158 return fromDomValue($1);
1165 private def Type getValueReturnType(GeneratedTransferObject object) {
1166 for (prop : object.properties) {
1167 if (prop.name == "value") {
1168 return prop.returnType;
1171 if (object.superType != null) {
1172 return getValueReturnType(object.superType);
1177 private def Class<?> generateValueTransformer(Class<?> inputType, Enumeration typeSpec) {
1179 val typeRef = new ReferencedTypeImpl(typeSpec.packageName, typeSpec.name);
1180 val schema = typeToSchemaNode.get(typeRef) as ExtendedType;
1181 val enumSchema = schema.baseType as EnumerationType;
1183 //log.info("Generating DOM Codec for {} with {}", inputType, inputType.classLoader)
1184 val ctCls = createClass(typeSpec.codecClassName) [
1185 //staticField(Map,"AUGMENTATION_SERIALIZERS");
1186 //implementsType(BINDING_CODEC)
1187 method(Object, "toDomValue", Object) [
1188 modifiers = PUBLIC + FINAL + STATIC
1193 «typeSpec.resolvedName» _value = («typeSpec.resolvedName») $1;
1194 «FOR en : enumSchema.values»
1195 if(«typeSpec.resolvedName».«BindingGeneratorUtil.parseToClassName(en.name)».equals(_value)) {
1203 method(Object, "serialize", Object) [
1205 return toDomValue($1);
1208 method(Object, "fromDomValue", Object) [
1209 modifiers = PUBLIC + FINAL + STATIC
1215 String _value = (String) $1;
1216 «FOR en : enumSchema.values»
1217 if("«en.name»".equals(_value)) {
1218 return «typeSpec.resolvedName».«BindingGeneratorUtil.parseToClassName(en.name)»;
1225 method(Object, "deserialize", Object) [
1227 return fromDomValue($1);
1232 val ret = ctCls.toClassImpl(inputType.classLoader, inputType.protectionDomain)
1233 log.debug("DOM Codec for {} was generated {}", inputType, ret)
1235 } catch (CodeGenerationException e) {
1236 throw new CodeGenerationException("Cannot compile Transformator for " + inputType, e);
1237 } catch (Exception e) {
1238 log.error("Cannot compile DOM Codec for {}", inputType, e);
1239 val exception = new CodeGenerationException("Cannot compile Transformator for " + inputType);
1240 exception.addSuppressed(e);
1246 def Class<?> toClassImpl(CtClass newClass, ClassLoader loader, ProtectionDomain domain) {
1247 val cls = newClass.toClass(loader, domain);
1248 if (classFileCapturePath !== null) {
1249 newClass.writeFile(classFileCapturePath.absolutePath);
1251 listener?.onCodecCreated(cls);
1255 def debugWriteClass(CtClass class1) {
1256 val path = class1.name.replace(".", "/") + ".class"
1258 val captureFile = new File(classFileCapturePath, path);
1259 captureFile.createNewFile
1263 private def dispatch String deserializeValue(Type type, String domParameter, TypeDefinition<?> typeDef) {
1264 if (INSTANCE_IDENTIFIER.equals(type)) {
1265 return '''(«InstanceIdentifier.name») «INSTANCE_IDENTIFIER_CODEC».deserialize(«domParameter»)'''
1266 } else if (CLASS_TYPE.equals(type)) {
1267 return '''(«Class.name») «IDENTITYREF_CODEC».deserialize(«domParameter»)'''
1269 return '''(«type.resolvedName») «domParameter»'''
1277 private def dispatch CharSequence deserializeProperty(DataSchemaNode container, Type type, String propertyName) '''
1278 «type.resolvedName» «propertyName» = null;
1281 private def dispatch CharSequence deserializeProperty(DataSchemaNode container, GeneratedTypeBuilder type,
1282 String propertyName) {
1283 _deserializeProperty(container, type.toInstance, propertyName)
1286 public static def toSetter(String it) {
1288 if (startsWith("is")) {
1289 return "set" + substring(2);
1290 } else if (startsWith("get")) {
1291 return "set" + substring(3);
1297 private def dispatch CharSequence deserializeProperty(DataSchemaNode container,GeneratedType type, String propertyName) '''
1298 «type.resolvedName» «propertyName» = value.«propertyName»();
1299 if(«propertyName» != null) {
1300 Object domValue = «type.serializer».toDomStatic(QNAME,«propertyName»);
1301 _childNodes.add(domValue);
1305 private def getBuilderName(GeneratedType type) '''«type.resolvedName»Builder'''
1307 private def staticQNameField(CtClass it, QName node) {
1308 val field = new CtField(ctQName, "QNAME", it);
1309 field.modifiers = PUBLIC + FINAL + STATIC;
1311 '''«QName.asCtClass.name».create("«node.namespace»","«node.formattedRevision»","«node.localName»")''')
1314 private def String serializeBodyImpl(GeneratedType type, DataNodeContainer nodeContainer) '''
1316 «QName.name» _resultName = «QName.name».create($1,QNAME.getLocalName());
1317 java.util.List _childNodes = new java.util.ArrayList();
1318 «type.resolvedName» value = («type.resolvedName») $2;
1319 «transformDataContainerBody(type, type.allProperties, nodeContainer)»
1320 «serializeAugmentations»
1321 return ($r) java.util.Collections.singletonMap(_resultName,_childNodes);
1325 private def dispatch String serializeBody(GeneratedType type, ListSchemaNode node) {
1326 return serializeBodyImpl(type, node);
1329 private def dispatch String serializeBody(GeneratedType type, NotificationDefinition node) {
1330 return serializeBodyImpl(type, node);
1333 private def dispatch String serializeBody(GeneratedType type, ContainerSchemaNode node) {
1334 return serializeBodyImpl(type, node);
1337 private def dispatch String serializeBody(GeneratedType type, ChoiceCaseNode node) {
1338 return serializeBodyImpl(type, node);
1341 private def dispatch String serializeBody(GeneratedType type, SchemaNode node) '''
1343 «QName.name» _resultName = «QName.name».create($1,QNAME.getLocalName());
1344 java.util.List _childNodes = new java.util.ArrayList();
1345 «type.resolvedName» value = («type.resolvedName») $2;
1346 return ($r) java.util.Collections.singletonMap(_resultName,_childNodes);
1350 private def transformDataContainerBody(Type type, Map<String, Type> properties, DataNodeContainer node) {
1352 «FOR child : node.childNodes»
1353 «val signature = properties.getFor(child)»
1354 «IF signature !== null»
1355 ////System.out.println("«type.name»#«signature.key»" + value.«signature.key»());
1356 «serializeProperty(child, signature.value, signature.key)»
1363 private def serializeAugmentations() '''
1364 java.util.List _augmentations = (java.util.List) «AUGMENTATION_CODEC».serialize(value);
1365 if(_augmentations != null) {
1366 _childNodes.addAll(_augmentations);
1370 def Entry<String, Type> getFor(Map<String, Type> map, DataSchemaNode node) {
1371 var sig = map.get(node.getterName);
1373 return new SimpleEntry(node.getterName, sig);
1375 sig = map.get(node.booleanGetterName);
1377 return new SimpleEntry(node.booleanGetterName, map.get(node.booleanGetterName));
1382 private static def String getBooleanGetterName(DataSchemaNode node) {
1383 return "is" + BindingMapping.getPropertyName(node.QName.localName).toFirstUpper;
1386 private static def String getGetterName(DataSchemaNode node) {
1387 return "get" + BindingMapping.getPropertyName(node.QName.localName).toFirstUpper;
1390 private static def String getGetterName(QName node) {
1391 return "get" + BindingMapping.getPropertyName(node.localName).toFirstUpper;
1394 private def dispatch CharSequence serializeProperty(ListSchemaNode schema, ParameterizedType type,
1395 String propertyName) '''
1396 «type.resolvedName» «propertyName» = value.«propertyName»();
1397 ////System.out.println("«propertyName»:" + «propertyName»);
1398 if(«propertyName» != null) {
1399 java.util.Iterator _iterator = «propertyName».iterator();
1400 boolean _hasNext = _iterator.hasNext();
1402 Object _listItem = _iterator.next();
1403 Object _domValue = «type.actualTypeArguments.get(0).serializer(schema).resolvedName».toDomStatic(_resultName,_listItem);
1404 _childNodes.add(_domValue);
1405 _hasNext = _iterator.hasNext();
1410 private def dispatch CharSequence serializeProperty(LeafSchemaNode schema, Type type, String propertyName) '''
1411 «type.resolvedName» «propertyName» = value.«propertyName»();
1413 if(«propertyName» != null) {
1414 «QName.name» _qname = «QName.name».create(_resultName,"«schema.QName.localName»");
1415 Object _propValue = «serializeValue(type, propertyName, schema.type)»;
1416 if(_propValue != null) {
1417 Object _domValue = java.util.Collections.singletonMap(_qname,_propValue);
1418 _childNodes.add(_domValue);
1423 private def dispatch serializeValue(GeneratedTransferObject type, String parameter, TypeDefinition<?> typeDefinition) {
1424 '''«type.valueSerializer(typeDefinition).resolvedName».toDomValue(«parameter»)'''
1427 private def dispatch serializeValue(Enumeration type, String parameter, TypeDefinition<?> typeDefinition) {
1428 '''«type.valueSerializer(typeDefinition).resolvedName».toDomValue(«parameter»)'''
1431 private def dispatch serializeValue(Type signature, String property, TypeDefinition<?> typeDefinition) {
1432 if (INSTANCE_IDENTIFIER == signature) {
1433 return '''«INSTANCE_IDENTIFIER_CODEC».serialize(«property»)'''
1434 } else if (CLASS_TYPE.equals(signature)) {
1435 return '''(«QName.resolvedName») «IDENTITYREF_CODEC».serialize(«property»)'''
1437 if ("char[]" == signature.name) {
1438 return '''new String(«property»)''';
1440 return '''«property»''';
1443 private def dispatch CharSequence serializeProperty(LeafListSchemaNode schema, ParameterizedType type,
1444 String propertyName) '''
1445 «type.resolvedName» «propertyName» = value.«propertyName»();
1446 if(«propertyName» != null) {
1447 «QName.name» _qname = «QName.name».create(_resultName,"«schema.QName.localName»");
1448 java.util.Iterator _iterator = «propertyName».iterator();
1449 boolean _hasNext = _iterator.hasNext();
1451 Object _listItem = _iterator.next();
1452 Object _propValue = «serializeValue(type.actualTypeArguments.get(0), "_listItem", schema.type)»;
1453 Object _domValue = java.util.Collections.singletonMap(_qname,_propValue);
1454 _childNodes.add(_domValue);
1455 _hasNext = _iterator.hasNext();
1460 private def dispatch CharSequence serializeProperty(ChoiceNode container, GeneratedType type,
1461 String propertyName) '''
1462 «type.resolvedName» «propertyName» = value.«propertyName»();
1463 if(«propertyName» != null) {
1464 java.util.List domValue = «type.serializer(container).resolvedName».toDomStatic(_resultName,«propertyName»);
1465 _childNodes.addAll(domValue);
1473 private def dispatch CharSequence serializeProperty(DataSchemaNode container, Type type, String propertyName) '''
1474 «type.resolvedName» «propertyName» = value.«propertyName»();
1475 if(«propertyName» != null) {
1476 Object domValue = «propertyName»;
1477 _childNodes.add(domValue);
1481 private def dispatch CharSequence serializeProperty(DataSchemaNode container, GeneratedTypeBuilder type,
1482 String propertyName) {
1483 serializeProperty(container, type.toInstance, propertyName)
1486 private def dispatch CharSequence serializeProperty(DataSchemaNode container, GeneratedType type,
1487 String propertyName) '''
1488 «type.resolvedName» «propertyName» = value.«propertyName»();
1489 if(«propertyName» != null) {
1490 Object domValue = «type.serializer(container).resolvedName».toDomStatic(_resultName,«propertyName»);
1491 _childNodes.add(domValue);
1495 private def codecClassName(GeneratedType typeSpec) {
1496 return '''«typeSpec.resolvedName»$Broker$Codec$DOM'''
1499 private def codecClassName(Class<?> typeSpec) {
1500 return '''«typeSpec.name»$Broker$Codec$DOM'''
1503 private def HashMap<String, Type> getAllProperties(GeneratedType type) {
1504 val ret = new HashMap<String, Type>();
1505 type.collectAllProperties(ret);
1509 private def dispatch void collectAllProperties(GeneratedType type, Map<String, Type> set) {
1510 for (definition : type.methodDefinitions) {
1511 set.put(definition.name, definition.returnType);
1513 for (property : type.properties) {
1514 set.put(property.getterName, property.returnType);
1516 for (parent : type.implements) {
1517 parent.collectAllProperties(set);
1521 def String getGetterName(GeneratedProperty property) {
1522 return "get" + property.name.toFirstUpper
1525 private def dispatch void collectAllProperties(Type type, Map<String, Type> set) {
1526 // NOOP for generic type.
1529 def String getResolvedName(Type type) {
1530 return type.asCtClass.name;
1533 def String getResolvedName(Class<?> type) {
1534 return type.asCtClass.name;
1537 def CtClass asCtClass(Type type) {
1538 val cls = loadClass(type.fullyQualifiedName)
1539 return cls.asCtClass;
1542 private def dispatch processException(Class<?> inputType, CodeGenerationException e) {
1543 log.error("Cannot compile DOM Codec for {}. One of it's prerequisites was not generated.", inputType);
1547 private def dispatch processException(Class<?> inputType, Exception e) {
1548 log.error("Cannot compile DOM Codec for {}", inputType, e);
1549 val exception = new CodeGenerationException("Cannot compile Transformator for " + inputType, e);
1553 private def setBodyChecked(CtMethod method, String body) {
1555 method.setBody(body);
1556 } catch (CannotCompileException e) {
1557 log.error("Cannot compile method: {}#{} {}, Reason: {} Body: {}", method.declaringClass, method.name,
1558 method.signature, e.message, body)
1563 private def <V> V withClassLoaderAndLock(ClassLoader cls, Lock lock, Callable<V> function) throws Exception {
1564 appendClassLoaderIfMissing(cls);
1565 ClassLoaderUtils.withClassLoaderAndLock(cls, lock, function);
1571 class PropertyPair {
1580 SchemaNode schemaNode;