/* * Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved. * * This program and the accompanying materials are made available under the * terms of the Eclipse Public License v1.0 which accompanies this distribution, * and is available at http://www.eclipse.org/legal/epl-v10.html */ package org.opendaylight.yangtools.yang.parser.stmt.reactor; import java.util.ArrayList; import java.util.Iterator; import java.util.List; import java.util.Map; import org.opendaylight.yangtools.yang.model.api.meta.IdentifierNamespace; import org.opendaylight.yangtools.yang.parser.spi.meta.NamespaceBehaviour; abstract class NamespaceBehaviourWithListeners<K, V, N extends IdentifierNamespace<K, V>> extends NamespaceBehaviour<K, V, N> { abstract static class ValueAddedListener<K> { private final NamespaceStorageNode ctxNode; private K key; public ValueAddedListener(final NamespaceStorageNode contextNode, K key) { this.ctxNode = contextNode; this.key = key; } public NamespaceStorageNode getCtxNode() { return ctxNode; } public K getKey() { return key; } void trigger(Object value) { onValueAdded(key, value); } abstract void onValueAdded(Object key, Object value); } protected final NamespaceBehaviour<K, V, N> delegate; private final List<VirtualNamespaceContext<?, V, ?, K>> derivedNamespaces = new ArrayList<>(); protected NamespaceBehaviourWithListeners(final NamespaceBehaviour<K, V, N> delegate) { super(delegate.getIdentifier()); this.delegate = delegate; } protected abstract void addListener(K key, ValueAddedListener<K> listener); protected abstract boolean isRequestedValue(ValueAddedListener<K> listener, NamespaceStorageNode storage, V value); @Override public abstract void addTo(final NamespaceStorageNode storage, final K key, final V value); protected void notifyListeners(final NamespaceStorageNode storage, Iterator<ValueAddedListener<K>> keyListeners, final V value) { List<ValueAddedListener<K>> toNotify = new ArrayList<>(); while (keyListeners.hasNext()) { ValueAddedListener<K> listener = keyListeners.next(); if (isRequestedValue(listener, storage, value)) { keyListeners.remove(); toNotify.add(listener); } } for (ValueAddedListener<K> listener : toNotify) { listener.trigger(value); } } protected void notifyDerivedNamespaces(final NamespaceStorageNode storage, final K key, final V value) { for (VirtualNamespaceContext<?, V, ?, K> derived : derivedNamespaces) { derived.addedToSourceNamespace(storage, key, value); } } final void addValueListener(final ValueAddedListener<K> listener) { addListener(listener.key, listener); } final void addDerivedNamespace(VirtualNamespaceContext<?, V, ?, K> namespace) { derivedNamespaces.add(namespace); } @Override public V getFrom(final NamespaceStorageNode storage, final K key) { return delegate.getFrom(storage, key); } @Override public Map<K, V> getAllFrom(final NamespaceStorageNode storage) { return delegate.getAllFrom(storage); } }