1 package org.opendaylight.controller.md.sal.dom.store.impl.tree;
3 import java.util.HashMap;
4 import java.util.HashSet;
7 import org.opendaylight.controller.md.sal.common.api.data.AsyncDataBroker.DataChangeScope;
8 import org.opendaylight.controller.md.sal.common.api.data.AsyncDataChangeListener;
9 import org.opendaylight.yangtools.concepts.AbstractObjectRegistration;
10 import org.opendaylight.yangtools.concepts.Identifiable;
11 import org.opendaylight.yangtools.concepts.ListenerRegistration;
12 import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier;
13 import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier.PathArgument;
14 import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
16 import com.google.common.base.Optional;
18 public class ListenerRegistrationNode implements StoreTreeNode<ListenerRegistrationNode>,Identifiable<PathArgument> {
20 private final ListenerRegistrationNode parent;
21 private final Map<PathArgument, ListenerRegistrationNode> children;
22 private final PathArgument identifier;
23 private final HashSet<DataChangeListenerRegistration<?>> listeners;
25 private ListenerRegistrationNode(final PathArgument identifier) {
26 this(null,identifier);
29 private ListenerRegistrationNode(final ListenerRegistrationNode parent,final PathArgument identifier) {
31 this.identifier = identifier;
32 children = new HashMap<>();
33 listeners = new HashSet<>();
36 public final static ListenerRegistrationNode createRoot() {
37 return new ListenerRegistrationNode(null);
41 public PathArgument getIdentifier() {
45 public Iterable<DataChangeListenerRegistration<?>> getListeners() {
50 public synchronized Optional<ListenerRegistrationNode> getChild(final PathArgument child) {
51 ListenerRegistrationNode potential = (children.get(child));
52 if(potential == null) {
53 potential = new ListenerRegistrationNode(this, child);
54 children.put(child, potential);
56 return Optional.of(potential);
59 public <L extends AsyncDataChangeListener<InstanceIdentifier, NormalizedNode<?, ?>>> ListenerRegistration<L> registerDataChangeListener(
60 final L listener, final DataChangeScope scope) {
61 DataChangeListenerRegistration<L> listenerReg = new DataChangeListenerRegistration<L>(listener, scope,this);
62 listeners.add(listenerReg);
66 private void removeListener(final DataChangeListenerRegistration<?> listener) {
67 listeners.remove(listener);
72 private void removeThisIfUnused() {
73 if(parent != null && listeners.isEmpty() && children.isEmpty()) {
74 parent.removeChildIfUnused(this);
78 public boolean isUnused() {
79 return (listeners.isEmpty() && children.isEmpty()) || areChildrenUnused();
82 private boolean areChildrenUnused() {
83 for(ListenerRegistrationNode child : children.values()) {
84 if(!child.isUnused()) {
91 private void removeChildIfUnused(final ListenerRegistrationNode listenerRegistrationNode) {
92 // FIXME Remove unnecessary
98 public static class DataChangeListenerRegistration<T extends AsyncDataChangeListener<InstanceIdentifier, NormalizedNode<?, ?>>> extends AbstractObjectRegistration<T>
99 implements ListenerRegistration<T> {
101 private final DataChangeScope scope;
102 private ListenerRegistrationNode node;
104 public DataChangeListenerRegistration(final T listener, final DataChangeScope scope, final ListenerRegistrationNode node) {
111 protected DataChangeScope getScope() {
116 protected void removeRegistration() {
117 node.removeListener(this);