/* * 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.groupbasedpolicy.util; import static com.google.common.base.Preconditions.checkNotNull; import java.util.Collection; import org.opendaylight.controller.md.sal.binding.api.ClusteredDataTreeChangeListener; import org.opendaylight.controller.md.sal.binding.api.DataBroker; import org.opendaylight.controller.md.sal.binding.api.DataObjectModification; import org.opendaylight.controller.md.sal.binding.api.DataObjectModification.ModificationType; import org.opendaylight.controller.md.sal.binding.api.DataTreeIdentifier; import org.opendaylight.controller.md.sal.binding.api.DataTreeModification; import org.opendaylight.yangtools.concepts.ListenerRegistration; import org.opendaylight.yangtools.yang.binding.DataObject; import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; /** * The purpose of this class is to eliminate boilerplate code used in most of * {@link ClusteredDataTreeChangeListener} implementations. * * @param <T> target class */ public abstract class DataTreeChangeHandler<T extends DataObject> implements ClusteredDataTreeChangeListener<T>, AutoCloseable { protected final DataBroker dataProvider; protected ListenerRegistration<DataTreeChangeHandler<T>> registeredListener; /** * * @param dataProvider cannot be {@code null} * @throws NullPointerException if <b>dataProvider</b> is {@code null} */ protected DataTreeChangeHandler(DataBroker dataProvider) { this.dataProvider = checkNotNull(dataProvider); } /** * * @param pointOfInterest identifier of root node * @throws NullPointerException if <b>pointOfInterest</b> is {@code null} */ protected void registerDataTreeChangeListener(DataTreeIdentifier<T> pointOfInterest) { registeredListener = dataProvider.registerDataTreeChangeListener(checkNotNull(pointOfInterest), this); } @Override public void onDataTreeChanged(Collection<DataTreeModification<T>> changes) { for (DataTreeModification<T> change : changes) { DataObjectModification<T> rootNode = change.getRootNode(); InstanceIdentifier<T> rootIdentifier = change.getRootPath().getRootIdentifier(); switch (rootNode.getModificationType()) { case WRITE: onWrite(rootNode, rootIdentifier); break; case DELETE: onDelete(rootNode, rootIdentifier); break; case SUBTREE_MODIFIED: onSubtreeModified(rootNode, rootIdentifier); break; } } } /** * Handles case where {@link DataObjectModification#getModificationType()} is * {@link ModificationType#WRITE}. <br> * <b>Parameters of this method are never {@code null}.</b> * * @param rootNode represents {@link DataObjectModification} as result of * {@link DataTreeModification#getRootNode()} * @param rootIdentifier represents {@link InstanceIdentifier} obtained from result of * {@link DataTreeModification#getRootPath()} */ protected abstract void onWrite(DataObjectModification<T> rootNode, InstanceIdentifier<T> rootIdentifier); /** * Handles case where {@link DataObjectModification#getModificationType()} is * {@link ModificationType#DELETE}. <br> * <b>Parameters of this method are never {@code null}.</b> * * @param rootNode represents {@link DataObjectModification} as result of * {@link DataTreeModification#getRootNode()} * @param rootIdentifier represents {@link InstanceIdentifier} obtained from result of * {@link DataTreeModification#getRootPath()} */ protected abstract void onDelete(DataObjectModification<T> rootNode, InstanceIdentifier<T> rootIdentifier); /** * Handles case where {@link DataObjectModification#getModificationType()} is * {@link ModificationType#SUBTREE_MODIFIED}. <br> * <b>Parameters of this method are never {@code null}.</b> * * @param rootNode represents {@link DataObjectModification} as result of * {@link DataTreeModification#getRootNode()} * @param rootIdentifier represents {@link InstanceIdentifier} obtained from result of * {@link DataTreeModification#getRootPath()} */ protected abstract void onSubtreeModified(DataObjectModification<T> rootNode, InstanceIdentifier<T> rootIdentifier); @Override public void close() { closeRegisteredListener(); } /** * For child classes which override close() method. */ protected void closeRegisteredListener() { registeredListener.close(); } }