2 * Copyright (c) 2014 Cisco Systems, Inc. and others. All rights reserved.
4 * This program and the accompanying materials are made available under the
5 * terms of the Eclipse Public License v1.0 which accompanies this distribution,
6 * and is available at http://www.eclipse.org/legal/epl-v10.html
8 package org.opendaylight.yangtools.sal.binding.generator.impl
10 import javassist.ClassPool
11 import org.opendaylight.yangtools.sal.binding.model.api.GeneratedType
12 import org.opendaylight.yangtools.yang.model.api.SchemaNode
13 import org.opendaylight.yangtools.sal.binding.generator.util.JavassistUtils
14 import javassist.CtClass
16 import org.opendaylight.yangtools.yang.common.QName
17 import javassist.CtField
18 import static javassist.Modifier.*
19 import static org.opendaylight.yangtools.sal.binding.generator.impl.CodecMapping.*
20 import org.opendaylight.yangtools.yang.model.api.ContainerSchemaNode
21 import org.opendaylight.yangtools.yang.model.api.ListSchemaNode
22 import org.opendaylight.yangtools.yang.model.api.DataNodeContainer
23 import org.opendaylight.yangtools.sal.binding.model.api.Type
24 import org.opendaylight.yangtools.sal.binding.model.api.type.builder.GeneratedTypeBuilder
25 import org.opendaylight.yangtools.binding.generator.util.Types
26 import org.opendaylight.yangtools.sal.binding.model.api.ParameterizedType
27 import java.util.HashMap
28 import org.opendaylight.yangtools.yang.model.api.DataSchemaNode
29 import org.opendaylight.yangtools.binding.generator.util.BindingGeneratorUtil
30 import org.opendaylight.yangtools.yang.model.api.LeafSchemaNode
31 import org.opendaylight.yangtools.yang.model.api.LeafListSchemaNode
33 import java.util.TreeSet
34 import com.google.common.base.Joiner
35 import org.opendaylight.yangtools.sal.binding.model.api.GeneratedTransferObject
36 import org.opendaylight.yangtools.sal.binding.model.api.Enumeration
37 import org.opendaylight.yangtools.yang.model.api.ChoiceCaseNode
38 import static org.opendaylight.yangtools.sal.binding.generator.util.ClassLoaderUtils.*;
39 import org.opendaylight.yangtools.yang.binding.BindingDeserializer
40 import org.opendaylight.yangtools.yang.binding.BindingCodec
41 import org.slf4j.LoggerFactory
42 import org.opendaylight.yangtools.sal.binding.generator.util.CodeGenerationException
43 import org.opendaylight.yangtools.yang.model.api.ChoiceNode
44 import java.security.ProtectionDomain
46 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier
47 import org.opendaylight.yangtools.sal.binding.model.api.GeneratedProperty
48 import java.util.Map.Entry
49 import java.util.AbstractMap.SimpleEntry
50 import org.opendaylight.yangtools.yang.binding.DataObject
51 import org.opendaylight.yangtools.yang.binding.Augmentation
52 import java.util.Iterator
53 import org.opendaylight.yangtools.yang.model.api.AugmentationSchema
54 import java.util.concurrent.ConcurrentHashMap
55 import static extension org.opendaylight.yangtools.sal.binding.generator.util.YangSchemaUtils.*;
56 import org.opendaylight.yangtools.binding.generator.util.ReferencedTypeImpl
57 import org.opendaylight.yangtools.yang.model.util.ExtendedType
58 import org.opendaylight.yangtools.yang.model.util.EnumerationType
59 import static com.google.common.base.Preconditions.*
60 import org.opendaylight.yangtools.yang.model.api.SchemaPath
61 import javassist.CtMethod
62 import javassist.CannotCompileException
63 import java.util.concurrent.locks.Lock
64 import java.util.concurrent.Callable
65 import org.opendaylight.yangtools.sal.binding.generator.util.ClassLoaderUtils
66 import org.opendaylight.yangtools.yang.model.api.TypeDefinition
67 import org.opendaylight.yangtools.yang.model.api.type.UnionTypeDefinition
68 import org.opendaylight.yangtools.yang.model.api.type.BitsTypeDefinition
69 import java.util.HashSet
70 import java.util.Collections
71 import org.opendaylight.yangtools.yang.model.api.type.BitsTypeDefinition.Bit
73 import org.opendaylight.yangtools.sal.binding.generator.util.XtendHelper
74 import org.opendaylight.yangtools.yang.model.api.NotificationDefinition
76 class TransformerGenerator {
78 private static val log = LoggerFactory.getLogger(TransformerGenerator)
80 public static val STRING = Types.typeForClass(String);
81 public static val BOOLEAN = Types.typeForClass(Boolean);
82 public static val INTEGER = Types.typeForClass(Integer);
83 public static val INSTANCE_IDENTIFIER = Types.typeForClass(InstanceIdentifier)
85 //public static val DECIMAL = Types.typeForClass(Decimal);
86 public static val LONG = Types.typeForClass(Long);
88 val ClassPool classPool
89 val extension JavassistUtils utils;
96 var File classFileCapturePath;
99 var Map<Type, Type> typeDefinitions = new ConcurrentHashMap();
102 var Map<Type, GeneratedTypeBuilder> typeToDefinition = new ConcurrentHashMap();
105 var Map<SchemaPath, GeneratedTypeBuilder> pathToType = new ConcurrentHashMap();
108 var Map<Type, SchemaNode> typeToSchemaNode = new ConcurrentHashMap();
111 var Map<Type, AugmentationSchema> typeToAugmentation = new ConcurrentHashMap();
114 var GeneratorListener listener;
117 var extension GeneratedClassLoadingStrategy classLoadingStrategy
119 public static val CLASS_TYPE = Types.typeForClass(Class);
121 public new(ClassPool pool) {
123 utils = new JavassistUtils(pool)
125 BINDING_CODEC = BindingCodec.asCtClass;
126 ctQName = QName.asCtClass
128 classLoadingStrategy = GeneratedClassLoadingStrategy.TCCLClassLoadingStrategy;
131 def Class<? extends BindingCodec<Map<QName, Object>, Object>> transformerFor(Class<?> inputType) {
132 return withClassLoaderAndLock(inputType.classLoader, lock) [ |
133 val ret = getGeneratedClass(inputType)
135 listener.onClassProcessed(inputType);
136 return ret as Class<? extends BindingCodec<Map<QName,Object>, Object>>;
138 val ref = Types.typeForClass(inputType)
139 val node = typeToSchemaNode.get(ref)
140 val typeSpecBuilder = typeToDefinition.get(ref)
141 checkState(typeSpecBuilder !== null, "Could not find typedefinition for %s", inputType.name);
142 val typeSpec = typeSpecBuilder.toInstance();
143 val newret = generateTransformerFor(inputType, typeSpec, node);
144 listener.onClassProcessed(inputType);
145 return newret as Class<? extends BindingCodec<Map<QName,Object>, Object>>;
149 def Class<? extends BindingCodec<Map<QName, Object>, Object>> transformerFor(Class<?> inputType, DataSchemaNode node) {
150 return withClassLoaderAndLock(inputType.classLoader, lock) [ |
151 val ret = getGeneratedClass(inputType)
153 listener.onClassProcessed(inputType);
154 return ret as Class<? extends BindingCodec<Map<QName,Object>, Object>>;
156 val ref = Types.typeForClass(inputType)
157 var typeSpecBuilder = typeToDefinition.get(ref)
158 if (typeSpecBuilder == null) {
159 typeSpecBuilder = pathToType.get(node.path);
161 var schemaNode = typeToSchemaNode.get(ref);
162 if (schemaNode === null) {
165 checkState(typeSpecBuilder !== null, "Could not find TypeDefinition for %s, $s", inputType.name, node);
166 val typeSpec = typeSpecBuilder.toInstance();
167 val newret = generateTransformerFor(inputType, typeSpec, schemaNode);
168 listener.onClassProcessed(inputType);
169 return newret as Class<? extends BindingCodec<Map<QName,Object>, Object>>;
173 def Class<? extends BindingCodec<Map<QName, Object>, Object>> augmentationTransformerFor(Class<?> inputType) {
174 return withClassLoaderAndLock(inputType.classLoader, lock) [ |
175 val ret = getGeneratedClass(inputType)
177 return ret as Class<? extends BindingCodec<Map<QName,Object>, Object>>;
179 val ref = Types.typeForClass(inputType)
180 val node = typeToAugmentation.get(ref)
181 val typeSpecBuilder = typeToDefinition.get(ref)
182 val typeSpec = typeSpecBuilder.toInstance();
183 val newret = generateAugmentationTransformerFor(inputType, typeSpec, node);
184 listener.onClassProcessed(inputType);
185 return newret as Class<? extends BindingCodec<Map<QName,Object>, Object>>;
189 def Class<? extends BindingCodec<Object, Object>> caseCodecFor(Class<?> inputType, ChoiceCaseNode node) {
190 return withClassLoaderAndLock(inputType.classLoader, lock) [ |
191 val ret = getGeneratedClass(inputType)
193 return ret as Class<? extends BindingCodec<Object, Object>>;
195 val ref = Types.typeForClass(inputType)
196 val typeSpecBuilder = typeToDefinition.get(ref)
197 val typeSpec = typeSpecBuilder.toInstance();
198 val newret = generateCaseCodec(inputType, typeSpec, node);
199 return newret as Class<? extends BindingCodec<Object, Object>>;
203 def Class<? extends BindingCodec<Map<QName, Object>, Object>> keyTransformerForIdentifiable(Class<?> parentType) {
204 return withClassLoaderAndLock(parentType.classLoader, lock) [ |
205 val inputName = parentType.name + "Key";
206 val inputType = loadClass(inputName);
207 val ret = getGeneratedClass(inputType)
209 return ret as Class<? extends BindingCodec<Map<QName,Object>, Object>>;
211 val ref = Types.typeForClass(parentType)
212 val node = typeToSchemaNode.get(ref) as ListSchemaNode
213 val typeSpecBuilder = typeToDefinition.get(ref)
214 val typeSpec = typeSpecBuilder.identifierDefinition;
215 val newret = generateKeyTransformerFor(inputType, typeSpec, node);
216 return newret as Class<? extends BindingCodec<Map<QName,Object>, Object>>;
220 def getIdentifierDefinition(GeneratedTypeBuilder builder) {
221 val inst = builder.toInstance
222 val keyMethod = inst.methodDefinitions.findFirst[name == "getKey"]
223 return keyMethod.returnType as GeneratedTransferObject
226 def Class<? extends BindingCodec<Map<QName, Object>, Object>> keyTransformerForIdentifier(Class<?> inputType) {
227 return withClassLoaderAndLock(inputType.classLoader, lock) [ |
228 val ret = getGeneratedClass(inputType)
230 return ret as Class<? extends BindingCodec<Map<QName,Object>, Object>>;
232 val ref = Types.typeForClass(inputType)
233 val node = typeToSchemaNode.get(ref) as ListSchemaNode
234 val typeSpecBuilder = typeToDefinition.get(ref)
235 val typeSpec = typeSpecBuilder.toInstance();
236 val newret = generateKeyTransformerFor(inputType, typeSpec, node);
237 return newret as Class<? extends BindingCodec<Map<QName,Object>, Object>>;
241 private def Class<?> keyTransformerFor(Class<?> inputType, GeneratedType type, ListSchemaNode schema) {
242 return withClassLoaderAndLock(inputType.classLoader, lock) [ |
243 val transformer = getGeneratedClass(inputType)
244 if (transformer != null) {
247 val newret = generateKeyTransformerFor(inputType, type, schema);
248 return newret as Class<? extends BindingCodec<Map<QName,Object>, Object>>;
252 private def Class<?> getGeneratedClass(Class<? extends Object> cls) {
255 return loadClass(cls.codecClassName)
256 } catch (ClassNotFoundException e) {
261 private def Class<?> keyTransformer(GeneratedType type, ListSchemaNode node) {
262 val cls = loadClass(type.resolvedName + "Key");
263 keyTransformerFor(cls, type, node);
266 private def serializer(Type type, DataSchemaNode node) {
267 val cls = loadClass(type.resolvedName);
268 transformerFor(cls, node);
271 private def Class<?> valueSerializer(GeneratedTransferObject type, TypeDefinition<?> typeDefinition) {
272 val cls = loadClass(type.resolvedName);
273 val transformer = cls.generatedClass;
274 if (transformer !== null) {
277 var baseType = typeDefinition;
278 while (baseType.baseType != null) {
279 baseType = baseType.baseType;
281 val finalType = baseType;
282 return withClassLoaderAndLock(cls.classLoader, lock) [ |
283 val valueTransformer = generateValueTransformer(cls, type, finalType);
284 return valueTransformer;
288 private def Class<?> valueSerializer(Enumeration type, TypeDefinition<?> typeDefinition) {
289 val cls = loadClass(type.resolvedName);
290 val transformer = cls.generatedClass;
291 if (transformer !== null) {
295 return withClassLoaderAndLock(cls.classLoader, lock) [ |
296 val valueTransformer = generateValueTransformer(cls, type);
297 return valueTransformer;
301 private def generateKeyTransformerFor(Class<? extends Object> inputType, GeneratedType typeSpec, ListSchemaNode node) {
304 //log.info("Generating DOM Codec for {} with {}", inputType, inputType.classLoader)
305 val properties = typeSpec.allProperties;
306 val ctCls = createClass(inputType.codecClassName) [
307 //staticField(Map,"AUGMENTATION_SERIALIZERS");
308 staticField(it, INSTANCE_IDENTIFIER_CODEC, BindingCodec)
309 staticField(it, IDENTITYREF_CODEC, BindingCodec)
310 staticQNameField(node.QName);
311 implementsType(BINDING_CODEC)
312 method(Object, "toDomStatic", QName, Object) [
313 modifiers = PUBLIC + FINAL + STATIC
316 «QName.name» _resultName;
318 _resultName = «QName.name».create($1,QNAME.getLocalName());
322 java.util.List _childNodes = new java.util.ArrayList();
323 «inputType.resolvedName» value = («inputType.name») $2;
324 «FOR key : node.keyDefinition»
325 «val propertyName = key.getterName»
326 «val keyDef = node.getDataChildByName(key)»
327 «val property = properties.get(propertyName)»
328 «serializeProperty(keyDef, property, propertyName)»;
330 return ($r) java.util.Collections.singletonMap(_resultName,_childNodes);
334 method(Object, "fromDomStatic", QName, Object) [
335 modifiers = PUBLIC + FINAL + STATIC
341 «QName.name» _localQName = $1;
342 java.util.Map _compositeNode = (java.util.Map) $2;
343 boolean _is_empty = true;
344 «FOR key : node.keyDefinition»
345 «val propertyName = key.getterName»
346 «val keyDef = node.getDataChildByName(key)»
347 «val property = properties.get(propertyName)»
348 «deserializeProperty(keyDef, property, propertyName)»;
350 «inputType.resolvedName» _value = new «inputType.name»(«node.keyDefinition.
351 keyConstructorList»);
356 method(Object, "serialize", Object) [
359 java.util.Map.Entry _input = (java.util.Map.Entry) $1;
360 «QName.name» _localQName = («QName.name») _input.getKey();
361 «inputType.name» _keyValue = («inputType.name») _input.getValue();
362 return toDomStatic(_localQName,_keyValue);
366 method(Object, "deserialize", Object) [
369 «QName.name» _qname = QNAME;
370 if($1 instanceof java.util.Map.Entry) {
371 _qname = («QName.name») ((java.util.Map.Entry) $1).getKey();
373 return fromDomStatic(_qname,$1);
378 val ret = ctCls.toClassImpl(inputType.classLoader, inputType.protectionDomain)
379 log.debug("DOM Codec for {} was generated {}", inputType, ret)
380 return ret as Class<? extends BindingCodec<Map<QName,Object>, ?>>;
381 } catch (Exception e) {
382 processException(inputType, e);
387 private def Class<? extends BindingCodec<Object, Object>> generateCaseCodec(Class<?> inputType, GeneratedType type,
388 ChoiceCaseNode node) {
391 //log.info("Generating DOM Codec for {} with {}, TCCL is: {}", inputType, inputType.classLoader,Thread.currentThread.contextClassLoader)
392 val ctCls = createClass(type.codecClassName) [
393 //staticField(Map,"AUGMENTATION_SERIALIZERS");
394 implementsType(BINDING_CODEC)
395 staticQNameField(node.QName);
396 staticField(it, INSTANCE_IDENTIFIER_CODEC, BindingCodec)
397 staticField(it, AUGMENTATION_CODEC, BindingCodec)
398 staticField(it, IDENTITYREF_CODEC, BindingCodec)
399 method(Object, "toDomStatic", QName, Object) [
400 modifiers = PUBLIC + FINAL + STATIC
403 «QName.name» _resultName = «QName.name».create($1,QNAME.getLocalName());
404 java.util.List _childNodes = new java.util.ArrayList();
405 «type.resolvedName» value = («type.resolvedName») $2;
406 «transformDataContainerBody(type, type.allProperties, node)»
407 return ($r) _childNodes;
411 method(Object, "serialize", Object) [
414 java.util.Map.Entry _input = (java.util.Map.Entry) $1;
415 «QName.name» _localName = QNAME;
416 if(_input.getKey() != null) {
417 _localName = («QName.name») _input.getKey();
419 return toDomStatic(_localName,_input.getValue());
423 method(Object, "fromDomStatic", QName, Object) [
424 modifiers = PUBLIC + FINAL + STATIC
425 bodyChecked = deserializeBody(type, node)
427 method(Object, "deserialize", Object) [
430 //System.out.println("«type.name»#deserialize: " +$1);
431 java.util.Map.Entry _input = (java.util.Map.Entry) $1;
432 return fromDomStatic((«QName.name»)_input.getKey(),_input.getValue());
438 val ret = ctCls.toClassImpl(inputType.classLoader, inputType.protectionDomain) as Class<? extends BindingCodec<Object, Object>>
439 listener?.onDataContainerCodecCreated(inputType, ret);
440 log.debug("DOM Codec for {} was generated {}", inputType, ret)
442 } catch (Exception e) {
443 processException(inputType, e);
448 private def dispatch Class<? extends BindingCodec<Map<QName, Object>, Object>> generateTransformerFor(
449 Class<?> inputType, GeneratedType typeSpec, SchemaNode node) {
452 //log.info("Generating DOM Codec for {} with {}", inputType, inputType.classLoader)
453 val ctCls = createClass(typeSpec.codecClassName) [
454 //staticField(Map,"AUGMENTATION_SERIALIZERS");
455 staticQNameField(node.QName);
456 staticField(it, INSTANCE_IDENTIFIER_CODEC, BindingCodec)
457 staticField(it, IDENTITYREF_CODEC, BindingCodec)
458 staticField(it, AUGMENTATION_CODEC, BindingCodec)
459 implementsType(BINDING_CODEC)
460 method(Object, "toDomStatic", QName, Object) [
461 modifiers = PUBLIC + FINAL + STATIC
462 bodyChecked = serializeBodyFacade(typeSpec, node)
464 method(Object, "serialize", Object) [
467 java.util.Map.Entry _input = (java.util.Map.Entry) $1;
468 «QName.name» _localName = QNAME;
469 if(_input.getKey() != null) {
470 _localName = («QName.name») _input.getKey();
472 return toDomStatic(_localName,_input.getValue());
476 method(Object, "fromDomStatic", QName, Object) [
477 modifiers = PUBLIC + FINAL + STATIC
478 bodyChecked = deserializeBody(typeSpec, node)
480 method(Object, "deserialize", Object) [
483 «QName.name» _qname = QNAME;
484 if($1 instanceof java.util.Map.Entry) {
485 _qname = («QName.name») ((java.util.Map.Entry) $1).getKey();
487 return fromDomStatic(_qname,$1);
493 val ret = ctCls.toClassImpl(inputType.classLoader, inputType.protectionDomain) as Class<? extends BindingCodec<Map<QName,Object>, Object>>
494 listener?.onDataContainerCodecCreated(inputType, ret);
495 log.debug("DOM Codec for {} was generated {}", inputType, ret)
497 } catch (Exception e) {
498 processException(inputType, e);
503 private def Class<? extends BindingCodec<Map<QName, Object>, Object>> generateAugmentationTransformerFor(
504 Class<?> inputType, GeneratedType type, AugmentationSchema node) {
507 //log.info("Generating DOM Codec for {} with {}", inputType, inputType.classLoader)
508 val properties = type.allProperties
509 val ctCls = createClass(type.codecClassName) [
510 //staticField(Map,"AUGMENTATION_SERIALIZERS");
511 staticQNameField(node.augmentationQName);
512 staticField(it, INSTANCE_IDENTIFIER_CODEC, BindingCodec)
513 staticField(it, AUGMENTATION_CODEC, BindingCodec)
514 staticField(it, IDENTITYREF_CODEC, BindingCodec)
515 implementsType(BINDING_CODEC)
516 method(Object, "toDomStatic", QName, Object) [
517 modifiers = PUBLIC + FINAL + STATIC
520 ////System.out.println("Qname " + $1);
521 ////System.out.println("Value " + $2);
522 «QName.name» _resultName = «QName.name».create(QNAME,QNAME.getLocalName());
523 java.util.List _childNodes = new java.util.ArrayList();
524 «type.resolvedName» value = («type.resolvedName») $2;
525 «FOR child : node.childNodes»
526 «var signature = properties.getFor(child)»
527 ////System.out.println("«signature.key»" + value.«signature.key»());
528 «serializeProperty(child, signature.value, signature.key)»
530 return ($r) _childNodes;
534 method(Object, "serialize", Object) [
537 java.util.Map.Entry _input = (java.util.Map.Entry) $1;
538 «QName.name» _localName = QNAME;
539 if(_input.getKey() != null) {
540 _localName = («QName.name») _input.getKey();
542 return toDomStatic(_localName,_input.getValue());
546 method(Object, "fromDomStatic", QName, Object) [
547 modifiers = PUBLIC + FINAL + STATIC
550 «QName.name» _localQName = QNAME;
555 java.util.Map _compositeNode = (java.util.Map) $2;
556 //System.out.println(_localQName + " " + _compositeNode);
557 «type.builderName» _builder = new «type.builderName»();
558 boolean _is_empty = true;
559 «FOR child : node.childNodes»
560 «val signature = properties.getFor(child)»
561 «deserializeProperty(child, signature.value, signature.key)»
562 _builder.«signature.key.toSetter»(«signature.key»);
567 return _builder.build();
571 method(Object, "deserialize", Object) [
573 return fromDomStatic(QNAME,$1);
578 val ret = ctCls.toClassImpl(inputType.classLoader, inputType.protectionDomain) as Class<? extends BindingCodec<Map<QName,Object>, Object>>
579 listener?.onDataContainerCodecCreated(inputType, ret);
581 } catch (Exception e) {
582 processException(inputType, e);
587 private def dispatch Class<? extends BindingCodec<Map<QName, Object>, Object>> generateTransformerFor(
588 Class<?> inputType, GeneratedType typeSpec, ChoiceNode node) {
591 //log.info("Generating DOM Codec for {} with {}", inputType, inputType.classLoader)
592 val ctCls = createClass(typeSpec.codecClassName) [
593 //staticField(Map,"AUGMENTATION_SERIALIZERS");
594 //staticQNameField(inputType);
595 staticField(it, INSTANCE_IDENTIFIER_CODEC, BindingCodec)
596 staticField(it, IDENTITYREF_CODEC, BindingCodec)
597 staticField(it, CLASS_TO_CASE_MAP, Map)
598 staticField(it, COMPOSITE_TO_CASE, Map)
599 //staticField(it,QNAME_TO_CASE_MAP,BindingCodec)
600 implementsType(BINDING_CODEC)
601 method(List, "toDomStatic", QName, Object) [
602 modifiers = PUBLIC + FINAL + STATIC
608 «DataObject.name» _baValue = («DataObject.name») $2;
609 Class _baClass = _baValue.getImplementedInterface();
610 «BINDING_CODEC.name» _codec = «CLASS_TO_CASE_MAP».get(_baClass);
614 java.util.Map.Entry _input = new «SimpleEntry.name»($1,_baValue);
615 Object _ret = _codec.serialize(_input);
616 ////System.out.println("«typeSpec.name»#toDomStatic: " + _ret);
617 return («List.name») _ret;
621 method(Object, "serialize", Object) [
623 throw new «UnsupportedOperationException.name»("Direct invocation not supported.");
626 method(Object, "fromDomStatic", QName, Map) [
627 modifiers = PUBLIC + FINAL + STATIC
630 «BINDING_CODEC.name» _codec = («BINDING_CODEC.name») «COMPOSITE_TO_CASE».get($2);
632 return _codec.deserialize(new «SimpleEntry.name»($1,$2));
638 method(Object, "deserialize", Object) [
640 throw new «UnsupportedOperationException.name»("Direct invocation not supported.");
645 val rawRet = ctCls.toClassImpl(inputType.classLoader, inputType.protectionDomain)
646 val ret = rawRet as Class<? extends BindingCodec<Map<QName,Object>, Object>>;
647 listener?.onChoiceCodecCreated(inputType, ret, node);
648 log.debug("DOM Codec for {} was generated {}", inputType, ret)
650 } catch (Exception e) {
651 processException(inputType, e);
656 private def keyConstructorList(List<QName> qnames) {
657 val names = new TreeSet<String>()
658 for (name : qnames) {
659 val fieldName = name.getterName;
660 names.add(fieldName);
662 return Joiner.on(",").join(names);
665 private def serializeBodyFacade(GeneratedType type, SchemaNode node) {
666 val ret = serializeBody(type, node);
670 private def String deserializeBody(GeneratedType type, SchemaNode node) {
671 val ret = deserializeBodyImpl(type, node);
675 private def deserializeKey(GeneratedType type, ListSchemaNode node) {
676 if (node.keyDefinition != null && !node.keyDefinition.empty) {
678 «type.resolvedName»Key getKey = («type.resolvedName»Key) «keyTransformer(type, node).canonicalName».fromDomStatic(_localQName,_compositeNode);
679 _builder.setKey(getKey);
684 private def String deserializeBodyWithAugmentations(GeneratedType type, DataNodeContainer node) '''
686 «QName.name» _localQName = «QName.name».create($1,QNAME.getLocalName());
690 java.util.Map _compositeNode = (java.util.Map) $2;
691 //System.out.println(_localQName + " " + _compositeNode);
692 «type.builderName» _builder = new «type.builderName»();
693 «deserializeDataNodeContainerBody(type, node)»
694 «deserializeAugmentations»
695 return _builder.build();
699 private def dispatch String deserializeBodyImpl(GeneratedType type, SchemaNode node) '''
701 «QName.name» _localQName = «QName.name».create($1,QNAME.getLocalName());
706 java.util.Map _compositeNode = (java.util.Map) $2;
707 «type.builderName» _builder = new «type.builderName»();
708 return _builder.build();
712 private def dispatch String deserializeBodyImpl(GeneratedType type, ListSchemaNode node) '''
714 «QName.name» _localQName = «QName.name».create($1,QNAME.getLocalName());
718 java.util.Map _compositeNode = (java.util.Map) $2;
719 //System.out.println(_localQName + " " + _compositeNode);
720 «type.builderName» _builder = new «type.builderName»();
721 «deserializeKey(type, node)»
722 «deserializeDataNodeContainerBody(type, node)»
723 «deserializeAugmentations»
724 return _builder.build();
728 private def dispatch String deserializeBodyImpl(GeneratedType type, ContainerSchemaNode node) {
729 return deserializeBodyWithAugmentations(type, node);
732 private def dispatch String deserializeBodyImpl(GeneratedType type, NotificationDefinition node) {
733 return deserializeBodyWithAugmentations(type, node);
736 private def dispatch String deserializeBodyImpl(GeneratedType type, ChoiceCaseNode node) {
737 return deserializeBodyWithAugmentations(type, node);
740 private def deserializeDataNodeContainerBody(GeneratedType type, DataNodeContainer node) {
741 deserializeNodeContainerBodyImpl(type, type.allProperties, node);
744 private def deserializeNodeContainerBodyImpl(GeneratedType type, HashMap<String, Type> properties,
745 DataNodeContainer node) {
747 boolean _is_empty = true;
748 «FOR child : node.childNodes»
749 «val signature = properties.getFor(child)»
750 «IF signature !== null»
751 «deserializeProperty(child, signature.value, signature.key)»
752 _builder.«signature.key.toSetter»(«signature.key»);
759 def deserializeAugmentations() '''
760 java.util.Map _augmentation = (java.util.Map) «AUGMENTATION_CODEC».deserialize(_compositeNode);
761 if(_augmentation != null) {
762 «Iterator.name» _entries = _augmentation.entrySet().iterator();
763 while(_entries.hasNext()) {
764 java.util.Map.Entry _entry = (java.util.Map.Entry) _entries.next();
765 ////System.out.println("Aug. key:" + _entry.getKey());
766 Class _type = (Class) _entry.getKey();
767 «Augmentation.resolvedName» _value = («Augmentation.name») _entry.getValue();
769 _builder.addAugmentation(_type,_value);
775 private def dispatch CharSequence deserializeProperty(ListSchemaNode schema, ParameterizedType type,
776 String propertyName) '''
777 java.util.List _dom_«propertyName» = _compositeNode.get(«QName.name».create(_localQName,"«schema.QName.
779 ////System.out.println("«propertyName»#deCode"+_dom_«propertyName»);
780 java.util.List «propertyName» = new java.util.ArrayList();
781 if(_dom_«propertyName» != null) {
782 java.util.List _serialized = new java.util.ArrayList();
783 java.util.Iterator _iterator = _dom_«propertyName».iterator();
784 boolean _hasNext = _iterator.hasNext();
786 Object _listItem = _iterator.next();
788 ////System.out.println(" item" + _listItem);
789 Object _value = «type.actualTypeArguments.get(0).serializer(schema).resolvedName».fromDomStatic(_localQName,_listItem);
790 ////System.out.println(" value" + _value);
791 «propertyName».add(_value);
792 _hasNext = _iterator.hasNext();
796 ////System.out.println(" list" + «propertyName»);
799 private def dispatch CharSequence deserializeProperty(LeafListSchemaNode schema, ParameterizedType type,
800 String propertyName) '''
801 java.util.List _dom_«propertyName» = _compositeNode.get(«QName.name».create(_localQName,"«schema.QName.
803 java.util.List «propertyName» = new java.util.ArrayList();
804 if(_dom_«propertyName» != null) {
805 java.util.List _serialized = new java.util.ArrayList();
806 java.util.Iterator _iterator = _dom_«propertyName».iterator();
807 boolean _hasNext = _iterator.hasNext();
810 Object _listItem = _iterator.next();
811 if(_listItem instanceof java.util.Map.Entry) {
812 Object _innerValue = ((java.util.Map.Entry) _listItem).getValue();
813 Object _value = «deserializeValue(type.actualTypeArguments.get(0), "_innerValue", schema.type)»;
814 «propertyName».add(_value);
816 _hasNext = _iterator.hasNext();
821 private def dispatch CharSequence deserializeProperty(LeafSchemaNode schema, Type type, String propertyName) '''
822 java.util.List _dom_«propertyName»_list =
823 _compositeNode.get(«QName.name».create(_localQName,"«schema.QName.localName»"));
824 «type.resolvedName» «propertyName» = null;
825 if(_dom_«propertyName»_list != null && _dom_«propertyName»_list.size() > 0) {
827 java.util.Map.Entry _dom_«propertyName» = (java.util.Map.Entry) _dom_«propertyName»_list.get(0);
828 Object _inner_value = _dom_«propertyName».getValue();
829 «propertyName» = «deserializeValue(type, "_inner_value", schema.type)»;
833 private def dispatch CharSequence deserializeProperty(ContainerSchemaNode schema, Type type,
834 String propertyName) '''
835 java.util.List _dom_«propertyName»_list =
836 _compositeNode.get(«QName.name».create(_localQName,"«schema.QName.localName»"));
837 «type.resolvedName» «propertyName» = null;
838 if(_dom_«propertyName»_list != null && _dom_«propertyName»_list.size() > 0) {
840 java.util.Map _dom_«propertyName» = (java.util.Map) _dom_«propertyName»_list.get(0);
841 «propertyName» = «type.serializer(schema).resolvedName».fromDomStatic(_localQName,_dom_«propertyName»);
845 private def dispatch CharSequence deserializeProperty(ChoiceNode schema, Type type, String propertyName) '''
846 «type.resolvedName» «propertyName» = «type.serializer(schema).resolvedName».fromDomStatic(_localQName,_compositeNode);
847 if(«propertyName» != null) {
852 private def dispatch String deserializeValue(GeneratedTransferObject type, String domParameter,
853 TypeDefinition<?> typeDefinition) '''
854 («type.resolvedName») «type.valueSerializer(typeDefinition).resolvedName».fromDomValue(«domParameter»)
857 private def dispatch String deserializeValue(Enumeration type, String domParameter, TypeDefinition<?> typeDefinition) '''
858 («type.resolvedName») «type.valueSerializer(typeDefinition).resolvedName».fromDomValue(«domParameter»)
861 private def dispatch Class<? extends BindingCodec<Map<QName, Object>, Object>> generateValueTransformer(
862 Class<?> inputType, GeneratedTransferObject typeSpec, TypeDefinition<?> typeDef) {
865 val returnType = typeSpec.valueReturnType;
866 if (returnType == null) {
867 val ctCls = createDummyImplementation(inputType, typeSpec);
868 val ret = ctCls.toClassImpl(inputType.classLoader, inputType.protectionDomain)
869 return ret as Class<? extends BindingCodec<Map<QName,Object>, Object>>;
872 val ctCls = createClass(typeSpec.codecClassName) [
873 //staticField(Map,"AUGMENTATION_SERIALIZERS");
874 if (inputType.isYangBindingAvailable) {
875 implementsType(BINDING_CODEC)
876 staticField(it, INSTANCE_IDENTIFIER_CODEC, BindingCodec)
877 staticField(it, IDENTITYREF_CODEC, BindingCodec)
878 implementsType(BindingDeserializer.asCtClass)
880 method(Object, "toDomValue", Object) [
881 modifiers = PUBLIC + FINAL + STATIC
882 val ctSpec = typeSpec.asCtClass;
885 ////System.out.println("«inputType.simpleName»#toDomValue: "+$1);
890 «typeSpec.resolvedName» _encapsulatedValue = («typeSpec.resolvedName») $1;
891 ////System.out.println("«inputType.simpleName»#toDomValue:Enc: "+_encapsulatedValue);
892 «returnType.resolvedName» _value = _encapsulatedValue.getValue();
893 ////System.out.println("«inputType.simpleName»#toDomValue:DeEnc: "+_value);
894 Object _domValue = «serializeValue(returnType, "_value", null)»;
899 method(Object, "serialize", Object) [
902 return toDomValue($1);
906 method(Object, "fromDomValue", Object) [
907 modifiers = PUBLIC + FINAL + STATIC
910 ////System.out.println("«inputType.simpleName»#fromDomValue: "+$1);
915 «returnType.resolvedName» _simpleValue = «deserializeValue(returnType, "$1", null)»;
916 «typeSpec.resolvedName» _value = new «typeSpec.resolvedName»(_simpleValue);
921 method(Object, "deserialize", Object) [
923 return fromDomValue($1);
929 val ret = ctCls.toClassImpl(inputType.classLoader, inputType.protectionDomain)
930 log.debug("DOM Codec for {} was generated {}", inputType, ret)
931 return ret as Class<? extends BindingCodec<Map<QName,Object>, Object>>;
932 } catch (Exception e) {
933 log.error("Cannot compile DOM Codec for {}", inputType, e);
934 val exception = new CodeGenerationException("Cannot compile Transformator for " + inputType);
935 exception.addSuppressed(e);
940 private def dispatch Class<? extends BindingCodec<Map<QName, Object>, Object>> generateValueTransformer(
941 Class<?> inputType, GeneratedTransferObject typeSpec, UnionTypeDefinition typeDef) {
943 val ctCls = createClass(typeSpec.codecClassName) [
944 val properties = typeSpec.allProperties;
945 val getterToTypeDefinition = XtendHelper.getTypes(typeDef).toMap[type|type.QName.getterName];
946 //staticField(Map,"AUGMENTATION_SERIALIZERS");
947 if (inputType.isYangBindingAvailable) {
948 implementsType(BINDING_CODEC)
949 staticField(it, INSTANCE_IDENTIFIER_CODEC, BindingCodec)
950 staticField(it, IDENTITYREF_CODEC, BindingCodec)
951 implementsType(BindingDeserializer.asCtClass)
953 method(Object, "toDomValue", Object) [
954 modifiers = PUBLIC + FINAL + STATIC
955 val ctSpec = inputType.asCtClass;
958 ////System.out.println("«inputType.simpleName»#toDomValue: "+$1);
963 «typeSpec.resolvedName» _value = («typeSpec.resolvedName») $1;
964 «FOR property : properties.entrySet»
965 «IF property.key != "getValue"»
966 «property.value.resolvedName» «property.key» = («property.value.resolvedName») _value.«property.
968 if(«property.key» != null) {
969 return «serializeValue(property.value, property.key,
970 getterToTypeDefinition.get(property.key))»;
979 method(Object, "serialize", Object) [
982 return toDomValue($1);
986 method(Object, "fromDomValue", Object) [
987 modifiers = PUBLIC + FINAL + STATIC
990 ////System.out.println("«inputType.simpleName»#fromDomValue: "+$1);
995 if($1 instanceof String) {
996 String _simpleValue = (String) $1;
997 return new «typeSpec.resolvedName»(_simpleValue.toCharArray());
1003 method(Object, "deserialize", Object) [
1005 return fromDomValue($1);
1011 val ret = ctCls.toClassImpl(inputType.classLoader, inputType.protectionDomain)
1012 log.debug("DOM Codec for {} was generated {}", inputType, ret)
1013 return ret as Class<? extends BindingCodec<Map<QName,Object>, Object>>;
1014 } catch (Exception e) {
1015 log.error("Cannot compile DOM Codec for {}", inputType, e);
1016 val exception = new CodeGenerationException("Cannot compile Transformator for " + inputType);
1017 exception.addSuppressed(e);
1022 private def dispatch Class<? extends BindingCodec<Map<QName, Object>, Object>> generateValueTransformer(
1023 Class<?> inputType, GeneratedTransferObject typeSpec, BitsTypeDefinition typeDef) {
1025 val ctCls = createClass(typeSpec.codecClassName) [
1026 //staticField(Map,"AUGMENTATION_SERIALIZERS");
1027 if (inputType.isYangBindingAvailable) {
1028 implementsType(BINDING_CODEC)
1029 staticField(it, INSTANCE_IDENTIFIER_CODEC, BindingCodec)
1030 staticField(it, IDENTITYREF_CODEC, BindingCodec)
1031 implementsType(BindingDeserializer.asCtClass)
1033 method(Object, "toDomValue", Object) [
1034 modifiers = PUBLIC + FINAL + STATIC
1035 val ctSpec = typeSpec.asCtClass;
1038 ////System.out.println("«inputType.simpleName»#toDomValue: "+$1);
1043 «typeSpec.resolvedName» _encapsulatedValue = («typeSpec.resolvedName») $1;
1044 «HashSet.resolvedName» _value = new «HashSet.resolvedName»();
1045 //System.out.println("«inputType.simpleName»#toDomValue:Enc: "+_encapsulatedValue);
1047 «FOR bit : typeDef.bits»
1048 «val getter = bit.getterName()»
1049 if(Boolean.TRUE.equals(_encapsulatedValue.«getter»())) {
1050 _value.add("«bit.name»");
1053 «Set.resolvedName» _domValue = «Collections.resolvedName».unmodifiableSet(_value);
1054 //System.out.println("«inputType.simpleName»#toDomValue:DeEnc: "+_domValue);
1060 method(Object, "serialize", Object) [
1063 return toDomValue($1);
1067 method(Object, "fromDomValue", Object) [
1068 modifiers = PUBLIC + FINAL + STATIC
1069 val sortedBits = typeDef.bits.sort[o1, o2|o1.propertyName.compareTo(o2.propertyName)]
1072 //System.out.println("«inputType.simpleName»#fromDomValue: "+$1);
1077 «Set.resolvedName» _domValue = («Set.resolvedName») $1;
1078 «FOR bit : sortedBits»
1079 Boolean «bit.propertyName» = Boolean.valueOf(_domValue.contains("«bit.name»"));
1082 return new «inputType.resolvedName»(«FOR bit : sortedBits SEPARATOR ","»«bit.propertyName»«ENDFOR»);
1086 method(Object, "deserialize", Object) [
1088 return fromDomValue($1);
1094 val ret = ctCls.toClassImpl(inputType.classLoader, inputType.protectionDomain)
1095 log.debug("DOM Codec for {} was generated {}", inputType, ret)
1096 return ret as Class<? extends BindingCodec<Map<QName,Object>, Object>>;
1097 } catch (Exception e) {
1098 log.error("Cannot compile DOM Codec for {}", inputType, e);
1099 val exception = new CodeGenerationException("Cannot compile Transformator for " + inputType);
1100 exception.addSuppressed(e);
1105 def String getPropertyName(Bit bit) {
1106 '''_«BindingGeneratorUtil.parseToValidParamName(bit.name)»'''
1109 def String getterName(Bit bit) {
1111 val paramName = BindingGeneratorUtil.parseToValidParamName(bit.name);
1112 return '''is«paramName.toFirstUpper»''';
1115 def boolean isYangBindingAvailable(Class<?> class1) {
1117 val bindingCodecClass = class1.classLoader.loadClass(BINDING_CODEC.name);
1118 return bindingCodecClass !== null;
1119 } catch (ClassNotFoundException e) {
1124 private def createDummyImplementation(Class<?> object, GeneratedTransferObject typeSpec) {
1125 log.trace("Generating Dummy DOM Codec for {} with {}", object, object.classLoader)
1126 return createClass(typeSpec.codecClassName) [
1127 if (object.isYangBindingAvailable) {
1128 implementsType(BINDING_CODEC)
1129 staticField(it, INSTANCE_IDENTIFIER_CODEC, BindingCodec)
1130 staticField(it, IDENTITYREF_CODEC, BindingCodec)
1131 implementsType(BindingDeserializer.asCtClass)
1133 //implementsType(BindingDeserializer.asCtClass)
1134 method(Object, "toDomValue", Object) [
1135 modifiers = PUBLIC + FINAL + STATIC
1140 return $1.toString();
1144 method(Object, "serialize", Object) [
1147 return toDomValue($1);
1151 method(Object, "fromDomValue", Object) [
1152 modifiers = PUBLIC + FINAL + STATIC
1153 bodyChecked = '''return null;'''
1155 method(Object, "deserialize", Object) [
1157 return fromDomValue($1);
1164 private def Type getValueReturnType(GeneratedTransferObject object) {
1165 for (prop : object.properties) {
1166 if (prop.name == "value") {
1167 return prop.returnType;
1170 if (object.superType != null) {
1171 return getValueReturnType(object.superType);
1176 private def Class<?> generateValueTransformer(Class<?> inputType, Enumeration typeSpec) {
1178 val typeRef = new ReferencedTypeImpl(typeSpec.packageName, typeSpec.name);
1179 val schema = typeToSchemaNode.get(typeRef) as ExtendedType;
1180 val enumSchema = schema.baseType as EnumerationType;
1182 //log.info("Generating DOM Codec for {} with {}", inputType, inputType.classLoader)
1183 val ctCls = createClass(typeSpec.codecClassName) [
1184 //staticField(Map,"AUGMENTATION_SERIALIZERS");
1185 //implementsType(BINDING_CODEC)
1186 method(Object, "toDomValue", Object) [
1187 modifiers = PUBLIC + FINAL + STATIC
1192 «typeSpec.resolvedName» _value = («typeSpec.resolvedName») $1;
1193 «FOR en : enumSchema.values»
1194 if(«typeSpec.resolvedName».«BindingGeneratorUtil.parseToClassName(en.name)».equals(_value)) {
1202 method(Object, "serialize", Object) [
1204 return toDomValue($1);
1207 method(Object, "fromDomValue", Object) [
1208 modifiers = PUBLIC + FINAL + STATIC
1214 String _value = (String) $1;
1215 «FOR en : enumSchema.values»
1216 if("«en.name»".equals(_value)) {
1217 return «typeSpec.resolvedName».«BindingGeneratorUtil.parseToClassName(en.name)»;
1224 method(Object, "deserialize", Object) [
1226 return fromDomValue($1);
1231 val ret = ctCls.toClassImpl(inputType.classLoader, inputType.protectionDomain)
1232 log.debug("DOM Codec for {} was generated {}", inputType, ret)
1234 } catch (CodeGenerationException e) {
1235 throw new CodeGenerationException("Cannot compile Transformator for " + inputType, e);
1236 } catch (Exception e) {
1237 log.error("Cannot compile DOM Codec for {}", inputType, e);
1238 val exception = new CodeGenerationException("Cannot compile Transformator for " + inputType);
1239 exception.addSuppressed(e);
1245 def Class<?> toClassImpl(CtClass newClass, ClassLoader loader, ProtectionDomain domain) {
1246 val cls = newClass.toClass(loader, domain);
1247 if (classFileCapturePath !== null) {
1248 newClass.writeFile(classFileCapturePath.absolutePath);
1250 listener?.onCodecCreated(cls);
1254 def debugWriteClass(CtClass class1) {
1255 val path = class1.name.replace(".", "/") + ".class"
1257 val captureFile = new File(classFileCapturePath, path);
1258 captureFile.createNewFile
1262 private def dispatch String deserializeValue(Type type, String domParameter, TypeDefinition<?> typeDef) {
1263 if (INSTANCE_IDENTIFIER.equals(type)) {
1264 return '''(«InstanceIdentifier.name») «INSTANCE_IDENTIFIER_CODEC».deserialize(«domParameter»)'''
1265 } else if (CLASS_TYPE.equals(type)) {
1266 return '''(«Class.name») «IDENTITYREF_CODEC».deserialize(«domParameter»)'''
1268 return '''(«type.resolvedName») «domParameter»'''
1276 private def dispatch CharSequence deserializeProperty(DataSchemaNode container, Type type, String propertyName) '''
1277 «type.resolvedName» «propertyName» = null;
1280 private def dispatch CharSequence deserializeProperty(DataSchemaNode container, GeneratedTypeBuilder type,
1281 String propertyName) {
1282 _deserializeProperty(container, type.toInstance, propertyName)
1285 public static def toSetter(String it) {
1287 if (startsWith("is")) {
1288 return "set" + substring(2);
1289 } else if (startsWith("get")) {
1290 return "set" + substring(3);
1296 private def dispatch CharSequence deserializeProperty(DataSchemaNode container,GeneratedType type, String propertyName) '''
1297 «type.resolvedName» «propertyName» = value.«propertyName»();
1298 if(«propertyName» != null) {
1299 Object domValue = «type.serializer».toDomStatic(QNAME,«propertyName»);
1300 _childNodes.add(domValue);
1304 private def getBuilderName(GeneratedType type) '''«type.resolvedName»Builder'''
1306 private def staticQNameField(CtClass it, QName node) {
1307 val field = new CtField(ctQName, "QNAME", it);
1308 field.modifiers = PUBLIC + FINAL + STATIC;
1310 '''«QName.asCtClass.name».create("«node.namespace»","«node.formattedRevision»","«node.localName»")''')
1313 private def String serializeBodyImpl(GeneratedType type, DataNodeContainer nodeContainer) '''
1315 «QName.name» _resultName = «QName.name».create($1,QNAME.getLocalName());
1316 java.util.List _childNodes = new java.util.ArrayList();
1317 «type.resolvedName» value = («type.resolvedName») $2;
1318 «transformDataContainerBody(type, type.allProperties, nodeContainer)»
1319 «serializeAugmentations»
1320 return ($r) java.util.Collections.singletonMap(_resultName,_childNodes);
1324 private def dispatch String serializeBody(GeneratedType type, ListSchemaNode node) {
1325 return serializeBodyImpl(type, node);
1328 private def dispatch String serializeBody(GeneratedType type, NotificationDefinition node) {
1329 return serializeBodyImpl(type, node);
1332 private def dispatch String serializeBody(GeneratedType type, ContainerSchemaNode node) {
1333 return serializeBodyImpl(type, node);
1336 private def dispatch String serializeBody(GeneratedType type, ChoiceCaseNode node) {
1337 return serializeBodyImpl(type, node);
1340 private def dispatch String serializeBody(GeneratedType type, SchemaNode node) '''
1342 «QName.name» _resultName = «QName.name».create($1,QNAME.getLocalName());
1343 java.util.List _childNodes = new java.util.ArrayList();
1344 «type.resolvedName» value = («type.resolvedName») $2;
1345 return ($r) java.util.Collections.singletonMap(_resultName,_childNodes);
1349 private def transformDataContainerBody(Type type, Map<String, Type> properties, DataNodeContainer node) {
1351 «FOR child : node.childNodes»
1352 «val signature = properties.getFor(child)»
1353 «IF signature !== null»
1354 ////System.out.println("«type.name»#«signature.key»" + value.«signature.key»());
1355 «serializeProperty(child, signature.value, signature.key)»
1362 private def serializeAugmentations() '''
1363 java.util.List _augmentations = (java.util.List) «AUGMENTATION_CODEC».serialize(value);
1364 if(_augmentations != null) {
1365 _childNodes.addAll(_augmentations);
1369 def Entry<String, Type> getFor(Map<String, Type> map, DataSchemaNode node) {
1370 var sig = map.get(node.getterName);
1372 return new SimpleEntry(node.getterName, sig);
1374 sig = map.get(node.booleanGetterName);
1376 return new SimpleEntry(node.booleanGetterName, map.get(node.booleanGetterName));
1381 private static def String getBooleanGetterName(DataSchemaNode node) {
1382 return "is" + BindingGeneratorUtil.parseToClassName(node.QName.localName);
1385 private static def String getGetterName(DataSchemaNode node) {
1386 return "get" + BindingGeneratorUtil.parseToClassName(node.QName.localName);
1389 private static def String getGetterName(QName node) {
1390 return "get" + BindingGeneratorUtil.parseToClassName(node.localName);
1393 private def dispatch CharSequence serializeProperty(ListSchemaNode schema, ParameterizedType type,
1394 String propertyName) '''
1395 «type.resolvedName» «propertyName» = value.«propertyName»();
1396 ////System.out.println("«propertyName»:" + «propertyName»);
1397 if(«propertyName» != null) {
1398 java.util.Iterator _iterator = «propertyName».iterator();
1399 boolean _hasNext = _iterator.hasNext();
1401 Object _listItem = _iterator.next();
1402 Object _domValue = «type.actualTypeArguments.get(0).serializer(schema).resolvedName».toDomStatic(_resultName,_listItem);
1403 _childNodes.add(_domValue);
1404 _hasNext = _iterator.hasNext();
1409 private def dispatch CharSequence serializeProperty(LeafSchemaNode schema, Type type, String propertyName) '''
1410 «type.resolvedName» «propertyName» = value.«propertyName»();
1412 if(«propertyName» != null) {
1413 «QName.name» _qname = «QName.name».create(_resultName,"«schema.QName.localName»");
1414 Object _propValue = «serializeValue(type, propertyName, schema.type)»;
1415 if(_propValue != null) {
1416 Object _domValue = java.util.Collections.singletonMap(_qname,_propValue);
1417 _childNodes.add(_domValue);
1422 private def dispatch serializeValue(GeneratedTransferObject type, String parameter, TypeDefinition<?> typeDefinition) {
1423 '''«type.valueSerializer(typeDefinition).resolvedName».toDomValue(«parameter»)'''
1426 private def dispatch serializeValue(Enumeration type, String parameter, TypeDefinition<?> typeDefinition) {
1427 '''«type.valueSerializer(typeDefinition).resolvedName».toDomValue(«parameter»)'''
1430 private def dispatch serializeValue(Type signature, String property, TypeDefinition<?> typeDefinition) {
1431 if (INSTANCE_IDENTIFIER == signature) {
1432 return '''«INSTANCE_IDENTIFIER_CODEC».serialize(«property»)'''
1433 } else if (CLASS_TYPE.equals(signature)) {
1434 return '''(«QName.resolvedName») «IDENTITYREF_CODEC».serialize(«property»)'''
1436 if ("char[]" == signature.name) {
1437 return '''new String(«property»)''';
1439 return '''«property»''';
1442 private def dispatch CharSequence serializeProperty(LeafListSchemaNode schema, ParameterizedType type,
1443 String propertyName) '''
1444 «type.resolvedName» «propertyName» = value.«propertyName»();
1445 if(«propertyName» != null) {
1446 «QName.name» _qname = «QName.name».create(_resultName,"«schema.QName.localName»");
1447 java.util.Iterator _iterator = «propertyName».iterator();
1448 boolean _hasNext = _iterator.hasNext();
1450 Object _listItem = _iterator.next();
1451 Object _propValue = «serializeValue(type.actualTypeArguments.get(0), "_listItem", schema.type)»;
1452 Object _domValue = java.util.Collections.singletonMap(_qname,_propValue);
1453 _childNodes.add(_domValue);
1454 _hasNext = _iterator.hasNext();
1459 private def dispatch CharSequence serializeProperty(ChoiceNode container, GeneratedType type,
1460 String propertyName) '''
1461 «type.resolvedName» «propertyName» = value.«propertyName»();
1462 if(«propertyName» != null) {
1463 java.util.List domValue = «type.serializer(container).resolvedName».toDomStatic(_resultName,«propertyName»);
1464 _childNodes.addAll(domValue);
1472 private def dispatch CharSequence serializeProperty(DataSchemaNode container, Type type, String propertyName) '''
1473 «type.resolvedName» «propertyName» = value.«propertyName»();
1474 if(«propertyName» != null) {
1475 Object domValue = «propertyName»;
1476 _childNodes.add(domValue);
1480 private def dispatch CharSequence serializeProperty(DataSchemaNode container, GeneratedTypeBuilder type,
1481 String propertyName) {
1482 serializeProperty(container, type.toInstance, propertyName)
1485 private def dispatch CharSequence serializeProperty(DataSchemaNode container, GeneratedType type,
1486 String propertyName) '''
1487 «type.resolvedName» «propertyName» = value.«propertyName»();
1488 if(«propertyName» != null) {
1489 Object domValue = «type.serializer(container).resolvedName».toDomStatic(_resultName,«propertyName»);
1490 _childNodes.add(domValue);
1494 private def codecClassName(GeneratedType typeSpec) {
1495 return '''«typeSpec.resolvedName»$Broker$Codec$DOM'''
1498 private def codecClassName(Class<?> typeSpec) {
1499 return '''«typeSpec.name»$Broker$Codec$DOM'''
1502 private def HashMap<String, Type> getAllProperties(GeneratedType type) {
1503 val ret = new HashMap<String, Type>();
1504 type.collectAllProperties(ret);
1508 private def dispatch void collectAllProperties(GeneratedType type, Map<String, Type> set) {
1509 for (definition : type.methodDefinitions) {
1510 set.put(definition.name, definition.returnType);
1512 for (property : type.properties) {
1513 set.put(property.getterName, property.returnType);
1515 for (parent : type.implements) {
1516 parent.collectAllProperties(set);
1520 def String getGetterName(GeneratedProperty property) {
1521 return "get" + property.name.toFirstUpper
1524 private def dispatch void collectAllProperties(Type type, Map<String, Type> set) {
1525 // NOOP for generic type.
1528 def String getResolvedName(Type type) {
1529 return type.asCtClass.name;
1532 def String getResolvedName(Class<?> type) {
1533 return type.asCtClass.name;
1536 def CtClass asCtClass(Type type) {
1537 val cls = loadClass(type.fullyQualifiedName)
1538 return cls.asCtClass;
1541 private def dispatch processException(Class<?> inputType, CodeGenerationException e) {
1542 log.error("Cannot compile DOM Codec for {}. One of it's prerequisites was not generated.", inputType);
1546 private def dispatch processException(Class<?> inputType, Exception e) {
1547 log.error("Cannot compile DOM Codec for {}", inputType, e);
1548 val exception = new CodeGenerationException("Cannot compile Transformator for " + inputType, e);
1552 private def setBodyChecked(CtMethod method, String body) {
1554 method.setBody(body);
1555 } catch (CannotCompileException e) {
1556 log.error("Cannot compile method: {}#{} {}, Reason: {} Body: {}", method.declaringClass, method.name,
1557 method.signature, e.message, body)
1562 private def <V> V withClassLoaderAndLock(ClassLoader cls, Lock lock, Callable<V> function) throws Exception {
1563 appendClassLoaderIfMissing(cls);
1564 ClassLoaderUtils.withClassLoaderAndLock(cls, lock, function);
1570 class PropertyPair {
1579 SchemaNode schemaNode;