X-Git-Url: https://git.opendaylight.org/gerrit/gitweb?p=controller.git;a=blobdiff_plain;f=opendaylight%2Fmd-sal%2Fsal-binding-broker%2Fsrc%2Fmain%2Fjava%2Forg%2Fopendaylight%2Fcontroller%2Fsal%2Fbinding%2Fdom%2Fserializer%2Fimpl%2FTransformerGenerator.xtend;h=5bc2d70c6a97a6cfba93ff15ee065ecbae352ae8;hp=b2d25af8850bd5b40a369e136baf710d9e669735;hb=178d185be418a9ed491201bd6a0e4d98efa9d820;hpb=5b4fe76e48ced1146c26421aa163626a36bc09c9 diff --git a/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/dom/serializer/impl/TransformerGenerator.xtend b/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/dom/serializer/impl/TransformerGenerator.xtend index b2d25af885..5bc2d70c6a 100644 --- a/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/dom/serializer/impl/TransformerGenerator.xtend +++ b/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/dom/serializer/impl/TransformerGenerator.xtend @@ -51,6 +51,19 @@ import org.opendaylight.yangtools.yang.model.util.ExtendedType import org.opendaylight.yangtools.yang.model.util.EnumerationType import static com.google.common.base.Preconditions.* import org.opendaylight.yangtools.yang.model.api.SchemaPath +import javassist.CtMethod +import javassist.CannotCompileException +import java.util.concurrent.locks.Lock +import java.util.concurrent.Callable +import org.opendaylight.controller.sal.binding.impl.util.ClassLoaderUtils +import org.opendaylight.yangtools.yang.model.api.TypeDefinition +import org.opendaylight.yangtools.yang.model.api.type.UnionTypeDefinition +import org.opendaylight.yangtools.yang.model.api.type.BitsTypeDefinition +import java.util.HashSet +import java.util.Collections +import org.opendaylight.yangtools.yang.model.api.type.BitsTypeDefinition.Bit +import java.util.Set +import org.opendaylight.controller.sal.binding.codegen.impl.XtendHelper class TransformerGenerator { @@ -91,7 +104,7 @@ class TransformerGenerator { @Property var GeneratorListener listener; - + public static val CLASS_TYPE = Types.typeForClass(Class); public new(ClassPool pool) { @@ -132,9 +145,13 @@ class TransformerGenerator { if (typeSpecBuilder == null) { typeSpecBuilder = pathToType.get(node.path); } + var schemaNode = typeToSchemaNode.get(ref); + if(schemaNode === null) { + schemaNode = node; + } checkState(typeSpecBuilder !== null, "Could not find TypeDefinition for %s, $s", inputType.name, node); val typeSpec = typeSpecBuilder.toInstance(); - val newret = generateTransformerFor(inputType, typeSpec, node); + val newret = generateTransformerFor(inputType, typeSpec, schemaNode); listener.onClassProcessed(inputType); return newret as Class, Object>>; ] @@ -238,19 +255,24 @@ class TransformerGenerator { transformerFor(cls, node); } - private def Class getValueSerializer(GeneratedTransferObject type) { + private def Class valueSerializer(GeneratedTransferObject type, TypeDefinition typeDefinition) { val cls = loadClassWithTCCL(type.resolvedName); val transformer = cls.generatedClass; if (transformer !== null) { return transformer; } + var baseType = typeDefinition; + while (baseType.baseType != null) { + baseType = baseType.baseType; + } + val finalType = baseType; return withClassLoaderAndLock(cls.classLoader, lock) [ | - val valueTransformer = generateValueTransformer(cls, type); + val valueTransformer = generateValueTransformer(cls, type, finalType); return valueTransformer; ] } - private def Class getValueSerializer(Enumeration type) { + private def Class valueSerializer(Enumeration type, TypeDefinition typeDefinition) { val cls = loadClassWithTCCL(type.resolvedName); val transformer = cls.generatedClass; if (transformer !== null) { @@ -276,7 +298,7 @@ class TransformerGenerator { implementsType(BINDING_CODEC) method(Object, "toDomStatic", QName, Object) [ modifiers = PUBLIC + FINAL + STATIC - body = ''' + bodyChecked = ''' { «QName.name» _resultName; if($1 != null) { @@ -298,7 +320,7 @@ class TransformerGenerator { ] method(Object, "fromDomStatic", QName, Object) [ modifiers = PUBLIC + FINAL + STATIC - body = ''' + bodyChecked = ''' { if($2 == null){ return null; @@ -319,7 +341,7 @@ class TransformerGenerator { ''' ] method(Object, "serialize", Object) [ - body = ''' + bodyChecked = ''' { java.util.Map.Entry _input = (java.util.Map.Entry) $1; «QName.name» _localQName = («QName.name») _input.getKey(); @@ -329,13 +351,13 @@ class TransformerGenerator { ''' ] method(Object, "deserialize", Object) [ - body = ''' + bodyChecked = ''' return fromDomStatic(QNAME,$1); ''' ] ] val ret = ctCls.toClassImpl(inputType.classLoader, inputType.protectionDomain) - log.info("DOM Codec for {} was generated {}", inputType, ret) + log.debug("DOM Codec for {} was generated {}", inputType, ret) return ret as Class, ?>>; } catch (Exception e) { processException(inputType, e); @@ -357,7 +379,7 @@ class TransformerGenerator { staticField(it, IDENTITYREF_CODEC, BindingCodec) method(Object, "toDomStatic", QName, Object) [ modifiers = PUBLIC + FINAL + STATIC - body = ''' + bodyChecked = ''' { «QName.name» _resultName = «QName.name».create($1,QNAME.getLocalName()); java.util.List _childNodes = new java.util.ArrayList(); @@ -368,7 +390,7 @@ class TransformerGenerator { ''' ] method(Object, "serialize", Object) [ - body = ''' + bodyChecked = ''' { java.util.Map.Entry _input = (java.util.Map.Entry) $1; «QName.name» _localName = QNAME; @@ -381,12 +403,12 @@ class TransformerGenerator { ] method(Object, "fromDomStatic", QName, Object) [ modifiers = PUBLIC + FINAL + STATIC - body = deserializeBody(type, node) + bodyChecked = deserializeBody(type, node) ] method(Object, "deserialize", Object) [ - body = ''' + bodyChecked = ''' { - //System.out.println("«type.name»#deserialize: " +$1); + ////System.out.println("«type.name»#deserialize: " +$1); java.util.Map.Entry _input = (java.util.Map.Entry) $1; return fromDomStatic((«QName.name»)_input.getKey(),_input.getValue()); } @@ -396,7 +418,7 @@ class TransformerGenerator { val ret = ctCls.toClassImpl(inputType.classLoader, inputType.protectionDomain) as Class> listener?.onDataContainerCodecCreated(inputType, ret); - log.info("DOM Codec for {} was generated {}", inputType, ret) + log.debug("DOM Codec for {} was generated {}", inputType, ret) return ret; } catch (Exception e) { processException(inputType, e); @@ -418,10 +440,10 @@ class TransformerGenerator { implementsType(BINDING_CODEC) method(Object, "toDomStatic", QName, Object) [ modifiers = PUBLIC + FINAL + STATIC - body = serializeBodyFacade(typeSpec, node) + bodyChecked = serializeBodyFacade(typeSpec, node) ] method(Object, "serialize", Object) [ - body = ''' + bodyChecked = ''' { java.util.Map.Entry _input = (java.util.Map.Entry) $1; «QName.name» _localName = QNAME; @@ -434,10 +456,10 @@ class TransformerGenerator { ] method(Object, "fromDomStatic", QName, Object) [ modifiers = PUBLIC + FINAL + STATIC - body = deserializeBody(typeSpec, node) + bodyChecked = deserializeBody(typeSpec, node) ] method(Object, "deserialize", Object) [ - body = ''' + bodyChecked = ''' return fromDomStatic(QNAME,$1); ''' ] @@ -445,7 +467,7 @@ class TransformerGenerator { val ret = ctCls.toClassImpl(inputType.classLoader, inputType.protectionDomain) as Class, Object>> listener?.onDataContainerCodecCreated(inputType, ret); - log.info("DOM Codec for {} was generated {}", inputType, ret) + log.debug("DOM Codec for {} was generated {}", inputType, ret) return ret; } catch (Exception e) { processException(inputType, e); @@ -468,16 +490,16 @@ class TransformerGenerator { implementsType(BINDING_CODEC) method(Object, "toDomStatic", QName, Object) [ modifiers = PUBLIC + FINAL + STATIC - body = ''' + bodyChecked = ''' { - //System.out.println("Qname " + $1); - //System.out.println("Value " + $2); + ////System.out.println("Qname " + $1); + ////System.out.println("Value " + $2); «QName.name» _resultName = «QName.name».create(QNAME,QNAME.getLocalName()); java.util.List _childNodes = new java.util.ArrayList(); «type.resolvedName» value = («type.resolvedName») $2; «FOR child : node.childNodes» «var signature = properties.getFor(child)» - //System.out.println("«signature.key»" + value.«signature.key»()); + ////System.out.println("«signature.key»" + value.«signature.key»()); «serializeProperty(child, signature.value, signature.key)» «ENDFOR» return ($r) _childNodes; @@ -485,7 +507,7 @@ class TransformerGenerator { ''' ] method(Object, "serialize", Object) [ - body = ''' + bodyChecked = ''' { java.util.Map.Entry _input = (java.util.Map.Entry) $1; «QName.name» _localName = QNAME; @@ -498,7 +520,7 @@ class TransformerGenerator { ] method(Object, "fromDomStatic", QName, Object) [ modifiers = PUBLIC + FINAL + STATIC - body = ''' + bodyChecked = ''' { «QName.name» _localQName = QNAME; @@ -506,7 +528,7 @@ class TransformerGenerator { return null; } java.util.Map _compositeNode = (java.util.Map) $2; - //System.out.println(_localQName + " " + _compositeNode); + System.out.println(_localQName + " " + _compositeNode); «type.builderName» _builder = new «type.builderName»(); boolean _is_empty = true; «FOR child : node.childNodes» @@ -522,7 +544,7 @@ class TransformerGenerator { ''' ] method(Object, "deserialize", Object) [ - body = ''' + bodyChecked = ''' return fromDomStatic(QNAME,$1); ''' ] @@ -553,7 +575,7 @@ class TransformerGenerator { implementsType(BINDING_CODEC) method(List, "toDomStatic", QName, Object) [ modifiers = PUBLIC + FINAL + STATIC - body = ''' + bodyChecked = ''' { if($2 == null) { return null; @@ -566,19 +588,19 @@ class TransformerGenerator { } java.util.Map.Entry _input = new «SimpleEntry.name»($1,_baValue); Object _ret = _codec.serialize(_input); - //System.out.println("«typeSpec.name»#toDomStatic: " + _ret); + ////System.out.println("«typeSpec.name»#toDomStatic: " + _ret); return («List.name») _ret; } ''' ] method(Object, "serialize", Object) [ - body = ''' + bodyChecked = ''' throw new «UnsupportedOperationException.name»("Direct invocation not supported."); ''' ] method(Object, "fromDomStatic", QName, Map) [ modifiers = PUBLIC + FINAL + STATIC - body = ''' + bodyChecked = ''' { «BINDING_CODEC.name» _codec = («BINDING_CODEC.name») «COMPOSITE_TO_CASE».get($2); if(_codec != null) { @@ -589,7 +611,7 @@ class TransformerGenerator { ''' ] method(Object, "deserialize", Object) [ - body = ''' + bodyChecked = ''' throw new «UnsupportedOperationException.name»("Direct invocation not supported."); ''' ] @@ -598,7 +620,7 @@ class TransformerGenerator { val rawRet = ctCls.toClassImpl(inputType.classLoader, inputType.protectionDomain) val ret = rawRet as Class, Object>>; listener?.onChoiceCodecCreated(inputType, ret, node); - log.info("DOM Codec for {} was generated {}", inputType, ret) + log.debug("DOM Codec for {} was generated {}", inputType, ret) return ret; } catch (Exception e) { processException(inputType, e); @@ -654,6 +676,7 @@ class TransformerGenerator { return null; } java.util.Map _compositeNode = (java.util.Map) $2; + System.out.println(_localQName + " " + _compositeNode); «type.builderName» _builder = new «type.builderName»(); «deserializeKey(type, node)» «deserializeDataNodeContainerBody(type, node)» @@ -669,6 +692,7 @@ class TransformerGenerator { return null; } java.util.Map _compositeNode = (java.util.Map) $2; + System.out.println(_localQName + " " + _compositeNode); «type.builderName» _builder = new «type.builderName»(); «deserializeDataNodeContainerBody(type, node)» «deserializeAugmentations» @@ -684,7 +708,7 @@ class TransformerGenerator { return null; } java.util.Map _compositeNode = (java.util.Map) $2; - //System.out.println(_localQName + " " + _compositeNode); + System.out.println(_localQName + " " + _compositeNode); «type.builderName» _builder = new «type.builderName»(); «deserializeDataNodeContainerBody(type, node)» «deserializeAugmentations» @@ -717,7 +741,7 @@ class TransformerGenerator { «Iterator.name» _entries = _augmentation.entrySet().iterator(); while(_entries.hasNext()) { java.util.Map.Entry _entry = (java.util.Map.Entry) _entries.next(); - //System.out.println("Aug. key:" + _entry.getKey()); + ////System.out.println("Aug. key:" + _entry.getKey()); Class _type = (Class) _entry.getKey(); «Augmentation.resolvedName» _value = («Augmentation.name») _entry.getValue(); if(_value != null) { @@ -731,7 +755,7 @@ class TransformerGenerator { String propertyName) ''' java.util.List _dom_«propertyName» = _compositeNode.get(«QName.name».create(_localQName,"«schema.QName. localName»")); - //System.out.println("«propertyName»#deCode"+_dom_«propertyName»); + ////System.out.println("«propertyName»#deCode"+_dom_«propertyName»); java.util.List «propertyName» = new java.util.ArrayList(); if(_dom_«propertyName» != null) { java.util.List _serialized = new java.util.ArrayList(); @@ -740,15 +764,15 @@ class TransformerGenerator { while(_hasNext) { Object _listItem = _iterator.next(); _is_empty = false; - //System.out.println(" item" + _listItem); + ////System.out.println(" item" + _listItem); Object _value = «type.actualTypeArguments.get(0).serializer(schema).resolvedName».fromDomStatic(_localQName,_listItem); - //System.out.println(" value" + _value); + ////System.out.println(" value" + _value); «propertyName».add(_value); _hasNext = _iterator.hasNext(); } } - //System.out.println(" list" + «propertyName»); + ////System.out.println(" list" + «propertyName»); ''' private def dispatch CharSequence deserializeProperty(LeafListSchemaNode schema, ParameterizedType type, @@ -765,7 +789,7 @@ class TransformerGenerator { Object _listItem = _iterator.next(); if(_listItem instanceof java.util.Map.Entry) { Object _innerValue = ((java.util.Map.Entry) _listItem).getValue(); - Object _value = «deserializeValue(type.actualTypeArguments.get(0), "_innerValue")»; + Object _value = «deserializeValue(type.actualTypeArguments.get(0), "_innerValue", schema.type)»; «propertyName».add(_value); } _hasNext = _iterator.hasNext(); @@ -781,7 +805,7 @@ class TransformerGenerator { _is_empty = false; java.util.Map.Entry _dom_«propertyName» = (java.util.Map.Entry) _dom_«propertyName»_list.get(0); Object _inner_value = _dom_«propertyName».getValue(); - «propertyName» = «deserializeValue(type, "_inner_value")»; + «propertyName» = «deserializeValue(type, "_inner_value", schema.type)»; } ''' @@ -804,16 +828,17 @@ class TransformerGenerator { } ''' - private def dispatch String deserializeValue(GeneratedTransferObject type, String domParameter) ''' - («type.resolvedName») «type.valueSerializer.resolvedName».fromDomValue(«domParameter») + private def dispatch String deserializeValue(GeneratedTransferObject type, String domParameter, + TypeDefinition typeDefinition) ''' + («type.resolvedName») «type.valueSerializer(typeDefinition).resolvedName».fromDomValue(«domParameter») ''' - private def dispatch String deserializeValue(Enumeration type, String domParameter) ''' - («type.resolvedName») «type.valueSerializer.resolvedName».fromDomValue(«domParameter») + private def dispatch String deserializeValue(Enumeration type, String domParameter, TypeDefinition typeDefinition) ''' + («type.resolvedName») «type.valueSerializer(typeDefinition).resolvedName».fromDomValue(«domParameter») ''' private def dispatch Class, Object>> generateValueTransformer( - Class inputType, GeneratedTransferObject typeSpec) { + Class inputType, GeneratedTransferObject typeSpec, TypeDefinition typeDef) { try { val returnType = typeSpec.valueReturnType; @@ -822,17 +847,10 @@ class TransformerGenerator { val ret = ctCls.toClassImpl(inputType.classLoader, inputType.protectionDomain) return ret as Class, Object>>; } - var hasBinding = false; - try { - val bindingCodecClass = loadClassWithTCCL(BINDING_CODEC.name); - hasBinding = bindingCodecClass !== null; - } catch (ClassNotFoundException e) { - hasBinding = false; - } - val hasYangBinding = hasBinding + val ctCls = createClass(typeSpec.codecClassName) [ //staticField(Map,"AUGMENTATION_SERIALIZERS"); - if (hasYangBinding) { + if (inputType.isYangBindingAvailable) { implementsType(BINDING_CODEC) staticField(it, INSTANCE_IDENTIFIER_CODEC, BindingCodec) staticField(it, IDENTITYREF_CODEC, BindingCodec) @@ -840,24 +858,25 @@ class TransformerGenerator { } method(Object, "toDomValue", Object) [ modifiers = PUBLIC + FINAL + STATIC - body = ''' + val ctSpec = typeSpec.asCtClass; + bodyChecked = ''' { - //System.out.println("«inputType.simpleName»#toDomValue: "+$1); + ////System.out.println("«inputType.simpleName»#toDomValue: "+$1); if($1 == null) { return null; } «typeSpec.resolvedName» _encapsulatedValue = («typeSpec.resolvedName») $1; - //System.out.println("«inputType.simpleName»#toDomValue:Enc: "+_encapsulatedValue); + ////System.out.println("«inputType.simpleName»#toDomValue:Enc: "+_encapsulatedValue); «returnType.resolvedName» _value = _encapsulatedValue.getValue(); - //System.out.println("«inputType.simpleName»#toDomValue:DeEnc: "+_value); - Object _domValue = «serializeValue(returnType, "_value")»; + ////System.out.println("«inputType.simpleName»#toDomValue:DeEnc: "+_value); + Object _domValue = «serializeValue(returnType, "_value", null)»; return _domValue; } ''' ] method(Object, "serialize", Object) [ - body = ''' + bodyChecked = ''' { return toDomValue($1); } @@ -865,21 +884,21 @@ class TransformerGenerator { ] method(Object, "fromDomValue", Object) [ modifiers = PUBLIC + FINAL + STATIC - body = ''' + bodyChecked = ''' { - //System.out.println("«inputType.simpleName»#fromDomValue: "+$1); + ////System.out.println("«inputType.simpleName»#fromDomValue: "+$1); if($1 == null) { return null; } - «returnType.resolvedName» _simpleValue = «deserializeValue(returnType, "$1")»; + «returnType.resolvedName» _simpleValue = «deserializeValue(returnType, "$1", null)»; «typeSpec.resolvedName» _value = new «typeSpec.resolvedName»(_simpleValue); return _value; } ''' ] method(Object, "deserialize", Object) [ - body = '''{ + bodyChecked = '''{ return fromDomValue($1); } ''' @@ -887,7 +906,7 @@ class TransformerGenerator { ] val ret = ctCls.toClassImpl(inputType.classLoader, inputType.protectionDomain) - log.info("DOM Codec for {} was generated {}", inputType, ret) + log.debug("DOM Codec for {} was generated {}", inputType, ret) return ret as Class, Object>>; } catch (Exception e) { log.error("Cannot compile DOM Codec for {}", inputType, e); @@ -895,21 +914,215 @@ class TransformerGenerator { exception.addSuppressed(e); throw exception; } + } + private def dispatch Class, Object>> generateValueTransformer( + Class inputType, GeneratedTransferObject typeSpec, UnionTypeDefinition typeDef) { + try { + val ctCls = createClass(typeSpec.codecClassName) [ + val properties = typeSpec.allProperties; + val getterToTypeDefinition = XtendHelper.getTypes(typeDef).toMap[type | type.QName.getterName]; + //staticField(Map,"AUGMENTATION_SERIALIZERS"); + if (inputType.isYangBindingAvailable) { + implementsType(BINDING_CODEC) + staticField(it, INSTANCE_IDENTIFIER_CODEC, BindingCodec) + staticField(it, IDENTITYREF_CODEC, BindingCodec) + implementsType(BindingDeserializer.asCtClass) + } + method(Object, "toDomValue", Object) [ + modifiers = PUBLIC + FINAL + STATIC + val ctSpec = inputType.asCtClass; + + bodyChecked = ''' + { + ////System.out.println("«inputType.simpleName»#toDomValue: "+$1); + + if($1 == null) { + return null; + } + «typeSpec.resolvedName» _value = («typeSpec.resolvedName») $1; + «FOR property : properties.entrySet» + «IF property.key != "getValue"» + «property.value.resolvedName» «property.key» = («property.value.resolvedName») _value.«property. + key»(); + if(«property.key» != null) { + return «serializeValue(property.value, property.key, getterToTypeDefinition.get(property.key))»; + } + «ENDIF» + «ENDFOR» + + return null; + } + ''' + ] + method(Object, "serialize", Object) [ + bodyChecked = ''' + { + return toDomValue($1); + } + ''' + ] + method(Object, "fromDomValue", Object) [ + modifiers = PUBLIC + FINAL + STATIC + bodyChecked = ''' + { + ////System.out.println("«inputType.simpleName»#fromDomValue: "+$1); + + if($1 == null) { + return null; + } + if($1 instanceof String) { + String _simpleValue = (String) $1; + return new «typeSpec.resolvedName»(_simpleValue.toCharArray()); + } + return null; + } + ''' + ] + method(Object, "deserialize", Object) [ + bodyChecked = '''{ + return fromDomValue($1); + } + ''' + ] + ] + + val ret = ctCls.toClassImpl(inputType.classLoader, inputType.protectionDomain) + log.debug("DOM Codec for {} was generated {}", inputType, ret) + return ret as Class, Object>>; + } catch (Exception e) { + log.error("Cannot compile DOM Codec for {}", inputType, e); + val exception = new CodeGenerationException("Cannot compile Transformator for " + inputType); + exception.addSuppressed(e); + throw exception; + } + } + + + private def dispatch Class, Object>> generateValueTransformer( + Class inputType, GeneratedTransferObject typeSpec, BitsTypeDefinition typeDef) { + try { + val ctCls = createClass(typeSpec.codecClassName) [ + //staticField(Map,"AUGMENTATION_SERIALIZERS"); + if (inputType.isYangBindingAvailable) { + implementsType(BINDING_CODEC) + staticField(it, INSTANCE_IDENTIFIER_CODEC, BindingCodec) + staticField(it, IDENTITYREF_CODEC, BindingCodec) + implementsType(BindingDeserializer.asCtClass) + } + method(Object, "toDomValue", Object) [ + modifiers = PUBLIC + FINAL + STATIC + val ctSpec = typeSpec.asCtClass; + bodyChecked = ''' + { + ////System.out.println("«inputType.simpleName»#toDomValue: "+$1); + + if($1 == null) { + return null; + } + «typeSpec.resolvedName» _encapsulatedValue = («typeSpec.resolvedName») $1; + «HashSet.resolvedName» _value = new «HashSet.resolvedName»(); + //System.out.println("«inputType.simpleName»#toDomValue:Enc: "+_encapsulatedValue); + + «FOR bit : typeDef.bits» + «val getter = bit.getterName()» + if(Boolean.TRUE.equals(_encapsulatedValue.«getter»())) { + _value.add("«bit.name»"); + } + «ENDFOR» + «Set.resolvedName» _domValue = «Collections.resolvedName».unmodifiableSet(_value); + //System.out.println("«inputType.simpleName»#toDomValue:DeEnc: "+_domValue); + + return _domValue; + } + ''' + ] + method(Object, "serialize", Object) [ + bodyChecked = ''' + { + return toDomValue($1); + } + ''' + ] + method(Object, "fromDomValue", Object) [ + modifiers = PUBLIC + FINAL + STATIC + val sortedBits = typeDef.bits.sort[o1, o2|o1.propertyName.compareTo(o2.propertyName)] + bodyChecked = ''' + { + //System.out.println("«inputType.simpleName»#fromDomValue: "+$1); + + if($1 == null) { + return null; + } + «Set.resolvedName» _domValue = («Set.resolvedName») $1; + «FOR bit : sortedBits» + Boolean «bit.propertyName» = Boolean.valueOf(_domValue.contains("«bit.name»")); + «ENDFOR» + + return new «inputType.resolvedName»(«FOR bit : sortedBits SEPARATOR ","»«bit.propertyName»«ENDFOR»); + } + ''' + ] + method(Object, "deserialize", Object) [ + bodyChecked = '''{ + return fromDomValue($1); + } + ''' + ] + ] + + val ret = ctCls.toClassImpl(inputType.classLoader, inputType.protectionDomain) + log.debug("DOM Codec for {} was generated {}", inputType, ret) + return ret as Class, Object>>; + } catch (Exception e) { + log.error("Cannot compile DOM Codec for {}", inputType, e); + val exception = new CodeGenerationException("Cannot compile Transformator for " + inputType); + exception.addSuppressed(e); + throw exception; + } + } + + def String getPropertyName(Bit bit) { + '''_«BindingGeneratorUtil.parseToValidParamName(bit.name)»''' + } + + def String getterName(Bit bit) { + + val paramName = BindingGeneratorUtil.parseToValidParamName(bit.name); + return '''is«paramName.toFirstUpper»'''; + } + + def boolean isYangBindingAvailable(Class class1) { + try { + val bindingCodecClass = class1.classLoader.loadClass(BINDING_CODEC.name); + return bindingCodecClass !== null; + } catch (ClassNotFoundException e) { + return false; + } } private def createDummyImplementation(Class object, GeneratedTransferObject typeSpec) { log.info("Generating Dummy DOM Codec for {} with {}", object, object.classLoader) return createClass(typeSpec.codecClassName) [ - //staticField(Map,"AUGMENTATION_SERIALIZERS"); - implementsType(BINDING_CODEC) - implementsType(BindingDeserializer.asCtClass) + if (object.isYangBindingAvailable) { + implementsType(BINDING_CODEC) + staticField(it, INSTANCE_IDENTIFIER_CODEC, BindingCodec) + staticField(it, IDENTITYREF_CODEC, BindingCodec) + implementsType(BindingDeserializer.asCtClass) + } + //implementsType(BindingDeserializer.asCtClass) method(Object, "toDomValue", Object) [ modifiers = PUBLIC + FINAL + STATIC - body = '''return null;''' + bodyChecked = '''{ + if($1 == null) { + return null; + } + return $1.toString(); + + }''' ] method(Object, "serialize", Object) [ - body = ''' + bodyChecked = ''' { return toDomValue($1); } @@ -917,10 +1130,10 @@ class TransformerGenerator { ] method(Object, "fromDomValue", Object) [ modifiers = PUBLIC + FINAL + STATIC - body = '''return null;''' + bodyChecked = '''return null;''' ] method(Object, "deserialize", Object) [ - body = '''{ + bodyChecked = '''{ return fromDomValue($1); } ''' @@ -940,7 +1153,7 @@ class TransformerGenerator { return null; } - private def dispatch Class generateValueTransformer(Class inputType, Enumeration typeSpec) { + private def Class generateValueTransformer(Class inputType, Enumeration typeSpec) { try { val typeRef = new ReferencedTypeImpl(typeSpec.packageName, typeSpec.name); val schema = typeToSchemaNode.get(typeRef) as ExtendedType; @@ -952,7 +1165,7 @@ class TransformerGenerator { //implementsType(BINDING_CODEC) method(Object, "toDomValue", Object) [ modifiers = PUBLIC + FINAL + STATIC - body = '''{ + bodyChecked = '''{ if($1 == null) { return null; } @@ -967,13 +1180,13 @@ class TransformerGenerator { ''' ] method(Object, "serialize", Object) [ - body = ''' + bodyChecked = ''' return toDomValue($1); ''' ] method(Object, "fromDomValue", Object) [ modifiers = PUBLIC + FINAL + STATIC - body = ''' + bodyChecked = ''' { if($1 == null) { return null; @@ -989,14 +1202,14 @@ class TransformerGenerator { ''' ] method(Object, "deserialize", Object) [ - body = ''' + bodyChecked = ''' return fromDomValue($1); ''' ] ] val ret = ctCls.toClassImpl(inputType.classLoader, inputType.protectionDomain) - log.info("DOM Codec for {} was generated {}", inputType, ret) + log.debug("DOM Codec for {} was generated {}", inputType, ret) return ret; } catch (CodeGenerationException e) { throw new CodeGenerationException("Cannot compile Transformator for " + inputType, e); @@ -1026,7 +1239,7 @@ class TransformerGenerator { } - private def dispatch String deserializeValue(Type type, String domParameter) { + private def dispatch String deserializeValue(Type type, String domParameter, TypeDefinition typeDef) { if (INSTANCE_IDENTIFIER.equals(type)) { return '''(«InstanceIdentifier.name») «INSTANCE_IDENTIFIER_CODEC».deserialize(«domParameter»)''' } else if (CLASS_TYPE.equals(type)) { @@ -1124,7 +1337,7 @@ class TransformerGenerator { «FOR child : node.childNodes» «val signature = properties.getFor(child)» «IF signature !== null» - //System.out.println("«type.name»#«signature.key»" + value.«signature.key»()); + ////System.out.println("«type.name»#«signature.key»" + value.«signature.key»()); «serializeProperty(child, signature.value, signature.key)» «ENDIF» «ENDFOR» @@ -1166,7 +1379,7 @@ class TransformerGenerator { private def dispatch CharSequence serializeProperty(ListSchemaNode schema, ParameterizedType type, String propertyName) ''' «type.resolvedName» «propertyName» = value.«propertyName»(); - //System.out.println("«propertyName»:" + «propertyName»); + ////System.out.println("«propertyName»:" + «propertyName»); if(«propertyName» != null) { java.util.Iterator _iterator = «propertyName».iterator(); boolean _hasNext = _iterator.hasNext(); @@ -1184,7 +1397,7 @@ class TransformerGenerator { if(«propertyName» != null) { «QName.name» _qname = «QName.name».create(_resultName,"«schema.QName.localName»"); - Object _propValue = «serializeValue(type, propertyName)»; + Object _propValue = «serializeValue(type, propertyName, schema.type)»; if(_propValue != null) { Object _domValue = java.util.Collections.singletonMap(_qname,_propValue); _childNodes.add(_domValue); @@ -1192,17 +1405,23 @@ class TransformerGenerator { } ''' - private def dispatch serializeValue(GeneratedTransferObject type, String parameter) '''«type.valueSerializer. - resolvedName».toDomValue(«parameter»)''' + private def dispatch serializeValue(GeneratedTransferObject type, String parameter, TypeDefinition typeDefinition) { + '''«type.valueSerializer(typeDefinition).resolvedName».toDomValue(«parameter»)''' + } - private def dispatch serializeValue(Enumeration type, String parameter) '''«type.valueSerializer.resolvedName».toDomValue(«parameter»)''' + private def dispatch serializeValue(Enumeration type, String parameter, TypeDefinition typeDefinition) { + '''«type.valueSerializer(typeDefinition).resolvedName».toDomValue(«parameter»)''' + } - private def dispatch serializeValue(Type signature, String property) { + private def dispatch serializeValue(Type signature, String property, TypeDefinition typeDefinition) { if (INSTANCE_IDENTIFIER == signature) { return '''«INSTANCE_IDENTIFIER_CODEC».serialize(«property»)''' - }else if (CLASS_TYPE.equals(signature)) { + } else if (CLASS_TYPE.equals(signature)) { return '''(«QName.resolvedName») «IDENTITYREF_CODEC».serialize(«property»)''' } + if ("char[]" == signature.name) { + return '''new String(«property»)'''; + } return '''«property»'''; } @@ -1215,7 +1434,7 @@ class TransformerGenerator { boolean _hasNext = _iterator.hasNext(); while(_hasNext) { Object _listItem = _iterator.next(); - Object _propValue = «serializeValue(type.actualTypeArguments.get(0), "_listItem")»; + Object _propValue = «serializeValue(type.actualTypeArguments.get(0), "_listItem", schema.type)»; Object _domValue = java.util.Collections.singletonMap(_qname,_propValue); _childNodes.add(_domValue); _hasNext = _iterator.hasNext(); @@ -1316,6 +1535,21 @@ class TransformerGenerator { throw exception; } + private def setBodyChecked(CtMethod method, String body) { + try { + method.setBody(body); + } catch (CannotCompileException e) { + log.error("Cannot compile method: {}#{} {}, Reason: {} Body: {}", method.declaringClass, method.name, + method.signature, e.message, body) + throw e; + } + } + + private def V withClassLoaderAndLock(ClassLoader cls, Lock lock, Callable function) throws Exception { + appendClassLoaderIfMissing(cls); + ClassLoaderUtils.withClassLoaderAndLock(cls, lock, function); + } + } @Data