X-Git-Url: https://git.opendaylight.org/gerrit/gitweb?a=blobdiff_plain;f=opendaylight%2Fmd-sal%2Fsal-binding-broker%2Fsrc%2Fmain%2Fjava%2Forg%2Fopendaylight%2Fcontroller%2Fsal%2Fbinding%2Fdom%2Fserializer%2Fimpl%2FTransformerGenerator.xtend;h=4271ef9c1a9bb5824f04673cbcf1e86f466c7c52;hb=d1ab4c3ea79bcd74e02aa9334bc660cb7fc6d037;hp=b2d25af8850bd5b40a369e136baf710d9e669735;hpb=5b4fe76e48ced1146c26421aa163626a36bc09c9;p=controller.git 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..4271ef9c1a 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,11 @@ 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 class TransformerGenerator { @@ -91,7 +96,7 @@ class TransformerGenerator { @Property var GeneratorListener listener; - + public static val CLASS_TYPE = Types.typeForClass(Class); public new(ClassPool pool) { @@ -276,7 +281,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 +303,7 @@ class TransformerGenerator { ] method(Object, "fromDomStatic", QName, Object) [ modifiers = PUBLIC + FINAL + STATIC - body = ''' + bodyChecked = ''' { if($2 == null){ return null; @@ -319,7 +324,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,7 +334,7 @@ class TransformerGenerator { ''' ] method(Object, "deserialize", Object) [ - body = ''' + bodyChecked = ''' return fromDomStatic(QNAME,$1); ''' ] @@ -357,7 +362,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 +373,7 @@ class TransformerGenerator { ''' ] method(Object, "serialize", Object) [ - body = ''' + bodyChecked = ''' { java.util.Map.Entry _input = (java.util.Map.Entry) $1; «QName.name» _localName = QNAME; @@ -381,10 +386,10 @@ 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); java.util.Map.Entry _input = (java.util.Map.Entry) $1; @@ -418,10 +423,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 +439,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); ''' ] @@ -468,7 +473,7 @@ 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); @@ -485,7 +490,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 +503,7 @@ class TransformerGenerator { ] method(Object, "fromDomStatic", QName, Object) [ modifiers = PUBLIC + FINAL + STATIC - body = ''' + bodyChecked = ''' { «QName.name» _localQName = QNAME; @@ -522,7 +527,7 @@ class TransformerGenerator { ''' ] method(Object, "deserialize", Object) [ - body = ''' + bodyChecked = ''' return fromDomStatic(QNAME,$1); ''' ] @@ -553,7 +558,7 @@ class TransformerGenerator { implementsType(BINDING_CODEC) method(List, "toDomStatic", QName, Object) [ modifiers = PUBLIC + FINAL + STATIC - body = ''' + bodyChecked = ''' { if($2 == null) { return null; @@ -572,13 +577,13 @@ class TransformerGenerator { ''' ] 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 +594,7 @@ class TransformerGenerator { ''' ] method(Object, "deserialize", Object) [ - body = ''' + bodyChecked = ''' throw new «UnsupportedOperationException.name»("Direct invocation not supported."); ''' ] @@ -822,17 +827,15 @@ 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; + if (returnType.name == 'char[]') { + val ctCls = createUnionImplementation(inputType, typeSpec); + val ret = ctCls.toClassImpl(inputType.classLoader, inputType.protectionDomain) + return ret as Class, Object>>; } - 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,7 +843,8 @@ class TransformerGenerator { } method(Object, "toDomValue", Object) [ modifiers = PUBLIC + FINAL + STATIC - body = ''' + val ctSpec = typeSpec.asCtClass; + bodyChecked = ''' { //System.out.println("«inputType.simpleName»#toDomValue: "+$1); @@ -857,7 +861,7 @@ class TransformerGenerator { ''' ] method(Object, "serialize", Object) [ - body = ''' + bodyChecked = ''' { return toDomValue($1); } @@ -865,7 +869,7 @@ class TransformerGenerator { ] method(Object, "fromDomValue", Object) [ modifiers = PUBLIC + FINAL + STATIC - body = ''' + bodyChecked = ''' { //System.out.println("«inputType.simpleName»#fromDomValue: "+$1); @@ -879,7 +883,7 @@ class TransformerGenerator { ''' ] method(Object, "deserialize", Object) [ - body = '''{ + bodyChecked = '''{ return fromDomValue($1); } ''' @@ -898,18 +902,104 @@ class TransformerGenerator { } + def createUnionImplementation(Class inputType, GeneratedTransferObject typeSpec) { + return createClass(typeSpec.codecClassName) [ + val properties = typeSpec.allProperties; + //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)»; + } + «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); + } + ''' + ] + ] + } + + 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 +1007,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); } ''' @@ -952,7 +1042,7 @@ class TransformerGenerator { //implementsType(BINDING_CODEC) method(Object, "toDomValue", Object) [ modifiers = PUBLIC + FINAL + STATIC - body = '''{ + bodyChecked = '''{ if($1 == null) { return null; } @@ -967,13 +1057,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,7 +1079,7 @@ class TransformerGenerator { ''' ] method(Object, "deserialize", Object) [ - body = ''' + bodyChecked = ''' return fromDomValue($1); ''' ] @@ -1200,9 +1290,12 @@ class TransformerGenerator { private def dispatch serializeValue(Type signature, String property) { 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»'''; } @@ -1316,6 +1409,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