/* * CDDL HEADER START * * The contents of this file are subject to the terms of the * Common Development and Distribution License, Version 1.0 only * (the "License"). You may not use this file except in compliance * with the License. * * You can obtain a copy of the license at legal-notices/CDDLv1_0.txt * or http://forgerock.org/license/CDDLv1.0.html. * See the License for the specific language governing permissions * and limitations under the License. * * When distributing Covered Code, include this CDDL HEADER in each * file and include the License file at legal-notices/CDDLv1_0.txt. * If applicable, add the following below this CDDL HEADER, with the * fields enclosed by brackets "[]" replaced with your own identifying * information: * Portions Copyright [yyyy] [name of copyright owner] * * CDDL HEADER END * * * Copyright 2008 Sun Microsystems, Inc. * Portions copyright 2015 ForgeRock AS */ package org.forgerock.opendj.config.server; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.forgerock.opendj.config.server.spi.ConfigAddListener; import org.forgerock.opendj.config.server.spi.ConfigDeleteListener; import org.forgerock.opendj.config.server.spi.ConfigurationRepository; import org.forgerock.opendj.ldap.DN; import org.forgerock.opendj.ldap.Entry; import org.forgerock.i18n.LocalizableMessageBuilder; /** * A configuration add listener which will monitor a parent entry to see when a * specified child entry has been added. When the child entry is added the add * listener will automatically register its "delayed" add or delete listener. */ final class DelayedConfigAddListener implements ConfigAddListener { private static final Logger debugLogger = LoggerFactory.getLogger(DelayedConfigAddListener.class); /** The name of the parent entry. */ private final DN parent; /** * The name of the subordinate entry which should have an add or * delete listener registered with it when it is created. */ private final DN child; /** * The add listener to be registered with the subordinate entry when * it is added (or null if a delete listener should be registered). */ private final ConfigAddListener delayedAddListener; /** * The delete listener to be registered with the subordinate entry * when it is added (or null if an add listener should be registered). */ private final ConfigDeleteListener delayedDeleteListener; private final ConfigurationRepository configRepository; /** * Create a new delayed add listener which will register an add listener * with the specified entry when it is added. * * @param child * The name of the subordinate entry which should have an add * listener registered with it when it is created. * @param addListener * The add listener to be added to the subordinate entry when it * is added. * @param configRepository * Repository of config entries. */ public DelayedConfigAddListener(DN child, ConfigAddListener addListener, ConfigurationRepository configRepository) { this.parent = child.parent(); this.child = child; this.delayedAddListener = addListener; this.delayedDeleteListener = null; this.configRepository = configRepository; } /** * Create a new delayed add listener which will register a delete listener * with the specified entry when it is added. * * @param child * The name of the subordinate entry which should have a delete * listener registered with it when it is created. * @param deleteListener * The delete listener to be added to the subordinate entry when * it is added. * @param configRepository * Repository of config entries. */ public DelayedConfigAddListener(DN child, ConfigDeleteListener deleteListener, ConfigurationRepository configRepository) { this.parent = child.parent(); this.child = child; this.delayedAddListener = null; this.configRepository = configRepository; this.delayedDeleteListener = deleteListener; } /** {@inheritDoc} */ @Override public ConfigChangeResult applyConfigurationAdd(Entry configEntry) { if (configEntry.getName().equals(child)) { // The subordinate entry matched our criteria so register the // listener(s). if (delayedAddListener != null) { configRepository.registerAddListener(configEntry.getName(), delayedAddListener); } if (delayedDeleteListener != null) { configRepository.registerDeleteListener(configEntry.getName(), delayedDeleteListener); } try { // We are no longer needed. if (configRepository.hasEntry(parent)) { configRepository.deregisterAddListener(parent, this); } } catch (ConfigException e) { debugLogger.trace("Unable to deregister add listener", e); // Ignore this error as it implies that this listener has // already been deregistered. } } return new ConfigChangeResult(); } /** {@inheritDoc} */ @Override public boolean configAddIsAcceptable(Entry configEntry, LocalizableMessageBuilder unacceptableReason) { // Always acceptable. return true; } /** * Gets the delayed add listener. * <p> * This method is provided for unit-testing. * * @return Returns the delayed add listener, or <code>null</code> if this * listener is delaying a delete listener. */ ConfigAddListener getDelayedAddListener() { return delayedAddListener; } /** * Gets the delayed delete listener. * <p> * This method is provided for unit-testing. * * @return Returns the delayed delete listener, or <code>null</code> if this * listener is delaying a add listener. */ ConfigDeleteListener getDelayedDeleteListener() { return delayedDeleteListener; } }