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.*
75 class TransformerGenerator extends AbstractTransformerGenerator {
76 private static val LOG = LoggerFactory.getLogger(TransformerGenerator)
78 public static val STRING = Types.typeForClass(String);
79 public static val BOOLEAN = Types.typeForClass(Boolean);
80 public static val INTEGER = Types.typeForClass(Integer);
81 public static val INSTANCE_IDENTIFIER = Types.typeForClass(InstanceIdentifier);
82 //public static val DECIMAL = Types.typeForClass(Decimal);
83 public static val LONG = Types.typeForClass(Long);
84 public static val CLASS_TYPE = Types.typeForClass(Class);
87 var File classFileCapturePath;
89 val CtClass BINDING_CODEC
92 public new(TypeResolver typeResolver, ClassPool pool) {
93 super(typeResolver, pool)
95 BINDING_CODEC = BindingCodec.asCtClass;
96 ctQName = QName.asCtClass
99 override transformerForImpl(Class inputType) {
100 return runOnClassLoader(inputType.classLoader) [ |
101 val ret = getGeneratedClass(inputType)
103 listener.onClassProcessed(inputType);
104 return ret as Class<? extends BindingCodec<Map<QName,Object>, Object>>;
106 val ref = Types.typeForClass(inputType)
107 val node = getSchemaNode(ref)
108 createMapping(inputType, node, null)
109 val typeSpecBuilder = getDefinition(ref)
110 checkState(typeSpecBuilder !== null, "Could not find typedefinition for %s", inputType.name);
111 val typeSpec = typeSpecBuilder.toInstance();
112 val newret = generateTransformerFor(inputType, typeSpec, node);
113 listener.onClassProcessed(inputType);
114 return newret as Class<? extends BindingCodec<Map<QName,Object>, Object>>;
118 def Class<? extends BindingCodec<Map<QName, Object>, Object>> transformerFor(Class<?> inputType, DataSchemaNode node) {
119 return runOnClassLoader(inputType.classLoader) [ |
120 createMapping(inputType, node, null)
121 val ret = getGeneratedClass(inputType)
123 listener.onClassProcessed(inputType);
124 return ret as Class<? extends BindingCodec<Map<QName,Object>, Object>>;
126 val ref = Types.typeForClass(inputType)
127 var typeSpecBuilder = getDefinition(ref)
128 if (typeSpecBuilder == null) {
129 typeSpecBuilder = getTypeBuilder(node.path);
132 checkState(typeSpecBuilder !== null, "Could not find TypeDefinition for %s, $s", inputType.name, node);
133 val typeSpec = typeSpecBuilder.toInstance();
134 val newret = generateTransformerFor(inputType, typeSpec, node);
135 listener.onClassProcessed(inputType);
136 return newret as Class<? extends BindingCodec<Map<QName,Object>, Object>>;
140 override augmentationTransformerForImpl(Class inputType) {
141 return runOnClassLoader(inputType.classLoader) [ |
143 val ret = getGeneratedClass(inputType)
145 return ret as Class<? extends BindingCodec<Map<QName,Object>, Object>>;
147 val ref = Types.typeForClass(inputType)
148 val node = getAugmentation(ref)
149 val typeSpecBuilder = getDefinition(ref)
150 val typeSpec = typeSpecBuilder.toInstance();
151 //mappingForNodes(node.childNodes, typeSpec.allProperties, bindingId)
152 val newret = generateAugmentationTransformerFor(inputType, typeSpec, node);
153 listener.onClassProcessed(inputType);
154 return newret as Class<? extends BindingCodec<Map<QName,Object>, Object>>;
158 override caseCodecForImpl(Class inputType, ChoiceCaseNode node) {
159 return runOnClassLoader(inputType.classLoader) [ |
160 createMapping(inputType, node, null)
161 val ret = getGeneratedClass(inputType)
163 return ret as Class<? extends BindingCodec<Object, Object>>;
165 val ref = Types.typeForClass(inputType)
166 val typeSpecBuilder = getDefinition(ref)
167 val typeSpec = typeSpecBuilder.toInstance();
168 val newret = generateCaseCodec(inputType, typeSpec, node);
169 return newret as Class<? extends BindingCodec<Object, Object>>;
173 override keyTransformerForIdentifiableImpl(Class parentType) {
174 return runOnClassLoader(parentType.classLoader) [ |
175 val inputName = parentType.name + "Key";
176 val inputType = loadClass(inputName);
177 val ret = getGeneratedClass(inputType)
179 return ret as Class<? extends BindingCodec<Map<QName,Object>, Object>>;
181 val ref = Types.typeForClass(parentType)
182 val node = getSchemaNode(ref) as ListSchemaNode
183 val typeSpecBuilder = getDefinition(ref)
184 val typeSpec = typeSpecBuilder.identifierDefinition;
185 val newret = generateKeyTransformerFor(inputType, typeSpec, node);
186 return newret as Class<? extends BindingCodec<Map<QName,Object>, Object>>;
190 private def void createMapping(Class<?> inputType, SchemaNode node, InstanceIdentifier<?> parentId) {
191 var ClassLoader cl = inputType.classLoader
193 cl = Thread.currentThread.contextClassLoader
195 ClassLoaderUtils.withClassLoader(cl,
197 if (!(node instanceof DataNodeContainer)) {
200 var InstanceIdentifier<?> bindingId = getBindingIdentifierByPath(node.path)
201 if (bindingId != null) {
204 val ref = Types.typeForClass(inputType)
205 var typeSpecBuilder = getDefinition(ref)
206 if (typeSpecBuilder == null) {
207 typeSpecBuilder = getTypeBuilder(node.path);
209 checkState(typeSpecBuilder !== null, "Could not find type definition for %s, $s", inputType.name, node);
210 val typeSpec = typeSpecBuilder.toInstance();
211 var InstanceIdentifier<?> parent
212 if (parentId == null) {
213 bindingId = InstanceIdentifier.create(inputType as Class)
215 putPathToBindingIdentifier(node.path, bindingId)
217 parent = putPathToBindingIdentifier(node.path, parentId, inputType)
219 val Map<String, Type> properties = typeSpec.allProperties
220 if (node instanceof DataNodeContainer) {
221 mappingForNodes((node as DataNodeContainer).childNodes, properties, parent)
222 } else if (node instanceof ChoiceNode) {
223 mappingForNodes((node as ChoiceNode).cases, properties, parent)
229 private def void mappingForNodes(Collection<? extends DataSchemaNode> childNodes, Map<String, Type> properties,
230 InstanceIdentifier<?> parent) {
231 for (DataSchemaNode child : childNodes) {
232 val signature = properties.getFor(child)
233 if (signature != null) {
234 val Type childType = signature.value
235 var Class<?> childTypeClass = null;
236 if (child instanceof ListSchemaNode && childType instanceof ParameterizedType) {
237 childTypeClass = loadClass((childType as ParameterizedType).actualTypeArguments.get(0))
239 childTypeClass = loadClass(childType)
241 createMapping(childTypeClass, child, parent)
246 def getIdentifierDefinition(GeneratedTypeBuilder builder) {
247 val inst = builder.toInstance
248 val keyMethod = inst.methodDefinitions.findFirst[name == "getKey"]
249 return keyMethod.returnType as GeneratedTransferObject
252 override keyTransformerForIdentifierImpl(Class inputType) {
253 return runOnClassLoader(inputType.classLoader) [ |
254 val ret = getGeneratedClass(inputType)
256 return ret as Class<? extends BindingCodec<Map<QName,Object>, Object>>;
258 val ref = Types.typeForClass(inputType)
259 val node = getSchemaNode(ref) as ListSchemaNode
260 val typeSpecBuilder = getDefinition(ref)
261 val typeSpec = typeSpecBuilder.toInstance();
262 val newret = generateKeyTransformerFor(inputType, typeSpec, node);
263 return newret as Class<? extends BindingCodec<Map<QName,Object>, Object>>;
267 private def Class<?> keyTransformerFor(Class<?> inputType, GeneratedType type, ListSchemaNode schema) {
268 return runOnClassLoader(inputType.classLoader) [ |
269 val transformer = getGeneratedClass(inputType)
270 if (transformer != null) {
273 val newret = generateKeyTransformerFor(inputType, type, schema);
274 return newret as Class<? extends BindingCodec<Map<QName,Object>, Object>>;
278 private def Class<?> getGeneratedClass(Class<? extends Object> cls) {
281 return loadClass(cls.codecClassName)
282 } catch (ClassNotFoundException e) {
287 private def Class<?> keyTransformer(GeneratedType type, ListSchemaNode node) {
288 val cls = loadClass(type.resolvedName + "Key");
289 keyTransformerFor(cls, type, node);
292 private def serializer(Type type, DataSchemaNode node) {
293 val cls = loadClass(type.resolvedName);
294 transformerFor(cls, node);
297 private def Class<?> valueSerializer(GeneratedTransferObject type, TypeDefinition<?> typeDefinition) {
298 val cls = loadClass(type.resolvedName);
299 val transformer = cls.generatedClass;
300 if (transformer !== null) {
303 var baseType = typeDefinition;
304 while (baseType.baseType != null) {
305 baseType = baseType.baseType;
307 val finalType = baseType;
308 return runOnClassLoader(cls.classLoader) [ |
309 val valueTransformer = generateValueTransformer(cls, type, finalType);
310 return valueTransformer;
314 private def Class<?> valueSerializer(Enumeration type, TypeDefinition<?> typeDefinition) {
315 val cls = loadClass(type.resolvedName);
316 val transformer = cls.generatedClass;
317 if (transformer !== null) {
321 return runOnClassLoader(cls.classLoader) [ |
322 val valueTransformer = generateValueTransformer(cls, type);
323 return valueTransformer;
327 private def generateKeyTransformerFor(Class<? extends Object> inputType, GeneratedType typeSpec, ListSchemaNode node) {
330 //log.info("Generating DOM Codec for {} with {}", inputType, inputType.classLoader)
331 val properties = typeSpec.allProperties;
332 val ctCls = createClass(inputType.codecClassName) [
333 //staticField(Map,"AUGMENTATION_SERIALIZERS");
334 staticField(it, INSTANCE_IDENTIFIER_CODEC, BindingCodec)
335 staticField(it, IDENTITYREF_CODEC, BindingCodec)
336 staticQNameField(node.QName);
337 implementsType(BINDING_CODEC)
338 method(Object, "toDomStatic", #[QName, Object]) [
339 modifiers = PUBLIC + FINAL + STATIC
342 «QName.name» _resultName;
344 _resultName = «QName.name».create($1,QNAME.getLocalName());
348 java.util.List _childNodes = new java.util.ArrayList();
349 «inputType.resolvedName» value = («inputType.name») $2;
350 «FOR key : node.keyDefinition»
351 «val propertyName = key.getterName»
352 «val keyDef = node.getDataChildByName(key)»
353 «val property = properties.get(propertyName)»
354 «serializeProperty(keyDef, property, propertyName)»;
356 return ($r) java.util.Collections.singletonMap(_resultName,_childNodes);
360 method(Object, "fromDomStatic", #[QName, Object]) [
361 modifiers = PUBLIC + FINAL + STATIC
367 «QName.name» _localQName = $1;
368 java.util.Map _compositeNode = (java.util.Map) $2;
369 boolean _is_empty = true;
370 «FOR key : node.keyDefinition»
371 «val propertyName = key.getterName»
372 «val keyDef = node.getDataChildByName(key)»
373 «val property = properties.get(propertyName)»
374 «deserializeProperty(keyDef, property, propertyName)»;
376 «inputType.resolvedName» _value = new «inputType.name»(«node.keyDefinition.
377 keyConstructorList»);
382 method(Object, "serialize", Object) [
385 java.util.Map.Entry _input = (java.util.Map.Entry) $1;
386 «QName.name» _localQName = («QName.name») _input.getKey();
387 «inputType.name» _keyValue = («inputType.name») _input.getValue();
388 return toDomStatic(_localQName,_keyValue);
392 method(Object, "deserialize", Object) [
395 «QName.name» _qname = QNAME;
396 if($1 instanceof java.util.Map.Entry) {
397 _qname = («QName.name») ((java.util.Map.Entry) $1).getKey();
399 return fromDomStatic(_qname,$1);
404 val ret = ctCls.toClassImpl(inputType.classLoader, inputType.protectionDomain)
405 LOG.debug("DOM Codec for {} was generated {}", inputType, ret)
406 return ret as Class<? extends BindingCodec<Map<QName,Object>, ?>>;
407 } catch (Exception e) {
408 processException(inputType, e);
413 private def Class<? extends BindingCodec<Object, Object>> generateCaseCodec(Class<?> inputType, GeneratedType type,
414 ChoiceCaseNode node) {
416 //log.info("Generating DOM Codec for {} with {}, TCCL is: {}", inputType, inputType.classLoader,Thread.currentThread.contextClassLoader)
417 val ctCls = createClass(type.codecClassName) [
418 //staticField(Map,"AUGMENTATION_SERIALIZERS");
419 implementsType(BINDING_CODEC)
420 staticQNameField(node.QName);
421 staticField(it, INSTANCE_IDENTIFIER_CODEC, BindingCodec)
422 staticField(it, AUGMENTATION_CODEC, BindingCodec)
423 staticField(it, IDENTITYREF_CODEC, BindingCodec)
424 method(Object, "toDomStatic", #[QName, Object]) [
425 modifiers = PUBLIC + FINAL + STATIC
428 «QName.name» _resultName = «QName.name».create($1,QNAME.getLocalName());
429 java.util.List _childNodes = new java.util.ArrayList();
430 «type.resolvedName» value = («type.resolvedName») $2;
431 «transformDataContainerBody(type, type.allProperties, node)»
432 return ($r) _childNodes;
436 method(Object, "serialize", Object) [
439 java.util.Map.Entry _input = (java.util.Map.Entry) $1;
440 «QName.name» _localName = QNAME;
441 if(_input.getKey() != null) {
442 _localName = («QName.name») _input.getKey();
444 return toDomStatic(_localName,_input.getValue());
448 method(Object, "fromDomStatic", #[QName, Object, InstanceIdentifier]) [
449 modifiers = PUBLIC + FINAL + STATIC
450 bodyChecked = deserializeBody(type, node, getBindingIdentifierByPath(node.path))
452 method(Object, "deserialize", #[Object, InstanceIdentifier]) [
455 //System.out.println("«type.name»#deserialize: " +$1);
456 java.util.Map.Entry _input = (java.util.Map.Entry) $1;
457 return fromDomStatic((«QName.name»)_input.getKey(),_input.getValue(),$2);
463 val ret = ctCls.toClassImpl(inputType.classLoader, inputType.protectionDomain) as Class<? extends BindingCodec<Object, Object>>
464 listener?.onDataContainerCodecCreated(inputType, ret);
465 LOG.debug("DOM Codec for {} was generated {}", inputType, ret)
467 } catch (Exception e) {
468 processException(inputType, e);
473 private def dispatch Class<? extends BindingCodec<Map<QName, Object>, Object>> generateTransformerFor(
474 Class<?> inputType, GeneratedType typeSpec, SchemaNode node) {
477 //log.info("Generating DOM Codec for {} with {}", inputType, inputType.classLoader)
478 val ctCls = createClass(typeSpec.codecClassName) [
479 //staticField(Map,"AUGMENTATION_SERIALIZERS");
480 staticQNameField(node.QName);
481 staticField(it, INSTANCE_IDENTIFIER_CODEC, BindingCodec)
482 staticField(it, IDENTITYREF_CODEC, BindingCodec)
483 staticField(it, AUGMENTATION_CODEC, BindingCodec)
484 implementsType(BINDING_CODEC)
486 method(Object, "toDomStatic", #[QName, Object]) [
487 modifiers = PUBLIC + FINAL + STATIC
488 bodyChecked = serializeBodyFacade(typeSpec, node)
490 method(Object, "serialize", Object) [
493 java.util.Map.Entry _input = (java.util.Map.Entry) $1;
494 «QName.name» _localName = QNAME;
495 if(_input.getKey() != null) {
496 _localName = («QName.name») _input.getKey();
498 return toDomStatic(_localName,_input.getValue());
503 method(Object, "fromDomStatic", #[QName, Object, InstanceIdentifier]) [
504 modifiers = PUBLIC + FINAL + STATIC
505 bodyChecked = deserializeBody(typeSpec, node, getBindingIdentifierByPath(node.path))
508 method(Object, "deserialize", #[Object, InstanceIdentifier]) [
511 «QName.name» _qname = QNAME;
512 if($1 instanceof java.util.Map.Entry) {
513 _qname = («QName.name») ((java.util.Map.Entry) $1).getKey();
515 return fromDomStatic(_qname,$1,$2);
521 val ret = ctCls.toClassImpl(inputType.classLoader, inputType.protectionDomain) as Class<? extends BindingCodec<Map<QName,Object>, Object>>
522 listener?.onDataContainerCodecCreated(inputType, ret);
523 LOG.debug("DOM Codec for {} was generated {}", inputType, ret)
525 } catch (Exception e) {
526 processException(inputType, e);
531 private def Class<? extends BindingCodec<Map<QName, Object>, Object>> generateAugmentationTransformerFor(
532 Class<?> inputType, GeneratedType type, AugmentationSchema node) {
535 //log.info("Generating DOM Codec for {} with {}", inputType, inputType.classLoader)
536 val properties = type.allProperties
537 val ctCls = createClass(type.codecClassName) [
538 //staticField(Map,"AUGMENTATION_SERIALIZERS");
539 staticQNameField(node.augmentationQName);
540 staticField(it, INSTANCE_IDENTIFIER_CODEC, BindingCodec)
541 staticField(it, AUGMENTATION_CODEC, BindingCodec)
542 staticField(it, IDENTITYREF_CODEC, BindingCodec)
543 implementsType(BINDING_CODEC)
545 method(Object, "toDomStatic", #[QName, Object]) [
546 modifiers = PUBLIC + FINAL + STATIC
549 ////System.out.println("Qname " + $1);
550 ////System.out.println("Value " + $2);
551 «QName.name» _resultName = «QName.name».create(QNAME,QNAME.getLocalName());
552 java.util.List _childNodes = new java.util.ArrayList();
553 «type.resolvedName» value = («type.resolvedName») $2;
554 «FOR child : node.childNodes»
555 «var signature = properties.getFor(child)»
556 ////System.out.println("«signature.key»" + value.«signature.key»());
557 «serializeProperty(child, signature.value, signature.key)»
559 return ($r) _childNodes;
563 method(Object, "serialize", Object) [
566 java.util.Map.Entry _input = (java.util.Map.Entry) $1;
567 «QName.name» _localName = QNAME;
568 if(_input.getKey() != null) {
569 _localName = («QName.name») _input.getKey();
571 return toDomStatic(_localName,_input.getValue());
576 method(Object, "fromDomStatic", #[QName, Object, InstanceIdentifier]) [
577 modifiers = PUBLIC + FINAL + STATIC
580 «QName.name» _localQName = QNAME;
585 java.util.Map _compositeNode = (java.util.Map) $2;
586 //System.out.println(_localQName + " " + _compositeNode);
587 «type.builderName» _builder = new «type.builderName»();
588 boolean _is_empty = true;
589 «FOR child : node.childNodes»
590 «val signature = properties.getFor(child)»
591 «deserializeProperty(child, signature.value, signature.key)»
592 _builder.«signature.key.toSetter»(«signature.key»);
597 return _builder.build();
602 method(Object, "deserialize", #[Object, InstanceIdentifier]) [
604 return fromDomStatic(QNAME,$1,$2);
609 val ret = ctCls.toClassImpl(inputType.classLoader, inputType.protectionDomain) as Class<? extends BindingCodec<Map<QName,Object>, Object>>
610 listener?.onDataContainerCodecCreated(inputType, ret);
612 } catch (Exception e) {
613 processException(inputType, e);
618 private def dispatch Class<? extends BindingCodec<Map<QName, Object>, Object>> generateTransformerFor(
619 Class<?> inputType, GeneratedType typeSpec, ChoiceNode node) {
622 //log.info("Generating DOM Codec for {} with {}", inputType, inputType.classLoader)
623 val ctCls = createClass(typeSpec.codecClassName) [
624 //staticField(Map,"AUGMENTATION_SERIALIZERS");
625 //staticQNameField(inputType);
626 staticField(it, INSTANCE_IDENTIFIER_CODEC, BindingCodec)
627 staticField(it, IDENTITYREF_CODEC, BindingCodec)
628 staticField(it, CLASS_TO_CASE_MAP, Map)
629 staticField(it, COMPOSITE_TO_CASE, Map)
630 //staticField(it,QNAME_TO_CASE_MAP,BindingCodec)
631 implementsType(BINDING_CODEC)
632 method(List, "toDomStatic", #[QName, Object]) [
633 modifiers = PUBLIC + FINAL + STATIC
639 «DataObject.name» _baValue = («DataObject.name») $2;
640 Class _baClass = _baValue.getImplementedInterface();
641 «BINDING_CODEC.name» _codec = «CLASS_TO_CASE_MAP».get(_baClass);
645 java.util.Map.Entry _input = new «SimpleEntry.name»($1,_baValue);
646 Object _ret = _codec.serialize(_input);
647 ////System.out.println("«typeSpec.name»#toDomStatic: " + _ret);
648 return («List.name») _ret;
652 method(Object, "serialize", Object) [
654 throw new «UnsupportedOperationException.name»("Direct invocation not supported.");
657 method(Object, "fromDomStatic", #[QName, Map, InstanceIdentifier]) [
658 modifiers = PUBLIC + FINAL + STATIC
661 «BINDING_CODEC.name» _codec = («BINDING_CODEC.name») «COMPOSITE_TO_CASE».get($2);
663 return _codec.deserialize(new «SimpleEntry.name»($1,$2),$3);
669 method(Object, "deserialize", #[Object, InstanceIdentifier]) [
671 throw new «UnsupportedOperationException.name»("Direct invocation not supported.");
676 val rawRet = ctCls.toClassImpl(inputType.classLoader, inputType.protectionDomain)
677 val ret = rawRet as Class<? extends BindingCodec<Map<QName,Object>, Object>>;
678 listener?.onChoiceCodecCreated(inputType, ret, node);
679 LOG.debug("DOM Codec for {} was generated {}", inputType, ret)
681 } catch (Exception e) {
682 processException(inputType, e);
687 private def keyConstructorList(List<QName> qnames) {
688 val names = new TreeSet<String>()
689 for (name : qnames) {
690 val fieldName = name.getterName;
691 names.add(fieldName);
693 return Joiner.on(",").join(names);
696 private def serializeBodyFacade(GeneratedType type, SchemaNode node) {
697 val ret = serializeBody(type, node);
701 private def String deserializeBody(GeneratedType type, SchemaNode node, InstanceIdentifier<?> bindingId) {
702 val ret = deserializeBodyImpl(type, node, bindingId);
706 private def deserializeKey(GeneratedType type, ListSchemaNode node) {
707 if (node.keyDefinition != null && !node.keyDefinition.empty) {
709 «type.resolvedName»Key getKey = («type.resolvedName»Key) «keyTransformer(type, node).canonicalName».fromDomStatic(_localQName,_compositeNode);
710 _builder.setKey(getKey);
715 private def String deserializeBodyWithAugmentations(GeneratedType type, DataNodeContainer node, InstanceIdentifier<?> bindingId) '''
717 «QName.name» _localQName = «QName.name».create($1,QNAME.getLocalName());
721 java.util.Map _compositeNode = (java.util.Map) $2;
722 //System.out.println(_localQName + " " + _compositeNode);
723 «type.builderName» _builder = new «type.builderName»();
724 «deserializeDataNodeContainerBody(type, node, bindingId)»
725 «type.deserializeAugmentations»
726 return _builder.build();
730 private def dispatch String deserializeBodyImpl(GeneratedType type, SchemaNode node, InstanceIdentifier<?> bindingId) '''
732 «QName.name» _localQName = «QName.name».create($1,QNAME.getLocalName());
737 java.util.Map _compositeNode = (java.util.Map) $2;
738 «type.builderName» _builder = new «type.builderName»();
739 return _builder.build();
743 private def dispatch String deserializeBodyImpl(GeneratedType type, ListSchemaNode node, InstanceIdentifier<?> bindingId) '''
745 «QName.name» _localQName = «QName.name».create($1,QNAME.getLocalName());
749 java.util.Map _compositeNode = (java.util.Map) $2;
750 //System.out.println(_localQName + " " + _compositeNode);
751 «type.builderName» _builder = new «type.builderName»();
752 «deserializeKey(type, node)»
753 «deserializeDataNodeContainerBody(type, node, bindingId)»
754 «type.deserializeAugmentations»
755 return _builder.build();
759 private def dispatch String deserializeBodyImpl(GeneratedType type, ContainerSchemaNode node, InstanceIdentifier<?> bindingId) {
760 return deserializeBodyWithAugmentations(type, node, bindingId);
763 private def dispatch String deserializeBodyImpl(GeneratedType type, NotificationDefinition node, InstanceIdentifier<?> bindingId) {
764 return deserializeBodyWithAugmentations(type, node, bindingId);
767 private def dispatch String deserializeBodyImpl(GeneratedType type, ChoiceCaseNode node, InstanceIdentifier<?> bindingId) {
768 return deserializeBodyWithAugmentations(type, node, bindingId);
771 private def deserializeDataNodeContainerBody(GeneratedType type, DataNodeContainer node, InstanceIdentifier<?> bindingId) {
772 deserializeNodeContainerBodyImpl(type, type.allProperties, node, bindingId);
775 private def deserializeNodeContainerBodyImpl(GeneratedType type, HashMap<String, Type> properties,
776 DataNodeContainer node, InstanceIdentifier<?> bindingId) {
778 boolean _is_empty = true;
779 «FOR child : node.childNodes»
780 «val signature = properties.getFor(child)»
781 «IF signature !== null»
782 «deserializeProperty(child, signature.value, signature.key)»
783 _builder.«signature.key.toSetter»(«signature.key»);
790 def deserializeAugmentations(GeneratedType type) '''
791 «InstanceIdentifier.resolvedName» iid = $3.builder().child(«type.resolvedName».class).build();
792 java.util.Map _augmentation = (java.util.Map) «AUGMENTATION_CODEC».deserialize(_compositeNode,$3);
793 if(_augmentation != null) {
794 «Iterator.name» _entries = _augmentation.entrySet().iterator();
795 while(_entries.hasNext()) {
796 java.util.Map.Entry _entry = (java.util.Map.Entry) _entries.next();
797 ////System.out.println("Aug. key:" + _entry.getKey());
798 Class _type = (Class) _entry.getKey();
799 «Augmentation.resolvedName» _value = («Augmentation.name») _entry.getValue();
801 _builder.addAugmentation(_type,_value);
807 private def dispatch CharSequence deserializeProperty(ListSchemaNode schema, ParameterizedType type,
808 String propertyName) '''
809 java.util.List _dom_«propertyName» = _compositeNode.get(«QName.name».create(_localQName,"«schema.QName.
811 ////System.out.println("«propertyName»#deCode"+_dom_«propertyName»);
812 java.util.List «propertyName» = new java.util.ArrayList();
813 if(_dom_«propertyName» != null) {
814 java.util.List _serialized = new java.util.ArrayList();
815 java.util.Iterator _iterator = _dom_«propertyName».iterator();
816 boolean _hasNext = _iterator.hasNext();
818 Object _listItem = _iterator.next();
820 ////System.out.println(" item" + _listItem);
821 «val param = type.actualTypeArguments.get(0)»
822 «InstanceIdentifier.resolvedName» iid = $3.builder().child(«param.resolvedName».class).build();
823 Object _value = «type.actualTypeArguments.get(0).serializer(schema).resolvedName».fromDomStatic(_localQName,_listItem,iid);
824 ////System.out.println(" value" + _value);
825 «propertyName».add(_value);
826 _hasNext = _iterator.hasNext();
830 ////System.out.println(" list" + «propertyName»);
833 private def dispatch CharSequence deserializeProperty(LeafListSchemaNode schema, ParameterizedType type,
834 String propertyName) '''
835 java.util.List _dom_«propertyName» = _compositeNode.get(«QName.name».create(_localQName,"«schema.QName.
837 java.util.List «propertyName» = new java.util.ArrayList();
838 if(_dom_«propertyName» != null) {
839 java.util.List _serialized = new java.util.ArrayList();
840 java.util.Iterator _iterator = _dom_«propertyName».iterator();
841 boolean _hasNext = _iterator.hasNext();
844 Object _listItem = _iterator.next();
845 if(_listItem instanceof java.util.Map.Entry) {
846 Object _innerValue = ((java.util.Map.Entry) _listItem).getValue();
847 Object _value = «deserializeValue(type.actualTypeArguments.get(0), "_innerValue", schema.type)»;
848 «propertyName».add(_value);
850 _hasNext = _iterator.hasNext();
855 private def dispatch CharSequence deserializeProperty(LeafSchemaNode schema, Type type, String propertyName) '''
856 java.util.List _dom_«propertyName»_list =
857 _compositeNode.get(«QName.name».create(_localQName,"«schema.QName.localName»"));
858 «type.resolvedName» «propertyName» = null;
859 if(_dom_«propertyName»_list != null && _dom_«propertyName»_list.size() > 0) {
861 java.util.Map.Entry _dom_«propertyName» = (java.util.Map.Entry) _dom_«propertyName»_list.get(0);
862 Object _inner_value = _dom_«propertyName».getValue();
863 «propertyName» = «deserializeValue(type, "_inner_value", schema.type)»;
867 private def dispatch CharSequence deserializeProperty(ContainerSchemaNode schema, Type type,
868 String propertyName) '''
869 java.util.List _dom_«propertyName»_list =
870 _compositeNode.get(«QName.name».create(_localQName,"«schema.QName.localName»"));
871 «type.resolvedName» «propertyName» = null;
872 if(_dom_«propertyName»_list != null && _dom_«propertyName»_list.size() > 0) {
874 java.util.Map _dom_«propertyName» = (java.util.Map) _dom_«propertyName»_list.get(0);
875 «InstanceIdentifier.resolvedName» iid = $3.builder().child(«type.resolvedName».class).build();
876 «propertyName» = «type.serializer(schema).resolvedName».fromDomStatic(_localQName,_dom_«propertyName»,iid);
880 private def dispatch CharSequence deserializeProperty(ChoiceNode schema, Type type, String propertyName) '''
881 «type.resolvedName» «propertyName» = «type.serializer(schema).resolvedName».fromDomStatic(_localQName,_compositeNode,$3);
882 if(«propertyName» != null) {
887 private def dispatch String deserializeValue(GeneratedTransferObject type, String domParameter,
888 TypeDefinition<?> typeDefinition) '''
889 («type.resolvedName») «type.valueSerializer(typeDefinition).resolvedName».fromDomValue(«domParameter»)
892 private def dispatch String deserializeValue(Enumeration type, String domParameter, TypeDefinition<?> typeDefinition) '''
893 («type.resolvedName») «type.valueSerializer(typeDefinition).resolvedName».fromDomValue(«domParameter»)
896 private def dispatch Class<? extends BindingCodec<Map<QName, Object>, Object>> generateValueTransformer(
897 Class<?> inputType, GeneratedTransferObject typeSpec, TypeDefinition<?> typeDef) {
900 val returnType = typeSpec.valueReturnType;
901 if (returnType == null) {
902 val ctCls = createDummyImplementation(inputType, typeSpec);
903 val ret = ctCls.toClassImpl(inputType.classLoader, inputType.protectionDomain)
904 return ret as Class<? extends BindingCodec<Map<QName,Object>, Object>>;
907 val ctCls = createClass(typeSpec.codecClassName) [
908 //staticField(Map,"AUGMENTATION_SERIALIZERS");
909 if (inputType.isYangBindingAvailable) {
910 implementsType(BINDING_CODEC)
911 staticField(it, INSTANCE_IDENTIFIER_CODEC, BindingCodec)
912 staticField(it, IDENTITYREF_CODEC, BindingCodec)
913 implementsType(BindingDeserializer.asCtClass)
915 method(Object, "toDomValue", Object) [
916 modifiers = PUBLIC + FINAL + STATIC
917 val ctSpec = typeSpec.asCtClass;
920 ////System.out.println("«inputType.simpleName»#toDomValue: "+$1);
925 «typeSpec.resolvedName» _encapsulatedValue = («typeSpec.resolvedName») $1;
926 ////System.out.println("«inputType.simpleName»#toDomValue:Enc: "+_encapsulatedValue);
927 «returnType.resolvedName» _value = _encapsulatedValue.getValue();
928 ////System.out.println("«inputType.simpleName»#toDomValue:DeEnc: "+_value);
929 Object _domValue = «serializeValue(returnType, "_value", null)»;
934 method(Object, "serialize", Object) [
937 return toDomValue($1);
941 method(Object, "fromDomValue", Object) [
942 modifiers = PUBLIC + FINAL + STATIC
945 ////System.out.println("«inputType.simpleName»#fromDomValue: "+$1);
950 «returnType.resolvedName» _simpleValue = «deserializeValue(returnType, "$1", null)»;
951 «typeSpec.resolvedName» _value = new «typeSpec.resolvedName»(_simpleValue);
956 method(Object, "deserialize", Object) [
958 return fromDomValue($1);
964 val ret = ctCls.toClassImpl(inputType.classLoader, inputType.protectionDomain)
965 LOG.debug("DOM Codec for {} was generated {}", inputType, ret)
966 return ret as Class<? extends BindingCodec<Map<QName,Object>, Object>>;
967 } catch (Exception e) {
968 LOG.error("Cannot compile DOM Codec for {}", inputType, e);
969 val exception = new CodeGenerationException("Cannot compile Transformator for " + inputType);
970 exception.addSuppressed(e);
975 private def dispatch Class<? extends BindingCodec<Map<QName, Object>, Object>> generateValueTransformer(
976 Class<?> inputType, GeneratedTransferObject typeSpec, UnionTypeDefinition typeDef) {
978 val ctCls = createClass(typeSpec.codecClassName) [
979 val properties = typeSpec.allProperties;
980 val getterToTypeDefinition = XtendHelper.getTypes(typeDef).toMap[type|type.QName.getterName];
981 //staticField(Map,"AUGMENTATION_SERIALIZERS");
982 if (inputType.isYangBindingAvailable) {
983 implementsType(BINDING_CODEC)
984 staticField(it, INSTANCE_IDENTIFIER_CODEC, BindingCodec)
985 staticField(it, IDENTITYREF_CODEC, BindingCodec)
986 implementsType(BindingDeserializer.asCtClass)
988 method(Object, "toDomValue", Object) [
989 modifiers = PUBLIC + FINAL + STATIC
990 val ctSpec = inputType.asCtClass;
993 ////System.out.println("«inputType.simpleName»#toDomValue: "+$1);
998 «typeSpec.resolvedName» _value = («typeSpec.resolvedName») $1;
999 «FOR property : properties.entrySet»
1000 «IF property.key != "getValue"»
1001 «property.value.resolvedName» «property.key» = («property.value.resolvedName») _value.«property.
1003 if(«property.key» != null) {
1004 return «serializeValue(property.value, property.key,
1005 getterToTypeDefinition.get(property.key))»;
1014 method(Object, "serialize", Object) [
1017 return toDomValue($1);
1021 method(Object, "fromDomValue", Object) [
1022 modifiers = PUBLIC + FINAL + STATIC
1025 ////System.out.println("«inputType.simpleName»#fromDomValue: "+$1);
1030 if($1 instanceof String) {
1031 String _simpleValue = (String) $1;
1032 return new «typeSpec.resolvedName»(_simpleValue.toCharArray());
1038 method(Object, "deserialize", Object) [
1040 return fromDomValue($1);
1046 val ret = ctCls.toClassImpl(inputType.classLoader, inputType.protectionDomain)
1047 LOG.debug("DOM Codec for {} was generated {}", inputType, ret)
1048 return ret as Class<? extends BindingCodec<Map<QName,Object>, Object>>;
1049 } catch (Exception e) {
1050 LOG.error("Cannot compile DOM Codec for {}", inputType, e);
1051 val exception = new CodeGenerationException("Cannot compile Transformator for " + inputType);
1052 exception.addSuppressed(e);
1057 private def dispatch Class<? extends BindingCodec<Map<QName, Object>, Object>> generateValueTransformer(
1058 Class<?> inputType, GeneratedTransferObject typeSpec, BitsTypeDefinition typeDef) {
1060 val ctCls = createClass(typeSpec.codecClassName) [
1061 //staticField(Map,"AUGMENTATION_SERIALIZERS");
1062 if (inputType.isYangBindingAvailable) {
1063 implementsType(BINDING_CODEC)
1064 staticField(it, INSTANCE_IDENTIFIER_CODEC, BindingCodec)
1065 staticField(it, IDENTITYREF_CODEC, BindingCodec)
1066 implementsType(BindingDeserializer.asCtClass)
1068 method(Object, "toDomValue", Object) [
1069 modifiers = PUBLIC + FINAL + STATIC
1070 val ctSpec = typeSpec.asCtClass;
1073 ////System.out.println("«inputType.simpleName»#toDomValue: "+$1);
1078 «typeSpec.resolvedName» _encapsulatedValue = («typeSpec.resolvedName») $1;
1079 «HashSet.resolvedName» _value = new «HashSet.resolvedName»();
1080 //System.out.println("«inputType.simpleName»#toDomValue:Enc: "+_encapsulatedValue);
1082 «FOR bit : typeDef.bits»
1083 «val getter = bit.getterName()»
1084 if(Boolean.TRUE.equals(_encapsulatedValue.«getter»())) {
1085 _value.add("«bit.name»");
1088 «Set.resolvedName» _domValue = «Collections.resolvedName».unmodifiableSet(_value);
1089 //System.out.println("«inputType.simpleName»#toDomValue:DeEnc: "+_domValue);
1095 method(Object, "serialize", Object) [
1098 return toDomValue($1);
1102 method(Object, "fromDomValue", Object) [
1103 modifiers = PUBLIC + FINAL + STATIC
1104 val sortedBits = typeDef.bits.sort[o1, o2|o1.propertyName.compareTo(o2.propertyName)]
1107 //System.out.println("«inputType.simpleName»#fromDomValue: "+$1);
1112 «Set.resolvedName» _domValue = («Set.resolvedName») $1;
1113 «FOR bit : sortedBits»
1114 Boolean «bit.propertyName» = Boolean.valueOf(_domValue.contains("«bit.name»"));
1117 return new «inputType.resolvedName»(«FOR bit : sortedBits SEPARATOR ","»«bit.propertyName»«ENDFOR»);
1121 method(Object, "deserialize", Object) [
1123 return fromDomValue($1);
1129 val ret = ctCls.toClassImpl(inputType.classLoader, inputType.protectionDomain)
1130 LOG.debug("DOM Codec for {} was generated {}", inputType, ret)
1131 return ret as Class<? extends BindingCodec<Map<QName,Object>, Object>>;
1132 } catch (Exception e) {
1133 LOG.error("Cannot compile DOM Codec for {}", inputType, e);
1134 val exception = new CodeGenerationException("Cannot compile Transformator for " + inputType);
1135 exception.addSuppressed(e);
1140 def String getPropertyName(Bit bit) {
1141 '''_«BindingGeneratorUtil.parseToValidParamName(bit.name)»'''
1144 def String getterName(Bit bit) {
1146 val paramName = BindingGeneratorUtil.parseToValidParamName(bit.name);
1147 return '''is«paramName.toFirstUpper»''';
1150 def boolean isYangBindingAvailable(Class<?> class1) {
1152 val bindingCodecClass = class1.classLoader.loadClass(BINDING_CODEC.name);
1153 return bindingCodecClass !== null;
1154 } catch (ClassNotFoundException e) {
1159 private def createDummyImplementation(Class<?> object, GeneratedTransferObject typeSpec) {
1160 LOG.trace("Generating Dummy DOM Codec for {} with {}", object, object.classLoader)
1161 return createClass(typeSpec.codecClassName) [
1162 if (object.isYangBindingAvailable) {
1163 implementsType(BINDING_CODEC)
1164 staticField(it, INSTANCE_IDENTIFIER_CODEC, BindingCodec)
1165 staticField(it, IDENTITYREF_CODEC, BindingCodec)
1166 implementsType(BindingDeserializer.asCtClass)
1168 //implementsType(BindingDeserializer.asCtClass)
1169 method(Object, "toDomValue", Object) [
1170 modifiers = PUBLIC + FINAL + STATIC
1175 return $1.toString();
1179 method(Object, "serialize", Object) [
1182 return toDomValue($1);
1186 method(Object, "fromDomValue", Object) [
1187 modifiers = PUBLIC + FINAL + STATIC
1188 bodyChecked = '''return null;'''
1190 method(Object, "deserialize", Object) [
1192 return fromDomValue($1);
1199 private def Type getValueReturnType(GeneratedTransferObject object) {
1200 for (prop : object.properties) {
1201 if (prop.name == "value") {
1202 return prop.returnType;
1205 if (object.superType != null) {
1206 return getValueReturnType(object.superType);
1211 private def Class<?> generateValueTransformer(Class<?> inputType, Enumeration typeSpec) {
1213 val typeRef = new ReferencedTypeImpl(typeSpec.packageName, typeSpec.name);
1214 val schema = getSchemaNode(typeRef) as ExtendedType;
1215 val enumSchema = schema.baseType as EnumerationType;
1217 //log.info("Generating DOM Codec for {} with {}", inputType, inputType.classLoader)
1218 val ctCls = createClass(typeSpec.codecClassName) [
1219 //staticField(Map,"AUGMENTATION_SERIALIZERS");
1220 //implementsType(BINDING_CODEC)
1221 method(Object, "toDomValue", Object) [
1222 modifiers = PUBLIC + FINAL + STATIC
1227 «typeSpec.resolvedName» _value = («typeSpec.resolvedName») $1;
1228 «FOR en : enumSchema.values»
1229 if(«typeSpec.resolvedName».«BindingGeneratorUtil.parseToClassName(en.name)».equals(_value)) {
1237 method(Object, "serialize", Object) [
1239 return toDomValue($1);
1242 method(Object, "fromDomValue", Object) [
1243 modifiers = PUBLIC + FINAL + STATIC
1249 String _value = (String) $1;
1250 «FOR en : enumSchema.values»
1251 if("«en.name»".equals(_value)) {
1252 return «typeSpec.resolvedName».«BindingGeneratorUtil.parseToClassName(en.name)»;
1259 method(Object, "deserialize", Object) [
1261 return fromDomValue($1);
1266 val ret = ctCls.toClassImpl(inputType.classLoader, inputType.protectionDomain)
1267 LOG.debug("DOM Codec for {} was generated {}", inputType, ret)
1269 } catch (CodeGenerationException e) {
1270 throw new CodeGenerationException("Cannot compile Transformator for " + inputType, e);
1271 } catch (Exception e) {
1272 LOG.error("Cannot compile DOM Codec for {}", inputType, e);
1273 val exception = new CodeGenerationException("Cannot compile Transformator for " + inputType);
1274 exception.addSuppressed(e);
1280 def Class<?> toClassImpl(CtClass newClass, ClassLoader loader, ProtectionDomain domain) {
1281 val cls = newClass.toClass(loader, domain);
1282 if (classFileCapturePath !== null) {
1283 newClass.writeFile(classFileCapturePath.absolutePath);
1285 listener?.onCodecCreated(cls);
1289 def debugWriteClass(CtClass class1) {
1290 val path = class1.name.replace(".", "/") + ".class"
1292 val captureFile = new File(classFileCapturePath, path);
1293 captureFile.createNewFile
1297 private def dispatch String deserializeValue(Type type, String domParameter, TypeDefinition<?> typeDef) {
1298 if (INSTANCE_IDENTIFIER.equals(type)) {
1299 return '''(«InstanceIdentifier.name») «INSTANCE_IDENTIFIER_CODEC».deserialize(«domParameter»)'''
1300 } else if (CLASS_TYPE.equals(type)) {
1301 return '''(«Class.name») «IDENTITYREF_CODEC».deserialize(«domParameter»)'''
1302 } else if (typeDef!=null && typeDef instanceof EmptyTypeDefinition) {
1303 if(domParameter == null) {
1304 return ''' Boolean.FALSE '''
1306 return ''' Boolean.TRUE '''
1309 return '''(«type.resolvedName») «domParameter»'''
1317 private def dispatch CharSequence deserializeProperty(DataSchemaNode container, Type type, String propertyName) '''
1318 «type.resolvedName» «propertyName» = null;
1321 private def dispatch CharSequence deserializeProperty(DataSchemaNode container, GeneratedTypeBuilder type,
1322 String propertyName) {
1323 _deserializeProperty(container, type.toInstance, propertyName)
1326 static def toSetter(String it) {
1328 if (startsWith("is")) {
1329 return "set" + substring(2);
1330 } else if (startsWith("get")) {
1331 return "set" + substring(3);
1337 private def dispatch CharSequence deserializeProperty(DataSchemaNode container,GeneratedType type, String propertyName) '''
1338 «type.resolvedName» «propertyName» = value.«propertyName»();
1339 if(«propertyName» != null) {
1340 Object domValue = «type.serializer».toDomStatic(QNAME,«propertyName»);
1341 _childNodes.add(domValue);
1345 private def getBuilderName(GeneratedType type) '''«type.resolvedName»Builder'''
1347 private def staticQNameField(CtClass it, QName node) {
1348 val field = new CtField(ctQName, "QNAME", it);
1349 field.modifiers = PUBLIC + FINAL + STATIC;
1351 '''«QName.asCtClass.name».create("«node.namespace»","«node.formattedRevision»","«node.localName»")''')
1354 private def String serializeBodyImpl(GeneratedType type, DataNodeContainer nodeContainer) '''
1356 «QName.name» _resultName = «QName.name».create($1,QNAME.getLocalName());
1357 java.util.List _childNodes = new java.util.ArrayList();
1358 «type.resolvedName» value = («type.resolvedName») $2;
1359 «transformDataContainerBody(type, type.allProperties, nodeContainer)»
1360 «serializeAugmentations»
1361 return ($r) java.util.Collections.singletonMap(_resultName,_childNodes);
1365 private def dispatch String serializeBody(GeneratedType type, ListSchemaNode node) {
1366 return serializeBodyImpl(type, node);
1369 private def dispatch String serializeBody(GeneratedType type, NotificationDefinition node) {
1370 return serializeBodyImpl(type, node);
1373 private def dispatch String serializeBody(GeneratedType type, ContainerSchemaNode node) {
1374 return serializeBodyImpl(type, node);
1377 private def dispatch String serializeBody(GeneratedType type, ChoiceCaseNode node) {
1378 return serializeBodyImpl(type, node);
1381 private def dispatch String serializeBody(GeneratedType type, SchemaNode node) '''
1383 «QName.name» _resultName = «QName.name».create($1,QNAME.getLocalName());
1384 java.util.List _childNodes = new java.util.ArrayList();
1385 «type.resolvedName» value = («type.resolvedName») $2;
1386 return ($r) java.util.Collections.singletonMap(_resultName,_childNodes);
1390 private def transformDataContainerBody(Type type, Map<String, Type> properties, DataNodeContainer node) {
1392 «FOR child : node.childNodes»
1393 «val signature = properties.getFor(child)»
1394 «IF signature !== null»
1395 ////System.out.println("«type.name»#«signature.key»" + value.«signature.key»());
1396 «serializeProperty(child, signature.value, signature.key)»
1403 private static def serializeAugmentations() '''
1404 java.util.List _augmentations = (java.util.List) «AUGMENTATION_CODEC».serialize(value);
1405 if(_augmentations != null) {
1406 _childNodes.addAll(_augmentations);
1410 private static def Entry<String, Type> getFor(Map<String, Type> map, DataSchemaNode node) {
1411 var sig = map.get(node.getterName);
1413 return new SimpleEntry(node.getterName, sig);
1415 sig = map.get(node.booleanGetterName);
1417 return new SimpleEntry(node.booleanGetterName, map.get(node.booleanGetterName));
1422 private static def String getBooleanGetterName(DataSchemaNode node) {
1423 return "is" + BindingMapping.getPropertyName(node.QName.localName).toFirstUpper;
1426 private static def String getGetterName(DataSchemaNode node) {
1427 return "get" + BindingMapping.getPropertyName(node.QName.localName).toFirstUpper;
1430 private static def String getGetterName(QName node) {
1431 return "get" + BindingMapping.getPropertyName(node.localName).toFirstUpper;
1434 private def dispatch CharSequence serializeProperty(ListSchemaNode schema, ParameterizedType type,
1435 String propertyName) '''
1436 «type.resolvedName» «propertyName» = value.«propertyName»();
1437 ////System.out.println("«propertyName»:" + «propertyName»);
1438 if(«propertyName» != null) {
1439 java.util.Iterator _iterator = «propertyName».iterator();
1440 boolean _hasNext = _iterator.hasNext();
1442 Object _listItem = _iterator.next();
1443 Object _domValue = «type.actualTypeArguments.get(0).serializer(schema).resolvedName».toDomStatic(_resultName,_listItem);
1444 _childNodes.add(_domValue);
1445 _hasNext = _iterator.hasNext();
1450 private def dispatch CharSequence serializeProperty(LeafSchemaNode schema, Type type, String propertyName) '''
1451 «type.resolvedName» «propertyName» = value.«propertyName»();
1453 if(«propertyName» != null) {
1454 «QName.name» _qname = «QName.name».create(_resultName,"«schema.QName.localName»");
1455 Object _propValue = «serializeValue(type, propertyName, schema.type)»;
1456 if(_propValue != null) {
1457 Object _domValue = java.util.Collections.singletonMap(_qname,_propValue);
1458 _childNodes.add(_domValue);
1463 private def dispatch serializeValue(GeneratedTransferObject type, String parameter, TypeDefinition<?> typeDefinition) {
1464 '''«type.valueSerializer(typeDefinition).resolvedName».toDomValue(«parameter»)'''
1467 private def dispatch serializeValue(Enumeration type, String parameter, TypeDefinition<?> typeDefinition) {
1468 '''«type.valueSerializer(typeDefinition).resolvedName».toDomValue(«parameter»)'''
1471 private def dispatch serializeValue(Type type, String parameter, EmptyTypeDefinition typeDefinition) {
1472 '''(«parameter».booleanValue() ? "" : null)'''
1475 private def dispatch serializeValue(Type signature, String property, TypeDefinition<?> typeDefinition) {
1476 serializeValue(signature,property)
1479 private def dispatch serializeValue(Type signature, String property, Void typeDefinition) {
1480 serializeValue(signature,property)
1483 private def dispatch serializeValue(Type signature, String property) {
1484 if (INSTANCE_IDENTIFIER == signature) {
1485 return '''«INSTANCE_IDENTIFIER_CODEC».serialize(«property»)'''
1486 } else if (CLASS_TYPE.equals(signature)) {
1487 return '''(«QName.resolvedName») «IDENTITYREF_CODEC».serialize(«property»)'''
1489 if ("char[]" == signature.name) {
1490 return '''new String(«property»)''';
1492 return '''«property»''';
1495 private def dispatch CharSequence serializeProperty(LeafListSchemaNode schema, ParameterizedType type,
1496 String propertyName) '''
1497 «type.resolvedName» «propertyName» = value.«propertyName»();
1498 if(«propertyName» != null) {
1499 «QName.name» _qname = «QName.name».create(_resultName,"«schema.QName.localName»");
1500 java.util.Iterator _iterator = «propertyName».iterator();
1501 boolean _hasNext = _iterator.hasNext();
1503 Object _listItem = _iterator.next();
1504 Object _propValue = «serializeValue(type.actualTypeArguments.get(0), "_listItem", schema.type)»;
1505 Object _domValue = java.util.Collections.singletonMap(_qname,_propValue);
1506 _childNodes.add(_domValue);
1507 _hasNext = _iterator.hasNext();
1512 private def dispatch CharSequence serializeProperty(ChoiceNode container, GeneratedType type,
1513 String propertyName) '''
1514 «type.resolvedName» «propertyName» = value.«propertyName»();
1515 if(«propertyName» != null) {
1516 java.util.List domValue = «type.serializer(container).resolvedName».toDomStatic(_resultName,«propertyName»);
1517 _childNodes.addAll(domValue);
1525 private def dispatch CharSequence serializeProperty(DataSchemaNode container, Type type, String propertyName) '''
1526 «type.resolvedName» «propertyName» = value.«propertyName»();
1527 if(«propertyName» != null) {
1528 Object domValue = «propertyName»;
1529 _childNodes.add(domValue);
1533 private def dispatch CharSequence serializeProperty(DataSchemaNode container, GeneratedTypeBuilder type,
1534 String propertyName) {
1535 serializeProperty(container, type.toInstance, propertyName)
1538 private def dispatch CharSequence serializeProperty(DataSchemaNode container, GeneratedType type,
1539 String propertyName) '''
1540 «type.resolvedName» «propertyName» = value.«propertyName»();
1541 if(«propertyName» != null) {
1542 Object domValue = «type.serializer(container).resolvedName».toDomStatic(_resultName,«propertyName»);
1543 _childNodes.add(domValue);
1547 private def codecClassName(GeneratedType typeSpec) {
1548 return '''«typeSpec.resolvedName»$Broker$Codec$DOM'''
1551 private def codecClassName(Class<?> typeSpec) {
1552 return '''«typeSpec.name»$Broker$Codec$DOM'''
1555 private def HashMap<String, Type> getAllProperties(GeneratedType type) {
1556 val ret = new HashMap<String, Type>();
1557 type.collectAllProperties(ret);
1561 private def dispatch void collectAllProperties(GeneratedType type, Map<String, Type> set) {
1562 for (definition : type.methodDefinitions) {
1563 set.put(definition.name, definition.returnType);
1565 for (property : type.properties) {
1566 set.put(property.getterName, property.returnType);
1568 for (parent : type.implements) {
1569 parent.collectAllProperties(set);
1573 def String getGetterName(GeneratedProperty property) {
1574 return "get" + property.name.toFirstUpper
1577 private def dispatch void collectAllProperties(Type type, Map<String, Type> set) {
1578 // NOOP for generic type.
1581 def String getResolvedName(Type type) {
1582 return type.asCtClass.name;
1585 def String getResolvedName(Class<?> type) {
1586 return type.asCtClass.name;
1589 def CtClass asCtClass(Type type) {
1590 val cls = loadClass(type.fullyQualifiedName)
1591 return cls.asCtClass;
1594 private def dispatch processException(Class<?> inputType, CodeGenerationException e) {
1595 LOG.error("Cannot compile DOM Codec for {}. One of it's prerequisites was not generated.", inputType);
1599 private def dispatch processException(Class<?> inputType, Exception e) {
1600 LOG.error("Cannot compile DOM Codec for {}", inputType, e);
1601 val exception = new CodeGenerationException("Cannot compile Transformator for " + inputType, e);
1605 private def setBodyChecked(CtMethod method, String body) {
1607 method.setBody(body);
1608 } catch (CannotCompileException e) {
1609 LOG.error("Cannot compile method: {}#{} {}, Reason: {} Body: {}", method.declaringClass, method.name,
1610 method.signature, e.message, body)
1617 class PropertyPair {
1626 SchemaNode schemaNode;