001/* 002 * The contents of this file are subject to the terms of the Common Development and 003 * Distribution License (the License). You may not use this file except in compliance with the 004 * License. 005 * 006 * You can obtain a copy of the License at legal/CDDLv1.0.txt. See the License for the 007 * specific language governing permission and limitations under the License. 008 * 009 * When distributing Covered Software, include this CDDL Header Notice in each file and include 010 * the License file at legal/CDDLv1.0.txt. If applicable, add the following below the CDDL 011 * Header, with the fields enclosed by brackets [] replaced by your own identifying 012 * information: "Portions Copyright [year] [name of copyright owner]". 013 * 014 * Copyright 2008-2009 Sun Microsystems, Inc. 015 * Portions Copyright 2013-2015 ForgeRock AS. 016 */ 017package org.forgerock.opendj.server.core; 018 019import java.util.List; 020import java.util.Set; 021import java.util.concurrent.CopyOnWriteArrayList; 022 023import org.forgerock.i18n.LocalizableMessage; 024import org.forgerock.opendj.ldap.DN; 025import org.forgerock.opendj.ldap.LdapException; 026import org.slf4j.Logger; 027import org.slf4j.LoggerFactory; 028 029/** 030 * This class provides a skeletal implementation of the {@link DataProvider} 031 * interface, to minimize the effort required to implement this interface. 032 */ 033public abstract class AbstractDataProvider implements DataProvider { 034 private static final Logger debugLogger = LoggerFactory.getLogger(AbstractDataProvider.class); 035 036 /** The list of event listeners associated with this data provider. */ 037 private final List<DataProviderEventListener> eventListeners = new CopyOnWriteArrayList<>(); 038 039 /** Creates a new abstract data provider. */ 040 protected AbstractDataProvider() { 041 // No implementation required. 042 } 043 044 /** 045 * {@inheritDoc} 046 * <p> 047 * The default implementation is to invoke {@code getEntry(dn)} and return 048 * {@code true} if the entry was successfully retrieved. 049 */ 050 @Override 051 public boolean containsEntry(final DN dn) throws LdapException { 052 return getEntry(dn) != null; 053 } 054 055 /** {@inheritDoc} */ 056 @Override 057 public final void deregisterEventListener(final DataProviderEventListener listener) { 058 eventListeners.remove(listener); 059 } 060 061 /** {@inheritDoc} */ 062 @Override 063 public final void registerEventListener(final DataProviderEventListener listener) { 064 eventListeners.add(listener); 065 } 066 067 /** 068 * {@inheritDoc} 069 * <p> 070 * The default implementation is to return false for all base DNs indicating 071 * that change notification is not supported. 072 */ 073 @Override 074 public boolean supportsChangeNotification(final DN baseDN) throws LdapException { 075 return false; 076 } 077 078 /** 079 * Notify all event listeners that this data provider has changed state due 080 * to an operational error, configuration change, or an administrative 081 * action. 082 * <p> 083 * This method can be used to forward events to parent data providers. 084 * 085 * @param event 086 * The data provider event. 087 */ 088 protected final void notifyDataProviderEventOccurred(final DataProviderEvent event) { 089 for (final DataProviderEventListener listener : eventListeners) { 090 try { 091 listener.handleDataProviderEvent(event); 092 } catch (final Exception e) { 093 debugLogger.trace("Unexpected error occurred while invoking listener", e); 094 } 095 } 096 } 097 098 /** 099 * Notify all event listeners that this data provider has changed state due 100 * to an operational error, configuration change, or an administrative 101 * action. 102 * <p> 103 * This method is equivalent to the following code: 104 * 105 * <pre> 106 * DataProviderEvent event = new DataProviderEvent(reason, types); 107 * notifyDataProviderStateChanged(event); 108 * </pre> 109 * 110 * @param reason 111 * A message describing this event. 112 * @param types 113 * The types of event that have occurred in the data provider. 114 */ 115 protected final void notifyDataProviderEventOccurred(final LocalizableMessage reason, 116 final Set<DataProviderEvent.Type> types) { 117 final DataProviderEvent event = new DataProviderEvent(reason, types); 118 notifyDataProviderEventOccurred(event); 119 } 120 121}