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.CodeGenerationException
33 import org.opendaylight.yangtools.sal.binding.generator.util.SourceCodeGenerator
34 import org.opendaylight.yangtools.sal.binding.generator.util.SourceCodeGeneratorFactory
35 import org.opendaylight.yangtools.sal.binding.generator.util.XtendHelper
36 import org.opendaylight.yangtools.sal.binding.model.api.Enumeration
37 import org.opendaylight.yangtools.sal.binding.model.api.GeneratedProperty
38 import org.opendaylight.yangtools.sal.binding.model.api.GeneratedTransferObject
39 import org.opendaylight.yangtools.sal.binding.model.api.GeneratedType
40 import org.opendaylight.yangtools.sal.binding.model.api.ParameterizedType
41 import org.opendaylight.yangtools.sal.binding.model.api.Type
42 import org.opendaylight.yangtools.sal.binding.model.api.type.builder.GeneratedTypeBuilder
43 import org.opendaylight.yangtools.util.ClassLoaderUtils
44 import org.opendaylight.yangtools.yang.binding.Augmentation
45 import org.opendaylight.yangtools.yang.binding.BindingCodec
46 import org.opendaylight.yangtools.yang.binding.BindingDeserializer
47 import org.opendaylight.yangtools.yang.binding.BindingMapping
48 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier
49 import org.opendaylight.yangtools.yang.common.QName
50 import org.opendaylight.yangtools.yang.model.api.AugmentationSchema
51 import org.opendaylight.yangtools.yang.model.api.ChoiceCaseNode
52 import org.opendaylight.yangtools.yang.model.api.ChoiceNode
53 import org.opendaylight.yangtools.yang.model.api.ContainerSchemaNode
54 import org.opendaylight.yangtools.yang.model.api.DataNodeContainer
55 import org.opendaylight.yangtools.yang.model.api.DataSchemaNode
56 import org.opendaylight.yangtools.yang.model.api.LeafListSchemaNode
57 import org.opendaylight.yangtools.yang.model.api.LeafSchemaNode
58 import org.opendaylight.yangtools.yang.model.api.ListSchemaNode
59 import org.opendaylight.yangtools.yang.model.api.NotificationDefinition
60 import org.opendaylight.yangtools.yang.model.api.SchemaNode
61 import org.opendaylight.yangtools.yang.model.api.TypeDefinition
62 import org.opendaylight.yangtools.yang.model.api.type.BitsTypeDefinition
63 import org.opendaylight.yangtools.yang.model.api.type.BitsTypeDefinition.Bit
64 import org.opendaylight.yangtools.yang.model.api.type.EmptyTypeDefinition
65 import org.opendaylight.yangtools.yang.model.api.type.UnionTypeDefinition
66 import org.opendaylight.yangtools.yang.model.util.EnumerationType
67 import org.opendaylight.yangtools.yang.model.util.ExtendedType
68 import org.slf4j.LoggerFactory
70 import static com.google.common.base.Preconditions.*
71 import static javassist.Modifier.*
72 import static org.opendaylight.yangtools.sal.binding.generator.impl.CodecMapping.*
74 import static extension org.opendaylight.yangtools.sal.binding.generator.util.YangSchemaUtils.*
76 class TransformerGenerator extends AbstractTransformerGenerator {
77 private static val LOG = LoggerFactory.getLogger(TransformerGenerator)
79 public static val STRING = Types.typeForClass(String);
80 public static val BOOLEAN = Types.typeForClass(Boolean);
81 public static val INTEGER = Types.typeForClass(Integer);
82 public static val INSTANCE_IDENTIFIER = Types.typeForClass(InstanceIdentifier);
83 //public static val DECIMAL = Types.typeForClass(Decimal);
84 public static val LONG = Types.typeForClass(Long);
85 public static val CLASS_TYPE = Types.typeForClass(Class);
88 var File classFileCapturePath;
90 val CtClass BINDING_CODEC
93 val SourceCodeGeneratorFactory sourceCodeGeneratorFactory = new SourceCodeGeneratorFactory();
95 public new(TypeResolver typeResolver, ClassPool pool) {
96 super(typeResolver, pool)
98 BINDING_CODEC = BindingCodec.asCtClass;
99 ctQName = QName.asCtClass
102 override transformerForImpl(Class inputType) {
103 return runOnClassLoader(inputType.classLoader) [ |
104 val ret = getGeneratedClass(inputType)
106 listener.onClassProcessed(inputType);
107 return ret as Class<? extends BindingCodec<Map<QName,Object>, Object>>;
109 val ref = Types.typeForClass(inputType)
110 val node = getSchemaNode(ref)
111 createMapping(inputType, node, null)
112 val typeSpecBuilder = getDefinition(ref)
113 checkState(typeSpecBuilder !== null, "Could not find typedefinition for %s", inputType.name);
114 val typeSpec = typeSpecBuilder.toInstance();
115 val newret = generateTransformerFor(inputType, typeSpec, node);
116 listener.onClassProcessed(inputType);
117 return newret as Class<? extends BindingCodec<Map<QName,Object>, Object>>;
121 def Class<? extends BindingCodec<Map<QName, Object>, Object>> transformerFor(Class<?> inputType, DataSchemaNode node) {
122 return runOnClassLoader(inputType.classLoader) [ |
123 createMapping(inputType, node, null)
124 val ret = getGeneratedClass(inputType)
126 listener.onClassProcessed(inputType);
127 return ret as Class<? extends BindingCodec<Map<QName,Object>, Object>>;
129 val ref = Types.typeForClass(inputType)
130 var typeSpecBuilder = getDefinition(ref)
131 if (typeSpecBuilder == null) {
132 typeSpecBuilder = getTypeBuilder(node.path);
135 checkState(typeSpecBuilder !== null, "Could not find TypeDefinition for %s, $s", inputType.name, node);
136 val typeSpec = typeSpecBuilder.toInstance();
137 val newret = generateTransformerFor(inputType, typeSpec, node);
138 listener.onClassProcessed(inputType);
139 return newret as Class<? extends BindingCodec<Map<QName,Object>, Object>>;
143 override augmentationTransformerForImpl(Class inputType) {
144 return runOnClassLoader(inputType.classLoader) [ |
146 val ret = getGeneratedClass(inputType)
148 return ret as Class<? extends BindingCodec<Map<QName,Object>, Object>>;
150 val ref = Types.typeForClass(inputType)
151 val node = getAugmentation(ref)
152 val typeSpecBuilder = getDefinition(ref)
153 val typeSpec = typeSpecBuilder.toInstance();
154 //mappingForNodes(node.childNodes, typeSpec.allProperties, bindingId)
155 val newret = generateAugmentationTransformerFor(inputType, typeSpec, node);
156 listener.onClassProcessed(inputType);
157 return newret as Class<? extends BindingCodec<Map<QName,Object>, Object>>;
161 override caseCodecForImpl(Class inputType, ChoiceCaseNode node) {
162 return runOnClassLoader(inputType.classLoader) [ |
163 createMapping(inputType, node, null)
164 val ret = getGeneratedClass(inputType)
166 return ret as Class<? extends BindingCodec<Object, Object>>;
168 val ref = Types.typeForClass(inputType)
169 val typeSpecBuilder = getDefinition(ref)
170 val typeSpec = typeSpecBuilder.toInstance();
171 val newret = generateCaseCodec(inputType, typeSpec, node);
172 return newret as Class<? extends BindingCodec<Object, Object>>;
176 override keyTransformerForIdentifiableImpl(Class parentType) {
177 return runOnClassLoader(parentType.classLoader) [ |
178 val inputName = parentType.name + "Key";
179 val inputType = loadClass(inputName);
180 val ret = getGeneratedClass(inputType)
182 return ret as Class<? extends BindingCodec<Map<QName,Object>, Object>>;
184 val ref = Types.typeForClass(parentType)
185 val node = getSchemaNode(ref) as ListSchemaNode
186 val typeSpecBuilder = getDefinition(ref)
187 val typeSpec = typeSpecBuilder.identifierDefinition;
188 val newret = generateKeyTransformerFor(inputType, typeSpec, node);
189 return newret as Class<? extends BindingCodec<Map<QName,Object>, Object>>;
193 private def void createMapping(Class<?> inputType, SchemaNode node, InstanceIdentifier<?> parentId) {
194 var ClassLoader cl = inputType.classLoader
196 cl = Thread.currentThread.contextClassLoader
198 ClassLoaderUtils.withClassLoader(cl,
200 if (!(node instanceof DataNodeContainer)) {
203 var InstanceIdentifier<?> bindingId = getBindingIdentifierByPath(node.path)
204 if (bindingId != null) {
207 val ref = Types.typeForClass(inputType)
208 var typeSpecBuilder = getDefinition(ref)
209 if (typeSpecBuilder == null) {
210 typeSpecBuilder = getTypeBuilder(node.path);
212 checkState(typeSpecBuilder !== null, "Could not find type definition for %s, $s", inputType.name, node);
213 val typeSpec = typeSpecBuilder.toInstance();
214 var InstanceIdentifier<?> parent
215 if (parentId == null) {
216 bindingId = InstanceIdentifier.create(inputType as Class)
218 putPathToBindingIdentifier(node.path, bindingId)
220 parent = putPathToBindingIdentifier(node.path, parentId, inputType)
222 val Map<String, Type> properties = typeSpec.allProperties
223 if (node instanceof DataNodeContainer) {
224 mappingForNodes((node as DataNodeContainer).childNodes, properties, parent)
225 } else if (node instanceof ChoiceNode) {
226 mappingForNodes((node as ChoiceNode).cases, properties, parent)
232 private def void mappingForNodes(Collection<? extends DataSchemaNode> childNodes, Map<String, Type> properties,
233 InstanceIdentifier<?> parent) {
234 for (DataSchemaNode child : childNodes) {
235 val signature = properties.getFor(child)
236 if (signature != null) {
237 val Type childType = signature.value
238 var Class<?> childTypeClass = null;
239 if (child instanceof ListSchemaNode && childType instanceof ParameterizedType) {
240 childTypeClass = loadClass((childType as ParameterizedType).actualTypeArguments.get(0))
242 childTypeClass = loadClass(childType)
244 createMapping(childTypeClass, child, parent)
249 def getIdentifierDefinition(GeneratedTypeBuilder builder) {
250 val inst = builder.toInstance
251 val keyMethod = inst.methodDefinitions.findFirst[name == "getKey"]
252 return keyMethod.returnType as GeneratedTransferObject
255 override keyTransformerForIdentifierImpl(Class inputType) {
256 return runOnClassLoader(inputType.classLoader) [ |
257 val ret = getGeneratedClass(inputType)
259 return ret as Class<? extends BindingCodec<Map<QName,Object>, Object>>;
261 val ref = Types.typeForClass(inputType)
262 val node = getSchemaNode(ref) as ListSchemaNode
263 val typeSpecBuilder = getDefinition(ref)
264 val typeSpec = typeSpecBuilder.toInstance();
265 val newret = generateKeyTransformerFor(inputType, typeSpec, node);
266 return newret as Class<? extends BindingCodec<Map<QName,Object>, Object>>;
270 private def Class<?> keyTransformerFor(Class<?> inputType, GeneratedType type, ListSchemaNode schema) {
271 return runOnClassLoader(inputType.classLoader) [ |
272 val transformer = getGeneratedClass(inputType)
273 if (transformer != null) {
276 val newret = generateKeyTransformerFor(inputType, type, schema);
277 return newret as Class<? extends BindingCodec<Map<QName,Object>, Object>>;
281 private def Class<?> getGeneratedClass(Class<? extends Object> cls) {
284 return loadClass(cls.codecClassName)
285 } catch (ClassNotFoundException e) {
290 private def Class<?> keyTransformer(GeneratedType type, ListSchemaNode node) {
291 val cls = loadClass(type.resolvedName + "Key");
292 keyTransformerFor(cls, type, node);
295 private def serializer(Type type, DataSchemaNode node) {
296 val cls = loadClass(type.resolvedName);
297 transformerFor(cls, node);
300 private def Class<?> valueSerializer(GeneratedTransferObject type, TypeDefinition<?> typeDefinition) {
301 val cls = loadClass(type.resolvedName);
302 val transformer = cls.generatedClass;
303 if (transformer !== null) {
306 var baseType = typeDefinition;
307 while (baseType.baseType != null) {
308 baseType = baseType.baseType;
310 val finalType = baseType;
311 return runOnClassLoader(cls.classLoader) [ |
312 val valueTransformer = generateValueTransformer(cls, type, finalType);
313 return valueTransformer;
317 private def Class<?> valueSerializer(Enumeration type, TypeDefinition<?> typeDefinition) {
318 val cls = loadClass(type.resolvedName);
319 val transformer = cls.generatedClass;
320 if (transformer !== null) {
324 return runOnClassLoader(cls.classLoader) [ |
325 val valueTransformer = generateValueTransformer(cls, type, typeDefinition);
326 return valueTransformer;
330 private def generateKeyTransformerFor(Class<? extends Object> inputType, GeneratedType typeSpec, ListSchemaNode node) {
333 val SourceCodeGenerator sourceGenerator = sourceCodeGeneratorFactory.getInstance( null );
335 //log.info("Generating DOM Codec for {} with {}", inputType, inputType.classLoader)
336 val properties = typeSpec.allProperties;
337 val ctCls = createClass(inputType.codecClassName) [
338 //staticField(Map,"AUGMENTATION_SERIALIZERS");
339 staticField(it, INSTANCE_IDENTIFIER_CODEC, BindingCodec, sourceGenerator)
340 staticField(it, IDENTITYREF_CODEC, BindingCodec, sourceGenerator)
341 staticQNameField(node.QName, sourceGenerator);
342 implementsType(BINDING_CODEC)
343 method(Object, "toDomStatic", #[QName, Object]) [
344 modifiers = PUBLIC + FINAL + STATIC
347 «QName.name» _resultName;
349 _resultName = «QName.name».create($1,QNAME.getLocalName());
353 java.util.List _childNodes = new java.util.ArrayList();
354 «inputType.resolvedName» value = («inputType.name») $2;
355 «FOR key : node.keyDefinition»
356 «val propertyName = key.getterName»
357 «val keyDef = node.getDataChildByName(key)»
358 «val property = properties.get(propertyName)»
359 «serializeProperty(keyDef, property, propertyName)»;
361 return ($r) java.util.Collections.singletonMap(_resultName,_childNodes);
364 setBodyChecked(body, sourceGenerator)
366 method(Object, "fromDomStatic", #[QName, Object]) [
367 modifiers = PUBLIC + FINAL + STATIC
373 «QName.name» _localQName = $1;
374 java.util.Map _compositeNode = (java.util.Map) $2;
375 boolean _is_empty = true;
376 «FOR key : node.keyDefinition»
377 «val propertyName = key.getterName»
378 «val keyDef = node.getDataChildByName(key)»
379 «val property = properties.get(propertyName)»
380 «deserializeProperty(keyDef, property, propertyName)»;
382 «inputType.resolvedName» _value = new «inputType.name»(«node.keyDefinition.
383 keyConstructorList»);
387 setBodyChecked(body, sourceGenerator)
389 method(Object, "serialize", Object) [
392 java.util.Map.Entry _input = (java.util.Map.Entry) $1;
393 «QName.name» _localQName = («QName.name») _input.getKey();
394 «inputType.name» _keyValue = («inputType.name») _input.getValue();
395 return toDomStatic(_localQName,_keyValue);
398 setBodyChecked(body, sourceGenerator)
400 method(Object, "deserialize", Object) [
403 «QName.name» _qname = QNAME;
404 if($1 instanceof java.util.Map.Entry) {
405 _qname = («QName.name») ((java.util.Map.Entry) $1).getKey();
407 return fromDomStatic(_qname,$1);
410 setBodyChecked(body, sourceGenerator)
413 val ret = ctCls.toClassImpl(inputType.classLoader, inputType.protectionDomain)
414 sourceGenerator.outputGeneratedSource( ctCls )
415 LOG.debug("DOM Codec for {} was generated {}", inputType, ret)
416 return ret as Class<? extends BindingCodec<Map<QName,Object>, ?>>;
417 } catch (Exception e) {
418 processException(inputType, e);
423 private def Class<? extends BindingCodec<Object, Object>> generateCaseCodec(Class<?> inputType, GeneratedType type,
424 ChoiceCaseNode node) {
426 val SourceCodeGenerator sourceGenerator = sourceCodeGeneratorFactory.getInstance( null );
428 //log.info("Generating DOM Codec for {} with {}, TCCL is: {}", inputType, inputType.classLoader,Thread.currentThread.contextClassLoader)
429 val ctCls = createClass(type.codecClassName) [
430 //staticField(Map,"AUGMENTATION_SERIALIZERS");
431 implementsType(BINDING_CODEC)
432 staticQNameField(node.QName, sourceGenerator);
433 staticField(it, INSTANCE_IDENTIFIER_CODEC, BindingCodec, sourceGenerator)
434 staticField(it, AUGMENTATION_CODEC, BindingCodec, sourceGenerator)
435 staticField(it, IDENTITYREF_CODEC, BindingCodec, sourceGenerator)
436 method(Object, "toDomStatic", #[QName, Object]) [
437 modifiers = PUBLIC + FINAL + STATIC
440 «QName.name» _resultName = «QName.name».create($1,QNAME.getLocalName());
441 java.util.List _childNodes = new java.util.ArrayList();
442 «type.resolvedName» value = («type.resolvedName») $2;
443 «transformDataContainerBody(type, type.allProperties, node)»
444 return ($r) _childNodes;
447 setBodyChecked( body, sourceGenerator)
449 method(Object, "serialize", Object) [
452 java.util.Map.Entry _input = (java.util.Map.Entry) $1;
453 «QName.name» _localName = QNAME;
454 if(_input.getKey() != null) {
455 _localName = («QName.name») _input.getKey();
457 return toDomStatic(_localName,_input.getValue());
460 setBodyChecked( body, sourceGenerator)
462 method(Object, "fromDomStatic", #[QName, Object, InstanceIdentifier]) [
463 modifiers = PUBLIC + FINAL + STATIC
464 setBodyChecked( deserializeBody(type, node, getBindingIdentifierByPath(node.path)),
467 method(Object, "deserialize", #[Object, InstanceIdentifier]) [
470 //System.out.println("«type.name»#deserialize: " +$1);
471 java.util.Map.Entry _input = (java.util.Map.Entry) $1;
472 return fromDomStatic((«QName.name»)_input.getKey(),_input.getValue(),$2);
475 setBodyChecked( body, sourceGenerator)
479 val ret = ctCls.toClassImpl(inputType.classLoader, inputType.protectionDomain) as Class<? extends BindingCodec<Object, Object>>
480 sourceGenerator.outputGeneratedSource( ctCls )
481 listener?.onDataContainerCodecCreated(inputType, ret);
482 LOG.debug("DOM Codec for {} was generated {}", inputType, ret)
484 } catch (Exception e) {
485 processException(inputType, e);
490 private def dispatch Class<? extends BindingCodec<Map<QName, Object>, Object>> generateTransformerFor(
491 Class<?> inputType, GeneratedType typeSpec, SchemaNode node) {
494 val SourceCodeGenerator sourceGenerator = sourceCodeGeneratorFactory.getInstance( null );
496 //log.info("Generating DOM Codec for {} with {}", inputType, inputType.classLoader)
497 val ctCls = createClass(typeSpec.codecClassName) [
499 //staticField(Map,"AUGMENTATION_SERIALIZERS");
500 staticQNameField(node.QName, sourceGenerator);
501 staticField(it, INSTANCE_IDENTIFIER_CODEC, BindingCodec, sourceGenerator)
502 staticField(it, IDENTITYREF_CODEC, BindingCodec, sourceGenerator)
503 staticField(it, AUGMENTATION_CODEC, BindingCodec, sourceGenerator)
504 implementsType(BINDING_CODEC)
506 method(Object, "toDomStatic", #[QName, Object]) [
507 modifiers = PUBLIC + FINAL + STATIC
508 setBodyChecked( serializeBodyFacade(typeSpec, node), sourceGenerator )
510 method(Object, "serialize", Object) [
513 java.util.Map.Entry _input = (java.util.Map.Entry) $1;
514 «QName.name» _localName = QNAME;
515 if(_input.getKey() != null) {
516 _localName = («QName.name») _input.getKey();
518 return toDomStatic(_localName,_input.getValue());
521 setBodyChecked( body, sourceGenerator )
524 method(Object, "fromDomStatic", #[QName, Object, InstanceIdentifier]) [
525 modifiers = PUBLIC + FINAL + STATIC
526 setBodyChecked( deserializeBody(typeSpec, node, getBindingIdentifierByPath(node.path)),
530 method(Object, "deserialize", #[Object, InstanceIdentifier]) [
533 «QName.name» _qname = QNAME;
534 if($1 instanceof java.util.Map.Entry) {
535 _qname = («QName.name») ((java.util.Map.Entry) $1).getKey();
537 return fromDomStatic(_qname,$1,$2);
540 setBodyChecked( body, sourceGenerator )
544 val ret = ctCls.toClassImpl(inputType.classLoader, inputType.protectionDomain) as Class<? extends BindingCodec<Map<QName,Object>, Object>>
546 sourceGenerator.outputGeneratedSource( ctCls )
548 listener?.onDataContainerCodecCreated(inputType, ret);
549 LOG.debug("DOM Codec for {} was generated {}", inputType, ret)
551 } catch (Exception e) {
552 processException(inputType, e);
557 private def Class<? extends BindingCodec<Map<QName, Object>, Object>> generateAugmentationTransformerFor(
558 Class<?> inputType, GeneratedType type, AugmentationSchema node) {
561 val SourceCodeGenerator sourceGenerator = sourceCodeGeneratorFactory.getInstance( null );
563 //log.info("Generating DOM Codec for {} with {}", inputType, inputType.classLoader)
564 val properties = type.allProperties
565 val ctCls = createClass(type.codecClassName) [
566 //staticField(Map,"AUGMENTATION_SERIALIZERS");
567 staticQNameField(node.augmentationQName, sourceGenerator);
568 staticField(it, INSTANCE_IDENTIFIER_CODEC, BindingCodec, sourceGenerator)
569 staticField(it, AUGMENTATION_CODEC, BindingCodec, sourceGenerator)
570 staticField(it, IDENTITYREF_CODEC, BindingCodec, sourceGenerator)
571 implementsType(BINDING_CODEC)
573 method(Object, "toDomStatic", #[QName, Object]) [
574 modifiers = PUBLIC + FINAL + STATIC
577 ////System.out.println("Qname " + $1);
578 ////System.out.println("Value " + $2);
579 «QName.name» _resultName = «QName.name».create(QNAME,QNAME.getLocalName());
580 java.util.List _childNodes = new java.util.ArrayList();
581 «type.resolvedName» value = («type.resolvedName») $2;
582 «FOR child : node.childNodes»
583 «var signature = properties.getFor(child)»
584 ////System.out.println("«signature.key»" + value.«signature.key»());
585 «serializeProperty(child, signature.value, signature.key)»
587 return ($r) _childNodes;
590 setBodyChecked( body, sourceGenerator )
592 method(Object, "serialize", Object) [
595 java.util.Map.Entry _input = (java.util.Map.Entry) $1;
596 «QName.name» _localName = QNAME;
597 if(_input.getKey() != null) {
598 _localName = («QName.name») _input.getKey();
600 return toDomStatic(_localName,_input.getValue());
603 setBodyChecked( body, sourceGenerator )
606 method(Object, "fromDomStatic", #[QName, Object, InstanceIdentifier]) [
607 modifiers = PUBLIC + FINAL + STATIC
610 «QName.name» _localQName = QNAME;
615 java.util.Map _compositeNode = (java.util.Map) $2;
616 //System.out.println(_localQName + " " + _compositeNode);
617 «type.builderName» _builder = new «type.builderName»();
618 boolean _is_empty = true;
619 «FOR child : node.childNodes»
620 «val signature = properties.getFor(child)»
621 «deserializeProperty(child, signature.value, signature.key)»
622 _builder.«signature.key.toSetter»(«signature.key»);
627 return _builder.build();
630 setBodyChecked( body, sourceGenerator )
633 method(Object, "deserialize", #[Object, InstanceIdentifier]) [
636 return fromDomStatic(QNAME,$1,$2);
639 setBodyChecked( body, sourceGenerator )
643 val ret = ctCls.toClassImpl(inputType.classLoader, inputType.protectionDomain) as Class<? extends BindingCodec<Map<QName,Object>, Object>>
644 sourceGenerator.outputGeneratedSource( ctCls )
645 listener?.onDataContainerCodecCreated(inputType, ret);
647 } catch (Exception e) {
648 processException(inputType, e);
653 private def dispatch Class<? extends BindingCodec<Map<QName, Object>, Object>> generateTransformerFor(
654 Class<?> inputType, GeneratedType typeSpec, ChoiceNode node) {
657 val SourceCodeGenerator sourceGenerator = sourceCodeGeneratorFactory.getInstance( null );
659 //log.info("Generating DOM Codec for {} with {}", inputType, inputType.classLoader)
660 val ctCls = createClass(typeSpec.codecClassName) [
661 //staticField(Map,"AUGMENTATION_SERIALIZERS");
662 //staticQNameField(inputType);
663 staticField(it, INSTANCE_IDENTIFIER_CODEC, BindingCodec, sourceGenerator)
664 staticField(it, IDENTITYREF_CODEC, BindingCodec, sourceGenerator)
665 staticField(it, DISPATCH_CODEC, BindingCodec, sourceGenerator)
666 //staticField(it,QNAME_TO_CASE_MAP,BindingCodec)
667 implementsType(BINDING_CODEC)
668 method(List, "toDomStatic", #[QName, Object]) [
669 modifiers = PUBLIC + FINAL + STATIC
675 if («DISPATCH_CODEC» == null) {
676 throw new «IllegalStateException.name»("Implementation of codec was not initialized.");
678 java.util.Map.Entry _input = new «SimpleEntry.name»($1,$2);
679 Object _ret = «DISPATCH_CODEC».serialize(_input);
680 ////System.out.println("«typeSpec.name»#toDomStatic: " + _ret);
681 return («List.name») _ret;
684 setBodyChecked( body, sourceGenerator )
686 method(Object, "serialize", Object) [
689 throw new «UnsupportedOperationException.name»("Direct invocation not supported.");
692 setBodyChecked( body, sourceGenerator )
694 method(Object, "fromDomStatic", #[QName, Map, InstanceIdentifier]) [
695 modifiers = PUBLIC + FINAL + STATIC
698 if («DISPATCH_CODEC» == null) {
699 throw new «IllegalStateException.name»("Implementation of codec was not initialized.");
701 return «DISPATCH_CODEC».deserialize($2,$3);
704 setBodyChecked( body, sourceGenerator )
706 method(Object, "deserialize", #[Object, InstanceIdentifier]) [
709 throw new «UnsupportedOperationException.name»("Direct invocation not supported.");
712 setBodyChecked( body, sourceGenerator )
716 val rawRet = ctCls.toClassImpl(inputType.classLoader, inputType.protectionDomain)
717 sourceGenerator.outputGeneratedSource( ctCls )
718 val ret = rawRet as Class<? extends BindingCodec<Map<QName,Object>, Object>>;
719 listener?.onChoiceCodecCreated(inputType, ret, node);
720 LOG.debug("DOM Codec for {} was generated {}", inputType, ret)
722 } catch (Exception e) {
723 processException(inputType, e);
728 private def keyConstructorList(List<QName> qnames) {
729 val names = new TreeSet<String>()
730 for (name : qnames) {
731 val fieldName = name.getterName;
732 names.add(fieldName);
734 return Joiner.on(",").join(names);
737 private def serializeBodyFacade(GeneratedType type, SchemaNode node) {
738 val ret = serializeBody(type, node);
742 private def String deserializeBody(GeneratedType type, SchemaNode node, InstanceIdentifier<?> bindingId) {
743 val ret = deserializeBodyImpl(type, node, bindingId);
747 private def deserializeKey(GeneratedType type, ListSchemaNode node) {
748 if (node.keyDefinition != null && !node.keyDefinition.empty) {
750 «type.resolvedName»Key getKey = («type.resolvedName»Key) «keyTransformer(type, node).canonicalName».fromDomStatic(_localQName,_compositeNode);
751 _builder.setKey(getKey);
756 private def String deserializeBodyWithAugmentations(GeneratedType type, DataNodeContainer node, InstanceIdentifier<?> bindingId) '''
758 «QName.name» _localQName = «QName.name».create($1,QNAME.getLocalName());
762 java.util.Map _compositeNode = (java.util.Map) $2;
763 //System.out.println(_localQName + " " + _compositeNode);
764 «type.builderName» _builder = new «type.builderName»();
765 «deserializeDataNodeContainerBody(type, node, bindingId)»
766 «type.deserializeAugmentations»
767 return _builder.build();
771 private def dispatch String deserializeBodyImpl(GeneratedType type, SchemaNode node, InstanceIdentifier<?> bindingId) '''
773 «QName.name» _localQName = «QName.name».create($1,QNAME.getLocalName());
778 java.util.Map _compositeNode = (java.util.Map) $2;
779 «type.builderName» _builder = new «type.builderName»();
780 return _builder.build();
784 private def dispatch String deserializeBodyImpl(GeneratedType type, ListSchemaNode node, InstanceIdentifier<?> bindingId) '''
786 «QName.name» _localQName = «QName.name».create($1,QNAME.getLocalName());
790 java.util.Map _compositeNode = (java.util.Map) $2;
791 //System.out.println(_localQName + " " + _compositeNode);
792 «type.builderName» _builder = new «type.builderName»();
793 «deserializeKey(type, node)»
794 «deserializeDataNodeContainerBody(type, node, bindingId)»
795 «type.deserializeAugmentations»
796 return _builder.build();
800 private def dispatch String deserializeBodyImpl(GeneratedType type, ContainerSchemaNode node, InstanceIdentifier<?> bindingId) {
801 return deserializeBodyWithAugmentations(type, node, bindingId);
804 private def dispatch String deserializeBodyImpl(GeneratedType type, NotificationDefinition node, InstanceIdentifier<?> bindingId) {
805 return deserializeBodyWithAugmentations(type, node, bindingId);
808 private def dispatch String deserializeBodyImpl(GeneratedType type, ChoiceCaseNode node, InstanceIdentifier<?> bindingId) {
809 return deserializeBodyWithAugmentations(type, node, bindingId);
812 private def deserializeDataNodeContainerBody(GeneratedType type, DataNodeContainer node, InstanceIdentifier<?> bindingId) {
813 deserializeNodeContainerBodyImpl(type, type.allProperties, node, bindingId);
816 private def deserializeNodeContainerBodyImpl(GeneratedType type, HashMap<String, Type> properties,
817 DataNodeContainer node, InstanceIdentifier<?> bindingId) {
819 boolean _is_empty = true;
820 «FOR child : node.childNodes»
821 «val signature = properties.getFor(child)»
822 «IF signature !== null»
823 «deserializeProperty(child, signature.value, signature.key)»
824 _builder.«signature.key.toSetter»(«signature.key»);
831 def deserializeAugmentations(GeneratedType type) '''
832 «InstanceIdentifier.resolvedName» iid = $3.builder().child(«type.resolvedName».class).build();
833 java.util.Map _augmentation = (java.util.Map) «AUGMENTATION_CODEC».deserialize(_compositeNode,$3);
834 if(_augmentation != null) {
835 «Iterator.name» _entries = _augmentation.entrySet().iterator();
836 while(_entries.hasNext()) {
837 java.util.Map.Entry _entry = (java.util.Map.Entry) _entries.next();
838 ////System.out.println("Aug. key:" + _entry.getKey());
839 Class _type = (Class) _entry.getKey();
840 «Augmentation.resolvedName» _value = («Augmentation.name») _entry.getValue();
842 _builder.addAugmentation(_type,_value);
848 private def dispatch CharSequence deserializeProperty(ListSchemaNode schema, ParameterizedType type,
849 String propertyName) '''
850 java.util.List _dom_«propertyName» = _compositeNode.get(«QName.name».create(_localQName,"«schema.QName.
852 ////System.out.println("«propertyName»#deCode"+_dom_«propertyName»);
853 java.util.List «propertyName» = new java.util.ArrayList();
854 if(_dom_«propertyName» != null) {
855 java.util.List _serialized = new java.util.ArrayList();
856 java.util.Iterator _iterator = _dom_«propertyName».iterator();
857 boolean _hasNext = _iterator.hasNext();
859 Object _listItem = _iterator.next();
861 ////System.out.println(" item" + _listItem);
862 «val param = type.actualTypeArguments.get(0)»
863 «InstanceIdentifier.resolvedName» iid = $3.builder().child(«param.resolvedName».class).build();
864 Object _value = «type.actualTypeArguments.get(0).serializer(schema).resolvedName».fromDomStatic(_localQName,_listItem,iid);
865 ////System.out.println(" value" + _value);
866 «propertyName».add(_value);
867 _hasNext = _iterator.hasNext();
871 ////System.out.println(" list" + «propertyName»);
874 private def dispatch CharSequence deserializeProperty(LeafListSchemaNode schema, ParameterizedType type,
875 String propertyName) '''
876 java.util.List _dom_«propertyName» = _compositeNode.get(«QName.name».create(_localQName,"«schema.QName.
878 java.util.List «propertyName» = new java.util.ArrayList();
879 if(_dom_«propertyName» != null) {
880 java.util.List _serialized = new java.util.ArrayList();
881 java.util.Iterator _iterator = _dom_«propertyName».iterator();
882 boolean _hasNext = _iterator.hasNext();
885 Object _listItem = _iterator.next();
886 if(_listItem instanceof java.util.Map.Entry) {
887 Object _innerValue = ((java.util.Map.Entry) _listItem).getValue();
888 Object _value = «deserializeValue(type.actualTypeArguments.get(0), "_innerValue", schema.type)»;
889 «propertyName».add(_value);
891 _hasNext = _iterator.hasNext();
896 private def dispatch CharSequence deserializeProperty(LeafSchemaNode schema, Type type, String propertyName) '''
897 java.util.List _dom_«propertyName»_list =
898 _compositeNode.get(«QName.name».create(_localQName,"«schema.QName.localName»"));
899 «type.resolvedName» «propertyName» = null;
900 if(_dom_«propertyName»_list != null && _dom_«propertyName»_list.size() > 0) {
902 java.util.Map.Entry _dom_«propertyName» = (java.util.Map.Entry) _dom_«propertyName»_list.get(0);
903 Object _inner_value = _dom_«propertyName».getValue();
904 «propertyName» = «deserializeValue(type, "_inner_value", schema.type)»;
908 private def dispatch CharSequence deserializeProperty(ContainerSchemaNode schema, Type type,
909 String propertyName) '''
910 java.util.List _dom_«propertyName»_list =
911 _compositeNode.get(«QName.name».create(_localQName,"«schema.QName.localName»"));
912 «type.resolvedName» «propertyName» = null;
913 if(_dom_«propertyName»_list != null && _dom_«propertyName»_list.size() > 0) {
915 java.util.Map _dom_«propertyName» = (java.util.Map) _dom_«propertyName»_list.get(0);
916 «InstanceIdentifier.resolvedName» iid = $3.builder().child(«type.resolvedName».class).build();
917 «propertyName» = «type.serializer(schema).resolvedName».fromDomStatic(_localQName,_dom_«propertyName»,iid);
921 private def dispatch CharSequence deserializeProperty(ChoiceNode schema, Type type, String propertyName) '''
922 «type.resolvedName» «propertyName» = «type.serializer(schema).resolvedName».fromDomStatic(_localQName,_compositeNode,$3);
923 if(«propertyName» != null) {
928 private def dispatch String deserializeValue(GeneratedTransferObject type, String domParameter,
929 TypeDefinition<?> typeDefinition) '''
930 («type.resolvedName») «type.valueSerializer(typeDefinition).resolvedName».fromDomValue(«domParameter»)
933 private def dispatch String deserializeValue(Enumeration type, String domParameter, TypeDefinition<?> typeDefinition) '''
934 («type.resolvedName») «type.valueSerializer(typeDefinition).resolvedName».fromDomValue(«domParameter»)
937 private def dispatch String deserializeValue(Type type, String domParameter, TypeDefinition<?> typeDef) {
938 if (INSTANCE_IDENTIFIER.equals(type)) {
939 return '''(«InstanceIdentifier.name») «INSTANCE_IDENTIFIER_CODEC».deserialize(«domParameter»)'''
940 } else if (CLASS_TYPE.equals(type)) {
941 return '''(«Class.name») «IDENTITYREF_CODEC».deserialize(«domParameter»)'''
942 } else if (typeDef!=null && typeDef instanceof EmptyTypeDefinition) {
943 if(domParameter == null) {
944 return ''' Boolean.FALSE '''
946 return ''' Boolean.TRUE '''
949 return '''(«type.resolvedName») «domParameter»'''
952 private def dispatch Class<? extends BindingCodec<Map<QName, Object>, Object>> generateValueTransformer(
953 Class<?> inputType, GeneratedTransferObject typeSpec, TypeDefinition<?> typeDef) {
956 val SourceCodeGenerator sourceGenerator = sourceCodeGeneratorFactory.getInstance( null );
958 val returnType = typeSpec.valueReturnType;
959 if (returnType == null) {
960 val ctCls = createDummyImplementation(inputType, typeSpec, sourceGenerator);
961 val ret = ctCls.toClassImpl(inputType.classLoader, inputType.protectionDomain)
962 sourceGenerator.outputGeneratedSource( ctCls )
963 return ret as Class<? extends BindingCodec<Map<QName,Object>, Object>>;
966 val ctCls = createClass(typeSpec.codecClassName) [
967 //staticField(Map,"AUGMENTATION_SERIALIZERS");
968 if (inputType.isYangBindingAvailable) {
969 implementsType(BINDING_CODEC)
970 staticField(it, INSTANCE_IDENTIFIER_CODEC, BindingCodec, sourceGenerator)
971 staticField(it, IDENTITYREF_CODEC, BindingCodec, sourceGenerator)
972 implementsType(BindingDeserializer.asCtClass)
974 method(Object, "toDomValue", Object) [
975 modifiers = PUBLIC + FINAL + STATIC
976 val ctSpec = typeSpec.asCtClass;
979 ////System.out.println("«inputType.simpleName»#toDomValue: "+$1);
984 «typeSpec.resolvedName» _encapsulatedValue = («typeSpec.resolvedName») $1;
985 ////System.out.println("«inputType.simpleName»#toDomValue:Enc: "+_encapsulatedValue);
986 «returnType.resolvedName» _value = _encapsulatedValue.getValue();
987 ////System.out.println("«inputType.simpleName»#toDomValue:DeEnc: "+_value);
988 Object _domValue = «serializeValue(returnType, "_value", null)»;
992 setBodyChecked( body, sourceGenerator )
994 method(Object, "serialize", Object) [
997 return toDomValue($1);
1000 setBodyChecked( body, sourceGenerator )
1002 method(Object, "fromDomValue", Object) [
1003 modifiers = PUBLIC + FINAL + STATIC
1006 ////System.out.println("«inputType.simpleName»#fromDomValue: "+$1);
1011 «returnType.resolvedName» _simpleValue = «deserializeValue(returnType, "$1", null)»;
1012 «typeSpec.resolvedName» _value = new «typeSpec.resolvedName»(_simpleValue);
1016 setBodyChecked( body, sourceGenerator )
1018 method(Object, "deserialize", Object) [
1021 return fromDomValue($1);
1024 setBodyChecked( body, sourceGenerator )
1028 val ret = ctCls.toClassImpl(inputType.classLoader, inputType.protectionDomain)
1029 sourceGenerator.outputGeneratedSource( ctCls )
1030 LOG.debug("DOM Codec for {} was generated {}", inputType, ret)
1031 return ret as Class<? extends BindingCodec<Map<QName,Object>, Object>>;
1032 } catch (Exception e) {
1033 LOG.error("Cannot compile DOM Codec for {}", inputType, e);
1034 val exception = new CodeGenerationException("Cannot compile Transformator for " + inputType);
1035 exception.addSuppressed(e);
1040 private def dispatch Class<? extends BindingCodec<Map<QName, Object>, Object>> generateValueTransformer(
1041 Class<?> inputType, GeneratedTransferObject typeSpec, UnionTypeDefinition typeDef) {
1043 val SourceCodeGenerator sourceGenerator = sourceCodeGeneratorFactory.getInstance( null );
1045 val ctCls = createClass(typeSpec.codecClassName) [
1046 val properties = typeSpec.allProperties;
1047 val getterToTypeDefinition = XtendHelper.getTypes(typeDef).toMap[type|type.QName.getterName];
1048 //staticField(Map,"AUGMENTATION_SERIALIZERS");
1049 if (inputType.isYangBindingAvailable) {
1050 implementsType(BINDING_CODEC)
1051 staticField(it, INSTANCE_IDENTIFIER_CODEC, BindingCodec, sourceGenerator)
1052 staticField(it, IDENTITYREF_CODEC, BindingCodec, sourceGenerator)
1053 implementsType(BindingDeserializer.asCtClass)
1055 method(Object, "toDomValue", Object) [
1056 modifiers = PUBLIC + FINAL + STATIC
1057 val ctSpec = inputType.asCtClass;
1060 ////System.out.println("«inputType.simpleName»#toDomValue: "+$1);
1065 «typeSpec.resolvedName» _value = («typeSpec.resolvedName») $1;
1066 «FOR property : properties.entrySet»
1067 «IF property.key != "getValue"»
1068 «property.value.resolvedName» «property.key» = («property.value.resolvedName») _value.«property.
1070 if(«property.key» != null) {
1071 return «serializeValue(property.value, property.key,
1072 getterToTypeDefinition.get(property.key))»;
1080 setBodyChecked( body, sourceGenerator )
1082 method(Object, "serialize", Object) [
1085 return toDomValue($1);
1088 setBodyChecked( body, sourceGenerator )
1090 method(Object, "fromDomValue", Object) [
1091 modifiers = PUBLIC + FINAL + STATIC
1094 ////System.out.println("«inputType.simpleName»#fromDomValue: "+$1);
1099 if($1 instanceof String) {
1100 String _simpleValue = (String) $1;
1101 return new «typeSpec.resolvedName»(_simpleValue.toCharArray());
1106 setBodyChecked( body, sourceGenerator )
1108 method(Object, "deserialize", Object) [
1111 return fromDomValue($1);
1114 setBodyChecked( body, sourceGenerator )
1118 val ret = ctCls.toClassImpl(inputType.classLoader, inputType.protectionDomain)
1119 sourceGenerator.outputGeneratedSource( ctCls )
1120 LOG.debug("DOM Codec for {} was generated {}", inputType, ret)
1121 return ret as Class<? extends BindingCodec<Map<QName,Object>, Object>>;
1122 } catch (Exception e) {
1123 LOG.error("Cannot compile DOM Codec for {}", inputType, e);
1124 val exception = new CodeGenerationException("Cannot compile Transformator for " + inputType);
1125 exception.addSuppressed(e);
1130 private def dispatch Class<? extends BindingCodec<Map<QName, Object>, Object>> generateValueTransformer(
1131 Class<?> inputType, GeneratedTransferObject typeSpec, BitsTypeDefinition typeDef) {
1133 val SourceCodeGenerator sourceGenerator = sourceCodeGeneratorFactory.getInstance( null );
1135 val ctCls = createClass(typeSpec.codecClassName) [
1136 //staticField(Map,"AUGMENTATION_SERIALIZERS");
1137 if (inputType.isYangBindingAvailable) {
1138 implementsType(BINDING_CODEC)
1139 staticField(it, INSTANCE_IDENTIFIER_CODEC, BindingCodec, sourceGenerator)
1140 staticField(it, IDENTITYREF_CODEC, BindingCodec, sourceGenerator)
1141 implementsType(BindingDeserializer.asCtClass)
1143 method(Object, "toDomValue", Object) [
1144 modifiers = PUBLIC + FINAL + STATIC
1145 val ctSpec = typeSpec.asCtClass;
1148 ////System.out.println("«inputType.simpleName»#toDomValue: "+$1);
1153 «typeSpec.resolvedName» _encapsulatedValue = («typeSpec.resolvedName») $1;
1154 «HashSet.resolvedName» _value = new «HashSet.resolvedName»();
1155 //System.out.println("«inputType.simpleName»#toDomValue:Enc: "+_encapsulatedValue);
1157 «FOR bit : typeDef.bits»
1158 «val getter = bit.getterName()»
1159 if(Boolean.TRUE.equals(_encapsulatedValue.«getter»())) {
1160 _value.add("«bit.name»");
1163 «Set.resolvedName» _domValue = «Collections.resolvedName».unmodifiableSet(_value);
1164 //System.out.println("«inputType.simpleName»#toDomValue:DeEnc: "+_domValue);
1169 setBodyChecked( body, sourceGenerator )
1171 method(Object, "serialize", Object) [
1174 return toDomValue($1);
1177 setBodyChecked( body, sourceGenerator )
1179 method(Object, "fromDomValue", Object) [
1180 modifiers = PUBLIC + FINAL + STATIC
1181 val sortedBits = typeDef.bits.sort[o1, o2|o1.propertyName.compareTo(o2.propertyName)]
1184 //System.out.println("«inputType.simpleName»#fromDomValue: "+$1);
1189 «Set.resolvedName» _domValue = («Set.resolvedName») $1;
1190 «FOR bit : sortedBits»
1191 Boolean «bit.propertyName» = Boolean.valueOf(_domValue.contains("«bit.name»"));
1194 return new «inputType.resolvedName»(«FOR bit : sortedBits SEPARATOR ","»«bit.propertyName»«ENDFOR»);
1197 setBodyChecked( body, sourceGenerator )
1199 method(Object, "deserialize", Object) [
1202 return fromDomValue($1);
1205 setBodyChecked( body, sourceGenerator )
1209 val ret = ctCls.toClassImpl(inputType.classLoader, inputType.protectionDomain)
1210 sourceGenerator.outputGeneratedSource( ctCls )
1211 LOG.debug("DOM Codec for {} was generated {}", inputType, ret)
1212 return ret as Class<? extends BindingCodec<Map<QName,Object>, Object>>;
1213 } catch (Exception e) {
1214 LOG.error("Cannot compile DOM Codec for {}", inputType, e);
1215 val exception = new CodeGenerationException("Cannot compile Transformator for " + inputType);
1216 exception.addSuppressed(e);
1221 def String getPropertyName(Bit bit) {
1222 '''_«BindingGeneratorUtil.parseToValidParamName(bit.name)»'''
1225 def String getterName(Bit bit) {
1227 val paramName = BindingGeneratorUtil.parseToValidParamName(bit.name);
1228 return '''is«paramName.toFirstUpper»''';
1231 def boolean isYangBindingAvailable(Class<?> class1) {
1233 val bindingCodecClass = class1.classLoader.loadClass(BINDING_CODEC.name);
1234 return bindingCodecClass !== null;
1235 } catch (ClassNotFoundException e) {
1240 private def createDummyImplementation(Class<?> object, GeneratedTransferObject typeSpec,
1241 SourceCodeGenerator sourceGenerator ) {
1242 LOG.trace("Generating Dummy DOM Codec for {} with {}", object, object.classLoader)
1243 return createClass(typeSpec.codecClassName) [
1244 if (object.isYangBindingAvailable) {
1245 implementsType(BINDING_CODEC)
1246 staticField(it, INSTANCE_IDENTIFIER_CODEC, BindingCodec, sourceGenerator)
1247 staticField(it, IDENTITYREF_CODEC, BindingCodec, sourceGenerator)
1248 implementsType(BindingDeserializer.asCtClass)
1250 //implementsType(BindingDeserializer.asCtClass)
1251 method(Object, "toDomValue", Object) [
1252 modifiers = PUBLIC + FINAL + STATIC
1258 return $1.toString();
1260 setBodyChecked( body, sourceGenerator )
1262 method(Object, "serialize", Object) [
1265 return toDomValue($1);
1268 setBodyChecked( body, sourceGenerator )
1270 method(Object, "fromDomValue", Object) [
1271 modifiers = PUBLIC + FINAL + STATIC
1272 val body = '''return null;'''
1273 setBodyChecked( body, sourceGenerator )
1275 method(Object, "deserialize", Object) [
1278 return fromDomValue($1);
1281 setBodyChecked( body, sourceGenerator )
1286 private def Type getValueReturnType(GeneratedTransferObject object) {
1287 for (prop : object.properties) {
1288 if (prop.name == "value") {
1289 return prop.returnType;
1292 if (object.superType != null) {
1293 return getValueReturnType(object.superType);
1298 private def dispatch Class<?> generateValueTransformer(Class<?> inputType, Enumeration typeSpec, TypeDefinition<?> type) {
1299 var EnumerationType enumSchemaType
1300 if (type instanceof EnumerationType) {
1301 enumSchemaType = type as EnumerationType
1303 val typeRef = new ReferencedTypeImpl(typeSpec.packageName, typeSpec.name);
1304 val schema = getSchemaNode(typeRef) as ExtendedType;
1305 enumSchemaType = schema.baseType as EnumerationType;
1307 val enumSchema = enumSchemaType;
1309 val SourceCodeGenerator sourceGenerator = sourceCodeGeneratorFactory.getInstance( null );
1311 //log.info("Generating DOM Codec for {} with {}", inputType, inputType.classLoader)
1312 val ctCls = createClass(typeSpec.codecClassName) [
1313 //staticField(Map,"AUGMENTATION_SERIALIZERS");
1314 //implementsType(BINDING_CODEC)
1315 method(Object, "toDomValue", Object) [
1316 modifiers = PUBLIC + FINAL + STATIC
1322 «typeSpec.resolvedName» _value = («typeSpec.resolvedName») $1;
1323 «FOR en : enumSchema.values»
1324 if(«typeSpec.resolvedName».«BindingMapping.getClassName(en.name)».equals(_value)) {
1331 setBodyChecked( body, sourceGenerator )
1333 method(Object, "serialize", Object) [
1336 return toDomValue($1);
1339 setBodyChecked( body, sourceGenerator )
1341 method(Object, "fromDomValue", Object) [
1342 modifiers = PUBLIC + FINAL + STATIC
1348 String _value = (String) $1;
1349 «FOR en : enumSchema.values»
1350 if("«en.name»".equals(_value)) {
1351 return «typeSpec.resolvedName».«BindingMapping.getClassName(en.name)»;
1357 setBodyChecked( body, sourceGenerator )
1359 method(Object, "deserialize", Object) [
1362 return fromDomValue($1);
1365 setBodyChecked( body, sourceGenerator )
1369 val ret = ctCls.toClassImpl(inputType.classLoader, inputType.protectionDomain)
1370 sourceGenerator.outputGeneratedSource( ctCls )
1371 LOG.debug("DOM Codec for {} was generated {}", inputType, ret)
1373 } catch (CodeGenerationException e) {
1374 throw new CodeGenerationException("Cannot compile Transformator for " + inputType, e);
1375 } catch (Exception e) {
1376 LOG.error("Cannot compile DOM Codec for {}", inputType, e);
1377 val exception = new CodeGenerationException("Cannot compile Transformator for " + inputType);
1378 exception.addSuppressed(e);
1384 def Class<?> toClassImpl(CtClass newClass, ClassLoader loader, ProtectionDomain domain) {
1385 val cls = newClass.toClass(loader, domain);
1386 if (classFileCapturePath !== null) {
1387 newClass.writeFile(classFileCapturePath.absolutePath);
1389 listener?.onCodecCreated(cls);
1393 def debugWriteClass(CtClass class1) {
1394 val path = class1.name.replace(".", "/") + ".class"
1396 val captureFile = new File(classFileCapturePath, path);
1397 captureFile.createNewFile
1405 private def dispatch CharSequence deserializeProperty(DataSchemaNode container, Type type, String propertyName) '''
1406 «type.resolvedName» «propertyName» = null;
1409 private def dispatch CharSequence deserializeProperty(DataSchemaNode container, GeneratedTypeBuilder type,
1410 String propertyName) {
1411 _deserializeProperty(container, type.toInstance, propertyName)
1414 static def toSetter(String it) {
1416 if (startsWith("is")) {
1417 return "set" + substring(2);
1418 } else if (startsWith("get")) {
1419 return "set" + substring(3);
1425 private def dispatch CharSequence deserializeProperty(DataSchemaNode container,GeneratedType type, String propertyName) '''
1426 «type.resolvedName» «propertyName» = value.«propertyName»();
1427 if(«propertyName» != null) {
1428 Object domValue = «type.serializer».toDomStatic(QNAME,«propertyName»);
1429 _childNodes.add(domValue);
1433 private def getBuilderName(GeneratedType type) '''«type.resolvedName»Builder'''
1435 private def staticQNameField(CtClass it, QName node, SourceCodeGenerator sourceGenerator) {
1436 val field = new CtField(ctQName, "QNAME", it);
1437 field.modifiers = PUBLIC + FINAL + STATIC;
1438 val code = '''«QName.asCtClass.name».create("«node.namespace»","«node.formattedRevision»","«node.localName»")'''
1439 addField(field, code )
1441 sourceGenerator.appendField( field, code );
1444 private def String serializeBodyImpl(GeneratedType type, DataNodeContainer nodeContainer) '''
1446 «QName.name» _resultName = «QName.name».create($1,QNAME.getLocalName());
1447 java.util.List _childNodes = new java.util.ArrayList();
1448 «type.resolvedName» value = («type.resolvedName») $2;
1449 «transformDataContainerBody(type, type.allProperties, nodeContainer)»
1450 «serializeAugmentations»
1451 return ($r) java.util.Collections.singletonMap(_resultName,_childNodes);
1455 private def dispatch String serializeBody(GeneratedType type, ListSchemaNode node) {
1456 return serializeBodyImpl(type, node);
1459 private def dispatch String serializeBody(GeneratedType type, NotificationDefinition node) {
1460 return serializeBodyImpl(type, node);
1463 private def dispatch String serializeBody(GeneratedType type, ContainerSchemaNode node) {
1464 return serializeBodyImpl(type, node);
1467 private def dispatch String serializeBody(GeneratedType type, ChoiceCaseNode node) {
1468 return serializeBodyImpl(type, node);
1471 private def dispatch String serializeBody(GeneratedType type, SchemaNode node) '''
1473 «QName.name» _resultName = «QName.name».create($1,QNAME.getLocalName());
1474 java.util.List _childNodes = new java.util.ArrayList();
1475 «type.resolvedName» value = («type.resolvedName») $2;
1476 return ($r) java.util.Collections.singletonMap(_resultName,_childNodes);
1480 private def transformDataContainerBody(Type type, Map<String, Type> properties, DataNodeContainer node) {
1482 «FOR child : node.childNodes»
1483 «val signature = properties.getFor(child)»
1484 «IF signature !== null»
1485 ////System.out.println("«type.name»#«signature.key»" + value.«signature.key»());
1486 «serializeProperty(child, signature.value, signature.key)»
1493 private static def serializeAugmentations() '''
1494 java.util.List _augmentations = (java.util.List) «AUGMENTATION_CODEC».serialize(value);
1495 if(_augmentations != null) {
1496 _childNodes.addAll(_augmentations);
1500 private static def Entry<String, Type> getFor(Map<String, Type> map, DataSchemaNode node) {
1501 var sig = map.get(node.getterName);
1503 return new SimpleEntry(node.getterName, sig);
1505 sig = map.get(node.booleanGetterName);
1507 return new SimpleEntry(node.booleanGetterName, map.get(node.booleanGetterName));
1512 private static def String getBooleanGetterName(DataSchemaNode node) {
1513 return "is" + BindingMapping.getPropertyName(node.QName.localName).toFirstUpper;
1516 private static def String getGetterName(DataSchemaNode node) {
1517 return "get" + BindingMapping.getPropertyName(node.QName.localName).toFirstUpper;
1520 private static def String getGetterName(QName node) {
1521 return "get" + BindingMapping.getPropertyName(node.localName).toFirstUpper;
1524 private def dispatch CharSequence serializeProperty(ListSchemaNode schema, ParameterizedType type,
1525 String propertyName) '''
1526 «type.resolvedName» «propertyName» = value.«propertyName»();
1527 ////System.out.println("«propertyName»:" + «propertyName»);
1528 if(«propertyName» != null) {
1529 java.util.Iterator _iterator = «propertyName».iterator();
1530 boolean _hasNext = _iterator.hasNext();
1532 Object _listItem = _iterator.next();
1533 Object _domValue = «type.actualTypeArguments.get(0).serializer(schema).resolvedName».toDomStatic(_resultName,_listItem);
1534 _childNodes.add(_domValue);
1535 _hasNext = _iterator.hasNext();
1540 private def dispatch CharSequence serializeProperty(LeafSchemaNode schema, Type type, String propertyName) '''
1541 «type.resolvedName» «propertyName» = value.«propertyName»();
1543 if(«propertyName» != null) {
1544 «QName.name» _qname = «QName.name».create(_resultName,"«schema.QName.localName»");
1545 Object _propValue = «serializeValue(type, propertyName, schema.type)»;
1546 if(_propValue != null) {
1547 Object _domValue = java.util.Collections.singletonMap(_qname,_propValue);
1548 _childNodes.add(_domValue);
1553 private def dispatch serializeValue(GeneratedTransferObject type, String parameter, TypeDefinition<?> typeDefinition) {
1554 '''«type.valueSerializer(typeDefinition).resolvedName».toDomValue(«parameter»)'''
1557 private def dispatch serializeValue(Enumeration type, String parameter, TypeDefinition<?> typeDefinition) {
1558 '''«type.valueSerializer(typeDefinition).resolvedName».toDomValue(«parameter»)'''
1561 private def dispatch serializeValue(Type type, String parameter, EmptyTypeDefinition typeDefinition) {
1562 '''(«parameter».booleanValue() ? "" : null)'''
1565 private def dispatch serializeValue(Type signature, String property, TypeDefinition<?> typeDefinition) {
1566 serializeValue(signature,property)
1569 private def dispatch serializeValue(Type signature, String property, Void typeDefinition) {
1570 serializeValue(signature,property)
1573 private def dispatch serializeValue(Type signature, String property) {
1574 if (INSTANCE_IDENTIFIER == signature) {
1575 return '''«INSTANCE_IDENTIFIER_CODEC».serialize(«property»)'''
1576 } else if (CLASS_TYPE.equals(signature)) {
1577 return '''(«QName.resolvedName») «IDENTITYREF_CODEC».serialize(«property»)'''
1579 if ("char[]" == signature.name) {
1580 return '''new String(«property»)''';
1582 return '''«property»''';
1585 private def dispatch CharSequence serializeProperty(LeafListSchemaNode schema, ParameterizedType type,
1586 String propertyName) '''
1587 «type.resolvedName» «propertyName» = value.«propertyName»();
1588 if(«propertyName» != null) {
1589 «QName.name» _qname = «QName.name».create(_resultName,"«schema.QName.localName»");
1590 java.util.Iterator _iterator = «propertyName».iterator();
1591 boolean _hasNext = _iterator.hasNext();
1593 Object _listItem = _iterator.next();
1594 Object _propValue = «serializeValue(type.actualTypeArguments.get(0), "_listItem", schema.type)»;
1595 Object _domValue = java.util.Collections.singletonMap(_qname,_propValue);
1596 _childNodes.add(_domValue);
1597 _hasNext = _iterator.hasNext();
1602 private def dispatch CharSequence serializeProperty(ChoiceNode container, GeneratedType type,
1603 String propertyName) '''
1604 «type.resolvedName» «propertyName» = value.«propertyName»();
1605 if(«propertyName» != null) {
1606 java.util.List domValue = «type.serializer(container).resolvedName».toDomStatic(_resultName,«propertyName»);
1607 _childNodes.addAll(domValue);
1615 private def dispatch CharSequence serializeProperty(DataSchemaNode container, Type type, String propertyName) '''
1616 «type.resolvedName» «propertyName» = value.«propertyName»();
1617 if(«propertyName» != null) {
1618 Object domValue = «propertyName»;
1619 _childNodes.add(domValue);
1623 private def dispatch CharSequence serializeProperty(DataSchemaNode container, GeneratedTypeBuilder type,
1624 String propertyName) {
1625 serializeProperty(container, type.toInstance, propertyName)
1628 private def dispatch CharSequence serializeProperty(DataSchemaNode container, GeneratedType type,
1629 String propertyName) '''
1630 «type.resolvedName» «propertyName» = value.«propertyName»();
1631 if(«propertyName» != null) {
1632 Object domValue = «type.serializer(container).resolvedName».toDomStatic(_resultName,«propertyName»);
1633 _childNodes.add(domValue);
1637 private def codecClassName(GeneratedType typeSpec) {
1638 return '''«typeSpec.resolvedName»$Broker$Codec$DOM'''
1641 private def codecClassName(Class<?> typeSpec) {
1642 return '''«typeSpec.name»$Broker$Codec$DOM'''
1645 private def HashMap<String, Type> getAllProperties(GeneratedType type) {
1646 val ret = new HashMap<String, Type>();
1647 type.collectAllProperties(ret);
1651 private def dispatch void collectAllProperties(GeneratedType type, Map<String, Type> set) {
1652 for (definition : type.methodDefinitions) {
1653 set.put(definition.name, definition.returnType);
1655 for (property : type.properties) {
1656 set.put(property.getterName, property.returnType);
1658 for (parent : type.implements) {
1659 parent.collectAllProperties(set);
1663 def String getGetterName(GeneratedProperty property) {
1664 return "get" + property.name.toFirstUpper
1667 private def dispatch void collectAllProperties(Type type, Map<String, Type> set) {
1668 // NOOP for generic type.
1671 def String getResolvedName(Type type) {
1672 return type.asCtClass.name;
1675 def String getResolvedName(Class<?> type) {
1676 return type.asCtClass.name;
1679 def CtClass asCtClass(Type type) {
1680 val cls = loadClass(type.fullyQualifiedName)
1681 return cls.asCtClass;
1684 private def dispatch processException(Class<?> inputType, CodeGenerationException e) {
1685 LOG.error("Cannot compile DOM Codec for {}. One of it's prerequisites was not generated.", inputType);
1689 private def dispatch processException(Class<?> inputType, Exception e) {
1690 LOG.error("Cannot compile DOM Codec for {}", inputType, e);
1691 val exception = new CodeGenerationException("Cannot compile Transformator for " + inputType, e);
1695 private def setBodyChecked(CtMethod method, String body, SourceCodeGenerator sourceGenerator ) {
1697 method.setBody(body);
1699 sourceGenerator.appendMethod( method, body );
1700 } catch (CannotCompileException e) {
1701 LOG.error("Cannot compile method: {}#{} {}, Reason: {} Body: {}", method.declaringClass, method.name,
1702 method.signature, e.message, body)
1709 class PropertyPair {
1718 SchemaNode schemaNode;