2 * Copyright (c) 2014 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.md.sal.dom.store.impl.tree;
10 import com.google.common.base.Optional;
11 import java.lang.ref.Reference;
12 import java.lang.ref.WeakReference;
13 import java.util.ArrayList;
14 import java.util.Collection;
15 import java.util.HashMap;
17 import org.opendaylight.controller.md.sal.dom.store.impl.DataChangeListenerRegistration;
18 import org.opendaylight.controller.md.sal.dom.store.impl.tree.ListenerTree.DataChangeListenerRegistrationImpl;
19 import org.opendaylight.yangtools.concepts.Identifiable;
20 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.PathArgument;
21 import org.opendaylight.yangtools.yang.data.api.schema.tree.StoreTreeNode;
22 import org.slf4j.Logger;
23 import org.slf4j.LoggerFactory;
26 * This is a single node within the listener tree. Note that the data returned from
27 * and instance of this class is guaranteed to have any relevance or consistency
28 * only as long as the {@link ListenerWalker} instance through which it is reached remains
31 * @author Robert Varga
33 public class ListenerNode implements StoreTreeNode<ListenerNode>, Identifiable<PathArgument> {
35 private static final Logger LOG = LoggerFactory.getLogger(ListenerNode.class);
37 private final Collection<DataChangeListenerRegistration<?>> listeners = new ArrayList<>();
38 private final Map<PathArgument, ListenerNode> children = new HashMap<>();
39 private final PathArgument identifier;
40 private final Reference<ListenerNode> parent;
42 ListenerNode(final ListenerNode parent, final PathArgument identifier) {
43 this.parent = new WeakReference<>(parent);
44 this.identifier = identifier;
48 public PathArgument getIdentifier() {
53 public Optional<ListenerNode> getChild(final PathArgument child) {
54 return Optional.fromNullable(children.get(child));
58 * Return the list of current listeners. This collection is guaranteed
59 * to be immutable only while the walker, through which this node is
60 * reachable remains unclosed.
62 * @return the list of current listeners
64 public Collection<DataChangeListenerRegistration<?>> getListeners() {
68 ListenerNode ensureChild(final PathArgument child) {
69 ListenerNode potential = children.get(child);
70 if (potential == null) {
71 potential = new ListenerNode(this, child);
72 children.put(child, potential);
77 void addListener(final DataChangeListenerRegistration<?> listener) {
78 listeners.add(listener);
79 LOG.debug("Listener {} registered", listener);
82 void removeListener(final DataChangeListenerRegistrationImpl<?> listener) {
83 listeners.remove(listener);
84 LOG.debug("Listener {} unregistered", listener);
86 // We have been called with the write-lock held, so we can perform some cleanup.
90 private void removeThisIfUnused() {
91 final ListenerNode p = parent.get();
92 if (p != null && listeners.isEmpty() && children.isEmpty()) {
93 p.removeChild(identifier);
97 private void removeChild(final PathArgument arg) {
103 public String toString() {
104 return "Node [identifier=" + identifier + ", listeners=" + listeners.size() + ", children=" + children.size() + "]";