opends/resource/config/config.ldif
@@ -1982,13 +1982,6 @@ objectClass: ds-cfg-branch cn: Syntaxes dn: cn=Absolute Subtree Specification,cn=Syntaxes,cn=config objectClass: top objectClass: ds-cfg-attribute-syntax cn: Absolute Subtree Specification ds-cfg-java-class: org.opends.server.schema.AbsoluteSubtreeSpecificationSyntax ds-cfg-enabled: true dn: cn=Sun-defined Access Control Information,cn=Syntaxes,cn=config objectClass: top objectClass: ds-cfg-attribute-syntax @@ -2252,13 +2245,6 @@ ds-cfg-java-class: org.opends.server.schema.ProtocolInformationSyntax ds-cfg-enabled: true dn: cn=Relative Subtree Specification,cn=Syntaxes,cn=config objectClass: top objectClass: ds-cfg-attribute-syntax cn: Relative Subtree Specification ds-cfg-java-class: org.opends.server.schema.RelativeSubtreeSpecificationSyntax ds-cfg-enabled: true dn: cn=Substring Assertion,cn=Syntaxes,cn=config objectClass: top objectClass: ds-cfg-attribute-syntax @@ -2270,7 +2256,7 @@ objectClass: top objectClass: ds-cfg-attribute-syntax cn: Subtree Specification ds-cfg-java-class: org.opends.server.schema.RFC3672SubtreeSpecificationSyntax ds-cfg-java-class: org.opends.server.schema.SubtreeSpecificationSyntax ds-cfg-enabled: true dn: cn=Supported Algorithm,cn=Syntaxes,cn=config opends/src/messages/messages/schema.properties
@@ -20,7 +20,7 @@ # # CDDL HEADER END # # Copyright 2006-2009 Sun Microsystems, Inc. # Copyright 2006-2010 Sun Microsystems, Inc. @@ -881,6 +881,8 @@ SEVERE_WARN_ATTR_SYNTAX_ATTRTYPE_INVALID_SUPERIOR_USAGE_268=The definition \ for attribute type %s is invalid because its attribute usage %s is not the \ same as the usage for its superior type %s MILD_ERR_ATTR_SYNTAX_SUBTREE_SPECIFICATION_INVALID_269=The provided \ value "%s" could not be parsed as a valid subtree specification SEVERE_WARN_ATTR_SYNTAX_ATTRTYPE_NONCOLLECTIVE_FROM_COLLECTIVE_270=The \ definition for attribute type %s is invalid because it is not defined as a \ collective type but the superior type %s is collective @@ -1023,4 +1025,4 @@ conflicting value "%d" for m(Minute) specification MILD_WARN_ATTR_DUPLICATE_HOUR_ASSERTION_FORMAT_316=The provided \ value "%s" could not be parsed as a valid assertion value because there is \ conflicting value "%d" for h(Hour) specification conflicting value "%d" for h(Hour) specification opends/src/server/org/opends/server/api/SubtreeSpecification.java
@@ -22,12 +22,13 @@ * CDDL HEADER END * * * Copyright 2006-2008 Sun Microsystems, Inc. * Copyright 2006-2010 Sun Microsystems, Inc. */ package org.opends.server.api; import org.opends.server.types.DN; import org.opends.server.types.Entry; @@ -53,6 +54,16 @@ /** * Get the absolute base DN of the subtree specification. * * @return Returns the absolute base DN of the subtree * specification. */ public abstract DN getBaseDN(); /** * Determine if an entry is within the scope of the subtree * specification. * @@ -66,6 +77,19 @@ /** * Determine if the specified DN is within the scope of the subtree * specification. * * @param dn The distinguished name. * @return Returns <code>true</code> if the DN is within the scope * of the subtree specification, or <code>false</code> * otherwise. */ public abstract boolean isDNWithinScope(DN dn); /** * Indicates whether the provided object is logically equal to this * subtree specification object. * opends/src/server/org/opends/server/core/AbsoluteSubtreeSpecification.java
@@ -22,7 +22,7 @@ * CDDL HEADER END * * * Copyright 2006-2008 Sun Microsystems, Inc. * Copyright 2006-2010 Sun Microsystems, Inc. */ package org.opends.server.core; import org.opends.messages.Message; @@ -278,13 +278,16 @@ public boolean isWithinScope(Entry entry) { if (isDNWithinScope(entry.getDN())) { try { return filter.matchesEntry(entry); } catch (DirectoryException e) { // TODO: need to decide what to do with the exception here. It's // probably safe to ignore, but we could log it perhaps. return false; if (filter != null) { try { return filter.matchesEntry(entry); } catch (DirectoryException e) { // TODO: need to decide what to do with the exception here. It's // probably safe to ignore, but we could log it perhaps. return false; } } return true; } else { return false; } opends/src/server/org/opends/server/core/RelativeSubtreeSpecification.java
@@ -22,7 +22,7 @@ * CDDL HEADER END * * * Copyright 2006-2008 Sun Microsystems, Inc. * Copyright 2006-2010 Sun Microsystems, Inc. */ package org.opends.server.core; import org.opends.messages.Message; @@ -287,13 +287,16 @@ public boolean isWithinScope(Entry entry) { if (isDNWithinScope(entry.getDN())) { try { return filter.matchesEntry(entry); } catch (DirectoryException e) { // TODO: need to decide what to do with the exception here. It's // probably safe to ignore, but we could log it perhaps. return false; if (filter != null) { try { return filter.matchesEntry(entry); } catch (DirectoryException e) { // TODO: need to decide what to do with the exception here. It's // probably safe to ignore, but we could log it perhaps. return false; } } return true; } else { return false; } opends/src/server/org/opends/server/core/SimpleSubtreeSpecification.java
@@ -22,7 +22,7 @@ * CDDL HEADER END * * * Copyright 2006-2008 Sun Microsystems, Inc. * Copyright 2006-2010 Sun Microsystems, Inc. */ package org.opends.server.core; @@ -404,16 +404,9 @@ } /** * Determine if the specified DN is within the scope of the subtree * specification. * * @param dn * The distringuished name. * @return Returns <code>true</code> if the DN is within the scope * of the subtree specification, or <code>false</code> * otherwise. * {@inheritDoc} */ protected final boolean isDNWithinScope(DN dn) { public final boolean isDNWithinScope(DN dn) { if (!dn.isDescendantOf(baseDN)) { return false; @@ -460,11 +453,9 @@ } /** * Get the absolute base DN of the subtree specification. * * @return Returns the absolute base DN of the subtree specification. * {@inheritDoc} */ protected final DN getBaseDN() { public final DN getBaseDN() { return baseDN; } opends/src/server/org/opends/server/core/SubentryManager.java
@@ -28,6 +28,7 @@ import org.opends.server.api.SubtreeSpecification; import java.util.*; import java.util.concurrent.CopyOnWriteArrayList; import java.util.concurrent.locks.ReentrantReadWriteLock; @@ -206,7 +207,7 @@ private void addSubEntry(Entry entry) throws DirectoryException { SubEntry subEntry = new SubEntry(entry); RFC3672SubtreeSpecification subSpec = SubtreeSpecification subSpec = subEntry.getSubTreeSpecification(); DN subDN = subSpec.getBaseDN(); List<SubEntry> subList = null; @@ -488,7 +489,7 @@ { for (SubEntry subEntry : subList) { RFC3672SubtreeSpecification subSpec = SubtreeSpecification subSpec = subEntry.getSubTreeSpecification(); if (subSpec.isDNWithinScope(dn)) { @@ -534,7 +535,7 @@ { for (SubEntry subEntry : subList) { RFC3672SubtreeSpecification subSpec = SubtreeSpecification subSpec = subEntry.getSubTreeSpecification(); if (subSpec.isWithinScope(entry)) { @@ -580,7 +581,7 @@ { for (SubEntry subEntry : subList) { RFC3672SubtreeSpecification subSpec = SubtreeSpecification subSpec = subEntry.getSubTreeSpecification(); if (subSpec.isDNWithinScope(dn)) { @@ -626,7 +627,7 @@ { for (SubEntry subEntry : subList) { RFC3672SubtreeSpecification subSpec = SubtreeSpecification subSpec = subEntry.getSubTreeSpecification(); if (subSpec.isWithinScope(entry)) { opends/src/server/org/opends/server/schema/SchemaConstants.java
@@ -22,7 +22,7 @@ * CDDL HEADER END * * * Copyright 2006-2009 Sun Microsystems, Inc. * Copyright 2006-2010 Sun Microsystems, Inc. */ package org.opends.server.schema; @@ -801,30 +801,6 @@ /** * The OID for the absolute subtree specification attribute syntax. */ public static final String SYNTAX_ABSOLUTE_SUBTREE_SPECIFICATION_OID = OID_OPENDS_SERVER_ATTRIBUTE_SYNTAX_BASE + ".3"; /** * The description for the absolute subtree specification attribute syntax. */ public static final String SYNTAX_ABSOLUTE_SUBTREE_SPECIFICATION_DESCRIPTION = "Absolute Subtree Specification"; /** * The name for the absolute subtree specification attribute syntax. */ public static final String SYNTAX_ABSOLUTE_SUBTREE_SPECIFICATION_NAME = "ds-absolute-subtree-specification"; /** * The OID for the aci attribute syntax. */ @@ -1668,26 +1644,26 @@ /** * The OID for the relative subtree specification attribute syntax. * The OID for the subtree specification attribute syntax. */ public static final String SYNTAX_RELATIVE_SUBTREE_SPECIFICATION_OID = OID_OPENDS_SERVER_ATTRIBUTE_SYNTAX_BASE + ".2"; public static final String SYNTAX_SUBTREE_SPECIFICATION_OID = "1.3.6.1.4.1.1466.115.121.1.45"; /** * The description for the relative subtree specification attribute syntax. * The description for the subtree specification attribute syntax. */ public static final String SYNTAX_RELATIVE_SUBTREE_SPECIFICATION_DESCRIPTION = "Relative Subtree Specification"; public static final String SYNTAX_SUBTREE_SPECIFICATION_DESCRIPTION = "Subtree Specification"; /** * The name for the relative subtree specification attribute syntax. * The name for the subtree specification attribute syntax. */ public static final String SYNTAX_RELATIVE_SUBTREE_SPECIFICATION_NAME = "ds-relative-subtree-specification"; public static final String SYNTAX_SUBTREE_SPECIFICATION_NAME = "SubtreeSpecification"; @@ -1695,7 +1671,7 @@ * The OID for the RFC3672 subtree specification attribute syntax. */ public static final String SYNTAX_RFC3672_SUBTREE_SPECIFICATION_OID = "1.3.6.1.4.1.1466.115.121.1.45"; SYNTAX_SUBTREE_SPECIFICATION_OID; @@ -1711,7 +1687,55 @@ * The name for the RFC3672 subtree specification attribute syntax. */ public static final String SYNTAX_RFC3672_SUBTREE_SPECIFICATION_NAME = "SubtreeSpecification"; SYNTAX_SUBTREE_SPECIFICATION_NAME; /** * The OID for the absolute subtree specification attribute syntax. */ public static final String SYNTAX_ABSOLUTE_SUBTREE_SPECIFICATION_OID = SYNTAX_SUBTREE_SPECIFICATION_OID; /** * The description for the absolute subtree specification attribute syntax. */ public static final String SYNTAX_ABSOLUTE_SUBTREE_SPECIFICATION_DESCRIPTION = "Absolute Subtree Specification"; /** * The name for the absolute subtree specification attribute syntax. */ public static final String SYNTAX_ABSOLUTE_SUBTREE_SPECIFICATION_NAME = SYNTAX_SUBTREE_SPECIFICATION_NAME; /** * The OID for the relative subtree specification attribute syntax. */ public static final String SYNTAX_RELATIVE_SUBTREE_SPECIFICATION_OID = SYNTAX_SUBTREE_SPECIFICATION_OID; /** * The description for the relative subtree specification attribute syntax. */ public static final String SYNTAX_RELATIVE_SUBTREE_SPECIFICATION_DESCRIPTION = "Relative Subtree Specification"; /** * The name for the relative subtree specification attribute syntax. */ public static final String SYNTAX_RELATIVE_SUBTREE_SPECIFICATION_NAME = SYNTAX_SUBTREE_SPECIFICATION_NAME; opends/src/server/org/opends/server/schema/SubtreeSpecificationSyntax.java
New file @@ -0,0 +1,320 @@ /* * 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 * trunk/opends/resource/legal-notices/OpenDS.LICENSE * or https://OpenDS.dev.java.net/OpenDS.LICENSE. * 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 * trunk/opends/resource/legal-notices/OpenDS.LICENSE. 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. */ package org.opends.server.schema; import org.opends.messages.Message; import static org.opends.server.loggers.debug.DebugLogger.*; import org.opends.server.loggers.debug.DebugTracer; import static org.opends.server.loggers.ErrorLogger.logError; import static org.opends.messages.SchemaMessages.*; import org.opends.messages.MessageBuilder; import static org.opends.server.schema.SchemaConstants.*; import org.opends.server.admin.std.server.AttributeSyntaxCfg; import org.opends.server.api.ApproximateMatchingRule; import org.opends.server.api.AttributeSyntax; import org.opends.server.api.AttributeValueDecoder; import org.opends.server.api.EqualityMatchingRule; import org.opends.server.api.OrderingMatchingRule; import org.opends.server.api.SubstringMatchingRule; import org.opends.server.api.SubtreeSpecification; import org.opends.server.config.ConfigException; import org.opends.server.core.AbsoluteSubtreeSpecification; import org.opends.server.core.DirectoryServer; import org.opends.server.core.RFC3672SubtreeSpecification; import org.opends.server.core.RelativeSubtreeSpecification; import org.opends.server.types.*; /** * This class defines the subtree specification attribute syntax, * which is used to specify the scope of sub-entries (RFC 3672). */ public final class SubtreeSpecificationSyntax extends AttributeSyntax<AttributeSyntaxCfg> { /** * The tracer object for the debug logger. */ private static final DebugTracer TRACER = getTracer(); // The default equality matching rule for this syntax. private EqualityMatchingRule defaultEqualityMatchingRule; // The default ordering matching rule for this syntax. private OrderingMatchingRule defaultOrderingMatchingRule; // The default substring matching rule for this syntax. private SubstringMatchingRule defaultSubstringMatchingRule; /** * Create a new attribute value decoder with the specified root DN. * * @param rootDN * The root DN for all decoded subtree specifications. * @return The attribute value decoder. */ public static AttributeValueDecoder<SubtreeSpecification> createAttributeValueDecoder(DN rootDN) { return new Decoder(rootDN); } /** * Internal class implementing an attribute value decoder. */ private static class Decoder implements AttributeValueDecoder<SubtreeSpecification> { // The root DN for all decoded relative subtree specifications. private DN rootDN; /** * Create a new decoder with the specified root DN. * * @param rootDN * The root DN for all decoded relative subtree * specifications. */ public Decoder(DN rootDN) { this.rootDN = rootDN; } /** * {@inheritDoc} */ public SubtreeSpecification decode(AttributeValue value) throws DirectoryException { // Try parsing the value with every subtree spec known. SubtreeSpecification subTreeSpec = null; String specString = value.toString(); try { subTreeSpec = RFC3672SubtreeSpecification.valueOf( rootDN, specString); return subTreeSpec; } catch (DirectoryException de) {} try { subTreeSpec = RelativeSubtreeSpecification.valueOf( rootDN, specString); return subTreeSpec; } catch (DirectoryException de) {} try { subTreeSpec = AbsoluteSubtreeSpecification.valueOf( specString); return subTreeSpec; } catch (DirectoryException de) {} if (subTreeSpec == null) { Message message = ERR_ATTR_SYNTAX_SUBTREE_SPECIFICATION_INVALID.get( specString); throw new DirectoryException( ResultCode.INVALID_ATTRIBUTE_SYNTAX, message); } return subTreeSpec; } } /** * Creates a new instance of this syntax. Note that the only thing * that should be done here is to invoke the default constructor for * the superclass. All initialization should be performed in the * <CODE>initializeSyntax</CODE> method. */ public SubtreeSpecificationSyntax() { // No implementation required. } /** * {@inheritDoc} */ public void initializeSyntax(AttributeSyntaxCfg configuration) throws ConfigException { defaultEqualityMatchingRule = DirectoryServer .getEqualityMatchingRule(EMR_OCTET_STRING_OID); if (defaultEqualityMatchingRule == null) { logError(ERR_ATTR_SYNTAX_UNKNOWN_EQUALITY_MATCHING_RULE.get( EMR_OCTET_STRING_OID, SYNTAX_SUBTREE_SPECIFICATION_NAME)); } defaultOrderingMatchingRule = DirectoryServer .getOrderingMatchingRule(OMR_OCTET_STRING_OID); if (defaultOrderingMatchingRule == null) { logError(ERR_ATTR_SYNTAX_UNKNOWN_ORDERING_MATCHING_RULE.get( OMR_OCTET_STRING_OID, SYNTAX_SUBTREE_SPECIFICATION_NAME)); } defaultSubstringMatchingRule = DirectoryServer .getSubstringMatchingRule(SMR_OCTET_STRING_OID); if (defaultSubstringMatchingRule == null) { logError(ERR_ATTR_SYNTAX_UNKNOWN_SUBSTRING_MATCHING_RULE.get( SMR_OCTET_STRING_OID, SYNTAX_SUBTREE_SPECIFICATION_NAME)); } } /** * Retrieves the common name for this attribute syntax. * * @return The common name for this attribute syntax. */ public String getSyntaxName() { return SYNTAX_SUBTREE_SPECIFICATION_NAME; } /** * Retrieves the OID for this attribute syntax. * * @return The OID for this attribute syntax. */ public String getOID() { return SYNTAX_SUBTREE_SPECIFICATION_OID; } /** * Retrieves a description for this attribute syntax. * * @return A description for this attribute syntax. */ public String getDescription() { return SYNTAX_SUBTREE_SPECIFICATION_DESCRIPTION; } /** * Retrieves the default equality matching rule that will be used for * attributes with this syntax. * * @return The default equality matching rule that will be used for * attributes with this syntax, or <CODE>null</CODE> if * equality matches will not be allowed for this type by * default. */ public EqualityMatchingRule getEqualityMatchingRule() { return defaultEqualityMatchingRule; } /** * Retrieves the default ordering matching rule that will be used for * attributes with this syntax. * * @return The default ordering matching rule that will be used for * attributes with this syntax, or <CODE>null</CODE> if * ordering matches will not be allowed for this type by * default. */ public OrderingMatchingRule getOrderingMatchingRule() { return defaultOrderingMatchingRule; } /** * Retrieves the default substring matching rule that will be used for * attributes with this syntax. * * @return The default substring matching rule that will be used for * attributes with this syntax, or <CODE>null</CODE> if * substring matches will not be allowed for this type by * default. */ public SubstringMatchingRule getSubstringMatchingRule() { return defaultSubstringMatchingRule; } /** * Retrieves the default approximate matching rule that will be used * for attributes with this syntax. * * @return The default approximate matching rule that will be used for * attributes with this syntax, or <CODE>null</CODE> if * approximate matches will not be allowed for this type by * default. */ public ApproximateMatchingRule getApproximateMatchingRule() { // There is no approximate matching rule by default. return null; } /** * Indicates whether the provided value is acceptable for use in an * attribute with this syntax. If it is not, then the reason may be * appended to the provided buffer. * * @param value * The value for which to make the determination. * @param invalidReason * The buffer to which the invalid reason should be appended. * @return <CODE>true</CODE> if the provided value is acceptable for * use with this syntax, or <CODE>false</CODE> if not. */ public boolean valueIsAcceptable(ByteSequence value, MessageBuilder invalidReason) { // Use the subtree specification code to make this determination. // Try parsing the value with every subtree spec known. SubtreeSpecification subTreeSpec = null; String specString = value.toString(); try { subTreeSpec = RFC3672SubtreeSpecification.valueOf( DN.nullDN(), specString); return true; } catch (DirectoryException de) {} try { subTreeSpec = RelativeSubtreeSpecification.valueOf( DN.nullDN(), specString); return true; } catch (DirectoryException de) {} try { subTreeSpec = AbsoluteSubtreeSpecification.valueOf( specString); return true; } catch (DirectoryException de) {} if (subTreeSpec == null) { Message message = ERR_ATTR_SYNTAX_SUBTREE_SPECIFICATION_INVALID.get( specString); invalidReason.append(message); } return false; } /** * {@inheritDoc} */ public boolean isBinary() { return false; } } opends/src/server/org/opends/server/types/SubEntry.java
@@ -27,6 +27,10 @@ package org.opends.server.types; import org.opends.messages.Message; import org.opends.server.core.AbsoluteSubtreeSpecification; import org.opends.server.core.RelativeSubtreeSpecification; import org.opends.server.api.SubtreeSpecification; import java.util.List; import java.util.ArrayList; import java.util.Set; @@ -37,6 +41,7 @@ import static org.opends.server.util.ServerConstants.*; import static org.opends.server.loggers.debug.DebugLogger.*; import static org.opends.messages.SchemaMessages.*; /** * This class represents RFC 3672 subentries and RFC 3671 @@ -113,7 +118,7 @@ private Entry entry; // Subtree specification. private RFC3672SubtreeSpecification subTreeSpec; private SubtreeSpecification subTreeSpec; // Collective subentry flag. private boolean isCollective = false; @@ -138,6 +143,8 @@ // Process subtree specification. this.subTreeSpec = null; String specString = null; boolean isValidSpec = true; AttributeType specAttrType = DirectoryServer.getAttributeType( ATTR_SUBTREE_SPEC_LC, true); List<Attribute> specAttrList = @@ -148,8 +155,46 @@ { for (AttributeValue value : attr) { this.subTreeSpec = RFC3672SubtreeSpecification.valueOf( entry.getDN().getParent(), value.toString()); // Try parsing the value with every subtree spec known. specString = value.toString(); try { this.subTreeSpec = RFC3672SubtreeSpecification.valueOf( entry.getDN().getParent(), specString); isValidSpec = true; } catch (DirectoryException de) { isValidSpec = false; } if (this.subTreeSpec != null) { break; } try { this.subTreeSpec = RelativeSubtreeSpecification.valueOf( entry.getDN().getParent(), specString); isValidSpec = true; } catch (DirectoryException de) { isValidSpec = false; } if (this.subTreeSpec != null) { break; } try { this.subTreeSpec = AbsoluteSubtreeSpecification.valueOf( specString); isValidSpec = true; } catch (DirectoryException de) { isValidSpec = false; } break; } if (this.subTreeSpec != null) @@ -158,6 +203,18 @@ } } } // Check that the subtree spec is flaged as valid. If it is not // that means all parsers have failed and it is ivalid syntax. if (!isValidSpec) { Message message = ERR_ATTR_SYNTAX_SUBTREE_SPECIFICATION_INVALID.get( specString); throw new DirectoryException( ResultCode.INVALID_ATTRIBUTE_SYNTAX, message); } // Subentry has to to have a subtree specification. if (this.subTreeSpec == null) { @@ -258,7 +315,7 @@ * Getter for subentry subtree specification. * @return subtree specification for this subentry. */ public RFC3672SubtreeSpecification getSubTreeSpecification() public SubtreeSpecification getSubTreeSpecification() { return this.subTreeSpec; } opends/tests/unit-tests-testng/src/server/org/opends/server/core/SubentryManagerTestCase.java
@@ -27,6 +27,7 @@ package org.opends.server.core; import org.opends.server.api.SubtreeSpecification; import java.util.ArrayList; import java.util.LinkedHashSet; import java.util.List; @@ -449,6 +450,87 @@ DN.decode("uid=rogasawara," + OLDBASE + "," + SUFFIX)).isEmpty()); } @Test public void testExtendedSubtreeSpecification() throws Exception { // This one should have been added during test setup so just // do a quick check here to make sure it is available there. assertNotNull(DirectoryServer.getEntry(ldapSubentry.getDN())); // RFC3672 Spec test subentry. List<SubEntry> rfc3672SubList = DirectoryServer.getSubentryManager().getSubentries(); for (SubEntry subentry : rfc3672SubList) { if (subentry.getDN().equals(ldapSubentry.getDN())) { SubtreeSpecification spec = subentry.getSubTreeSpecification(); assertTrue(spec instanceof RFC3672SubtreeSpecification); } } InternalClientConnection connection = InternalClientConnection.getRootConnection(); // Add Relative Spec test subentry. Entry relativeSubentry = TestCaseUtils.makeEntry( "dn: cn=Relative Subentry," + SUFFIX, "objectClass: top", "objectclass: subentry", "subtreeSpecification: {relativeBase \"ou=Test SubEntry Manager\"}", "cn: Subentry"); AddOperation addOperation = connection.processAdd(relativeSubentry.getDN(), relativeSubentry.getObjectClasses(), relativeSubentry.getUserAttributes(), relativeSubentry.getOperationalAttributes()); assertEquals(addOperation.getResultCode(), ResultCode.SUCCESS); assertNotNull(DirectoryServer.getEntry(relativeSubentry.getDN())); List<SubEntry> relativeSubList = DirectoryServer.getSubentryManager().getSubentries(); for (SubEntry subentry : relativeSubList) { if (subentry.getDN().equals(relativeSubentry.getDN())) { SubtreeSpecification spec = subentry.getSubTreeSpecification(); assertTrue(spec instanceof RelativeSubtreeSpecification); } } // Remove Relative Spec test subentry. TestCaseUtils.deleteEntry(relativeSubentry.getDN()); // Add Absolute Spec test subentry. Entry absoluteSubentry = TestCaseUtils.makeEntry( "dn: cn=Absolute Subentry," + SUFFIX, "objectClass: top", "objectclass: subentry", "subtreeSpecification: {absoluteBase \"ou=Test SubEntry Manager\"}", "cn: Subentry"); addOperation = connection.processAdd(absoluteSubentry.getDN(), absoluteSubentry.getObjectClasses(), absoluteSubentry.getUserAttributes(), absoluteSubentry.getOperationalAttributes()); assertEquals(addOperation.getResultCode(), ResultCode.SUCCESS); assertNotNull(DirectoryServer.getEntry(absoluteSubentry.getDN())); List<SubEntry> absoluteSubList = DirectoryServer.getSubentryManager().getSubentries(); for (SubEntry subentry : absoluteSubList) { if (subentry.getDN().equals(absoluteSubentry.getDN())) { SubtreeSpecification spec = subentry.getSubTreeSpecification(); assertTrue(spec instanceof AbsoluteSubtreeSpecification); } } // Remove Absolute Spec test subentry. TestCaseUtils.deleteEntry(absoluteSubentry.getDN()); } private void addTestEntries() throws Exception { InternalClientConnection connection =