{
List<Message> errors = new LinkedList<Message>();
// Check to see if the base DN is already registered with the server.
Backend existingBackend = baseDNs.get(baseDN);
if (existingBackend != null)
{
Message message = ERR_REGISTER_BASEDN_ALREADY_EXISTS.
get(String.valueOf(baseDN), backend.getBackendID(),
existingBackend.getBackendID());
throw new DirectoryException(ResultCode.UNWILLING_TO_PERFORM, message);
}
// Check to see if the backend is already registered with the server for
// any other base DN(s). The new base DN must not have any hierarchical
// relationship with any other base Dns for the same backend.
LinkedList<DN> otherBaseDNs = new LinkedList<DN>();
for (DN dn : baseDNs.keySet())
{
Backend b = baseDNs.get(dn);
if (b.equals(backend))
{
otherBaseDNs.add(dn);
if (baseDN.isAncestorOf(dn) || baseDN.isDescendantOf(dn))
{
Message message = ERR_REGISTER_BASEDN_HIERARCHY_CONFLICT.
get(String.valueOf(baseDN), backend.getBackendID(),
String.valueOf(dn));
throw new DirectoryException(ResultCode.UNWILLING_TO_PERFORM,
message);
}
}
}
// Check to see if the new base DN is subordinate to any other base DN
// already defined. If it is, then any other base DN(s) for the same
// backend must also be subordinate to the same base DN.
Backend superiorBackend = null;
DN superiorBaseDN ;
DN parentDN = baseDN.getParent();
while (parentDN != null)
{
if (baseDNs.containsKey(parentDN))
{
superiorBaseDN = parentDN;
superiorBackend = baseDNs.get(parentDN);
for (DN dn : otherBaseDNs)
{
if (! dn.isDescendantOf(superiorBaseDN))
{
Message message = ERR_REGISTER_BASEDN_DIFFERENT_PARENT_BASES.
get(String.valueOf(baseDN), backend.getBackendID(),
String.valueOf(dn));
throw new DirectoryException(ResultCode.UNWILLING_TO_PERFORM,
message);
}
}
break;
}
parentDN = parentDN.getParent();
}
if (superiorBackend == null)
{
if (backend.getParentBackend() != null)
{
Message message = ERR_REGISTER_BASEDN_NEW_BASE_NOT_SUBORDINATE.
get(String.valueOf(baseDN), backend.getBackendID(),
backend.getParentBackend().getBackendID());
throw new DirectoryException(ResultCode.UNWILLING_TO_PERFORM,
message);
}
}
// Check to see if the new base DN should be the superior base DN for any
// other base DN(s) already defined.
LinkedList<Backend> subordinateBackends = new LinkedList<Backend>();
LinkedList<DN> subordinateBaseDNs = new LinkedList<DN>();
for (DN dn : baseDNs.keySet())
{
Backend b = baseDNs.get(dn);
parentDN = dn.getParent();
while (parentDN != null)
{
if (parentDN.equals(baseDN))
{
subordinateBaseDNs.add(dn);
subordinateBackends.add(b);
break;
}
else if (baseDNs.containsKey(parentDN))
{
break;
}
parentDN = parentDN.getParent();
}
}
// If we've gotten here, then the new base DN is acceptable. If we should
// actually apply the changes then do so now.
// Check to see if any of the registered backends already contain an
// entry with the DN specified as the base DN. This could happen if
// we're creating a new subordinate backend in an existing directory
// (e.g., moving the "ou=People,dc=example,dc=com" branch to its own
// backend when that data already exists under the "dc=example,dc=com"
// backend). This condition shouldn't prevent the new base DN from
// being registered, but it's definitely important enough that we let
// the administrator know about it and remind them that the existing
// backend will need to be reinitialized.
if (superiorBackend != null)
{
if (superiorBackend.entryExists(baseDN))
{
Message message = WARN_REGISTER_BASEDN_ENTRIES_IN_MULTIPLE_BACKENDS.
get(superiorBackend.getBackendID(), String.valueOf(baseDN),
backend.getBackendID());
errors.add(message);
}
}
baseDNs.put(baseDN, backend);
if (superiorBackend == null)
{
if (isPrivate)
{
if (!testOnly)
{
backend.setPrivateBackend(true);
}
privateNamingContexts.put(baseDN, backend);
}
else
{
if (!testOnly)
{
backend.setPrivateBackend(false);
}
publicNamingContexts.put(baseDN, backend);
}
}
else if (otherBaseDNs.isEmpty())
{
if (!testOnly)
{
backend.setParentBackend(superiorBackend);
superiorBackend.addSubordinateBackend(backend);
}
}
if (!testOnly)
{
for (Backend b : subordinateBackends)
{
Backend oldParentBackend = b.getParentBackend();
if (oldParentBackend != null)
{
oldParentBackend.removeSubordinateBackend(b);
}
b.setParentBackend(backend);
backend.addSubordinateBackend(b);
}