X-Git-Url: https://git.opendaylight.org/gerrit/gitweb?a=blobdiff_plain;f=opendaylight%2Fmd-sal%2Fsal-dom-broker%2Fsrc%2Fmain%2Fjava%2Forg%2Fopendaylight%2Fcontroller%2Fmd%2Fsal%2Fdom%2Fstore%2Fimpl%2Ftree%2FListenerRegistrationNode.java;h=854c125af17a732f1d1c40365cb355ddae25a317;hb=accc07b1785811ed85038ac3c313c1d01724dc08;hp=d6d1ca309fc7eaa5b55ed83b52a07cb7f60c6506;hpb=822e5c6c51346ef6ca8254b5597b95742a05fc7d;p=controller.git diff --git a/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/tree/ListenerRegistrationNode.java b/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/tree/ListenerRegistrationNode.java index d6d1ca309f..854c125af1 100644 --- a/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/tree/ListenerRegistrationNode.java +++ b/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/tree/ListenerRegistrationNode.java @@ -1,36 +1,40 @@ package org.opendaylight.controller.md.sal.dom.store.impl.tree; +import java.util.Collection; import java.util.HashMap; +import java.util.HashSet; import java.util.Map; -import java.util.concurrent.ConcurrentSkipListSet; import org.opendaylight.controller.md.sal.common.api.data.AsyncDataBroker.DataChangeScope; import org.opendaylight.controller.md.sal.common.api.data.AsyncDataChangeListener; import org.opendaylight.yangtools.concepts.AbstractObjectRegistration; import org.opendaylight.yangtools.concepts.Identifiable; -import org.opendaylight.yangtools.concepts.ListenerRegistration; import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier; import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier.PathArgument; import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import com.google.common.base.Optional; -public class ListenerRegistrationNode implements StoreTreeNode,Identifiable { +public class ListenerRegistrationNode implements StoreTreeNode, Identifiable { + + private static final Logger LOG = LoggerFactory.getLogger(ListenerRegistrationNode.class); private final ListenerRegistrationNode parent; private final Map children; private final PathArgument identifier; - private final ConcurrentSkipListSet> listeners; + private final HashSet> listeners; private ListenerRegistrationNode(final PathArgument identifier) { - this(null,identifier); + this(null, identifier); } - private ListenerRegistrationNode(final ListenerRegistrationNode parent,final PathArgument identifier) { + private ListenerRegistrationNode(final ListenerRegistrationNode parent, final PathArgument identifier) { this.parent = parent; this.identifier = identifier; children = new HashMap<>(); - listeners = new ConcurrentSkipListSet<>(); + listeners = new HashSet<>(); } public final static ListenerRegistrationNode createRoot() { @@ -42,35 +46,58 @@ public class ListenerRegistrationNode implements StoreTreeNode> getListeners() { - return listeners; + /** + * Return the list of current listeners. Any caller wishing to use this method + * has to make sure the collection remains unchanged while it's executing. This + * means the caller has to synchronize externally both the registration and + * unregistration process. + * + * @return the list of current listeners + */ + @SuppressWarnings({ "rawtypes", "unchecked" }) + public Collection> getListeners() { + return (Collection) listeners; } @Override public synchronized Optional getChild(final PathArgument child) { + return Optional.fromNullable(children.get(child)); + } + + public synchronized ListenerRegistrationNode ensureChild(final PathArgument child) { ListenerRegistrationNode potential = (children.get(child)); - if(potential == null) { + if (potential == null) { potential = new ListenerRegistrationNode(this, child); children.put(child, potential); } - return Optional.of(potential); + return potential; } - public >> ListenerRegistration registerDataChangeListener( + /** + * Registers listener on this node. + * + * @param path Full path on which listener is registered. + * @param listener Listener + * @param scope Scope of triggering event. + * @return + */ + public synchronized >> DataChangeListenerRegistration registerDataChangeListener(final InstanceIdentifier path, final L listener, final DataChangeScope scope) { - DataChangeListenerRegistration listenerReg = new DataChangeListenerRegistration(listener, scope,this); + + DataChangeListenerRegistration listenerReg = new DataChangeListenerRegistration(path,listener, scope, this); listeners.add(listenerReg); + LOG.debug("Listener {} registered", listener); return listenerReg; } - private void removeListener(final DataChangeListenerRegistration listener) { + private synchronized void removeListener(final DataChangeListenerRegistration listener) { listeners.remove(listener); + LOG.debug("Listener {} unregistered", listener); removeThisIfUnused(); } - private void removeThisIfUnused() { - if(parent != null && listeners.isEmpty() && children.isEmpty()) { + if (parent != null && listeners.isEmpty() && children.isEmpty()) { parent.removeChildIfUnused(this); } } @@ -80,8 +107,8 @@ public class ListenerRegistrationNode implements StoreTreeNode>> extends AbstractObjectRegistration - implements ListenerRegistration { + public static class DataChangeListenerRegistration>> + extends AbstractObjectRegistration implements + org.opendaylight.controller.md.sal.dom.store.impl.DataChangeListenerRegistration { private final DataChangeScope scope; private ListenerRegistrationNode node; + private final InstanceIdentifier path; - public DataChangeListenerRegistration(final T listener, final DataChangeScope scope, final ListenerRegistrationNode node) { + public DataChangeListenerRegistration(final InstanceIdentifier path,final T listener, final DataChangeScope scope, + final ListenerRegistrationNode node) { super(listener); - + this.path = path; this.scope = scope; this.node = node; } - protected DataChangeScope getScope() { + @Override + public DataChangeScope getScope() { return scope; } @@ -117,5 +145,10 @@ public class ListenerRegistrationNode implements StoreTreeNode