2 * Copyright (c) 2013 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.controller.sal.binding.codegen.impl
11 import javassist.ClassPool
12 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier
13 import org.opendaylight.yangtools.yang.binding.Notification
14 import org.opendaylight.yangtools.yang.binding.RpcImplementation
15 import org.opendaylight.yangtools.yang.binding.util.BindingReflections
16 import org.opendaylight.yangtools.yang.binding.util.ClassLoaderUtils
18 import static extension org.opendaylight.controller.sal.binding.codegen.RuntimeCodeSpecification.*
19 import org.opendaylight.yangtools.yang.binding.RpcService
21 class RuntimeCodeGenerator extends AbstractRuntimeCodeGenerator {
27 override directProxySupplier(Class iface) {
29 val proxyName = iface.directProxyName;
30 val potentialClass = ClassLoaderUtils.tryToLoadClassWithTCCL(proxyName)
31 if(potentialClass != null) {
32 return potentialClass.newInstance as RpcService;
34 val supertype = iface.asCtClass
35 val createdCls = createClass(iface.directProxyName, supertype) [
36 field(DELEGATE_FIELD, iface);
37 implementsType(RpcImplementation.asCtClass)
38 implementMethodsFrom(supertype) [
41 if(«DELEGATE_FIELD» == null) {
42 throw new java.lang.IllegalStateException("No default provider is available");
44 return ($r) «DELEGATE_FIELD».«it.name»($$);
48 implementMethodsFrom(RpcImplementation.asCtClass) [
51 throw new java.lang.IllegalStateException("No provider is processing supplied message");
57 return createdCls.toClass(iface.classLoader).newInstance as RpcService
61 override routerSupplier(Class iface, RpcServiceMetadata metadata) {
63 val supertype = iface.asCtClass
64 val routerName = iface.routerName;
65 val potentialClass = ClassLoaderUtils.tryToLoadClassWithTCCL(routerName)
66 if(potentialClass != null) {
67 return potentialClass.newInstance as RpcService;
70 val targetCls = createClass(iface.routerName, supertype) [
73 field(DELEGATE_FIELD, iface)
74 //field(REMOTE_INVOKER_FIELD,iface);
75 implementsType(RpcImplementation.asCtClass)
77 for (ctx : metadata.contexts) {
78 field(ctx.routingTableField, Map)
80 implementMethodsFrom(supertype) [
81 if (parameterTypes.size === 1) {
82 val rpcMeta = metadata.getRpcMethod(name);
86 throw new IllegalArgumentException("RPC input must not be null and must contain a value for field «rpcMeta.inputRouteGetter.name»");
88 if($1.«rpcMeta.inputRouteGetter.name»() == null) {
89 throw new IllegalArgumentException("Field «rpcMeta.inputRouteGetter.name» must not be null");
91 final «InstanceIdentifier.name» identifier = $1.«rpcMeta.inputRouteGetter.name»()«IF rpcMeta.
92 routeEncapsulated».getValue()«ENDIF»;
93 «supertype.name» instance = («supertype.name») «rpcMeta.context.routingTableField».get(identifier);
94 if(instance == null) {
95 instance = «DELEGATE_FIELD»;
97 if(instance == null) {
98 throw new java.lang.IllegalStateException("No routable provider is processing routed message for " + String.valueOf(identifier));
100 return ($r) instance.«it.name»($$);
103 } else if (parameterTypes.size === 0) {
104 body = '''return ($r) «DELEGATE_FIELD».«it.name»($$);'''
107 implementMethodsFrom(RpcImplementation.asCtClass) [
110 throw new java.lang.IllegalStateException("No provider is processing supplied message");
116 return targetCls.toClass(iface.classLoader,iface.protectionDomain).newInstance as RpcService
120 override generateListenerInvoker(Class iface) {
121 val callbacks = iface.methods.filter[BindingReflections.isNotificationCallback(it)]
123 val supportedNotification = callbacks.map[parameterTypes.get(0) as Class<? extends Notification>].toSet;
125 val targetCls = createClass(iface.invokerName, brokerNotificationListener) [
126 field(DELEGATE_FIELD, iface)
127 implementMethodsFrom(brokerNotificationListener) [
130 «FOR callback : callbacks SEPARATOR " else "»
131 «val cls = callback.parameterTypes.get(0).name»
132 if($1 instanceof «cls») {
133 «DELEGATE_FIELD».«callback.name»((«cls») $1);
142 val finalClass = targetCls.toClass(iface.classLoader, iface.protectionDomain)
143 return new RuntimeGeneratedInvokerPrototype(supportedNotification,
144 finalClass as Class<? extends org.opendaylight.controller.sal.binding.api.NotificationListener<?>>);