Add missing copyright text
[controller.git] / opendaylight / md-sal / sal-binding-broker / src / main / java / org / opendaylight / controller / sal / binding / codegen / impl / RpcRouterCodegenInstance.java
index 052fd2169a523b955a427f036e2a0ab6b7a03bc4..d69aeed3523a660177774826a25be1db2f2974c7 100644 (file)
@@ -8,11 +8,14 @@
 package org.opendaylight.controller.sal.binding.codegen.impl;
 
 import static org.opendaylight.controller.sal.binding.codegen.RuntimeCodeHelper.setRoutingTable;
-
+import com.google.common.collect.ImmutableMap;
+import com.google.common.collect.ImmutableSet;
+import java.util.ArrayList;
+import java.util.Collection;
 import java.util.HashMap;
 import java.util.Map;
 import java.util.Set;
-
+import javax.annotation.concurrent.GuardedBy;
 import org.opendaylight.controller.md.sal.common.api.routing.RouteChange;
 import org.opendaylight.controller.md.sal.common.api.routing.RouteChangeListener;
 import org.opendaylight.controller.sal.binding.api.BindingAwareBroker.RoutedRpcRegistration;
@@ -22,23 +25,18 @@ import org.opendaylight.controller.sal.binding.api.rpc.RpcRoutingTable;
 import org.opendaylight.controller.sal.binding.codegen.RuntimeCodeHelper;
 import org.opendaylight.yangtools.concepts.AbstractObjectRegistration;
 import org.opendaylight.yangtools.concepts.ListenerRegistration;
-import org.opendaylight.yangtools.concepts.util.ListenerRegistry;
+import org.opendaylight.yangtools.util.ListenerRegistry;
 import org.opendaylight.yangtools.yang.binding.BaseIdentity;
 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
 import org.opendaylight.yangtools.yang.binding.RpcService;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-import com.google.common.collect.ImmutableMap;
-import com.google.common.collect.ImmutableSet;
-
 public class RpcRouterCodegenInstance<T extends RpcService> implements //
 RpcRouter<T>, RouteChangeListener<Class<? extends BaseIdentity>, InstanceIdentifier<?>> {
 
     private static final Logger LOG = LoggerFactory.getLogger(RpcRouterCodegenInstance.class);
 
-    private T defaultService;
-
     private final Class<T> serviceType;
 
     private final T invocationProxy;
@@ -49,11 +47,8 @@ RpcRouter<T>, RouteChangeListener<Class<? extends BaseIdentity>, InstanceIdentif
 
     private final Map<Class<? extends BaseIdentity>, RpcRoutingTableImpl<? extends BaseIdentity, T>> routingTables;
 
-    private final String name;
-
     @SuppressWarnings("unchecked")
     public RpcRouterCodegenInstance(final String name,final Class<T> type, final T routerImpl, final Iterable<Class<? extends BaseIdentity>> contexts) {
-        this.name = name;
         this.listeners = ListenerRegistry.create();
         this.serviceType = type;
         this.invocationProxy = routerImpl;
@@ -90,7 +85,7 @@ RpcRouter<T>, RouteChangeListener<Class<? extends BaseIdentity>, InstanceIdentif
 
     @Override
     public T getDefaultService() {
-        return defaultService;
+        return RuntimeCodeHelper.getDelegate(invocationProxy);
     }
 
     @Override
@@ -125,14 +120,27 @@ RpcRouter<T>, RouteChangeListener<Class<? extends BaseIdentity>, InstanceIdentif
         return new RoutedRpcRegistrationImpl(service);
     }
 
+    public void removeDefaultImplementation(final T instance) {
+        RpcService current = RuntimeCodeHelper.getDelegate(invocationProxy);
+        if(instance == current) {
+            RuntimeCodeHelper.setDelegate(invocationProxy, null);
+        }
+    }
+
     @Override
     public RpcRegistration<T> registerDefaultService(final T service) {
-        // TODO Auto-generated method stub
         RuntimeCodeHelper.setDelegate(invocationProxy, service);
-        return null;
+        return new DefaultRpcImplementationRegistration(service);
     }
 
-    private class RoutedRpcRegistrationImpl extends AbstractObjectRegistration<T> implements RoutedRpcRegistration<T> {
+    private final class RoutedRpcRegistrationImpl extends AbstractObjectRegistration<T> implements RoutedRpcRegistration<T> {
+        /*
+         * FIXME: retaining this collection is not completely efficient. We really should be storing
+         *        a reference to this registration, as a particular listener may be registered multiple
+         *        times -- and then this goes kaboom in various aspects.
+         */
+        @GuardedBy("this")
+        private final Collection<Class<? extends BaseIdentity>> contexts = new ArrayList<>(1);
 
         public RoutedRpcRegistrationImpl(final T instance) {
             super(instance);
@@ -144,28 +152,65 @@ RpcRouter<T>, RouteChangeListener<Class<? extends BaseIdentity>, InstanceIdentif
         }
 
         @Override
-        public void registerPath(final Class<? extends BaseIdentity> context, final InstanceIdentifier<?> path) {
+        public synchronized void registerPath(final Class<? extends BaseIdentity> context, final InstanceIdentifier<?> path) {
+            if (isClosed()) {
+                LOG.debug("Closed registration of {} ignoring new path {}", getInstance(), path);
+                return;
+            }
+
             routingTables.get(context).updateRoute(path, getInstance());
+            contexts.add(context);
         }
 
         @Override
-        public void unregisterPath(final Class<? extends BaseIdentity> context, final InstanceIdentifier<?> path) {
+        public synchronized void unregisterPath(final Class<? extends BaseIdentity> context, final InstanceIdentifier<?> path) {
+            if (isClosed()) {
+                LOG.debug("Closed unregistration of {} ignoring new path {}", getInstance(), path);
+                return;
+            }
+
             routingTables.get(context).removeRoute(path, getInstance());
+            contexts.remove(context);
         }
 
+        @Deprecated
         @Override
         public void registerInstance(final Class<? extends BaseIdentity> context, final InstanceIdentifier<?> instance) {
             registerPath(context, instance);
         }
 
+        @Deprecated
         @Override
         public void unregisterInstance(final Class<? extends BaseIdentity> context, final InstanceIdentifier<?> instance) {
             unregisterPath(context, instance);
         }
 
+        @Override
+        protected synchronized void removeRegistration() {
+            for (Class<? extends BaseIdentity> ctx : contexts) {
+                routingTables.get(ctx).removeAllReferences(getInstance());
+            }
+            contexts.clear();
+        }
+    }
+
+    private final class DefaultRpcImplementationRegistration extends AbstractObjectRegistration<T> implements RpcRegistration<T> {
+
+
+        protected DefaultRpcImplementationRegistration(final T instance) {
+            super(instance);
+        }
+
         @Override
         protected void removeRegistration() {
+            removeDefaultImplementation(this.getInstance());
+        }
 
+        @Override
+        public Class<T> getServiceType() {
+            return serviceType;
         }
     }
+
+
 }