SubentryManager.java revision 977c119be44776249cd87ed32e1f678978f3ad7d
/*
* 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
* 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 2009-2010 Sun Microsystems, Inc.
* Portions Copyright 2011-2015 ForgeRock AS
*/
/**
* This class provides a mechanism for interacting with subentries defined in
* the Directory Server. It will handle all necessary processing at server
* startup to identify and load subentries within the server.
* <BR><BR>
* FIXME: At the present time, it assumes that all of the necessary
* information about subentries defined in the server can be held in
* memory. If it is determined that this approach is not workable
* in all cases, then we will need an alternate strategy.
*/
public class SubentryManager extends InternalDirectoryServerPlugin
implements BackendInitializationListener
{
/** A mapping between the DNs and applicable subentries. */
/** A mapping between the DNs and applicable collective subentries. */
/** A mapping between subentry DNs and subentry objects. */
/** Internal search all operational attributes. */
/** Lock to protect internal data structures. */
private final ReadWriteLock lock;
/** The set of change notification listeners. */
/** Dummy configuration DN for Subentry Manager. */
/**
* Creates a new instance of this subentry manager.
*
* @throws DirectoryException If a problem occurs while
* creating an instance of
* the subentry manager.
*/
public SubentryManager() throws DirectoryException
{
true);
lock = new ReentrantReadWriteLock();
dn2SubEntry = new HashMap<>();
dn2CollectiveSubEntry = new HashMap<>();
dit2SubEntry = new DITCacheMap<>();
changeListeners = new CopyOnWriteArrayList<>();
requestAttrs = new LinkedHashSet<>();
}
/**
* Perform any required finalization tasks for Subentry Manager.
* This should only be called at Directory Server shutdown.
*/
public void finalizeSubentryManager()
{
// Deregister as internal plugin and
// backend initialization listener.
}
/**
* Registers the provided change notification listener with this manager
* so that it will be notified of any add, delete, modify, or modify DN
* operations that are performed.
*
* @param changeListener The change notification listener to register
* with this manager.
*/
public void registerChangeListener(
{
}
/**
* Deregisters the provided change notification listener with this manager
* so that it will no longer be notified of any add, delete, modify, or
* modify DN operations that are performed.
*
* @param changeListener The change notification listener to deregister
* with this manager.
*/
public void deregisterChangeListener(
{
}
/**
* Add a given entry to this subentry manager.
* @param entry to add.
*/
{
try
{
{
}
else
{
}
{
{
}
else
{
}
}
}
finally
{
}
}
/**
* Remove a given entry from this subentry manager.
* @param entry to remove.
*/
{
try
{
boolean removed = false;
while (setIterator.hasNext())
{
while (listIterator.hasNext())
{
{
removed = true;
break;
}
}
{
}
if (removed)
{
return;
}
}
while (setIterator.hasNext())
{
while (listIterator.hasNext())
{
{
removed = true;
break;
}
}
{
}
if (removed)
{
return;
}
}
}
finally
{
}
}
/**
* {@inheritDoc} In this case, the server will search the backend to find
* all subentries that it may contain and register them with this manager.
*/
{
try
{
")");
{
}
}
catch (Exception e)
{
logger.traceException(e);
}
{
try
{
{
continue;
}
}
catch (Exception e)
{
logger.traceException(e);
// FIXME -- Is there anything that we need to do here?
continue;
}
try
{
}
catch (Exception e)
{
logger.traceException(e);
// FIXME -- Is there anything that we need to do here?
continue;
}
{
{
try
{
// Notify change listeners.
{
try
{
}
catch (Exception e)
{
logger.traceException(e);
}
}
}
catch (Exception e)
{
logger.traceException(e);
// FIXME -- Handle this.
continue;
}
}
}
}
}
/**
* Return all subentries for this manager.
* Note that this getter will skip any collective subentries,
* returning only applicable regular subentries.
* @return all subentries for this manager.
*/
{
if (dn2SubEntry.isEmpty())
{
return Collections.emptyList();
}
try
{
{
}
}
finally
{
}
return subentries;
}
/**
* Return subentries applicable to specific DN.
* Note that this getter will skip any collective subentries,
* returning only applicable regular subentries.
* @param dn for which to retrieve applicable
* subentries.
* @return applicable subentries.
*/
{
if (dn2SubEntry.isEmpty())
{
return Collections.emptyList();
}
try
{
{
{
{
{
}
}
}
}
}
finally
{
}
return subentries;
}
/**
* Return subentries applicable to specific entry.
* Note that this getter will skip any collective subentries,
* returning only applicable regular subentries.
* @param entry for which to retrieve applicable
* subentries.
* @return applicable subentries.
*/
{
if (dn2SubEntry.isEmpty())
{
return Collections.emptyList();
}
try
{
{
{
{
{
}
}
}
}
}
finally
{
}
return subentries;
}
/**
* Return collective subentries applicable to specific DN.
* Note that this getter will skip any regular subentries,
* returning only applicable collective subentries.
* @param dn for which to retrieve applicable
* subentries.
* @return applicable subentries.
*/
{
if (dn2CollectiveSubEntry.isEmpty())
{
return Collections.emptyList();
}
try
{
{
{
{
{
}
}
}
}
}
finally
{
}
return subentries;
}
/**
* Return collective subentries applicable to specific entry.
* Note that this getter will skip any regular subentries,
* returning only applicable collective subentries.
* @param entry for which to retrieve applicable
* subentries.
* @return applicable subentries.
*/
{
if (dn2CollectiveSubEntry.isEmpty())
{
return Collections.emptyList();
}
try
{
{
{
{
{
}
}
}
}
}
finally
{
}
return subentries;
}
/**
* {@inheritDoc} In this case, the server will de-register
* all subentries associated with the provided backend.
*/
{
try
{
while (setIterator.hasNext())
{
while (listIterator.hasNext())
{
{
// Notify change listeners.
{
try
{
}
catch (Exception e)
{
logger.traceException(e);
}
}
}
}
{
}
}
while (setIterator.hasNext())
{
while (listIterator.hasNext())
{
{
// Notify change listeners.
{
try
{
}
catch (Exception e)
{
logger.traceException(e);
}
}
}
}
{
}
}
}
finally
{
}
}
{
{
try
{
try
{
// Notify change listeners.
{
try
{
}
catch (Exception e)
{
logger.traceException(e);
}
}
}
catch (Exception e)
{
logger.traceException(e);
// FIXME -- Handle this.
}
}
finally
{
}
}
}
{
try
{
{
// Notify change listeners.
{
try
{
}
catch (Exception e)
{
logger.traceException(e);
}
}
}
}
finally
{
}
}
{
boolean notify = false;
try
{
{
notify = true;
}
{
try
{
notify = true;
}
catch (Exception e)
{
logger.traceException(e);
// FIXME -- Handle this.
}
}
if (notify)
{
// Notify change listeners.
{
try
{
}
catch (Exception e)
{
logger.traceException(e);
}
}
}
}
finally
{
}
}
{
try
{
{
try
{
}
catch (Exception e)
{
// Shouldnt happen.
logger.traceException(e);
}
// Notify change listeners.
{
try
{
}
catch (Exception e)
{
logger.traceException(e);
}
}
}
}
finally
{
}
}
/** {@inheritDoc} */
public PreOperation doPreOperation(
{
{
addOperation.getMessageID())))
{
}
{
try
{
}
catch (DirectoryException de)
{
}
}
}
}
/** {@inheritDoc} */
public PreOperation doPreOperation(
{
boolean hasSubentryWritePrivilege = false;
try
{
{
{
{
}
hasSubentryWritePrivilege = true;
}
{
try
{
}
catch (DirectoryException de)
{
}
}
}
}
finally
{
}
}
/** {@inheritDoc} */
public PreOperation doPreOperation(
{
{
{
}
{
try
{
}
catch (DirectoryException de)
{
}
}
}
}
/** {@inheritDoc} */
{
boolean hasSubentryWritePrivilege = false;
try
{
{
{
{
}
hasSubentryWritePrivilege = true;
}
{
try
{
}
catch (DirectoryException de)
{
}
}
}
}
finally
{
}
}
/** {@inheritDoc} */
public PostOperation doPostOperation(
{
// Only do something if the operation is successful, meaning there
// has been a change.
{
}
// If we've gotten here, then everything is acceptable.
}
/** {@inheritDoc} */
public PostOperation doPostOperation(
{
// Only do something if the operation is successful, meaning there
// has been a change.
{
}
// If we've gotten here, then everything is acceptable.
}
/** {@inheritDoc} */
public PostOperation doPostOperation(
{
// Only do something if the operation is successful, meaning there
// has been a change.
{
}
// If we've gotten here, then everything is acceptable.
}
/** {@inheritDoc} */
public PostOperation doPostOperation(
{
// Only do something if the operation is successful, meaning there
// has been a change.
{
}
// If we've gotten here, then everything is acceptable.
}
/** {@inheritDoc} */
public void doPostSynchronization(
{
{
}
}
/** {@inheritDoc} */
public void doPostSynchronization(
{
{
}
}
/** {@inheritDoc} */
public void doPostSynchronization(
{
{
}
}
/** {@inheritDoc} */
public void doPostSynchronization(
{
{
}
}
}