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 com.google.common.base.Joiner
12 import java.security.ProtectionDomain
13 import java.util.AbstractMap.SimpleEntry
14 import java.util.Collection
15 import java.util.Collections
16 import java.util.HashMap
17 import java.util.HashSet
18 import java.util.Iterator
21 import java.util.Map.Entry
23 import java.util.TreeSet
24 import javassist.CannotCompileException
25 import javassist.ClassPool
26 import javassist.CtClass
27 import javassist.CtField
28 import javassist.CtMethod
29 import org.opendaylight.yangtools.binding.generator.util.BindingGeneratorUtil
30 import org.opendaylight.yangtools.binding.generator.util.ReferencedTypeImpl
31 import org.opendaylight.yangtools.binding.generator.util.Types
32 import org.opendaylight.yangtools.sal.binding.generator.util.ClassLoaderUtils
33 import org.opendaylight.yangtools.sal.binding.generator.util.CodeGenerationException
34 import org.opendaylight.yangtools.sal.binding.generator.util.XtendHelper
35 import org.opendaylight.yangtools.sal.binding.model.api.Enumeration
36 import org.opendaylight.yangtools.sal.binding.model.api.GeneratedProperty
37 import org.opendaylight.yangtools.sal.binding.model.api.GeneratedTransferObject
38 import org.opendaylight.yangtools.sal.binding.model.api.GeneratedType
39 import org.opendaylight.yangtools.sal.binding.model.api.ParameterizedType
40 import org.opendaylight.yangtools.sal.binding.model.api.Type
41 import org.opendaylight.yangtools.sal.binding.model.api.type.builder.GeneratedTypeBuilder
42 import org.opendaylight.yangtools.yang.binding.Augmentation
43 import org.opendaylight.yangtools.yang.binding.BindingCodec
44 import org.opendaylight.yangtools.yang.binding.BindingDeserializer
45 import org.opendaylight.yangtools.yang.binding.BindingMapping
46 import org.opendaylight.yangtools.yang.binding.DataObject
47 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier
48 import org.opendaylight.yangtools.yang.common.QName
49 import org.opendaylight.yangtools.yang.model.api.AugmentationSchema
50 import org.opendaylight.yangtools.yang.model.api.ChoiceCaseNode
51 import org.opendaylight.yangtools.yang.model.api.ChoiceNode
52 import org.opendaylight.yangtools.yang.model.api.ContainerSchemaNode
53 import org.opendaylight.yangtools.yang.model.api.DataNodeContainer
54 import org.opendaylight.yangtools.yang.model.api.DataSchemaNode
55 import org.opendaylight.yangtools.yang.model.api.LeafListSchemaNode
56 import org.opendaylight.yangtools.yang.model.api.LeafSchemaNode
57 import org.opendaylight.yangtools.yang.model.api.ListSchemaNode
58 import org.opendaylight.yangtools.yang.model.api.NotificationDefinition
59 import org.opendaylight.yangtools.yang.model.api.SchemaNode
60 import org.opendaylight.yangtools.yang.model.api.TypeDefinition
61 import org.opendaylight.yangtools.yang.model.api.type.BitsTypeDefinition
62 import org.opendaylight.yangtools.yang.model.api.type.BitsTypeDefinition.Bit
63 import org.opendaylight.yangtools.yang.model.api.type.EmptyTypeDefinition
64 import org.opendaylight.yangtools.yang.model.api.type.UnionTypeDefinition
65 import org.opendaylight.yangtools.yang.model.util.EnumerationType
66 import org.opendaylight.yangtools.yang.model.util.ExtendedType
67 import org.slf4j.LoggerFactory
69 import static com.google.common.base.Preconditions.*
70 import static javassist.Modifier.*
71 import static org.opendaylight.yangtools.sal.binding.generator.impl.CodecMapping.*
73 import static extension org.opendaylight.yangtools.sal.binding.generator.util.YangSchemaUtils.*
74 import java.util.ArrayList
76 class TransformerGenerator extends AbstractTransformerGenerator {
77 private static val LOG = LoggerFactory.getLogger(TransformerGenerator)
79 public static val STRING = Types.typeForClass(String);
80 public static val BOOLEAN = Types.typeForClass(Boolean);
81 public static val INTEGER = Types.typeForClass(Integer);
82 public static val INSTANCE_IDENTIFIER = Types.typeForClass(InstanceIdentifier);
83 //public static val DECIMAL = Types.typeForClass(Decimal);
84 public static val LONG = Types.typeForClass(Long);
85 public static val CLASS_TYPE = Types.typeForClass(Class);
88 var File classFileCapturePath;
90 val CtClass BINDING_CODEC
93 public new(TypeResolver typeResolver, ClassPool pool) {
94 super(typeResolver, pool)
96 BINDING_CODEC = BindingCodec.asCtClass;
97 ctQName = QName.asCtClass
100 override transformerForImpl(Class inputType) {
101 return runOnClassLoader(inputType.classLoader) [ |
102 val ret = getGeneratedClass(inputType)
104 listener.onClassProcessed(inputType);
105 return ret as Class<? extends BindingCodec<Map<QName,Object>, Object>>;
107 val ref = Types.typeForClass(inputType)
108 val node = getSchemaNode(ref)
109 createMapping(inputType, node, null)
110 val typeSpecBuilder = getDefinition(ref)
111 checkState(typeSpecBuilder !== null, "Could not find typedefinition for %s", inputType.name);
112 val typeSpec = typeSpecBuilder.toInstance();
113 val newret = generateTransformerFor(inputType, typeSpec, node);
114 listener.onClassProcessed(inputType);
115 return newret as Class<? extends BindingCodec<Map<QName,Object>, Object>>;
119 def Class<? extends BindingCodec<Map<QName, Object>, Object>> transformerFor(Class<?> inputType, DataSchemaNode node) {
120 return runOnClassLoader(inputType.classLoader) [ |
121 createMapping(inputType, node, null)
122 val ret = getGeneratedClass(inputType)
124 listener.onClassProcessed(inputType);
125 return ret as Class<? extends BindingCodec<Map<QName,Object>, Object>>;
127 val ref = Types.typeForClass(inputType)
128 var typeSpecBuilder = getDefinition(ref)
129 if (typeSpecBuilder == null) {
130 typeSpecBuilder = getTypeBuilder(node.path);
133 checkState(typeSpecBuilder !== null, "Could not find TypeDefinition for %s, $s", inputType.name, node);
134 val typeSpec = typeSpecBuilder.toInstance();
135 val newret = generateTransformerFor(inputType, typeSpec, node);
136 listener.onClassProcessed(inputType);
137 return newret as Class<? extends BindingCodec<Map<QName,Object>, Object>>;
141 override augmentationTransformerForImpl(Class inputType) {
142 return runOnClassLoader(inputType.classLoader) [ |
144 val ret = getGeneratedClass(inputType)
146 return ret as Class<? extends BindingCodec<Map<QName,Object>, Object>>;
148 val ref = Types.typeForClass(inputType)
149 val node = getAugmentation(ref)
150 val typeSpecBuilder = getDefinition(ref)
151 val typeSpec = typeSpecBuilder.toInstance();
152 //mappingForNodes(node.childNodes, typeSpec.allProperties, bindingId)
153 val newret = generateAugmentationTransformerFor(inputType, typeSpec, node);
154 listener.onClassProcessed(inputType);
155 return newret as Class<? extends BindingCodec<Map<QName,Object>, Object>>;
159 override caseCodecForImpl(Class inputType, ChoiceCaseNode node) {
160 return runOnClassLoader(inputType.classLoader) [ |
161 createMapping(inputType, node, null)
162 val ret = getGeneratedClass(inputType)
164 return ret as Class<? extends BindingCodec<Object, Object>>;
166 val ref = Types.typeForClass(inputType)
167 val typeSpecBuilder = getDefinition(ref)
168 val typeSpec = typeSpecBuilder.toInstance();
169 val newret = generateCaseCodec(inputType, typeSpec, node);
170 return newret as Class<? extends BindingCodec<Object, Object>>;
174 override keyTransformerForIdentifiableImpl(Class parentType) {
175 return runOnClassLoader(parentType.classLoader) [ |
176 val inputName = parentType.name + "Key";
177 val inputType = loadClass(inputName);
178 val ret = getGeneratedClass(inputType)
180 return ret as Class<? extends BindingCodec<Map<QName,Object>, Object>>;
182 val ref = Types.typeForClass(parentType)
183 val node = getSchemaNode(ref) as ListSchemaNode
184 val typeSpecBuilder = getDefinition(ref)
185 val typeSpec = typeSpecBuilder.identifierDefinition;
186 val newret = generateKeyTransformerFor(inputType, typeSpec, node);
187 return newret as Class<? extends BindingCodec<Map<QName,Object>, Object>>;
191 private def void createMapping(Class<?> inputType, SchemaNode node, InstanceIdentifier<?> parentId) {
192 var ClassLoader cl = inputType.classLoader
194 cl = Thread.currentThread.contextClassLoader
196 ClassLoaderUtils.withClassLoader(cl,
198 if (!(node instanceof DataNodeContainer)) {
201 var InstanceIdentifier<?> bindingId = getBindingIdentifierByPath(node.path)
202 if (bindingId != null) {
205 val ref = Types.typeForClass(inputType)
206 var typeSpecBuilder = getDefinition(ref)
207 if (typeSpecBuilder == null) {
208 typeSpecBuilder = getTypeBuilder(node.path);
210 checkState(typeSpecBuilder !== null, "Could not find type definition for %s, $s", inputType.name, node);
211 val typeSpec = typeSpecBuilder.toInstance();
212 var InstanceIdentifier<?> parent
213 if (parentId == null) {
214 bindingId = InstanceIdentifier.create(inputType as Class)
216 putPathToBindingIdentifier(node.path, bindingId)
218 parent = putPathToBindingIdentifier(node.path, parentId, inputType)
220 val Map<String, Type> properties = typeSpec.allProperties
221 if (node instanceof DataNodeContainer) {
222 mappingForNodes((node as DataNodeContainer).childNodes, properties, parent)
223 } else if (node instanceof ChoiceNode) {
224 mappingForNodes((node as ChoiceNode).cases, properties, parent)
230 private def void mappingForNodes(Collection<? extends DataSchemaNode> childNodes, Map<String, Type> properties,
231 InstanceIdentifier<?> parent) {
232 for (DataSchemaNode child : childNodes) {
233 val signature = properties.getFor(child)
234 if (signature != null) {
235 val Type childType = signature.value
236 var Class<?> childTypeClass = null;
237 if (child instanceof ListSchemaNode && childType instanceof ParameterizedType) {
238 childTypeClass = loadClass((childType as ParameterizedType).actualTypeArguments.get(0))
240 childTypeClass = loadClass(childType)
242 createMapping(childTypeClass, child, parent)
247 def getIdentifierDefinition(GeneratedTypeBuilder builder) {
248 val inst = builder.toInstance
249 val keyMethod = inst.methodDefinitions.findFirst[name == "getKey"]
250 return keyMethod.returnType as GeneratedTransferObject
253 override keyTransformerForIdentifierImpl(Class inputType) {
254 return runOnClassLoader(inputType.classLoader) [ |
255 val ret = getGeneratedClass(inputType)
257 return ret as Class<? extends BindingCodec<Map<QName,Object>, Object>>;
259 val ref = Types.typeForClass(inputType)
260 val node = getSchemaNode(ref) as ListSchemaNode
261 val typeSpecBuilder = getDefinition(ref)
262 val typeSpec = typeSpecBuilder.toInstance();
263 val newret = generateKeyTransformerFor(inputType, typeSpec, node);
264 return newret as Class<? extends BindingCodec<Map<QName,Object>, Object>>;
268 private def Class<?> keyTransformerFor(Class<?> inputType, GeneratedType type, ListSchemaNode schema) {
269 return runOnClassLoader(inputType.classLoader) [ |
270 val transformer = getGeneratedClass(inputType)
271 if (transformer != null) {
274 val newret = generateKeyTransformerFor(inputType, type, schema);
275 return newret as Class<? extends BindingCodec<Map<QName,Object>, Object>>;
279 private def Class<?> getGeneratedClass(Class<? extends Object> cls) {
282 return loadClass(cls.codecClassName)
283 } catch (ClassNotFoundException e) {
288 private def Class<?> keyTransformer(GeneratedType type, ListSchemaNode node) {
289 val cls = loadClass(type.resolvedName + "Key");
290 keyTransformerFor(cls, type, node);
293 private def serializer(Type type, DataSchemaNode node) {
294 val cls = loadClass(type.resolvedName);
295 transformerFor(cls, node);
298 private def Class<?> valueSerializer(GeneratedTransferObject type, TypeDefinition<?> typeDefinition) {
299 val cls = loadClass(type.resolvedName);
300 val transformer = cls.generatedClass;
301 if (transformer !== null) {
304 var baseType = typeDefinition;
305 while (baseType.baseType != null) {
306 baseType = baseType.baseType;
308 val finalType = baseType;
309 return runOnClassLoader(cls.classLoader) [ |
310 val valueTransformer = generateValueTransformer(cls, type, finalType);
311 return valueTransformer;
315 private def Class<?> valueSerializer(Enumeration type, TypeDefinition<?> typeDefinition) {
316 val cls = loadClass(type.resolvedName);
317 val transformer = cls.generatedClass;
318 if (transformer !== null) {
322 return runOnClassLoader(cls.classLoader) [ |
323 val valueTransformer = generateValueTransformer(cls, type, typeDefinition);
324 return valueTransformer;
328 private def generateKeyTransformerFor(Class<? extends Object> inputType, GeneratedType typeSpec, ListSchemaNode node) {
331 //log.info("Generating DOM Codec for {} with {}", inputType, inputType.classLoader)
332 val properties = typeSpec.allProperties;
333 val ctCls = createClass(inputType.codecClassName) [
334 //staticField(Map,"AUGMENTATION_SERIALIZERS");
335 staticField(it, INSTANCE_IDENTIFIER_CODEC, BindingCodec)
336 staticField(it, IDENTITYREF_CODEC, BindingCodec)
337 staticQNameField(node.QName);
338 implementsType(BINDING_CODEC)
339 method(Object, "toDomStatic", #[QName, Object]) [
340 modifiers = PUBLIC + FINAL + STATIC
343 «QName.name» _resultName;
345 _resultName = «QName.name».create($1,QNAME.getLocalName());
349 java.util.List _childNodes = new java.util.ArrayList();
350 «inputType.resolvedName» value = («inputType.name») $2;
351 «FOR key : node.keyDefinition»
352 «val propertyName = key.getterName»
353 «val keyDef = node.getDataChildByName(key)»
354 «val property = properties.get(propertyName)»
355 «serializeProperty(keyDef, property, propertyName)»;
357 return ($r) java.util.Collections.singletonMap(_resultName,_childNodes);
361 method(Object, "fromDomStatic", #[QName, Object]) [
362 modifiers = PUBLIC + FINAL + STATIC
368 «QName.name» _localQName = $1;
369 java.util.Map _compositeNode = (java.util.Map) $2;
370 boolean _is_empty = true;
371 «FOR key : node.keyDefinition»
372 «val propertyName = key.getterName»
373 «val keyDef = node.getDataChildByName(key)»
374 «val property = properties.get(propertyName)»
375 «deserializeProperty(keyDef, property, propertyName)»;
377 «inputType.resolvedName» _value = new «inputType.name»(«node.keyDefinition.
378 keyConstructorList»);
383 method(Object, "serialize", Object) [
386 java.util.Map.Entry _input = (java.util.Map.Entry) $1;
387 «QName.name» _localQName = («QName.name») _input.getKey();
388 «inputType.name» _keyValue = («inputType.name») _input.getValue();
389 return toDomStatic(_localQName,_keyValue);
393 method(Object, "deserialize", Object) [
396 «QName.name» _qname = QNAME;
397 if($1 instanceof java.util.Map.Entry) {
398 _qname = («QName.name») ((java.util.Map.Entry) $1).getKey();
400 return fromDomStatic(_qname,$1);
405 val ret = ctCls.toClassImpl(inputType.classLoader, inputType.protectionDomain)
406 LOG.debug("DOM Codec for {} was generated {}", inputType, ret)
407 return ret as Class<? extends BindingCodec<Map<QName,Object>, ?>>;
408 } catch (Exception e) {
409 processException(inputType, e);
414 private def Class<? extends BindingCodec<Object, Object>> generateCaseCodec(Class<?> inputType, GeneratedType type,
415 ChoiceCaseNode node) {
417 //log.info("Generating DOM Codec for {} with {}, TCCL is: {}", inputType, inputType.classLoader,Thread.currentThread.contextClassLoader)
418 val ctCls = createClass(type.codecClassName) [
419 //staticField(Map,"AUGMENTATION_SERIALIZERS");
420 implementsType(BINDING_CODEC)
421 staticQNameField(node.QName);
422 staticField(it, INSTANCE_IDENTIFIER_CODEC, BindingCodec)
423 staticField(it, AUGMENTATION_CODEC, BindingCodec)
424 staticField(it, IDENTITYREF_CODEC, BindingCodec)
425 method(Object, "toDomStatic", #[QName, Object]) [
426 modifiers = PUBLIC + FINAL + STATIC
429 «QName.name» _resultName = «QName.name».create($1,QNAME.getLocalName());
430 java.util.List _childNodes = new java.util.ArrayList();
431 «type.resolvedName» value = («type.resolvedName») $2;
432 «transformDataContainerBody(type, type.allProperties, node)»
433 return ($r) _childNodes;
437 method(Object, "serialize", Object) [
440 java.util.Map.Entry _input = (java.util.Map.Entry) $1;
441 «QName.name» _localName = QNAME;
442 if(_input.getKey() != null) {
443 _localName = («QName.name») _input.getKey();
445 return toDomStatic(_localName,_input.getValue());
449 method(Object, "fromDomStatic", #[QName, Object, InstanceIdentifier]) [
450 modifiers = PUBLIC + FINAL + STATIC
451 bodyChecked = deserializeBody(type, node, getBindingIdentifierByPath(node.path))
453 method(Object, "deserialize", #[Object, InstanceIdentifier]) [
456 //System.out.println("«type.name»#deserialize: " +$1);
457 java.util.Map.Entry _input = (java.util.Map.Entry) $1;
458 return fromDomStatic((«QName.name»)_input.getKey(),_input.getValue(),$2);
464 val ret = ctCls.toClassImpl(inputType.classLoader, inputType.protectionDomain) as Class<? extends BindingCodec<Object, Object>>
465 listener?.onDataContainerCodecCreated(inputType, ret);
466 LOG.debug("DOM Codec for {} was generated {}", inputType, ret)
468 } catch (Exception e) {
469 processException(inputType, e);
474 private def dispatch Class<? extends BindingCodec<Map<QName, Object>, Object>> generateTransformerFor(
475 Class<?> inputType, GeneratedType typeSpec, SchemaNode node) {
478 //log.info("Generating DOM Codec for {} with {}", inputType, inputType.classLoader)
479 val ctCls = createClass(typeSpec.codecClassName) [
480 //staticField(Map,"AUGMENTATION_SERIALIZERS");
481 staticQNameField(node.QName);
482 staticField(it, INSTANCE_IDENTIFIER_CODEC, BindingCodec)
483 staticField(it, IDENTITYREF_CODEC, BindingCodec)
484 staticField(it, AUGMENTATION_CODEC, BindingCodec)
485 implementsType(BINDING_CODEC)
487 method(Object, "toDomStatic", #[QName, Object]) [
488 modifiers = PUBLIC + FINAL + STATIC
489 bodyChecked = serializeBodyFacade(typeSpec, node)
491 method(Object, "serialize", Object) [
494 java.util.Map.Entry _input = (java.util.Map.Entry) $1;
495 «QName.name» _localName = QNAME;
496 if(_input.getKey() != null) {
497 _localName = («QName.name») _input.getKey();
499 return toDomStatic(_localName,_input.getValue());
504 method(Object, "fromDomStatic", #[QName, Object, InstanceIdentifier]) [
505 modifiers = PUBLIC + FINAL + STATIC
506 bodyChecked = deserializeBody(typeSpec, node, getBindingIdentifierByPath(node.path))
509 method(Object, "deserialize", #[Object, InstanceIdentifier]) [
512 «QName.name» _qname = QNAME;
513 if($1 instanceof java.util.Map.Entry) {
514 _qname = («QName.name») ((java.util.Map.Entry) $1).getKey();
516 return fromDomStatic(_qname,$1,$2);
522 val ret = ctCls.toClassImpl(inputType.classLoader, inputType.protectionDomain) as Class<? extends BindingCodec<Map<QName,Object>, Object>>
523 listener?.onDataContainerCodecCreated(inputType, ret);
524 LOG.debug("DOM Codec for {} was generated {}", inputType, ret)
526 } catch (Exception e) {
527 processException(inputType, e);
532 private def Class<? extends BindingCodec<Map<QName, Object>, Object>> generateAugmentationTransformerFor(
533 Class<?> inputType, GeneratedType type, AugmentationSchema node) {
536 //log.info("Generating DOM Codec for {} with {}", inputType, inputType.classLoader)
537 val properties = type.allProperties
538 val ctCls = createClass(type.codecClassName) [
539 //staticField(Map,"AUGMENTATION_SERIALIZERS");
540 staticQNameField(node.augmentationQName);
541 staticField(it, INSTANCE_IDENTIFIER_CODEC, BindingCodec)
542 staticField(it, AUGMENTATION_CODEC, BindingCodec)
543 staticField(it, IDENTITYREF_CODEC, BindingCodec)
544 implementsType(BINDING_CODEC)
546 method(Object, "toDomStatic", #[QName, Object]) [
547 modifiers = PUBLIC + FINAL + STATIC
550 ////System.out.println("Qname " + $1);
551 ////System.out.println("Value " + $2);
552 «QName.name» _resultName = «QName.name».create(QNAME,QNAME.getLocalName());
553 java.util.List _childNodes = new java.util.ArrayList();
554 «type.resolvedName» value = («type.resolvedName») $2;
555 «FOR child : node.childNodes»
556 «var signature = properties.getFor(child)»
557 ////System.out.println("«signature.key»" + value.«signature.key»());
558 «serializeProperty(child, signature.value, signature.key)»
560 return ($r) _childNodes;
564 method(Object, "serialize", Object) [
567 java.util.Map.Entry _input = (java.util.Map.Entry) $1;
568 «QName.name» _localName = QNAME;
569 if(_input.getKey() != null) {
570 _localName = («QName.name») _input.getKey();
572 return toDomStatic(_localName,_input.getValue());
577 method(Object, "fromDomStatic", #[QName, Object, InstanceIdentifier]) [
578 modifiers = PUBLIC + FINAL + STATIC
581 «QName.name» _localQName = QNAME;
586 java.util.Map _compositeNode = (java.util.Map) $2;
587 //System.out.println(_localQName + " " + _compositeNode);
588 «type.builderName» _builder = new «type.builderName»();
589 boolean _is_empty = true;
590 «FOR child : node.childNodes»
591 «val signature = properties.getFor(child)»
592 «deserializeProperty(child, signature.value, signature.key)»
593 _builder.«signature.key.toSetter»(«signature.key»);
598 return _builder.build();
603 method(Object, "deserialize", #[Object, InstanceIdentifier]) [
605 return fromDomStatic(QNAME,$1,$2);
610 val ret = ctCls.toClassImpl(inputType.classLoader, inputType.protectionDomain) as Class<? extends BindingCodec<Map<QName,Object>, Object>>
611 listener?.onDataContainerCodecCreated(inputType, ret);
613 } catch (Exception e) {
614 processException(inputType, e);
619 private def dispatch Class<? extends BindingCodec<Map<QName, Object>, Object>> generateTransformerFor(
620 Class<?> inputType, GeneratedType typeSpec, ChoiceNode node) {
623 //log.info("Generating DOM Codec for {} with {}", inputType, inputType.classLoader)
624 val ctCls = createClass(typeSpec.codecClassName) [
625 //staticField(Map,"AUGMENTATION_SERIALIZERS");
626 //staticQNameField(inputType);
627 staticField(it, INSTANCE_IDENTIFIER_CODEC, BindingCodec)
628 staticField(it, IDENTITYREF_CODEC, BindingCodec)
629 staticField(it, DISPATCH_CODEC, BindingCodec)
630 //staticField(it,QNAME_TO_CASE_MAP,BindingCodec)
631 implementsType(BINDING_CODEC)
632 method(List, "toDomStatic", #[QName, Object]) [
633 modifiers = PUBLIC + FINAL + STATIC
639 if («DISPATCH_CODEC» == null) {
640 throw new «IllegalStateException.name»("Implementation of codec was not initialized.");
642 java.util.Map.Entry _input = new «SimpleEntry.name»($1,$2);
643 Object _ret = «DISPATCH_CODEC».serialize(_input);
644 ////System.out.println("«typeSpec.name»#toDomStatic: " + _ret);
645 return («List.name») _ret;
649 method(Object, "serialize", Object) [
651 throw new «UnsupportedOperationException.name»("Direct invocation not supported.");
654 method(Object, "fromDomStatic", #[QName, Map, InstanceIdentifier]) [
655 modifiers = PUBLIC + FINAL + STATIC
658 if («DISPATCH_CODEC» == null) {
659 throw new «IllegalStateException.name»("Implementation of codec was not initialized.");
661 return «DISPATCH_CODEC».deserialize($2,$3);
665 method(Object, "deserialize", #[Object, InstanceIdentifier]) [
667 throw new «UnsupportedOperationException.name»("Direct invocation not supported.");
672 val rawRet = ctCls.toClassImpl(inputType.classLoader, inputType.protectionDomain)
673 val ret = rawRet as Class<? extends BindingCodec<Map<QName,Object>, Object>>;
674 listener?.onChoiceCodecCreated(inputType, ret, node);
675 LOG.debug("DOM Codec for {} was generated {}", inputType, ret)
677 } catch (Exception e) {
678 processException(inputType, e);
683 private def keyConstructorList(List<QName> qnames) {
684 val names = new TreeSet<String>()
685 for (name : qnames) {
686 val fieldName = name.getterName;
687 names.add(fieldName);
689 return Joiner.on(",").join(names);
692 private def serializeBodyFacade(GeneratedType type, SchemaNode node) {
693 val ret = serializeBody(type, node);
697 private def String deserializeBody(GeneratedType type, SchemaNode node, InstanceIdentifier<?> bindingId) {
698 val ret = deserializeBodyImpl(type, node, bindingId);
702 private def deserializeKey(GeneratedType type, ListSchemaNode node) {
703 if (node.keyDefinition != null && !node.keyDefinition.empty) {
705 «type.resolvedName»Key getKey = («type.resolvedName»Key) «keyTransformer(type, node).canonicalName».fromDomStatic(_localQName,_compositeNode);
706 _builder.setKey(getKey);
711 private def String deserializeBodyWithAugmentations(GeneratedType type, DataNodeContainer node, InstanceIdentifier<?> bindingId) '''
713 «QName.name» _localQName = «QName.name».create($1,QNAME.getLocalName());
717 java.util.Map _compositeNode = (java.util.Map) $2;
718 //System.out.println(_localQName + " " + _compositeNode);
719 «type.builderName» _builder = new «type.builderName»();
720 «deserializeDataNodeContainerBody(type, node, bindingId)»
721 «type.deserializeAugmentations»
722 return _builder.build();
726 private def dispatch String deserializeBodyImpl(GeneratedType type, SchemaNode node, InstanceIdentifier<?> bindingId) '''
728 «QName.name» _localQName = «QName.name».create($1,QNAME.getLocalName());
733 java.util.Map _compositeNode = (java.util.Map) $2;
734 «type.builderName» _builder = new «type.builderName»();
735 return _builder.build();
739 private def dispatch String deserializeBodyImpl(GeneratedType type, ListSchemaNode node, InstanceIdentifier<?> bindingId) '''
741 «QName.name» _localQName = «QName.name».create($1,QNAME.getLocalName());
745 java.util.Map _compositeNode = (java.util.Map) $2;
746 //System.out.println(_localQName + " " + _compositeNode);
747 «type.builderName» _builder = new «type.builderName»();
748 «deserializeKey(type, node)»
749 «deserializeDataNodeContainerBody(type, node, bindingId)»
750 «type.deserializeAugmentations»
751 return _builder.build();
755 private def dispatch String deserializeBodyImpl(GeneratedType type, ContainerSchemaNode node, InstanceIdentifier<?> bindingId) {
756 return deserializeBodyWithAugmentations(type, node, bindingId);
759 private def dispatch String deserializeBodyImpl(GeneratedType type, NotificationDefinition node, InstanceIdentifier<?> bindingId) {
760 return deserializeBodyWithAugmentations(type, node, bindingId);
763 private def dispatch String deserializeBodyImpl(GeneratedType type, ChoiceCaseNode node, InstanceIdentifier<?> bindingId) {
764 return deserializeBodyWithAugmentations(type, node, bindingId);
767 private def deserializeDataNodeContainerBody(GeneratedType type, DataNodeContainer node, InstanceIdentifier<?> bindingId) {
768 deserializeNodeContainerBodyImpl(type, type.allProperties, node, bindingId);
771 private def deserializeNodeContainerBodyImpl(GeneratedType type, HashMap<String, Type> properties,
772 DataNodeContainer node, InstanceIdentifier<?> bindingId) {
774 boolean _is_empty = true;
775 «FOR child : node.childNodes»
776 «val signature = properties.getFor(child)»
777 «IF signature !== null»
778 «deserializeProperty(child, signature.value, signature.key)»
779 _builder.«signature.key.toSetter»(«signature.key»);
786 def deserializeAugmentations(GeneratedType type) '''
787 «InstanceIdentifier.resolvedName» iid = $3.builder().child(«type.resolvedName».class).build();
788 java.util.Map _augmentation = (java.util.Map) «AUGMENTATION_CODEC».deserialize(_compositeNode,$3);
789 if(_augmentation != null) {
790 «Iterator.name» _entries = _augmentation.entrySet().iterator();
791 while(_entries.hasNext()) {
792 java.util.Map.Entry _entry = (java.util.Map.Entry) _entries.next();
793 ////System.out.println("Aug. key:" + _entry.getKey());
794 Class _type = (Class) _entry.getKey();
795 «Augmentation.resolvedName» _value = («Augmentation.name») _entry.getValue();
797 _builder.addAugmentation(_type,_value);
803 private def dispatch CharSequence deserializeProperty(ListSchemaNode schema, ParameterizedType type,
804 String propertyName) '''
805 java.util.List _dom_«propertyName» = _compositeNode.get(«QName.name».create(_localQName,"«schema.QName.
807 ////System.out.println("«propertyName»#deCode"+_dom_«propertyName»);
808 java.util.List «propertyName» = new java.util.ArrayList();
809 if(_dom_«propertyName» != null) {
810 java.util.List _serialized = new java.util.ArrayList();
811 java.util.Iterator _iterator = _dom_«propertyName».iterator();
812 boolean _hasNext = _iterator.hasNext();
814 Object _listItem = _iterator.next();
816 ////System.out.println(" item" + _listItem);
817 «val param = type.actualTypeArguments.get(0)»
818 «InstanceIdentifier.resolvedName» iid = $3.builder().child(«param.resolvedName».class).build();
819 Object _value = «type.actualTypeArguments.get(0).serializer(schema).resolvedName».fromDomStatic(_localQName,_listItem,iid);
820 ////System.out.println(" value" + _value);
821 «propertyName».add(_value);
822 _hasNext = _iterator.hasNext();
826 ////System.out.println(" list" + «propertyName»);
829 private def dispatch CharSequence deserializeProperty(LeafListSchemaNode schema, ParameterizedType type,
830 String propertyName) '''
831 java.util.List _dom_«propertyName» = _compositeNode.get(«QName.name».create(_localQName,"«schema.QName.
833 java.util.List «propertyName» = new java.util.ArrayList();
834 if(_dom_«propertyName» != null) {
835 java.util.List _serialized = new java.util.ArrayList();
836 java.util.Iterator _iterator = _dom_«propertyName».iterator();
837 boolean _hasNext = _iterator.hasNext();
840 Object _listItem = _iterator.next();
841 if(_listItem instanceof java.util.Map.Entry) {
842 Object _innerValue = ((java.util.Map.Entry) _listItem).getValue();
843 Object _value = «deserializeValue(type.actualTypeArguments.get(0), "_innerValue", schema.type)»;
844 «propertyName».add(_value);
846 _hasNext = _iterator.hasNext();
851 private def dispatch CharSequence deserializeProperty(LeafSchemaNode schema, Type type, String propertyName) '''
852 java.util.List _dom_«propertyName»_list =
853 _compositeNode.get(«QName.name».create(_localQName,"«schema.QName.localName»"));
854 «type.resolvedName» «propertyName» = null;
855 if(_dom_«propertyName»_list != null && _dom_«propertyName»_list.size() > 0) {
857 java.util.Map.Entry _dom_«propertyName» = (java.util.Map.Entry) _dom_«propertyName»_list.get(0);
858 Object _inner_value = _dom_«propertyName».getValue();
859 «propertyName» = «deserializeValue(type, "_inner_value", schema.type)»;
863 private def dispatch CharSequence deserializeProperty(ContainerSchemaNode schema, Type type,
864 String propertyName) '''
865 java.util.List _dom_«propertyName»_list =
866 _compositeNode.get(«QName.name».create(_localQName,"«schema.QName.localName»"));
867 «type.resolvedName» «propertyName» = null;
868 if(_dom_«propertyName»_list != null && _dom_«propertyName»_list.size() > 0) {
870 java.util.Map _dom_«propertyName» = (java.util.Map) _dom_«propertyName»_list.get(0);
871 «InstanceIdentifier.resolvedName» iid = $3.builder().child(«type.resolvedName».class).build();
872 «propertyName» = «type.serializer(schema).resolvedName».fromDomStatic(_localQName,_dom_«propertyName»,iid);
876 private def dispatch CharSequence deserializeProperty(ChoiceNode schema, Type type, String propertyName) '''
877 «type.resolvedName» «propertyName» = «type.serializer(schema).resolvedName».fromDomStatic(_localQName,_compositeNode,$3);
878 if(«propertyName» != null) {
883 private def dispatch String deserializeValue(GeneratedTransferObject type, String domParameter,
884 TypeDefinition<?> typeDefinition) '''
885 («type.resolvedName») «type.valueSerializer(typeDefinition).resolvedName».fromDomValue(«domParameter»)
888 private def dispatch String deserializeValue(Enumeration type, String domParameter, TypeDefinition<?> typeDefinition) '''
889 («type.resolvedName») «type.valueSerializer(typeDefinition).resolvedName».fromDomValue(«domParameter»)
892 private def dispatch String deserializeValue(Type type, String domParameter, TypeDefinition<?> typeDef) {
893 if (INSTANCE_IDENTIFIER.equals(type)) {
894 return '''(«InstanceIdentifier.name») «INSTANCE_IDENTIFIER_CODEC».deserialize(«domParameter»)'''
895 } else if (CLASS_TYPE.equals(type)) {
896 return '''(«Class.name») «IDENTITYREF_CODEC».deserialize(«domParameter»)'''
897 } else if (typeDef!=null && typeDef instanceof EmptyTypeDefinition) {
898 if(domParameter == null) {
899 return ''' Boolean.FALSE '''
901 return ''' Boolean.TRUE '''
904 return '''(«type.resolvedName») «domParameter»'''
907 private def dispatch Class<? extends BindingCodec<Map<QName, Object>, Object>> generateValueTransformer(
908 Class<?> inputType, GeneratedTransferObject typeSpec, TypeDefinition<?> typeDef) {
911 val returnType = typeSpec.valueReturnType;
912 if (returnType == null) {
913 val ctCls = createDummyImplementation(inputType, typeSpec);
914 val ret = ctCls.toClassImpl(inputType.classLoader, inputType.protectionDomain)
915 return ret as Class<? extends BindingCodec<Map<QName,Object>, Object>>;
918 val ctCls = createClass(typeSpec.codecClassName) [
919 //staticField(Map,"AUGMENTATION_SERIALIZERS");
920 if (inputType.isYangBindingAvailable) {
921 implementsType(BINDING_CODEC)
922 staticField(it, INSTANCE_IDENTIFIER_CODEC, BindingCodec)
923 staticField(it, IDENTITYREF_CODEC, BindingCodec)
924 implementsType(BindingDeserializer.asCtClass)
926 method(Object, "toDomValue", Object) [
927 modifiers = PUBLIC + FINAL + STATIC
928 val ctSpec = typeSpec.asCtClass;
931 ////System.out.println("«inputType.simpleName»#toDomValue: "+$1);
936 «typeSpec.resolvedName» _encapsulatedValue = («typeSpec.resolvedName») $1;
937 ////System.out.println("«inputType.simpleName»#toDomValue:Enc: "+_encapsulatedValue);
938 «returnType.resolvedName» _value = _encapsulatedValue.getValue();
939 ////System.out.println("«inputType.simpleName»#toDomValue:DeEnc: "+_value);
940 Object _domValue = «serializeValue(returnType, "_value", null)»;
945 method(Object, "serialize", Object) [
948 return toDomValue($1);
952 method(Object, "fromDomValue", Object) [
953 modifiers = PUBLIC + FINAL + STATIC
956 ////System.out.println("«inputType.simpleName»#fromDomValue: "+$1);
961 «returnType.resolvedName» _simpleValue = «deserializeValue(returnType, "$1", null)»;
962 «typeSpec.resolvedName» _value = new «typeSpec.resolvedName»(_simpleValue);
967 method(Object, "deserialize", Object) [
969 return fromDomValue($1);
975 val ret = ctCls.toClassImpl(inputType.classLoader, inputType.protectionDomain)
976 LOG.debug("DOM Codec for {} was generated {}", inputType, ret)
977 return ret as Class<? extends BindingCodec<Map<QName,Object>, Object>>;
978 } catch (Exception e) {
979 LOG.error("Cannot compile DOM Codec for {}", inputType, e);
980 val exception = new CodeGenerationException("Cannot compile Transformator for " + inputType);
981 exception.addSuppressed(e);
986 private def dispatch Class<? extends BindingCodec<Map<QName, Object>, Object>> generateValueTransformer(
987 Class<?> inputType, GeneratedTransferObject typeSpec, UnionTypeDefinition typeDef) {
989 val ctCls = createClass(typeSpec.codecClassName) [
990 val properties = typeSpec.allProperties;
991 val getterToTypeDefinition = XtendHelper.getTypes(typeDef).toMap[type|type.QName.getterName];
992 //staticField(Map,"AUGMENTATION_SERIALIZERS");
993 if (inputType.isYangBindingAvailable) {
994 implementsType(BINDING_CODEC)
995 staticField(it, INSTANCE_IDENTIFIER_CODEC, BindingCodec)
996 staticField(it, IDENTITYREF_CODEC, BindingCodec)
997 implementsType(BindingDeserializer.asCtClass)
999 method(Object, "toDomValue", Object) [
1000 modifiers = PUBLIC + FINAL + STATIC
1001 val ctSpec = inputType.asCtClass;
1004 ////System.out.println("«inputType.simpleName»#toDomValue: "+$1);
1009 «typeSpec.resolvedName» _value = («typeSpec.resolvedName») $1;
1010 «FOR property : properties.entrySet»
1011 «IF property.key != "getValue"»
1012 «property.value.resolvedName» «property.key» = («property.value.resolvedName») _value.«property.
1014 if(«property.key» != null) {
1015 return «serializeValue(property.value, property.key,
1016 getterToTypeDefinition.get(property.key))»;
1025 method(Object, "serialize", Object) [
1028 return toDomValue($1);
1032 method(Object, "fromDomValue", Object) [
1033 modifiers = PUBLIC + FINAL + STATIC
1036 ////System.out.println("«inputType.simpleName»#fromDomValue: "+$1);
1041 if($1 instanceof String) {
1042 String _simpleValue = (String) $1;
1043 return new «typeSpec.resolvedName»(_simpleValue.toCharArray());
1049 method(Object, "deserialize", Object) [
1051 return fromDomValue($1);
1057 val ret = ctCls.toClassImpl(inputType.classLoader, inputType.protectionDomain)
1058 LOG.debug("DOM Codec for {} was generated {}", inputType, ret)
1059 return ret as Class<? extends BindingCodec<Map<QName,Object>, Object>>;
1060 } catch (Exception e) {
1061 LOG.error("Cannot compile DOM Codec for {}", inputType, e);
1062 val exception = new CodeGenerationException("Cannot compile Transformator for " + inputType);
1063 exception.addSuppressed(e);
1068 private def dispatch Class<? extends BindingCodec<Map<QName, Object>, Object>> generateValueTransformer(
1069 Class<?> inputType, GeneratedTransferObject typeSpec, BitsTypeDefinition typeDef) {
1071 val ctCls = createClass(typeSpec.codecClassName) [
1072 //staticField(Map,"AUGMENTATION_SERIALIZERS");
1073 if (inputType.isYangBindingAvailable) {
1074 implementsType(BINDING_CODEC)
1075 staticField(it, INSTANCE_IDENTIFIER_CODEC, BindingCodec)
1076 staticField(it, IDENTITYREF_CODEC, BindingCodec)
1077 implementsType(BindingDeserializer.asCtClass)
1079 method(Object, "toDomValue", Object) [
1080 modifiers = PUBLIC + FINAL + STATIC
1081 val ctSpec = typeSpec.asCtClass;
1084 ////System.out.println("«inputType.simpleName»#toDomValue: "+$1);
1089 «typeSpec.resolvedName» _encapsulatedValue = («typeSpec.resolvedName») $1;
1090 «HashSet.resolvedName» _value = new «HashSet.resolvedName»();
1091 //System.out.println("«inputType.simpleName»#toDomValue:Enc: "+_encapsulatedValue);
1093 «FOR bit : typeDef.bits»
1094 «val getter = bit.getterName()»
1095 if(Boolean.TRUE.equals(_encapsulatedValue.«getter»())) {
1096 _value.add("«bit.name»");
1099 «Set.resolvedName» _domValue = «Collections.resolvedName».unmodifiableSet(_value);
1100 //System.out.println("«inputType.simpleName»#toDomValue:DeEnc: "+_domValue);
1106 method(Object, "serialize", Object) [
1109 return toDomValue($1);
1113 method(Object, "fromDomValue", Object) [
1114 modifiers = PUBLIC + FINAL + STATIC
1115 val sortedBits = new ArrayList(typeDef.bits)
1116 Collections.sort(sortedBits, [o1, o2|
1117 o1.propertyName.compareTo(o2.propertyName)
1121 //System.out.println("«inputType.simpleName»#fromDomValue: "+$1);
1126 «Set.resolvedName» _domValue = («Set.resolvedName») $1;
1127 «FOR bit : sortedBits»
1128 Boolean «bit.propertyName» = Boolean.valueOf(_domValue.contains("«bit.name»"));
1131 return new «inputType.resolvedName»(«FOR bit : sortedBits SEPARATOR ","»«bit.propertyName»«ENDFOR»);
1135 method(Object, "deserialize", Object) [
1137 return fromDomValue($1);
1143 val ret = ctCls.toClassImpl(inputType.classLoader, inputType.protectionDomain)
1144 LOG.debug("DOM Codec for {} was generated {}", inputType, ret)
1145 return ret as Class<? extends BindingCodec<Map<QName,Object>, Object>>;
1146 } catch (Exception e) {
1147 LOG.error("Cannot compile DOM Codec for {}", inputType, e);
1148 val exception = new CodeGenerationException("Cannot compile Transformator for " + inputType);
1149 exception.addSuppressed(e);
1154 def String getPropertyName(Bit bit) {
1155 '''_«BindingGeneratorUtil.parseToValidParamName(bit.name)»'''
1158 def String getterName(Bit bit) {
1160 val paramName = BindingGeneratorUtil.parseToValidParamName(bit.name);
1161 return '''is«paramName.toFirstUpper»''';
1164 def boolean isYangBindingAvailable(Class<?> class1) {
1166 val bindingCodecClass = class1.classLoader.loadClass(BINDING_CODEC.name);
1167 return bindingCodecClass !== null;
1168 } catch (ClassNotFoundException e) {
1173 private def createDummyImplementation(Class<?> object, GeneratedTransferObject typeSpec) {
1174 LOG.trace("Generating Dummy DOM Codec for {} with {}", object, object.classLoader)
1175 return createClass(typeSpec.codecClassName) [
1176 if (object.isYangBindingAvailable) {
1177 implementsType(BINDING_CODEC)
1178 staticField(it, INSTANCE_IDENTIFIER_CODEC, BindingCodec)
1179 staticField(it, IDENTITYREF_CODEC, BindingCodec)
1180 implementsType(BindingDeserializer.asCtClass)
1182 //implementsType(BindingDeserializer.asCtClass)
1183 method(Object, "toDomValue", Object) [
1184 modifiers = PUBLIC + FINAL + STATIC
1189 return $1.toString();
1193 method(Object, "serialize", Object) [
1196 return toDomValue($1);
1200 method(Object, "fromDomValue", Object) [
1201 modifiers = PUBLIC + FINAL + STATIC
1202 bodyChecked = '''return null;'''
1204 method(Object, "deserialize", Object) [
1206 return fromDomValue($1);
1213 private def Type getValueReturnType(GeneratedTransferObject object) {
1214 for (prop : object.properties) {
1215 if (prop.name == "value") {
1216 return prop.returnType;
1219 if (object.superType != null) {
1220 return getValueReturnType(object.superType);
1225 private def dispatch Class<?> generateValueTransformer(Class<?> inputType, Enumeration typeSpec, TypeDefinition<?> type) {
1226 var EnumerationType enumSchemaType
1227 if (type instanceof EnumerationType) {
1228 enumSchemaType = type as EnumerationType
1230 val typeRef = new ReferencedTypeImpl(typeSpec.packageName, typeSpec.name);
1231 val schema = getSchemaNode(typeRef) as ExtendedType;
1232 enumSchemaType = schema.baseType as EnumerationType;
1234 val enumSchema = enumSchemaType;
1236 //log.info("Generating DOM Codec for {} with {}", inputType, inputType.classLoader)
1237 val ctCls = createClass(typeSpec.codecClassName) [
1238 //staticField(Map,"AUGMENTATION_SERIALIZERS");
1239 //implementsType(BINDING_CODEC)
1240 method(Object, "toDomValue", Object) [
1241 modifiers = PUBLIC + FINAL + STATIC
1246 «typeSpec.resolvedName» _value = («typeSpec.resolvedName») $1;
1247 «FOR en : enumSchema.values»
1248 if(«typeSpec.resolvedName».«BindingMapping.getClassName(en.name)».equals(_value)) {
1256 method(Object, "serialize", Object) [
1258 return toDomValue($1);
1261 method(Object, "fromDomValue", Object) [
1262 modifiers = PUBLIC + FINAL + STATIC
1268 String _value = (String) $1;
1269 «FOR en : enumSchema.values»
1270 if("«en.name»".equals(_value)) {
1271 return «typeSpec.resolvedName».«BindingMapping.getClassName(en.name)»;
1278 method(Object, "deserialize", Object) [
1280 return fromDomValue($1);
1285 val ret = ctCls.toClassImpl(inputType.classLoader, inputType.protectionDomain)
1286 LOG.debug("DOM Codec for {} was generated {}", inputType, ret)
1288 } catch (CodeGenerationException e) {
1289 throw new CodeGenerationException("Cannot compile Transformator for " + inputType, e);
1290 } catch (Exception e) {
1291 LOG.error("Cannot compile DOM Codec for {}", inputType, e);
1292 val exception = new CodeGenerationException("Cannot compile Transformator for " + inputType);
1293 exception.addSuppressed(e);
1299 def Class<?> toClassImpl(CtClass newClass, ClassLoader loader, ProtectionDomain domain) {
1300 val cls = newClass.toClass(loader, domain);
1301 if (classFileCapturePath !== null) {
1302 newClass.writeFile(classFileCapturePath.absolutePath);
1304 listener?.onCodecCreated(cls);
1308 def debugWriteClass(CtClass class1) {
1309 val path = class1.name.replace(".", "/") + ".class"
1311 val captureFile = new File(classFileCapturePath, path);
1312 captureFile.createNewFile
1320 private def dispatch CharSequence deserializeProperty(DataSchemaNode container, Type type, String propertyName) '''
1321 «type.resolvedName» «propertyName» = null;
1324 private def dispatch CharSequence deserializeProperty(DataSchemaNode container, GeneratedTypeBuilder type,
1325 String propertyName) {
1326 _deserializeProperty(container, type.toInstance, propertyName)
1329 static def toSetter(String it) {
1331 if (startsWith("is")) {
1332 return "set" + substring(2);
1333 } else if (startsWith("get")) {
1334 return "set" + substring(3);
1340 private def dispatch CharSequence deserializeProperty(DataSchemaNode container,GeneratedType type, String propertyName) '''
1341 «type.resolvedName» «propertyName» = value.«propertyName»();
1342 if(«propertyName» != null) {
1343 Object domValue = «type.serializer».toDomStatic(QNAME,«propertyName»);
1344 _childNodes.add(domValue);
1348 private def getBuilderName(GeneratedType type) '''«type.resolvedName»Builder'''
1350 private def staticQNameField(CtClass it, QName node) {
1351 val field = new CtField(ctQName, "QNAME", it);
1352 field.modifiers = PUBLIC + FINAL + STATIC;
1354 '''«QName.asCtClass.name».create("«node.namespace»","«node.formattedRevision»","«node.localName»")''')
1357 private def String serializeBodyImpl(GeneratedType type, DataNodeContainer nodeContainer) '''
1359 «QName.name» _resultName = «QName.name».create($1,QNAME.getLocalName());
1360 java.util.List _childNodes = new java.util.ArrayList();
1361 «type.resolvedName» value = («type.resolvedName») $2;
1362 «transformDataContainerBody(type, type.allProperties, nodeContainer)»
1363 «serializeAugmentations»
1364 return ($r) java.util.Collections.singletonMap(_resultName,_childNodes);
1368 private def dispatch String serializeBody(GeneratedType type, ListSchemaNode node) {
1369 return serializeBodyImpl(type, node);
1372 private def dispatch String serializeBody(GeneratedType type, NotificationDefinition node) {
1373 return serializeBodyImpl(type, node);
1376 private def dispatch String serializeBody(GeneratedType type, ContainerSchemaNode node) {
1377 return serializeBodyImpl(type, node);
1380 private def dispatch String serializeBody(GeneratedType type, ChoiceCaseNode node) {
1381 return serializeBodyImpl(type, node);
1384 private def dispatch String serializeBody(GeneratedType type, SchemaNode node) '''
1386 «QName.name» _resultName = «QName.name».create($1,QNAME.getLocalName());
1387 java.util.List _childNodes = new java.util.ArrayList();
1388 «type.resolvedName» value = («type.resolvedName») $2;
1389 return ($r) java.util.Collections.singletonMap(_resultName,_childNodes);
1393 private def transformDataContainerBody(Type type, Map<String, Type> properties, DataNodeContainer node) {
1395 «FOR child : node.childNodes»
1396 «val signature = properties.getFor(child)»
1397 «IF signature !== null»
1398 ////System.out.println("«type.name»#«signature.key»" + value.«signature.key»());
1399 «serializeProperty(child, signature.value, signature.key)»
1406 private static def serializeAugmentations() '''
1407 java.util.List _augmentations = (java.util.List) «AUGMENTATION_CODEC».serialize(value);
1408 if(_augmentations != null) {
1409 _childNodes.addAll(_augmentations);
1413 private static def Entry<String, Type> getFor(Map<String, Type> map, DataSchemaNode node) {
1414 var sig = map.get(node.getterName);
1416 return new SimpleEntry(node.getterName, sig);
1418 sig = map.get(node.booleanGetterName);
1420 return new SimpleEntry(node.booleanGetterName, map.get(node.booleanGetterName));
1425 private static def String getBooleanGetterName(DataSchemaNode node) {
1426 return "is" + BindingMapping.getPropertyName(node.QName.localName).toFirstUpper;
1429 private static def String getGetterName(DataSchemaNode node) {
1430 return "get" + BindingMapping.getPropertyName(node.QName.localName).toFirstUpper;
1433 private static def String getGetterName(QName node) {
1434 return "get" + BindingMapping.getPropertyName(node.localName).toFirstUpper;
1437 private def dispatch CharSequence serializeProperty(ListSchemaNode schema, ParameterizedType type,
1438 String propertyName) '''
1439 «type.resolvedName» «propertyName» = value.«propertyName»();
1440 ////System.out.println("«propertyName»:" + «propertyName»);
1441 if(«propertyName» != null) {
1442 java.util.Iterator _iterator = «propertyName».iterator();
1443 boolean _hasNext = _iterator.hasNext();
1445 Object _listItem = _iterator.next();
1446 Object _domValue = «type.actualTypeArguments.get(0).serializer(schema).resolvedName».toDomStatic(_resultName,_listItem);
1447 _childNodes.add(_domValue);
1448 _hasNext = _iterator.hasNext();
1453 private def dispatch CharSequence serializeProperty(LeafSchemaNode schema, Type type, String propertyName) '''
1454 «type.resolvedName» «propertyName» = value.«propertyName»();
1456 if(«propertyName» != null) {
1457 «QName.name» _qname = «QName.name».create(_resultName,"«schema.QName.localName»");
1458 Object _propValue = «serializeValue(type, propertyName, schema.type)»;
1459 if(_propValue != null) {
1460 Object _domValue = java.util.Collections.singletonMap(_qname,_propValue);
1461 _childNodes.add(_domValue);
1466 private def dispatch serializeValue(GeneratedTransferObject type, String parameter, TypeDefinition<?> typeDefinition) {
1467 '''«type.valueSerializer(typeDefinition).resolvedName».toDomValue(«parameter»)'''
1470 private def dispatch serializeValue(Enumeration type, String parameter, TypeDefinition<?> typeDefinition) {
1471 '''«type.valueSerializer(typeDefinition).resolvedName».toDomValue(«parameter»)'''
1474 private def dispatch serializeValue(Type type, String parameter, EmptyTypeDefinition typeDefinition) {
1475 '''(«parameter».booleanValue() ? "" : null)'''
1478 private def dispatch serializeValue(Type signature, String property, TypeDefinition<?> typeDefinition) {
1479 serializeValue(signature,property)
1482 private def dispatch serializeValue(Type signature, String property, Void typeDefinition) {
1483 serializeValue(signature,property)
1486 private def dispatch serializeValue(Type signature, String property) {
1487 if (INSTANCE_IDENTIFIER == signature) {
1488 return '''«INSTANCE_IDENTIFIER_CODEC».serialize(«property»)'''
1489 } else if (CLASS_TYPE.equals(signature)) {
1490 return '''(«QName.resolvedName») «IDENTITYREF_CODEC».serialize(«property»)'''
1492 if ("char[]" == signature.name) {
1493 return '''new String(«property»)''';
1495 return '''«property»''';
1498 private def dispatch CharSequence serializeProperty(LeafListSchemaNode schema, ParameterizedType type,
1499 String propertyName) '''
1500 «type.resolvedName» «propertyName» = value.«propertyName»();
1501 if(«propertyName» != null) {
1502 «QName.name» _qname = «QName.name».create(_resultName,"«schema.QName.localName»");
1503 java.util.Iterator _iterator = «propertyName».iterator();
1504 boolean _hasNext = _iterator.hasNext();
1506 Object _listItem = _iterator.next();
1507 Object _propValue = «serializeValue(type.actualTypeArguments.get(0), "_listItem", schema.type)»;
1508 Object _domValue = java.util.Collections.singletonMap(_qname,_propValue);
1509 _childNodes.add(_domValue);
1510 _hasNext = _iterator.hasNext();
1515 private def dispatch CharSequence serializeProperty(ChoiceNode container, GeneratedType type,
1516 String propertyName) '''
1517 «type.resolvedName» «propertyName» = value.«propertyName»();
1518 if(«propertyName» != null) {
1519 java.util.List domValue = «type.serializer(container).resolvedName».toDomStatic(_resultName,«propertyName»);
1520 _childNodes.addAll(domValue);
1528 private def dispatch CharSequence serializeProperty(DataSchemaNode container, Type type, String propertyName) '''
1529 «type.resolvedName» «propertyName» = value.«propertyName»();
1530 if(«propertyName» != null) {
1531 Object domValue = «propertyName»;
1532 _childNodes.add(domValue);
1536 private def dispatch CharSequence serializeProperty(DataSchemaNode container, GeneratedTypeBuilder type,
1537 String propertyName) {
1538 serializeProperty(container, type.toInstance, propertyName)
1541 private def dispatch CharSequence serializeProperty(DataSchemaNode container, GeneratedType type,
1542 String propertyName) '''
1543 «type.resolvedName» «propertyName» = value.«propertyName»();
1544 if(«propertyName» != null) {
1545 Object domValue = «type.serializer(container).resolvedName».toDomStatic(_resultName,«propertyName»);
1546 _childNodes.add(domValue);
1550 private def codecClassName(GeneratedType typeSpec) {
1551 return '''«typeSpec.resolvedName»$Broker$Codec$DOM'''
1554 private def codecClassName(Class<?> typeSpec) {
1555 return '''«typeSpec.name»$Broker$Codec$DOM'''
1558 private def HashMap<String, Type> getAllProperties(GeneratedType type) {
1559 val ret = new HashMap<String, Type>();
1560 type.collectAllProperties(ret);
1564 private def dispatch void collectAllProperties(GeneratedType type, Map<String, Type> set) {
1565 for (definition : type.methodDefinitions) {
1566 set.put(definition.name, definition.returnType);
1568 for (property : type.properties) {
1569 set.put(property.getterName, property.returnType);
1571 for (parent : type.implements) {
1572 parent.collectAllProperties(set);
1576 def String getGetterName(GeneratedProperty property) {
1577 return "get" + property.name.toFirstUpper
1580 private def dispatch void collectAllProperties(Type type, Map<String, Type> set) {
1581 // NOOP for generic type.
1584 def String getResolvedName(Type type) {
1585 return type.asCtClass.name;
1588 def String getResolvedName(Class<?> type) {
1589 return type.asCtClass.name;
1592 def CtClass asCtClass(Type type) {
1593 val cls = loadClass(type.fullyQualifiedName)
1594 return cls.asCtClass;
1597 private def dispatch processException(Class<?> inputType, CodeGenerationException e) {
1598 LOG.error("Cannot compile DOM Codec for {}. One of it's prerequisites was not generated.", inputType);
1602 private def dispatch processException(Class<?> inputType, Exception e) {
1603 LOG.error("Cannot compile DOM Codec for {}", inputType, e);
1604 val exception = new CodeGenerationException("Cannot compile Transformator for " + inputType, e);
1608 private def setBodyChecked(CtMethod method, String body) {
1610 method.setBody(body);
1611 } catch (CannotCompileException e) {
1612 LOG.error("Cannot compile method: {}#{} {}, Reason: {} Body: {}", method.declaringClass, method.name,
1613 method.signature, e.message, body)
1620 class PropertyPair {
1629 SchemaNode schemaNode;