import org.opendaylight.yangtools.yang.binding.RpcService
import javassist.CtClass
-import static com.google.common.base.Preconditions.*
-
-import javassist.CtField
-import javassist.Modifier
import javassist.CtMethod
import org.opendaylight.yangtools.yang.binding.InstanceIdentifier
import org.opendaylight.yangtools.yang.binding.annotations.RoutingContext
import java.util.Map
import java.util.HashMap
-import javassist.NotFoundException
-import javassist.LoaderClassPath
-import org.opendaylight.controller.sal.binding.codegen.impl.JavassistUtils.MethodGenerator
-import org.opendaylight.controller.sal.binding.codegen.impl.JavassistUtils.ClassGenerator
+
+
import org.opendaylight.yangtools.yang.binding.NotificationListener
import org.opendaylight.yangtools.yang.binding.Notification
-import java.util.Arrays
+
import static extension org.opendaylight.controller.sal.binding.codegen.YangtoolsMappingHelper.*
import static extension org.opendaylight.controller.sal.binding.codegen.RuntimeCodeSpecification.*
import java.util.HashSet
-import static org.opendaylight.controller.sal.binding.impl.osgi.ClassLoaderUtils.*
+import static org.opendaylight.controller.sal.binding.impl.util.ClassLoaderUtils.*
import org.opendaylight.controller.sal.binding.spi.NotificationInvokerFactory
import org.opendaylight.controller.sal.binding.spi.NotificationInvokerFactory.NotificationInvoker
import java.util.Set
import org.opendaylight.controller.sal.binding.codegen.RuntimeCodeHelper
import java.util.WeakHashMap
-import javassist.ClassClassPath
import org.opendaylight.yangtools.yang.binding.annotations.QName
import org.opendaylight.yangtools.yang.binding.DataContainer
import org.opendaylight.yangtools.yang.binding.RpcImplementation
+import org.opendaylight.controller.sal.binding.codegen.util.JavassistUtils
class RuntimeCodeGenerator implements org.opendaylight.controller.sal.binding.codegen.RuntimeCodeGenerator, NotificationInvokerFactory {
val CtClass BROKER_NOTIFICATION_LISTENER;
val ClassPool classPool;
+ val extension JavassistUtils utils;
val Map<Class<? extends NotificationListener>, RuntimeGeneratedInvokerPrototype> invokerClasses;
public new(ClassPool pool) {
classPool = pool;
+ utils = new JavassistUtils(pool);
invokerClasses = new WeakHashMap();
BROKER_NOTIFICATION_LISTENER = org.opendaylight.controller.sal.binding.api.NotificationListener.asCtClass;
}
val targetCls = createClass(iface.directProxyName, supertype) [
field(DELEGATE_FIELD, iface);
implementMethodsFrom(supertype) [
- body = '''return ($r) «DELEGATE_FIELD».«it.name»($$);'''
+ body = '''
+ {
+ if(«DELEGATE_FIELD» == null) {
+ throw new java.lang.IllegalStateException("No provider is processing supplied message");
+ }
+ return ($r) «DELEGATE_FIELD».«it.name»($$);
+ }
+ '''
]
]
return targetCls.toClass(iface.classLoader).newInstance as T
}
override <T extends RpcService> getRouterFor(Class<T> iface) {
- val contexts = new HashSet<Class<? extends BaseIdentity>>
-
- val instance = <RpcRouterCodegenInstance<T>>withClassLoader(iface.classLoader) [ |
+ val instance = <RpcRouterCodegenInstance<T>>withClassLoaderAndLock(iface.classLoader,lock) [ |
val supertype = iface.asCtClass
val metadata = supertype.rpcMetadata;
val targetCls = createClass(iface.routerName, supertype) [
]
val finalClass = targetCls.toClass(iface.classLoader, iface.protectionDomain)
return new RuntimeGeneratedInvokerPrototype(supportedNotification,
- finalClass as Class<? extends org.opendaylight.controller.sal.binding.api.NotificationListener>);
- }
-
- private def void method(CtClass it, Class<?> returnType, String name, Class<?> parameter, MethodGenerator function1) {
- val method = new CtMethod(returnType.asCtClass, name, Arrays.asList(parameter.asCtClass), it);
- function1.process(method);
- it.addMethod(method);
- }
-
- private def void implementMethodsFrom(CtClass target, CtClass source, MethodGenerator function1) {
- for (method : source.methods) {
- if (method.declaringClass == source) {
- val redeclaredMethod = new CtMethod(method, target, null);
- function1.process(redeclaredMethod);
- target.addMethod(redeclaredMethod);
- }
- }
+ finalClass as Class<? extends org.opendaylight.controller.sal.binding.api.NotificationListener<?>>);
}
- private def CtClass createClass(String fqn, ClassGenerator cls) {
- val target = classPool.makeClass(fqn);
- cls.process(target);
- return target;
- }
-
- private def CtClass createClass(String fqn, CtClass superInterface, ClassGenerator cls) {
- val target = classPool.makeClass(fqn);
- target.implementsType(superInterface);
- cls.process(target);
- return target;
- }
-
- private def void implementsType(CtClass it, CtClass supertype) {
- checkArgument(supertype.interface, "Supertype must be interface");
- addInterface(supertype);
- }
+
- private def asCtClass(Class<?> class1) {
- classPool.get(class1);
- }
- private def CtField field(CtClass it, String name, Class<?> returnValue) {
- val field = new CtField(returnValue.asCtClass, name, it);
- field.modifiers = Modifier.PUBLIC
- addField(field);
- return field;
- }
-
- def get(ClassPool pool, Class<?> cls) {
- try {
- return pool.get(cls.name)
- } catch (NotFoundException e) {
- pool.appendClassPath(new LoaderClassPath(cls.classLoader));
- try {
- return pool.get(cls.name)
-
- } catch (NotFoundException ef) {
- pool.appendClassPath(new ClassClassPath(cls));
- return pool.get(cls.name)
- }
- }
- }
protected def resolveInvokerClass(Class<? extends NotificationListener> class1) {
- val invoker = invokerClasses.get(class1);
- if (invoker !== null) {
- return invoker;
- }
- val newInvoker = generateListenerInvoker(class1);
- invokerClasses.put(class1, newInvoker);
- return newInvoker
+ return <RuntimeGeneratedInvokerPrototype>withClassLoaderAndLock(class1.classLoader,lock) [|
+ val invoker = invokerClasses.get(class1);
+ if (invoker !== null) {
+ return invoker;
+ }
+ val newInvoker = generateListenerInvoker(class1);
+ invokerClasses.put(class1, newInvoker);
+ return newInvoker
+
+ ]
}
}
val NotificationListener delegate;
@Property
- var org.opendaylight.controller.sal.binding.api.NotificationListener invocationProxy;
+ var org.opendaylight.controller.sal.binding.api.NotificationListener<Notification> invocationProxy;
@Property
var RuntimeGeneratedInvokerPrototype prototype;
new(NotificationListener delegate, RuntimeGeneratedInvokerPrototype prototype) {
_delegate = delegate;
_prototype = prototype;
- _invocationProxy = prototype.protoClass.newInstance;
+ _invocationProxy = prototype.protoClass.newInstance as org.opendaylight.controller.sal.binding.api.NotificationListener<Notification>;
RuntimeCodeHelper.setDelegate(_invocationProxy, delegate);
}
val Set<Class<? extends Notification>> supportedNotifications;
@Property
- val Class<? extends org.opendaylight.controller.sal.binding.api.NotificationListener> protoClass;
+ val Class<? extends org.opendaylight.controller.sal.binding.api.NotificationListener<?>> protoClass;
}
package class RpcServiceMetadata {