DN2URI.java revision 36e213444660f0a74ed415adeab490a5f3d50a6f
/*
* 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 2006-2010 Sun Microsystems, Inc.
* Portions Copyright 2012-2015 ForgeRock AS
*/
/**
* This class represents the referral tree which contains URIs from referral
* entries.
* <p>
* The key is the DN of the referral entry and the value is that of a pair
* (DN, list of labeled URI in the ref attribute for that entry). The DN must be
* duplicated in the value because the key is suitable for comparisons but is
* not reversible to a valid DN. Duplicate keys are permitted since a referral
* entry can contain multiple values of the ref attribute. Key order is the same
* as in dn2id so that all referrals in a subtree can be retrieved by cursoring
* through a range of the records.
*/
class DN2URI extends AbstractTree
{
private final int prefixRDNComponents;
/**
* The standard attribute type that is used to specify the set of referral
* URLs in a referral entry.
*/
/**
* A flag that indicates whether there are any referrals contained in this
* tree. It should only be set to {@code false} when it is known that
* there are no referrals.
*/
/**
* Create a new object representing a referral tree in a given
* entryContainer.
*
* @param treeName
* The name of the referral tree.
* @param entryContainer
* The entryContainer of the DN tree.
* @throws StorageRuntimeException
* If an error occurs in the storage.
*/
{
super(treeName);
}
/** Encodes the value. */
{
{
ByteStringBuilder b = new ByteStringBuilder();
// encode the dn inside the value
// because the dn is encoded in a non reversible way in the key
{
}
return b;
}
return null;
}
/** Decodes the value as a pair where the first element is the DN key and the second is the actual value. */
{
}
{
}
{
{
}
}
{
if (decodeDN)
{
try
{
}
catch (DirectoryException e)
{
throw new StorageRuntimeException("Unable to decode DN from binary value", e);
}
}
return null;
}
{
for (int i = 0; i < nbElems; i++)
{
final int stringLength = r.getInt();
}
return results;
}
/**
* Puts a URI value in the referral tree.
*
* @param txn a non null transaction
* @param dn The DN of the referral entry.
* @param labeledURIs The labeled URI value of the ref attribute.
* @throws StorageRuntimeException If an error occurs in the storage.
*/
private void update(final WriteableTransaction txn, final DN dn, final Collection<String> labeledURIs)
throws StorageRuntimeException
{
{
{
{
{
}
return oldValue;
}
else
{
}
}
});
}
/**
* Delete URI values for a given referral entry from the referral tree.
*
* @param txn a non null transaction
* @param dn The DN of the referral entry for which URI values are to be
* deleted.
* @return true if the values were deleted, false if not.
* @throws StorageRuntimeException If an error occurs in the storage.
*/
{
{
return true;
}
return false;
}
/**
* Delete a single URI value from the referral tree.
* @param txn a non null transaction
* @param dn The DN of the referral entry.
* @param labeledURIs The URI value to be deleted.
* @throws StorageRuntimeException If an error occurs in the storage.
*/
private void delete(final WriteableTransaction txn, final DN dn, final Collection<String> labeledURIs)
throws StorageRuntimeException
{
{
{
{
{
}
}
return oldValue;
}
});
}
/**
* Indicates whether the underlying tree contains any referrals.
*
* @param txn The transaction to use when making the determination.
* @return {@code true} if it is believed that the underlying tree may
* contain at least one referral, or {@code false} if it is certain
* that it doesn't.
*/
{
{
}
catch (Exception e)
{
logger.traceException(e);
return ConditionResult.UNDEFINED;
}
}
/**
* Update the referral tree for an entry that has been modified. Does
* not do anything unless the entry before the modification or the entry after
* the modification is a referral entry.
*
* @param txn a non null transaction
* @param before The entry before the modifications have been applied.
* @param after The entry after the modifications have been applied.
* @param mods The sequence of modifications made to the entry.
* @throws StorageRuntimeException If an error occurs in the storage.
*/
throws StorageRuntimeException
{
{
{
{
case ADD:
if (a != null)
{
}
break;
case DELETE:
{
}
else
{
}
break;
case INCREMENT:
// Nonsensical.
break;
case REPLACE:
if (a != null)
{
}
break;
}
}
}
}
{
for (ByteString v : a)
{
}
return results;
}
/**
* Update the referral tree for an entry that has been replaced. Does not
* do anything unless the entry before it was replaced or the entry after it
* was replaced is a referral entry.
*
* @param txn
* A transaction used for the update, or null if none is
* required.
* @param before
* The entry before it was replaced.
* @param after
* The entry after it was replaced.
* @throws StorageRuntimeException
* If an error occurs in the storage.
*/
throws StorageRuntimeException
{
}
/**
* Update the referral tree for a new entry. Does nothing if the entry
* is not a referral entry.
* @param txn a non null transaction
* @param entry The entry to be added.
* @throws StorageRuntimeException If an error occurs in the storage.
*/
throws StorageRuntimeException
{
if (labeledURIs != null)
{
}
}
/**
* Update the referral tree for a deleted entry. Does nothing if the entry
* was not a referral entry.
* @param txn a non null transaction
* @param entry The entry to be deleted.
* @throws StorageRuntimeException If an error occurs in the storage.
*/
{
if (labeledURIs != null)
{
}
}
{
}
{
}
{
try
{
}
catch (DirectoryException e)
{
return ByteString.empty();
}
}
/**
* Checks whether the target of an operation is a referral entry and throws
* a Directory referral exception if it is.
* @param entry The target entry of the operation, or the base entry of a
* search operation.
* @param searchScope The scope of the search operation, or null if the
* operation is not a search operation.
* @throws DirectoryException If a referral is found at or above the target
* DN. The referral URLs will be set appropriately for the references found
* in the referral entry.
*/
{
if (referralURLs != null)
{
}
}
/**
* Throws a Directory referral exception for the case where a referral entry
* exists at or above the target DN of an operation.
* @param targetDN The target DN of the operation, or the base object of a
* search operation.
* @param referralDN The DN of the referral entry.
* @param labeledURIs The set of labeled URIs in the referral entry.
* @param searchScope The scope of the search operation, or null if the
* operation is not a search operation.
* @throws DirectoryException If a referral is found at or above the target
* DN. The referral URLs will be set appropriately for the references found
* in the referral entry.
*/
{
{
// Remove the label part of the labeled URI if there is a label.
if (i != -1)
{
}
try
{
{
{
}
if (searchScope == null)
{
// RFC 3296, 5.2. Target Object Considerations:
// In cases where the URI to be returned is a LDAP URL, the server
// SHOULD trim any present scope, filter, or attribute list from the
// URI before returning it. Critical extensions MUST NOT be trimmed
// or modified.
}
else
{
// RFC 3296, 5.3. Base Object Considerations:
// In cases where the URI to be returned is a LDAP URL, the server
// MUST provide an explicit scope specifier from the LDAP URL prior
// to returning it.
}
}
}
catch (DirectoryException e)
{
logger.traceException(e);
// Return the non-LDAP URI as is.
}
}
// Throw a directory referral exception containing the URIs.
throw new DirectoryException(
}
/**
* Process referral entries that are above the target DN of an operation.
* @param txn a non null transaction
* @param targetDN The target DN of the operation, or the base object of a
* search operation.
* @param searchScope The scope of the search operation, or null if the
* operation is not a search operation.
* @throws DirectoryException If a referral is found at or above the target
* DN. The referral URLs will be set appropriately for the references found
* in the referral entry.
*/
void targetEntryReferrals(ReadableTransaction txn, DN targetDN, SearchScope searchScope) throws DirectoryException
{
{
}
{
return;
}
{
// Go up through the DIT hierarchy until we find a referral.
{
// Look for a record whose key matches the current DN.
{
// Construct a set of all the labeled URIs in the referral.
}
}
}
catch (StorageRuntimeException e)
{
logger.traceException(e);
}
}
{
}
/**
* Return search result references for a search operation using the referral
* tree to find all referral entries within scope of the search.
* @param txn a non null transaction
* @param searchOp The search operation for which search result references
* should be returned.
* @return <CODE>true</CODE> if the caller should continue processing the
* search request and sending additional entries and references, or
* <CODE>false</CODE> if not for some reason (e.g., the size limit
* has been reached or the search has been abandoned).
* @throws DirectoryException If a Directory Server error occurs.
*/
boolean returnSearchReferences(ReadableTransaction txn, SearchOperation searchOp) throws DirectoryException
{
{
}
{
return true;
}
/*
* We will iterate forwards through a range of the keys to
* find subordinates of the base entry from the top of the tree downwards.
*/
{
// Initialize the cursor very close to the starting value then
// step forward until we pass the ending value.
{
// We have found a subordinate referral.
// Make sure the referral is within scope.
{
continue;
}
// Construct a list of all the URIs in the referral.
{
return false;
}
}
}
catch (StorageRuntimeException e)
{
logger.traceException(e);
}
return true;
}
private SearchResultReference toSearchResultReference(DN dn, Collection<String> labeledURIs, SearchScope scope)
{
{
// Remove the label part of the labeled URI if there is a label.
if (i != -1)
{
}
// From RFC 3296 section 5.4:
// If the URI component is not a LDAP URL, it should be returned as
// is. If the LDAP URL's DN part is absent or empty, the DN part
// must be modified to contain the DN of the referral object. If
// the URI component is a LDAP URL, the URI SHOULD be modified to
// add an explicit scope specifier.
try
{
{
{
}
{
}
else
{
}
}
}
catch (DirectoryException e)
{
logger.traceException(e);
// Return the non-LDAP URI as is.
}
}
return new SearchResultReference(URIList);
}
{
}
}