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, typeDefinition);
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 String deserializeValue(Type type, String domParameter, TypeDefinition<?> typeDef) {
897 if (INSTANCE_IDENTIFIER.equals(type)) {
898 return '''(«InstanceIdentifier.name») «INSTANCE_IDENTIFIER_CODEC».deserialize(«domParameter»)'''
899 } else if (CLASS_TYPE.equals(type)) {
900 return '''(«Class.name») «IDENTITYREF_CODEC».deserialize(«domParameter»)'''
901 } else if (typeDef!=null && typeDef instanceof EmptyTypeDefinition) {
902 if(domParameter == null) {
903 return ''' Boolean.FALSE '''
905 return ''' Boolean.TRUE '''
908 return '''(«type.resolvedName») «domParameter»'''
911 private def dispatch Class<? extends BindingCodec<Map<QName, Object>, Object>> generateValueTransformer(
912 Class<?> inputType, GeneratedTransferObject typeSpec, TypeDefinition<?> typeDef) {
915 val returnType = typeSpec.valueReturnType;
916 if (returnType == null) {
917 val ctCls = createDummyImplementation(inputType, typeSpec);
918 val ret = ctCls.toClassImpl(inputType.classLoader, inputType.protectionDomain)
919 return ret as Class<? extends BindingCodec<Map<QName,Object>, Object>>;
922 val ctCls = createClass(typeSpec.codecClassName) [
923 //staticField(Map,"AUGMENTATION_SERIALIZERS");
924 if (inputType.isYangBindingAvailable) {
925 implementsType(BINDING_CODEC)
926 staticField(it, INSTANCE_IDENTIFIER_CODEC, BindingCodec)
927 staticField(it, IDENTITYREF_CODEC, BindingCodec)
928 implementsType(BindingDeserializer.asCtClass)
930 method(Object, "toDomValue", Object) [
931 modifiers = PUBLIC + FINAL + STATIC
932 val ctSpec = typeSpec.asCtClass;
935 ////System.out.println("«inputType.simpleName»#toDomValue: "+$1);
940 «typeSpec.resolvedName» _encapsulatedValue = («typeSpec.resolvedName») $1;
941 ////System.out.println("«inputType.simpleName»#toDomValue:Enc: "+_encapsulatedValue);
942 «returnType.resolvedName» _value = _encapsulatedValue.getValue();
943 ////System.out.println("«inputType.simpleName»#toDomValue:DeEnc: "+_value);
944 Object _domValue = «serializeValue(returnType, "_value", null)»;
949 method(Object, "serialize", Object) [
952 return toDomValue($1);
956 method(Object, "fromDomValue", Object) [
957 modifiers = PUBLIC + FINAL + STATIC
960 ////System.out.println("«inputType.simpleName»#fromDomValue: "+$1);
965 «returnType.resolvedName» _simpleValue = «deserializeValue(returnType, "$1", null)»;
966 «typeSpec.resolvedName» _value = new «typeSpec.resolvedName»(_simpleValue);
971 method(Object, "deserialize", Object) [
973 return fromDomValue($1);
979 val ret = ctCls.toClassImpl(inputType.classLoader, inputType.protectionDomain)
980 LOG.debug("DOM Codec for {} was generated {}", inputType, ret)
981 return ret as Class<? extends BindingCodec<Map<QName,Object>, Object>>;
982 } catch (Exception e) {
983 LOG.error("Cannot compile DOM Codec for {}", inputType, e);
984 val exception = new CodeGenerationException("Cannot compile Transformator for " + inputType);
985 exception.addSuppressed(e);
990 private def dispatch Class<? extends BindingCodec<Map<QName, Object>, Object>> generateValueTransformer(
991 Class<?> inputType, GeneratedTransferObject typeSpec, UnionTypeDefinition typeDef) {
993 val ctCls = createClass(typeSpec.codecClassName) [
994 val properties = typeSpec.allProperties;
995 val getterToTypeDefinition = XtendHelper.getTypes(typeDef).toMap[type|type.QName.getterName];
996 //staticField(Map,"AUGMENTATION_SERIALIZERS");
997 if (inputType.isYangBindingAvailable) {
998 implementsType(BINDING_CODEC)
999 staticField(it, INSTANCE_IDENTIFIER_CODEC, BindingCodec)
1000 staticField(it, IDENTITYREF_CODEC, BindingCodec)
1001 implementsType(BindingDeserializer.asCtClass)
1003 method(Object, "toDomValue", Object) [
1004 modifiers = PUBLIC + FINAL + STATIC
1005 val ctSpec = inputType.asCtClass;
1008 ////System.out.println("«inputType.simpleName»#toDomValue: "+$1);
1013 «typeSpec.resolvedName» _value = («typeSpec.resolvedName») $1;
1014 «FOR property : properties.entrySet»
1015 «IF property.key != "getValue"»
1016 «property.value.resolvedName» «property.key» = («property.value.resolvedName») _value.«property.
1018 if(«property.key» != null) {
1019 return «serializeValue(property.value, property.key,
1020 getterToTypeDefinition.get(property.key))»;
1029 method(Object, "serialize", Object) [
1032 return toDomValue($1);
1036 method(Object, "fromDomValue", Object) [
1037 modifiers = PUBLIC + FINAL + STATIC
1040 ////System.out.println("«inputType.simpleName»#fromDomValue: "+$1);
1045 if($1 instanceof String) {
1046 String _simpleValue = (String) $1;
1047 return new «typeSpec.resolvedName»(_simpleValue.toCharArray());
1053 method(Object, "deserialize", Object) [
1055 return fromDomValue($1);
1061 val ret = ctCls.toClassImpl(inputType.classLoader, inputType.protectionDomain)
1062 LOG.debug("DOM Codec for {} was generated {}", inputType, ret)
1063 return ret as Class<? extends BindingCodec<Map<QName,Object>, Object>>;
1064 } catch (Exception e) {
1065 LOG.error("Cannot compile DOM Codec for {}", inputType, e);
1066 val exception = new CodeGenerationException("Cannot compile Transformator for " + inputType);
1067 exception.addSuppressed(e);
1072 private def dispatch Class<? extends BindingCodec<Map<QName, Object>, Object>> generateValueTransformer(
1073 Class<?> inputType, GeneratedTransferObject typeSpec, BitsTypeDefinition typeDef) {
1075 val ctCls = createClass(typeSpec.codecClassName) [
1076 //staticField(Map,"AUGMENTATION_SERIALIZERS");
1077 if (inputType.isYangBindingAvailable) {
1078 implementsType(BINDING_CODEC)
1079 staticField(it, INSTANCE_IDENTIFIER_CODEC, BindingCodec)
1080 staticField(it, IDENTITYREF_CODEC, BindingCodec)
1081 implementsType(BindingDeserializer.asCtClass)
1083 method(Object, "toDomValue", Object) [
1084 modifiers = PUBLIC + FINAL + STATIC
1085 val ctSpec = typeSpec.asCtClass;
1088 ////System.out.println("«inputType.simpleName»#toDomValue: "+$1);
1093 «typeSpec.resolvedName» _encapsulatedValue = («typeSpec.resolvedName») $1;
1094 «HashSet.resolvedName» _value = new «HashSet.resolvedName»();
1095 //System.out.println("«inputType.simpleName»#toDomValue:Enc: "+_encapsulatedValue);
1097 «FOR bit : typeDef.bits»
1098 «val getter = bit.getterName()»
1099 if(Boolean.TRUE.equals(_encapsulatedValue.«getter»())) {
1100 _value.add("«bit.name»");
1103 «Set.resolvedName» _domValue = «Collections.resolvedName».unmodifiableSet(_value);
1104 //System.out.println("«inputType.simpleName»#toDomValue:DeEnc: "+_domValue);
1110 method(Object, "serialize", Object) [
1113 return toDomValue($1);
1117 method(Object, "fromDomValue", Object) [
1118 modifiers = PUBLIC + FINAL + STATIC
1119 val sortedBits = typeDef.bits.sort[o1, o2|o1.propertyName.compareTo(o2.propertyName)]
1122 //System.out.println("«inputType.simpleName»#fromDomValue: "+$1);
1127 «Set.resolvedName» _domValue = («Set.resolvedName») $1;
1128 «FOR bit : sortedBits»
1129 Boolean «bit.propertyName» = Boolean.valueOf(_domValue.contains("«bit.name»"));
1132 return new «inputType.resolvedName»(«FOR bit : sortedBits SEPARATOR ","»«bit.propertyName»«ENDFOR»);
1136 method(Object, "deserialize", Object) [
1138 return fromDomValue($1);
1144 val ret = ctCls.toClassImpl(inputType.classLoader, inputType.protectionDomain)
1145 LOG.debug("DOM Codec for {} was generated {}", inputType, ret)
1146 return ret as Class<? extends BindingCodec<Map<QName,Object>, Object>>;
1147 } catch (Exception e) {
1148 LOG.error("Cannot compile DOM Codec for {}", inputType, e);
1149 val exception = new CodeGenerationException("Cannot compile Transformator for " + inputType);
1150 exception.addSuppressed(e);
1155 def String getPropertyName(Bit bit) {
1156 '''_«BindingGeneratorUtil.parseToValidParamName(bit.name)»'''
1159 def String getterName(Bit bit) {
1161 val paramName = BindingGeneratorUtil.parseToValidParamName(bit.name);
1162 return '''is«paramName.toFirstUpper»''';
1165 def boolean isYangBindingAvailable(Class<?> class1) {
1167 val bindingCodecClass = class1.classLoader.loadClass(BINDING_CODEC.name);
1168 return bindingCodecClass !== null;
1169 } catch (ClassNotFoundException e) {
1174 private def createDummyImplementation(Class<?> object, GeneratedTransferObject typeSpec) {
1175 LOG.trace("Generating Dummy DOM Codec for {} with {}", object, object.classLoader)
1176 return createClass(typeSpec.codecClassName) [
1177 if (object.isYangBindingAvailable) {
1178 implementsType(BINDING_CODEC)
1179 staticField(it, INSTANCE_IDENTIFIER_CODEC, BindingCodec)
1180 staticField(it, IDENTITYREF_CODEC, BindingCodec)
1181 implementsType(BindingDeserializer.asCtClass)
1183 //implementsType(BindingDeserializer.asCtClass)
1184 method(Object, "toDomValue", Object) [
1185 modifiers = PUBLIC + FINAL + STATIC
1190 return $1.toString();
1194 method(Object, "serialize", Object) [
1197 return toDomValue($1);
1201 method(Object, "fromDomValue", Object) [
1202 modifiers = PUBLIC + FINAL + STATIC
1203 bodyChecked = '''return null;'''
1205 method(Object, "deserialize", Object) [
1207 return fromDomValue($1);
1214 private def Type getValueReturnType(GeneratedTransferObject object) {
1215 for (prop : object.properties) {
1216 if (prop.name == "value") {
1217 return prop.returnType;
1220 if (object.superType != null) {
1221 return getValueReturnType(object.superType);
1226 private def dispatch Class<?> generateValueTransformer(Class<?> inputType, Enumeration typeSpec, TypeDefinition<?> type) {
1227 var EnumerationType enumSchemaType
1228 if (type instanceof EnumerationType) {
1229 enumSchemaType = type as EnumerationType
1231 val typeRef = new ReferencedTypeImpl(typeSpec.packageName, typeSpec.name);
1232 val schema = getSchemaNode(typeRef) as ExtendedType;
1233 enumSchemaType = schema.baseType as EnumerationType;
1235 val enumSchema = enumSchemaType;
1237 //log.info("Generating DOM Codec for {} with {}", inputType, inputType.classLoader)
1238 val ctCls = createClass(typeSpec.codecClassName) [
1239 //staticField(Map,"AUGMENTATION_SERIALIZERS");
1240 //implementsType(BINDING_CODEC)
1241 method(Object, "toDomValue", Object) [
1242 modifiers = PUBLIC + FINAL + STATIC
1247 «typeSpec.resolvedName» _value = («typeSpec.resolvedName») $1;
1248 «FOR en : enumSchema.values»
1249 if(«typeSpec.resolvedName».«BindingMapping.getClassName(en.name)».equals(_value)) {
1257 method(Object, "serialize", Object) [
1259 return toDomValue($1);
1262 method(Object, "fromDomValue", Object) [
1263 modifiers = PUBLIC + FINAL + STATIC
1269 String _value = (String) $1;
1270 «FOR en : enumSchema.values»
1271 if("«en.name»".equals(_value)) {
1272 return «typeSpec.resolvedName».«BindingMapping.getClassName(en.name)»;
1279 method(Object, "deserialize", Object) [
1281 return fromDomValue($1);
1286 val ret = ctCls.toClassImpl(inputType.classLoader, inputType.protectionDomain)
1287 LOG.debug("DOM Codec for {} was generated {}", inputType, ret)
1289 } catch (CodeGenerationException e) {
1290 throw new CodeGenerationException("Cannot compile Transformator for " + inputType, e);
1291 } catch (Exception e) {
1292 LOG.error("Cannot compile DOM Codec for {}", inputType, e);
1293 val exception = new CodeGenerationException("Cannot compile Transformator for " + inputType);
1294 exception.addSuppressed(e);
1300 def Class<?> toClassImpl(CtClass newClass, ClassLoader loader, ProtectionDomain domain) {
1301 val cls = newClass.toClass(loader, domain);
1302 if (classFileCapturePath !== null) {
1303 newClass.writeFile(classFileCapturePath.absolutePath);
1305 listener?.onCodecCreated(cls);
1309 def debugWriteClass(CtClass class1) {
1310 val path = class1.name.replace(".", "/") + ".class"
1312 val captureFile = new File(classFileCapturePath, path);
1313 captureFile.createNewFile
1321 private def dispatch CharSequence deserializeProperty(DataSchemaNode container, Type type, String propertyName) '''
1322 «type.resolvedName» «propertyName» = null;
1325 private def dispatch CharSequence deserializeProperty(DataSchemaNode container, GeneratedTypeBuilder type,
1326 String propertyName) {
1327 _deserializeProperty(container, type.toInstance, propertyName)
1330 static def toSetter(String it) {
1332 if (startsWith("is")) {
1333 return "set" + substring(2);
1334 } else if (startsWith("get")) {
1335 return "set" + substring(3);
1341 private def dispatch CharSequence deserializeProperty(DataSchemaNode container,GeneratedType type, String propertyName) '''
1342 «type.resolvedName» «propertyName» = value.«propertyName»();
1343 if(«propertyName» != null) {
1344 Object domValue = «type.serializer».toDomStatic(QNAME,«propertyName»);
1345 _childNodes.add(domValue);
1349 private def getBuilderName(GeneratedType type) '''«type.resolvedName»Builder'''
1351 private def staticQNameField(CtClass it, QName node) {
1352 val field = new CtField(ctQName, "QNAME", it);
1353 field.modifiers = PUBLIC + FINAL + STATIC;
1355 '''«QName.asCtClass.name».create("«node.namespace»","«node.formattedRevision»","«node.localName»")''')
1358 private def String serializeBodyImpl(GeneratedType type, DataNodeContainer nodeContainer) '''
1360 «QName.name» _resultName = «QName.name».create($1,QNAME.getLocalName());
1361 java.util.List _childNodes = new java.util.ArrayList();
1362 «type.resolvedName» value = («type.resolvedName») $2;
1363 «transformDataContainerBody(type, type.allProperties, nodeContainer)»
1364 «serializeAugmentations»
1365 return ($r) java.util.Collections.singletonMap(_resultName,_childNodes);
1369 private def dispatch String serializeBody(GeneratedType type, ListSchemaNode node) {
1370 return serializeBodyImpl(type, node);
1373 private def dispatch String serializeBody(GeneratedType type, NotificationDefinition node) {
1374 return serializeBodyImpl(type, node);
1377 private def dispatch String serializeBody(GeneratedType type, ContainerSchemaNode node) {
1378 return serializeBodyImpl(type, node);
1381 private def dispatch String serializeBody(GeneratedType type, ChoiceCaseNode node) {
1382 return serializeBodyImpl(type, node);
1385 private def dispatch String serializeBody(GeneratedType type, SchemaNode node) '''
1387 «QName.name» _resultName = «QName.name».create($1,QNAME.getLocalName());
1388 java.util.List _childNodes = new java.util.ArrayList();
1389 «type.resolvedName» value = («type.resolvedName») $2;
1390 return ($r) java.util.Collections.singletonMap(_resultName,_childNodes);
1394 private def transformDataContainerBody(Type type, Map<String, Type> properties, DataNodeContainer node) {
1396 «FOR child : node.childNodes»
1397 «val signature = properties.getFor(child)»
1398 «IF signature !== null»
1399 ////System.out.println("«type.name»#«signature.key»" + value.«signature.key»());
1400 «serializeProperty(child, signature.value, signature.key)»
1407 private static def serializeAugmentations() '''
1408 java.util.List _augmentations = (java.util.List) «AUGMENTATION_CODEC».serialize(value);
1409 if(_augmentations != null) {
1410 _childNodes.addAll(_augmentations);
1414 private static def Entry<String, Type> getFor(Map<String, Type> map, DataSchemaNode node) {
1415 var sig = map.get(node.getterName);
1417 return new SimpleEntry(node.getterName, sig);
1419 sig = map.get(node.booleanGetterName);
1421 return new SimpleEntry(node.booleanGetterName, map.get(node.booleanGetterName));
1426 private static def String getBooleanGetterName(DataSchemaNode node) {
1427 return "is" + BindingMapping.getPropertyName(node.QName.localName).toFirstUpper;
1430 private static def String getGetterName(DataSchemaNode node) {
1431 return "get" + BindingMapping.getPropertyName(node.QName.localName).toFirstUpper;
1434 private static def String getGetterName(QName node) {
1435 return "get" + BindingMapping.getPropertyName(node.localName).toFirstUpper;
1438 private def dispatch CharSequence serializeProperty(ListSchemaNode schema, ParameterizedType type,
1439 String propertyName) '''
1440 «type.resolvedName» «propertyName» = value.«propertyName»();
1441 ////System.out.println("«propertyName»:" + «propertyName»);
1442 if(«propertyName» != null) {
1443 java.util.Iterator _iterator = «propertyName».iterator();
1444 boolean _hasNext = _iterator.hasNext();
1446 Object _listItem = _iterator.next();
1447 Object _domValue = «type.actualTypeArguments.get(0).serializer(schema).resolvedName».toDomStatic(_resultName,_listItem);
1448 _childNodes.add(_domValue);
1449 _hasNext = _iterator.hasNext();
1454 private def dispatch CharSequence serializeProperty(LeafSchemaNode schema, Type type, String propertyName) '''
1455 «type.resolvedName» «propertyName» = value.«propertyName»();
1457 if(«propertyName» != null) {
1458 «QName.name» _qname = «QName.name».create(_resultName,"«schema.QName.localName»");
1459 Object _propValue = «serializeValue(type, propertyName, schema.type)»;
1460 if(_propValue != null) {
1461 Object _domValue = java.util.Collections.singletonMap(_qname,_propValue);
1462 _childNodes.add(_domValue);
1467 private def dispatch serializeValue(GeneratedTransferObject type, String parameter, TypeDefinition<?> typeDefinition) {
1468 '''«type.valueSerializer(typeDefinition).resolvedName».toDomValue(«parameter»)'''
1471 private def dispatch serializeValue(Enumeration type, String parameter, TypeDefinition<?> typeDefinition) {
1472 '''«type.valueSerializer(typeDefinition).resolvedName».toDomValue(«parameter»)'''
1475 private def dispatch serializeValue(Type type, String parameter, EmptyTypeDefinition typeDefinition) {
1476 '''(«parameter».booleanValue() ? "" : null)'''
1479 private def dispatch serializeValue(Type signature, String property, TypeDefinition<?> typeDefinition) {
1480 serializeValue(signature,property)
1483 private def dispatch serializeValue(Type signature, String property, Void typeDefinition) {
1484 serializeValue(signature,property)
1487 private def dispatch serializeValue(Type signature, String property) {
1488 if (INSTANCE_IDENTIFIER == signature) {
1489 return '''«INSTANCE_IDENTIFIER_CODEC».serialize(«property»)'''
1490 } else if (CLASS_TYPE.equals(signature)) {
1491 return '''(«QName.resolvedName») «IDENTITYREF_CODEC».serialize(«property»)'''
1493 if ("char[]" == signature.name) {
1494 return '''new String(«property»)''';
1496 return '''«property»''';
1499 private def dispatch CharSequence serializeProperty(LeafListSchemaNode schema, ParameterizedType type,
1500 String propertyName) '''
1501 «type.resolvedName» «propertyName» = value.«propertyName»();
1502 if(«propertyName» != null) {
1503 «QName.name» _qname = «QName.name».create(_resultName,"«schema.QName.localName»");
1504 java.util.Iterator _iterator = «propertyName».iterator();
1505 boolean _hasNext = _iterator.hasNext();
1507 Object _listItem = _iterator.next();
1508 Object _propValue = «serializeValue(type.actualTypeArguments.get(0), "_listItem", schema.type)»;
1509 Object _domValue = java.util.Collections.singletonMap(_qname,_propValue);
1510 _childNodes.add(_domValue);
1511 _hasNext = _iterator.hasNext();
1516 private def dispatch CharSequence serializeProperty(ChoiceNode container, GeneratedType type,
1517 String propertyName) '''
1518 «type.resolvedName» «propertyName» = value.«propertyName»();
1519 if(«propertyName» != null) {
1520 java.util.List domValue = «type.serializer(container).resolvedName».toDomStatic(_resultName,«propertyName»);
1521 _childNodes.addAll(domValue);
1529 private def dispatch CharSequence serializeProperty(DataSchemaNode container, Type type, String propertyName) '''
1530 «type.resolvedName» «propertyName» = value.«propertyName»();
1531 if(«propertyName» != null) {
1532 Object domValue = «propertyName»;
1533 _childNodes.add(domValue);
1537 private def dispatch CharSequence serializeProperty(DataSchemaNode container, GeneratedTypeBuilder type,
1538 String propertyName) {
1539 serializeProperty(container, type.toInstance, propertyName)
1542 private def dispatch CharSequence serializeProperty(DataSchemaNode container, GeneratedType type,
1543 String propertyName) '''
1544 «type.resolvedName» «propertyName» = value.«propertyName»();
1545 if(«propertyName» != null) {
1546 Object domValue = «type.serializer(container).resolvedName».toDomStatic(_resultName,«propertyName»);
1547 _childNodes.add(domValue);
1551 private def codecClassName(GeneratedType typeSpec) {
1552 return '''«typeSpec.resolvedName»$Broker$Codec$DOM'''
1555 private def codecClassName(Class<?> typeSpec) {
1556 return '''«typeSpec.name»$Broker$Codec$DOM'''
1559 private def HashMap<String, Type> getAllProperties(GeneratedType type) {
1560 val ret = new HashMap<String, Type>();
1561 type.collectAllProperties(ret);
1565 private def dispatch void collectAllProperties(GeneratedType type, Map<String, Type> set) {
1566 for (definition : type.methodDefinitions) {
1567 set.put(definition.name, definition.returnType);
1569 for (property : type.properties) {
1570 set.put(property.getterName, property.returnType);
1572 for (parent : type.implements) {
1573 parent.collectAllProperties(set);
1577 def String getGetterName(GeneratedProperty property) {
1578 return "get" + property.name.toFirstUpper
1581 private def dispatch void collectAllProperties(Type type, Map<String, Type> set) {
1582 // NOOP for generic type.
1585 def String getResolvedName(Type type) {
1586 return type.asCtClass.name;
1589 def String getResolvedName(Class<?> type) {
1590 return type.asCtClass.name;
1593 def CtClass asCtClass(Type type) {
1594 val cls = loadClass(type.fullyQualifiedName)
1595 return cls.asCtClass;
1598 private def dispatch processException(Class<?> inputType, CodeGenerationException e) {
1599 LOG.error("Cannot compile DOM Codec for {}. One of it's prerequisites was not generated.", inputType);
1603 private def dispatch processException(Class<?> inputType, Exception e) {
1604 LOG.error("Cannot compile DOM Codec for {}", inputType, e);
1605 val exception = new CodeGenerationException("Cannot compile Transformator for " + inputType, e);
1609 private def setBodyChecked(CtMethod method, String body) {
1611 method.setBody(body);
1612 } catch (CannotCompileException e) {
1613 LOG.error("Cannot compile method: {}#{} {}, Reason: {} Body: {}", method.declaringClass, method.name,
1614 method.signature, e.message, body)
1621 class PropertyPair {
1630 SchemaNode schemaNode;