1 package org.opendaylight.controller.sal.binding.dom.serializer.impl
3 import javassist.ClassPool
4 import org.opendaylight.yangtools.sal.binding.model.api.GeneratedType
5 import org.opendaylight.yangtools.yang.model.api.SchemaNode
6 import org.opendaylight.controller.sal.binding.codegen.util.JavassistUtils
7 import javassist.CtClass
9 import org.opendaylight.yangtools.yang.common.QName
10 import javassist.CtField
11 import static javassist.Modifier.*
12 import static org.opendaylight.controller.sal.binding.dom.serializer.impl.CodecMapping.*
13 import org.opendaylight.yangtools.yang.model.api.ContainerSchemaNode
14 import org.opendaylight.yangtools.yang.model.api.ListSchemaNode
15 import org.opendaylight.yangtools.yang.model.api.DataNodeContainer
16 import org.opendaylight.yangtools.sal.binding.model.api.Type
17 import org.opendaylight.yangtools.sal.binding.model.api.type.builder.GeneratedTypeBuilder
18 import org.opendaylight.yangtools.binding.generator.util.Types
19 import org.opendaylight.yangtools.sal.binding.model.api.ParameterizedType
20 import java.util.HashMap
21 import org.opendaylight.yangtools.yang.model.api.DataSchemaNode
22 import org.opendaylight.yangtools.binding.generator.util.BindingGeneratorUtil
23 import org.opendaylight.yangtools.yang.model.api.LeafSchemaNode
24 import org.opendaylight.yangtools.yang.model.api.LeafListSchemaNode
26 import java.util.TreeSet
27 import com.google.common.base.Joiner
28 import org.opendaylight.yangtools.sal.binding.model.api.GeneratedTransferObject
29 import org.opendaylight.yangtools.sal.binding.model.api.Enumeration
30 import org.opendaylight.yangtools.yang.model.api.ChoiceCaseNode
31 import static org.opendaylight.controller.sal.binding.impl.util.ClassLoaderUtils.*;
32 import org.opendaylight.yangtools.yang.binding.BindingDeserializer
33 import org.opendaylight.yangtools.yang.binding.BindingCodec
34 import org.slf4j.LoggerFactory
35 import org.opendaylight.controller.sal.binding.codegen.CodeGenerationException
36 import org.opendaylight.yangtools.yang.model.api.ChoiceNode
37 import java.security.ProtectionDomain
39 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier
40 import org.opendaylight.yangtools.sal.binding.model.api.GeneratedProperty
41 import java.util.Map.Entry
42 import java.util.AbstractMap.SimpleEntry
43 import org.opendaylight.yangtools.yang.binding.DataObject
44 import org.opendaylight.yangtools.yang.binding.Augmentation
45 import java.util.Iterator
46 import org.opendaylight.yangtools.yang.model.api.AugmentationSchema
47 import java.util.concurrent.ConcurrentHashMap
48 import static extension org.opendaylight.controller.sal.binding.impl.util.YangSchemaUtils.*;
49 import org.opendaylight.yangtools.binding.generator.util.ReferencedTypeImpl
50 import org.opendaylight.yangtools.yang.model.util.ExtendedType
51 import org.opendaylight.yangtools.yang.model.util.EnumerationType
53 class TransformerGenerator {
55 private static val log = LoggerFactory.getLogger(TransformerGenerator)
57 public static val STRING = Types.typeForClass(String);
58 public static val BOOLEAN = Types.typeForClass(Boolean);
59 public static val INTEGER = Types.typeForClass(Integer);
60 public static val INSTANCE_IDENTIFIER = Types.typeForClass(InstanceIdentifier)
62 //public static val DECIMAL = Types.typeForClass(Decimal);
63 public static val LONG = Types.typeForClass(Long);
65 val ClassPool classPool
66 val extension JavassistUtils utils;
73 var File classFileCapturePath;
76 var Map<Type, Type> typeDefinitions = new ConcurrentHashMap();
79 var Map<Type, GeneratedTypeBuilder> typeToDefinition = new ConcurrentHashMap();
82 var Map<Type, SchemaNode> typeToSchemaNode = new ConcurrentHashMap();
85 var Map<Type, AugmentationSchema> typeToAugmentation = new ConcurrentHashMap();
88 var GeneratorListener listener;
90 public new(ClassPool pool) {
92 utils = new JavassistUtils(pool)
94 BINDING_CODEC = BindingCodec.asCtClass;
95 ctQName = QName.asCtClass
98 def Class<? extends BindingCodec<Map<QName, Object>, Object>> transformerFor(Class<?> inputType) {
99 return withClassLoaderAndLock(inputType.classLoader, lock) [ |
100 val ret = getGeneratedClass(inputType)
102 listener.onClassProcessed(inputType);
103 return ret as Class<? extends BindingCodec<Map<QName,Object>, Object>>;
105 val ref = Types.typeForClass(inputType)
106 val node = typeToSchemaNode.get(ref)
107 val typeSpecBuilder = typeToDefinition.get(ref)
108 val typeSpec = typeSpecBuilder.toInstance();
109 val newret = generateTransformerFor(inputType, typeSpec, node);
110 listener.onClassProcessed(inputType);
111 return newret as Class<? extends BindingCodec<Map<QName,Object>, Object>>;
115 def Class<? extends BindingCodec<Map<QName, Object>, Object>> augmentationTransformerFor(Class<?> inputType) {
116 return withClassLoaderAndLock(inputType.classLoader, lock) [ |
117 val ret = getGeneratedClass(inputType)
119 return ret as Class<? extends BindingCodec<Map<QName,Object>, Object>>;
121 val ref = Types.typeForClass(inputType)
122 val node = typeToAugmentation.get(ref)
123 val typeSpecBuilder = typeToDefinition.get(ref)
124 val typeSpec = typeSpecBuilder.toInstance();
125 val newret = generateAugmentationTransformerFor(inputType, typeSpec, node);
126 listener.onClassProcessed(inputType);
127 return newret as Class<? extends BindingCodec<Map<QName,Object>, Object>>;
131 def Class<? extends BindingCodec<Object, Object>> caseCodecFor(Class<?> inputType, ChoiceCaseNode node) {
132 return withClassLoaderAndLock(inputType.classLoader, lock) [ |
133 val ret = getGeneratedClass(inputType)
135 return ret as Class<? extends BindingCodec<Object, Object>>;
137 val ref = Types.typeForClass(inputType)
138 val typeSpecBuilder = typeToDefinition.get(ref)
139 val typeSpec = typeSpecBuilder.toInstance();
140 val newret = generateCaseCodec(inputType, typeSpec, node);
141 return newret as Class<? extends BindingCodec<Object, Object>>;
145 def Class<? extends BindingCodec<Map<QName, Object>, Object>> keyTransformerForIdentifiable(Class<?> parentType) {
146 return withClassLoaderAndLock(parentType.classLoader, lock) [ |
147 val inputName = parentType.name + "Key";
148 val inputType = loadClassWithTCCL(inputName);
149 val ret = getGeneratedClass(inputType)
151 return ret as Class<? extends BindingCodec<Map<QName,Object>, Object>>;
153 val ref = Types.typeForClass(parentType)
154 val node = typeToSchemaNode.get(ref) as ListSchemaNode
155 val typeSpecBuilder = typeToDefinition.get(ref)
156 val typeSpec = typeSpecBuilder.identifierDefinition;
157 val newret = generateKeyTransformerFor(inputType, typeSpec, node);
158 return newret as Class<? extends BindingCodec<Map<QName,Object>, Object>>;
162 def getIdentifierDefinition(GeneratedTypeBuilder builder) {
163 val inst = builder.toInstance
164 val keyMethod = inst.methodDefinitions.findFirst[name == "getKey"]
165 return keyMethod.returnType as GeneratedTransferObject
168 def Class<? extends BindingCodec<Map<QName, Object>, Object>> keyTransformerForIdentifier(Class<?> inputType) {
169 return withClassLoaderAndLock(inputType.classLoader, lock) [ |
170 val ret = getGeneratedClass(inputType)
172 return ret as Class<? extends BindingCodec<Map<QName,Object>, Object>>;
174 val ref = Types.typeForClass(inputType)
175 val node = typeToSchemaNode.get(ref) as ListSchemaNode
176 val typeSpecBuilder = typeToDefinition.get(ref)
177 val typeSpec = typeSpecBuilder.toInstance();
178 val newret = generateKeyTransformerFor(inputType, typeSpec, node);
179 return newret as Class<? extends BindingCodec<Map<QName,Object>, Object>>;
183 private def Class<?> keyTransformerFor(Class<?> inputType, GeneratedType type, ListSchemaNode schema) {
184 return withClassLoaderAndLock(inputType.classLoader, lock) [ |
185 val transformer = getGeneratedClass(inputType)
186 if (transformer != null) {
189 val newret = generateKeyTransformerFor(inputType, type, schema);
190 return newret as Class<? extends BindingCodec<Map<QName,Object>, Object>>;
194 private def Class<?> getGeneratedClass(Class<? extends Object> cls) {
197 return loadClassWithTCCL(cls.codecClassName)
198 } catch (ClassNotFoundException e) {
203 private def Class<?> keyTransformer(GeneratedType type, ListSchemaNode node) {
204 val cls = loadClassWithTCCL(type.resolvedName + "Key");
205 keyTransformerFor(cls, type, node);
208 private def serializer(Type type) {
209 val cls = loadClassWithTCCL(type.resolvedName);
215 private def Class<?> getValueSerializer(GeneratedTransferObject type) {
216 val cls = loadClassWithTCCL(type.resolvedName);
217 val transformer = cls.generatedClass;
218 if (transformer !== null) {
221 return withClassLoaderAndLock(cls.classLoader, lock) [ |
222 val valueTransformer = generateValueTransformer(cls, type);
223 return valueTransformer;
227 private def Class<?> getValueSerializer(Enumeration type) {
228 val cls = loadClassWithTCCL(type.resolvedName);
229 val transformer = cls.generatedClass;
230 if (transformer !== null) {
234 return withClassLoaderAndLock(cls.classLoader, lock) [ |
235 val valueTransformer = generateValueTransformer(cls, type);
236 return valueTransformer;
240 private def generateKeyTransformerFor(Class<? extends Object> inputType, GeneratedType typeSpec, ListSchemaNode node) {
243 //log.info("Generating DOM Codec for {} with {}", inputType, inputType.classLoader)
244 val properties = typeSpec.allProperties;
245 val ctCls = createClass(inputType.codecClassName) [
246 //staticField(Map,"AUGMENTATION_SERIALIZERS");
247 staticField(it, INSTANCE_IDENTIFIER_CODEC, BindingCodec)
248 staticQNameField(node.QName);
249 implementsType(BINDING_CODEC)
250 method(Object, "toDomStatic", QName, Object) [
251 modifiers = PUBLIC + FINAL + STATIC
254 «QName.name» _resultName;
256 _resultName = «QName.name».create($1,QNAME.getLocalName());
260 java.util.List _childNodes = new java.util.ArrayList();
261 «inputType.resolvedName» value = («inputType.name») $2;
262 «FOR key : node.keyDefinition»
263 «val propertyName = key.getterName»
264 «val keyDef = node.getDataChildByName(key)»
265 «val property = properties.get(propertyName)»
266 «serializeProperty(keyDef, property, propertyName)»;
268 return ($r) java.util.Collections.singletonMap(_resultName,_childNodes);
272 method(Object, "fromDomStatic", QName, Object) [
273 modifiers = PUBLIC + FINAL + STATIC
279 «QName.name» _localQName = $1;
280 java.util.Map _compositeNode = (java.util.Map) $2;
281 boolean _is_empty = true;
282 «FOR key : node.keyDefinition»
283 «val propertyName = key.getterName»
284 «val keyDef = node.getDataChildByName(key)»
285 «val property = properties.get(propertyName)»
286 «deserializeProperty(keyDef, property, propertyName)»;
288 «inputType.resolvedName» _value = new «inputType.name»(«node.keyDefinition.
289 keyConstructorList»);
294 method(Object, "serialize", Object) [
297 java.util.Map.Entry _input = (java.util.Map.Entry) $1;
298 «QName.name» _localQName = («QName.name») _input.getKey();
299 «inputType.name» _keyValue = («inputType.name») _input.getValue();
300 return toDomStatic(_localQName,_keyValue);
304 method(Object, "deserialize", Object) [
306 return fromDomStatic(QNAME,$1);
310 val ret = ctCls.toClassImpl(inputType.classLoader, inputType.protectionDomain)
311 log.info("DOM Codec for {} was generated {}", inputType, ret)
312 return ret as Class<? extends BindingCodec<Map<QName,Object>, ?>>;
313 } catch (Exception e) {
314 processException(inputType, e);
319 private def Class<? extends BindingCodec<Object, Object>> generateCaseCodec(Class<?> inputType, GeneratedType type,
320 ChoiceCaseNode node) {
323 //log.info("Generating DOM Codec for {} with {}, TCCL is: {}", inputType, inputType.classLoader,Thread.currentThread.contextClassLoader)
324 val ctCls = createClass(type.codecClassName) [
325 //staticField(Map,"AUGMENTATION_SERIALIZERS");
326 implementsType(BINDING_CODEC)
327 staticQNameField(node.QName);
328 staticField(it, INSTANCE_IDENTIFIER_CODEC, BindingCodec)
329 staticField(it, AUGMENTATION_CODEC, BindingCodec)
330 method(Object, "toDomStatic", QName, Object) [
331 modifiers = PUBLIC + FINAL + STATIC
334 «QName.name» _resultName = «QName.name».create($1,QNAME.getLocalName());
335 java.util.List _childNodes = new java.util.ArrayList();
336 «type.resolvedName» value = («type.resolvedName») $2;
337 «transformDataContainerBody(type, type.allProperties, node)»
338 return ($r) _childNodes;
342 method(Object, "serialize", Object) [
345 java.util.Map.Entry _input = (java.util.Map.Entry) $1;
346 «QName.name» _localName = QNAME;
347 if(_input.getKey() != null) {
348 _localName = («QName.name») _input.getKey();
350 return toDomStatic(_localName,_input.getValue());
354 method(Object, "fromDomStatic", QName, Object) [
355 modifiers = PUBLIC + FINAL + STATIC
356 body = deserializeBody(type, node)
358 method(Object, "deserialize", Object) [
361 //System.out.println("«type.name»#deserialize: " +$1);
362 java.util.Map.Entry _input = (java.util.Map.Entry) $1;
363 return fromDomStatic((«QName.name»)_input.getKey(),_input.getValue());
369 val ret = ctCls.toClassImpl(inputType.classLoader, inputType.protectionDomain) as Class<? extends BindingCodec<Object, Object>>
370 listener?.onDataContainerCodecCreated(inputType,ret);
371 log.info("DOM Codec for {} was generated {}", inputType, ret)
373 } catch (Exception e) {
374 processException(inputType, e);
379 private def dispatch Class<? extends BindingCodec<Map<QName, Object>, Object>> generateTransformerFor(
380 Class<?> inputType, GeneratedType typeSpec, SchemaNode node) {
383 //log.info("Generating DOM Codec for {} with {}", inputType, inputType.classLoader)
384 val ctCls = createClass(typeSpec.codecClassName) [
385 //staticField(Map,"AUGMENTATION_SERIALIZERS");
386 staticQNameField(node.QName);
387 staticField(it, INSTANCE_IDENTIFIER_CODEC, BindingCodec)
388 staticField(it, AUGMENTATION_CODEC, BindingCodec)
389 implementsType(BINDING_CODEC)
390 method(Object, "toDomStatic", QName, Object) [
391 modifiers = PUBLIC + FINAL + STATIC
392 body = serializeBodyFacade(typeSpec, node)
394 method(Object, "serialize", Object) [
397 java.util.Map.Entry _input = (java.util.Map.Entry) $1;
398 «QName.name» _localName = QNAME;
399 if(_input.getKey() != null) {
400 _localName = («QName.name») _input.getKey();
402 return toDomStatic(_localName,_input.getValue());
406 method(Object, "fromDomStatic", QName, Object) [
407 modifiers = PUBLIC + FINAL + STATIC
408 body = deserializeBody(typeSpec, node)
410 method(Object, "deserialize", Object) [
412 return fromDomStatic(QNAME,$1);
417 val ret = ctCls.toClassImpl(inputType.classLoader, inputType.protectionDomain) as Class<? extends BindingCodec<Map<QName,Object>, Object>>
418 listener?.onDataContainerCodecCreated(inputType, ret);
419 log.info("DOM Codec for {} was generated {}", inputType, ret)
421 } catch (Exception e) {
422 processException(inputType, e);
427 private def Class<? extends BindingCodec<Map<QName, Object>, Object>> generateAugmentationTransformerFor(
428 Class<?> inputType, GeneratedType type, AugmentationSchema node) {
431 //log.info("Generating DOM Codec for {} with {}", inputType, inputType.classLoader)
432 val properties = type.allProperties
433 val ctCls = createClass(type.codecClassName) [
434 //staticField(Map,"AUGMENTATION_SERIALIZERS");
435 staticQNameField(node.augmentationQName);
436 staticField(it, INSTANCE_IDENTIFIER_CODEC, BindingCodec)
437 staticField(it, AUGMENTATION_CODEC, BindingCodec)
438 implementsType(BINDING_CODEC)
439 method(Object, "toDomStatic", QName, Object) [
440 modifiers = PUBLIC + FINAL + STATIC
443 //System.out.println("Qname " + $1);
444 //System.out.println("Value " + $2);
445 «QName.name» _resultName = «QName.name».create($1,QNAME.getLocalName());
446 java.util.List _childNodes = new java.util.ArrayList();
447 «type.resolvedName» value = («type.resolvedName») $2;
448 «FOR child : node.childNodes»
449 «var signature = properties.getFor(child)»
450 //System.out.println("«signature.key»" + value.«signature.key»());
451 «serializeProperty(child, signature.value, signature.key)»
453 return ($r) _childNodes;
457 method(Object, "serialize", Object) [
460 java.util.Map.Entry _input = (java.util.Map.Entry) $1;
461 «QName.name» _localName = QNAME;
462 if(_input.getKey() != null) {
463 _localName = («QName.name») _input.getKey();
465 return toDomStatic(_localName,_input.getValue());
469 method(Object, "fromDomStatic", QName, Object) [
470 modifiers = PUBLIC + FINAL + STATIC
473 «QName.name» _localQName = QNAME;
478 java.util.Map _compositeNode = (java.util.Map) $2;
479 //System.out.println(_localQName + " " + _compositeNode);
480 «type.builderName» _builder = new «type.builderName»();
481 boolean _is_empty = true;
482 «FOR child : node.childNodes»
483 «val signature = properties.getFor(child)»
484 «deserializeProperty(child, signature.value, signature.key)»
485 _builder.«signature.key.toSetter»(«signature.key»);
490 return _builder.build();
494 method(Object, "deserialize", Object) [
496 return fromDomStatic(QNAME,$1);
501 val ret = ctCls.toClassImpl(inputType.classLoader, inputType.protectionDomain) as Class<? extends BindingCodec<Map<QName,Object>, Object>>
502 listener?.onDataContainerCodecCreated(inputType, ret);
504 } catch (Exception e) {
505 processException(inputType, e);
510 private def dispatch Class<? extends BindingCodec<Map<QName, Object>, Object>> generateTransformerFor(
511 Class<?> inputType, GeneratedType typeSpec, ChoiceNode node) {
514 //log.info("Generating DOM Codec for {} with {}", inputType, inputType.classLoader)
515 val ctCls = createClass(typeSpec.codecClassName) [
516 //staticField(Map,"AUGMENTATION_SERIALIZERS");
517 //staticQNameField(inputType);
518 staticField(it, INSTANCE_IDENTIFIER_CODEC, BindingCodec)
519 staticField(it, CLASS_TO_CASE_MAP, Map)
520 staticField(it, COMPOSITE_TO_CASE, Map)
521 //staticField(it,QNAME_TO_CASE_MAP,BindingCodec)
522 implementsType(BINDING_CODEC)
523 method(List, "toDomStatic", QName, Object) [
524 modifiers = PUBLIC + FINAL + STATIC
530 «DataObject.name» _baValue = («DataObject.name») $2;
531 Class _baClass = _baValue.getImplementedInterface();
532 «BINDING_CODEC.name» _codec = «CLASS_TO_CASE_MAP».get(_baClass);
536 java.util.Map.Entry _input = new «SimpleEntry.name»($1,_baValue);
537 Object _ret = _codec.serialize(_input);
538 //System.out.println("«typeSpec.name»#toDomStatic: " + _ret);
539 return («List.name») _ret;
543 method(Object, "serialize", Object) [
545 throw new «UnsupportedOperationException.name»("Direct invocation not supported.");
548 method(Object, "fromDomStatic", QName, Map) [
549 modifiers = PUBLIC + FINAL + STATIC
552 «BINDING_CODEC.name» _codec = («BINDING_CODEC.name») «COMPOSITE_TO_CASE».get($2);
554 return _codec.deserialize(new «SimpleEntry.name»($1,$2));
560 method(Object, "deserialize", Object) [
562 throw new «UnsupportedOperationException.name»("Direct invocation not supported.");
567 val rawRet = ctCls.toClassImpl(inputType.classLoader, inputType.protectionDomain)
568 val ret = rawRet as Class<? extends BindingCodec<Map<QName,Object>, Object>>;
569 listener?.onChoiceCodecCreated(inputType, ret, node);
570 log.info("DOM Codec for {} was generated {}", inputType, ret)
572 } catch (Exception e) {
573 processException(inputType, e);
578 private def keyConstructorList(List<QName> qnames) {
579 val names = new TreeSet<String>()
580 for (name : qnames) {
581 val fieldName = name.getterName;
582 names.add(fieldName);
584 return Joiner.on(",").join(names);
587 private def serializeBodyFacade(GeneratedType type, SchemaNode node) {
588 val ret = serializeBody(type, node);
592 private def String deserializeBody(GeneratedType type, SchemaNode node) {
593 val ret = deserializeBodyImpl(type, node);
597 private def deserializeKey(GeneratedType type, ListSchemaNode node) {
598 if (node.keyDefinition != null && !node.keyDefinition.empty) {
600 «type.resolvedName»Key getKey = («type.resolvedName»Key) «keyTransformer(type, node).canonicalName».fromDomStatic(_localQName,_compositeNode);
601 _builder.setKey(getKey);
606 private def dispatch String deserializeBodyImpl(GeneratedType type, SchemaNode node) '''
608 «QName.name» _localQName = «QName.name».create($1,QNAME.getLocalName());
613 java.util.Map _compositeNode = (java.util.Map) $2;
614 «type.builderName» _builder = new «type.builderName»();
615 return _builder.build();
619 private def dispatch String deserializeBodyImpl(GeneratedType type, ListSchemaNode node) '''
621 «QName.name» _localQName = «QName.name».create($1,QNAME.getLocalName());
625 java.util.Map _compositeNode = (java.util.Map) $2;
626 «type.builderName» _builder = new «type.builderName»();
627 «deserializeKey(type, node)»
628 «deserializeDataNodeContainerBody(type, node)»
629 «deserializeAugmentations»
630 return _builder.build();
634 private def dispatch String deserializeBodyImpl(GeneratedType type, ContainerSchemaNode node) '''
636 «QName.name» _localQName = «QName.name».create($1,QNAME.getLocalName());
640 java.util.Map _compositeNode = (java.util.Map) $2;
641 «type.builderName» _builder = new «type.builderName»();
642 «deserializeDataNodeContainerBody(type, node)»
643 «deserializeAugmentations»
644 return _builder.build();
648 private def dispatch String deserializeBodyImpl(GeneratedType type, ChoiceCaseNode node) '''
650 «QName.name» _localQName = «QName.name».create($1,QNAME.getLocalName());
655 java.util.Map _compositeNode = (java.util.Map) $2;
656 //System.out.println(_localQName + " " + _compositeNode);
657 «type.builderName» _builder = new «type.builderName»();
658 «deserializeDataNodeContainerBody(type, node)»
659 «deserializeAugmentations»
660 return _builder.build();
664 private def deserializeDataNodeContainerBody(GeneratedType type, DataNodeContainer node) {
665 deserializeNodeContainerBodyImpl(type, type.allProperties, node);
668 private def deserializeNodeContainerBodyImpl(GeneratedType type, HashMap<String, Type> properties,
669 DataNodeContainer node) {
671 boolean _is_empty = true;
672 «FOR child : node.childNodes»
673 «val signature = properties.getFor(child)»
674 «IF signature !== null»
675 «deserializeProperty(child, signature.value, signature.key)»
676 _builder.«signature.key.toSetter»(«signature.key»);
683 def deserializeAugmentations() '''
684 java.util.Map _augmentation = (java.util.Map) «AUGMENTATION_CODEC».deserialize(_compositeNode);
685 if(_augmentation != null) {
686 «Iterator.name» _entries = _augmentation.entrySet().iterator();
687 while(_entries.hasNext()) {
688 java.util.Map.Entry _entry = (java.util.Map.Entry) _entries.next();
689 //System.out.println("Aug. key:" + _entry.getKey());
690 Class _type = (Class) _entry.getKey();
691 «Augmentation.resolvedName» _value = («Augmentation.name») _entry.getValue();
693 _builder.addAugmentation(_type,_value);
699 private def dispatch CharSequence deserializeProperty(ListSchemaNode schema, ParameterizedType type,
700 String propertyName) '''
701 java.util.List _dom_«propertyName» = _compositeNode.get(«QName.name».create(_localQName,"«schema.QName.
703 //System.out.println("«propertyName»#deCode"+_dom_«propertyName»);
704 java.util.List «propertyName» = new java.util.ArrayList();
705 if(_dom_«propertyName» != null) {
706 java.util.List _serialized = new java.util.ArrayList();
707 java.util.Iterator _iterator = _dom_«propertyName».iterator();
708 boolean _hasNext = _iterator.hasNext();
710 Object _listItem = _iterator.next();
712 //System.out.println(" item" + _listItem);
713 Object _value = «type.actualTypeArguments.get(0).serializer.resolvedName».fromDomStatic(_localQName,_listItem);
714 //System.out.println(" value" + _value);
715 «propertyName».add(_value);
716 _hasNext = _iterator.hasNext();
720 //System.out.println(" list" + «propertyName»);
723 private def dispatch CharSequence deserializeProperty(LeafListSchemaNode schema, ParameterizedType type,
724 String propertyName) '''
725 java.util.List _dom_«propertyName» = _compositeNode.get(«QName.name».create(_localQName,"«schema.QName.
727 java.util.List «propertyName» = new java.util.ArrayList();
728 if(_dom_«propertyName» != null) {
729 java.util.List _serialized = new java.util.ArrayList();
730 java.util.Iterator _iterator = _dom_«propertyName».iterator();
731 boolean _hasNext = _iterator.hasNext();
734 Object _listItem = _iterator.next();
735 if(_listItem instanceof java.util.Map.Entry) {
736 Object _innerValue = ((java.util.Map.Entry) _listItem).getValue();
737 Object _value = «deserializeValue(type.actualTypeArguments.get(0), "_innerValue")»;
738 «propertyName».add(_value);
740 _hasNext = _iterator.hasNext();
745 private def dispatch CharSequence deserializeProperty(LeafSchemaNode schema, Type type, String propertyName) '''
746 java.util.List _dom_«propertyName»_list =
747 _compositeNode.get(«QName.name».create(_localQName,"«schema.QName.localName»"));
748 «type.resolvedName» «propertyName» = null;
749 if(_dom_«propertyName»_list != null && _dom_«propertyName»_list.size() > 0) {
751 java.util.Map.Entry _dom_«propertyName» = (java.util.Map.Entry) _dom_«propertyName»_list.get(0);
752 Object _inner_value = _dom_«propertyName».getValue();
753 «propertyName» = «deserializeValue(type, "_inner_value")»;
757 private def dispatch CharSequence deserializeProperty(ContainerSchemaNode schema, Type type,
758 String propertyName) '''
759 java.util.List _dom_«propertyName»_list =
760 _compositeNode.get(«QName.name».create(_localQName,"«schema.QName.localName»"));
761 «type.resolvedName» «propertyName» = null;
762 if(_dom_«propertyName»_list != null && _dom_«propertyName»_list.size() > 0) {
764 java.util.Map _dom_«propertyName» = (java.util.Map) _dom_«propertyName»_list.get(0);
765 «propertyName» = «type.serializer.resolvedName».fromDomStatic(_localQName,_dom_«propertyName»);
769 private def dispatch CharSequence deserializeProperty(ChoiceNode schema, Type type, String propertyName) '''
770 «type.resolvedName» «propertyName» = «type.serializer.resolvedName».fromDomStatic(_localQName,_compositeNode);
771 if(«propertyName» != null) {
776 private def dispatch String deserializeValue(GeneratedTransferObject type, String domParameter) '''
777 («type.resolvedName») «type.valueSerializer.resolvedName».fromDomValue(«domParameter»)
780 private def dispatch String deserializeValue(Enumeration type, String domParameter) '''
781 («type.resolvedName») «type.valueSerializer.resolvedName».fromDomValue(«domParameter»)
784 private def dispatch Class<? extends BindingCodec<Map<QName, Object>, Object>> generateValueTransformer(
785 Class<?> inputType, GeneratedTransferObject typeSpec) {
788 val returnType = typeSpec.valueReturnType;
789 if (returnType == null) {
790 val ctCls = createDummyImplementation(inputType, typeSpec);
791 val ret = ctCls.toClassImpl(inputType.classLoader, inputType.protectionDomain)
792 return ret as Class<? extends BindingCodec<Map<QName,Object>, Object>>;
794 var hasBinding = false;
796 val bindingCodecClass = loadClassWithTCCL(BINDING_CODEC.name);
797 hasBinding = bindingCodecClass !== null;
798 } catch (ClassNotFoundException e) {
801 val hasYangBinding = hasBinding
802 val ctCls = createClass(typeSpec.codecClassName) [
803 //staticField(Map,"AUGMENTATION_SERIALIZERS");
804 if (hasYangBinding) {
805 implementsType(BINDING_CODEC)
806 staticField(it, INSTANCE_IDENTIFIER_CODEC, BindingCodec)
807 implementsType(BindingDeserializer.asCtClass)
809 method(Object, "toDomValue", Object) [
810 modifiers = PUBLIC + FINAL + STATIC
813 //System.out.println("«inputType.simpleName»#toDomValue: "+$1);
818 «typeSpec.resolvedName» _encapsulatedValue = («typeSpec.resolvedName») $1;
819 //System.out.println("«inputType.simpleName»#toDomValue:Enc: "+_encapsulatedValue);
820 «returnType.resolvedName» _value = _encapsulatedValue.getValue();
821 //System.out.println("«inputType.simpleName»#toDomValue:DeEnc: "+_value);
822 Object _domValue = «serializeValue(returnType, "_value")»;
827 method(Object, "serialize", Object) [
830 return toDomValue($1);
834 method(Object, "fromDomValue", Object) [
835 modifiers = PUBLIC + FINAL + STATIC
838 //System.out.println("«inputType.simpleName»#fromDomValue: "+$1);
843 «returnType.resolvedName» _simpleValue = «deserializeValue(returnType, "$1")»;
844 «typeSpec.resolvedName» _value = new «typeSpec.resolvedName»(_simpleValue);
849 method(Object, "deserialize", Object) [
851 return fromDomValue($1);
857 val ret = ctCls.toClassImpl(inputType.classLoader, inputType.protectionDomain)
858 log.info("DOM Codec for {} was generated {}", inputType, ret)
859 return ret as Class<? extends BindingCodec<Map<QName,Object>, Object>>;
860 } catch (Exception e) {
861 log.error("Cannot compile DOM Codec for {}", inputType, e);
862 val exception = new CodeGenerationException("Cannot compile Transformator for " + inputType);
863 exception.addSuppressed(e);
869 private def createDummyImplementation(Class<?> object, GeneratedTransferObject typeSpec) {
870 log.info("Generating Dummy DOM Codec for {} with {}", object, object.classLoader)
871 return createClass(typeSpec.codecClassName) [
872 //staticField(Map,"AUGMENTATION_SERIALIZERS");
873 implementsType(BINDING_CODEC)
874 implementsType(BindingDeserializer.asCtClass)
875 method(Object, "toDomValue", Object) [
876 modifiers = PUBLIC + FINAL + STATIC
877 body = '''return null;'''
879 method(Object, "serialize", Object) [
882 return toDomValue($1);
886 method(Object, "fromDomValue", Object) [
887 modifiers = PUBLIC + FINAL + STATIC
888 body = '''return null;'''
890 method(Object, "deserialize", Object) [
892 return fromDomValue($1);
899 private def Type getValueReturnType(GeneratedTransferObject object) {
900 for (prop : object.properties) {
901 if (prop.name == "value") {
902 return prop.returnType;
905 if (object.superType != null) {
906 return getValueReturnType(object.superType);
911 private def dispatch Class<?> generateValueTransformer(Class<?> inputType, Enumeration typeSpec) {
913 val typeRef = new ReferencedTypeImpl(typeSpec.packageName, typeSpec.name);
914 val schema = typeToSchemaNode.get(typeRef) as ExtendedType;
915 val enumSchema = schema.baseType as EnumerationType;
917 //log.info("Generating DOM Codec for {} with {}", inputType, inputType.classLoader)
918 val ctCls = createClass(typeSpec.codecClassName) [
919 //staticField(Map,"AUGMENTATION_SERIALIZERS");
920 //implementsType(BINDING_CODEC)
921 method(Object, "toDomValue", Object) [
922 modifiers = PUBLIC + FINAL + STATIC
927 «typeSpec.resolvedName» _value = («typeSpec.resolvedName») $1;
928 «FOR en : enumSchema.values»
929 if(«typeSpec.resolvedName».«BindingGeneratorUtil.parseToClassName(en.name)».equals(_value)) {
937 method(Object, "serialize", Object) [
939 return toDomValue($1);
942 method(Object, "fromDomValue", Object) [
943 modifiers = PUBLIC + FINAL + STATIC
949 String _value = (String) $1;
950 «FOR en : enumSchema.values»
951 if("«en.name»".equals(_value)) {
952 return «typeSpec.resolvedName».«BindingGeneratorUtil.parseToClassName(en.name)»;
959 method(Object, "deserialize", Object) [
961 return fromDomValue($1);
966 val ret = ctCls.toClassImpl(inputType.classLoader, inputType.protectionDomain)
967 log.info("DOM Codec for {} was generated {}", inputType, ret)
969 } catch (CodeGenerationException e) {
970 throw new CodeGenerationException("Cannot compile Transformator for " + inputType, e);
971 } catch (Exception e) {
972 log.error("Cannot compile DOM Codec for {}", inputType, e);
973 val exception = new CodeGenerationException("Cannot compile Transformator for " + inputType);
974 exception.addSuppressed(e);
980 def Class<?> toClassImpl(CtClass newClass, ClassLoader loader, ProtectionDomain domain) {
981 val cls = newClass.toClass(loader, domain);
982 if (classFileCapturePath !== null) {
983 newClass.writeFile(classFileCapturePath.absolutePath);
985 listener?.onCodecCreated(cls);
989 def debugWriteClass(CtClass class1) {
990 val path = class1.name.replace(".", "/") + ".class"
992 val captureFile = new File(classFileCapturePath, path);
993 captureFile.createNewFile
997 private def dispatch String deserializeValue(Type type, String domParameter) {
998 if (INSTANCE_IDENTIFIER.equals(type)) {
1000 return '''(«InstanceIdentifier.name») «INSTANCE_IDENTIFIER_CODEC».deserialize(«domParameter»)'''
1003 return '''(«type.resolvedName») «domParameter»'''
1011 private def dispatch CharSequence deserializeProperty(DataSchemaNode container, Type type, String propertyName) '''
1012 «type.resolvedName» «propertyName» = null;
1015 private def dispatch CharSequence deserializeProperty(DataSchemaNode container, GeneratedTypeBuilder type,
1016 String propertyName) {
1017 _deserializeProperty(container, type.toInstance, propertyName)
1020 public static def toSetter(String it) {
1022 if (startsWith("is")) {
1023 return "set" + substring(2);
1024 } else if (startsWith("get")) {
1025 return "set" + substring(3);
1031 private def dispatch CharSequence deserializeProperty(DataSchemaNode container,GeneratedType type, String propertyName) '''
1032 «type.resolvedName» «propertyName» = value.«propertyName»();
1033 if(«propertyName» != null) {
1034 Object domValue = «type.serializer».toDomStatic(QNAME,«propertyName»);
1035 _childNodes.add(domValue);
1039 private def getBuilderName(GeneratedType type) '''«type.resolvedName»Builder'''
1041 private def staticQNameField(CtClass it, QName node) {
1042 val field = new CtField(ctQName, "QNAME", it);
1043 field.modifiers = PUBLIC + FINAL + STATIC;
1045 '''«QName.asCtClass.name».create("«node.namespace»","«node.formattedRevision»","«node.localName»")''')
1048 private def dispatch String serializeBody(GeneratedType type, ListSchemaNode node) '''
1050 «QName.name» _resultName = «QName.name».create($1,QNAME.getLocalName());
1051 java.util.List _childNodes = new java.util.ArrayList();
1052 «type.resolvedName» value = («type.resolvedName») $2;
1053 «transformDataContainerBody(type, type.allProperties, node)»
1054 «serializeAugmentations»
1055 return ($r) java.util.Collections.singletonMap(_resultName,_childNodes);
1059 private def dispatch String serializeBody(GeneratedType type, ContainerSchemaNode node) '''
1061 «QName.name» _resultName = «QName.name».create($1,QNAME.getLocalName());
1062 java.util.List _childNodes = new java.util.ArrayList();
1063 «type.resolvedName» value = («type.resolvedName») $2;
1064 «transformDataContainerBody(type, type.allProperties, node)»
1065 «serializeAugmentations»
1066 return ($r) java.util.Collections.singletonMap(_resultName,_childNodes);
1070 private def dispatch String serializeBody(GeneratedType type, ChoiceCaseNode node) '''
1072 «QName.name» _resultName = «QName.name».create($1,QNAME.getLocalName());
1073 java.util.List _childNodes = new java.util.ArrayList();
1074 «type.resolvedName» value = («type.resolvedName») $2;
1075 «transformDataContainerBody(type, type.allProperties, node)»
1076 «serializeAugmentations»
1077 return ($r) java.util.Collections.singletonMap(_resultName,_childNodes);
1081 private def dispatch String serializeBody(GeneratedType type, SchemaNode node) '''
1083 «QName.name» _resultName = «QName.name».create($1,QNAME.getLocalName());
1084 java.util.List _childNodes = new java.util.ArrayList();
1085 «type.resolvedName» value = («type.resolvedName») $2;
1086 return ($r) java.util.Collections.singletonMap(_resultName,_childNodes);
1090 private def transformDataContainerBody(Type type, Map<String, Type> properties, DataNodeContainer node) {
1092 «FOR child : node.childNodes»
1093 «val signature = properties.getFor(child)»
1094 «IF signature !== null»
1095 //System.out.println("«type.name»#«signature.key»" + value.«signature.key»());
1096 «serializeProperty(child, signature.value, signature.key)»
1103 private def serializeAugmentations() '''
1104 java.util.List _augmentations = (java.util.List) «AUGMENTATION_CODEC».serialize(value);
1105 if(_augmentations != null) {
1106 _childNodes.addAll(_augmentations);
1110 def Entry<String, Type> getFor(Map<String, Type> map, DataSchemaNode node) {
1111 var sig = map.get(node.getterName);
1113 return new SimpleEntry(node.getterName, sig);
1115 sig = map.get(node.booleanGetterName);
1117 return new SimpleEntry(node.booleanGetterName, map.get(node.booleanGetterName));
1122 private static def String getBooleanGetterName(DataSchemaNode node) {
1123 return "is" + BindingGeneratorUtil.parseToClassName(node.QName.localName);
1126 private static def String getGetterName(DataSchemaNode node) {
1127 return "get" + BindingGeneratorUtil.parseToClassName(node.QName.localName);
1130 private static def String getGetterName(QName node) {
1131 return "get" + BindingGeneratorUtil.parseToClassName(node.localName);
1134 private def dispatch CharSequence serializeProperty(ListSchemaNode schema, ParameterizedType type,
1135 String propertyName) '''
1136 «type.resolvedName» «propertyName» = value.«propertyName»();
1137 //System.out.println("«propertyName»:" + «propertyName»);
1138 if(«propertyName» != null) {
1139 java.util.Iterator _iterator = «propertyName».iterator();
1140 boolean _hasNext = _iterator.hasNext();
1142 Object _listItem = _iterator.next();
1143 Object _domValue = «type.actualTypeArguments.get(0).serializer.resolvedName».toDomStatic(_resultName,_listItem);
1144 _childNodes.add(_domValue);
1145 _hasNext = _iterator.hasNext();
1150 private def dispatch CharSequence serializeProperty(LeafSchemaNode schema, Type type, String propertyName) '''
1151 «type.resolvedName» «propertyName» = value.«propertyName»();
1153 if(«propertyName» != null) {
1154 «QName.name» _qname = «QName.name».create(_resultName,"«schema.QName.localName»");
1155 Object _propValue = «serializeValue(type, propertyName)»;
1156 if(_propValue != null) {
1157 Object _domValue = java.util.Collections.singletonMap(_qname,_propValue);
1158 _childNodes.add(_domValue);
1163 private def dispatch serializeValue(GeneratedTransferObject type, String parameter) '''«type.valueSerializer.
1164 resolvedName».toDomValue(«parameter»)'''
1166 private def dispatch serializeValue(Enumeration type, String parameter) '''«type.valueSerializer.resolvedName».toDomValue(«parameter»)'''
1168 private def dispatch serializeValue(Type signature, String property) {
1169 if (INSTANCE_IDENTIFIER == signature) {
1170 return '''«INSTANCE_IDENTIFIER_CODEC».serialize(«property»)'''
1172 return '''«property»''';
1175 private def dispatch CharSequence serializeProperty(LeafListSchemaNode schema, ParameterizedType type,
1176 String propertyName) '''
1177 «type.resolvedName» «propertyName» = value.«propertyName»();
1178 if(«propertyName» != null) {
1179 «QName.name» _qname = «QName.name».create(_resultName,"«schema.QName.localName»");
1180 java.util.Iterator _iterator = «propertyName».iterator();
1181 boolean _hasNext = _iterator.hasNext();
1183 Object _listItem = _iterator.next();
1184 Object _propValue = «serializeValue(type.actualTypeArguments.get(0), "_listItem")»;
1185 Object _domValue = java.util.Collections.singletonMap(_qname,_propValue);
1186 _childNodes.add(_domValue);
1187 _hasNext = _iterator.hasNext();
1192 private def dispatch CharSequence serializeProperty(ChoiceNode container, GeneratedType type,
1193 String propertyName) '''
1194 «type.resolvedName» «propertyName» = value.«propertyName»();
1195 if(«propertyName» != null) {
1196 java.util.List domValue = «type.serializer.resolvedName».toDomStatic(_resultName,«propertyName»);
1197 _childNodes.addAll(domValue);
1205 private def dispatch CharSequence serializeProperty(DataSchemaNode container, Type type, String propertyName) '''
1206 «type.resolvedName» «propertyName» = value.«propertyName»();
1207 if(«propertyName» != null) {
1208 Object domValue = «propertyName»;
1209 _childNodes.add(domValue);
1213 private def dispatch CharSequence serializeProperty(DataSchemaNode container, GeneratedTypeBuilder type,
1214 String propertyName) {
1215 serializeProperty(container, type.toInstance, propertyName)
1218 private def dispatch CharSequence serializeProperty(DataSchemaNode container, GeneratedType type,
1219 String propertyName) '''
1220 «type.resolvedName» «propertyName» = value.«propertyName»();
1221 if(«propertyName» != null) {
1222 Object domValue = «type.serializer.resolvedName».toDomStatic(_resultName,«propertyName»);
1223 _childNodes.add(domValue);
1227 private def codecClassName(GeneratedType typeSpec) {
1228 return '''«typeSpec.resolvedName»$Broker$Codec$DOM'''
1231 private def codecClassName(Class<?> typeSpec) {
1232 return '''«typeSpec.name»$Broker$Codec$DOM'''
1235 private def HashMap<String, Type> getAllProperties(GeneratedType type) {
1236 val ret = new HashMap<String, Type>();
1237 type.collectAllProperties(ret);
1241 private def dispatch void collectAllProperties(GeneratedType type, Map<String, Type> set) {
1242 for (definition : type.methodDefinitions) {
1243 set.put(definition.name, definition.returnType);
1245 for (property : type.properties) {
1246 set.put(property.getterName, property.returnType);
1248 for (parent : type.implements) {
1249 parent.collectAllProperties(set);
1253 def String getGetterName(GeneratedProperty property) {
1254 return "get" + property.name.toFirstUpper
1257 private def dispatch void collectAllProperties(Type type, Map<String, Type> set) {
1258 // NOOP for generic type.
1261 def String getResolvedName(Type type) {
1262 return type.asCtClass.name;
1265 def String getResolvedName(Class<?> type) {
1266 return type.asCtClass.name;
1269 def CtClass asCtClass(Type type) {
1270 val cls = loadClassWithTCCL(type.fullyQualifiedName)
1271 return cls.asCtClass;
1274 private def dispatch processException(Class<?> inputType, CodeGenerationException e) {
1275 log.error("Cannot compile DOM Codec for {}. One of it's prerequisites was not generated.", inputType);
1279 private def dispatch processException(Class<?> inputType, Exception e) {
1280 log.error("Cannot compile DOM Codec for {}", inputType, e);
1281 val exception = new CodeGenerationException("Cannot compile Transformator for " + inputType, e);
1288 class PropertyPair {
1297 SchemaNode schemaNode;