From c73429505ef9b16e4c343c49e240f21d78fa34ca Mon Sep 17 00:00:00 2001
From: ludovicp <ludovicp@localhost>
Date: Fri, 30 Jul 2010 11:59:52 +0000
Subject: [PATCH] Extend RFC3672 subtreeSpecification to allow OpenDS specific RelativeSubtreeSpec and AbsoluteSubtreeSpec.
---
opendj-sdk/opends/src/server/org/opends/server/schema/SubtreeSpecificationSyntax.java | 320 ++++++++++++++++++++++++++
opendj-sdk/opends/src/server/org/opends/server/api/SubtreeSpecification.java | 26 ++
opendj-sdk/opends/src/server/org/opends/server/core/AbsoluteSubtreeSpecification.java | 17
opendj-sdk/opends/src/server/org/opends/server/types/SubEntry.java | 65 +++++
opendj-sdk/opends/resource/config/config.ldif | 16 -
opendj-sdk/opends/src/server/org/opends/server/core/RelativeSubtreeSpecification.java | 17
opendj-sdk/opends/src/server/org/opends/server/core/SubentryManager.java | 11
opendj-sdk/opends/src/messages/messages/schema.properties | 6
opendj-sdk/opends/src/server/org/opends/server/core/SimpleSubtreeSpecification.java | 19 -
opendj-sdk/opends/src/server/org/opends/server/schema/SchemaConstants.java | 96 +++++---
opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/core/SubentryManagerTestCase.java | 82 ++++++
11 files changed, 584 insertions(+), 91 deletions(-)
diff --git a/opendj-sdk/opends/resource/config/config.ldif b/opendj-sdk/opends/resource/config/config.ldif
index 7e0f22d..f66374b 100644
--- a/opendj-sdk/opends/resource/config/config.ldif
+++ b/opendj-sdk/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
diff --git a/opendj-sdk/opends/src/messages/messages/schema.properties b/opendj-sdk/opends/src/messages/messages/schema.properties
index 15c5608..ac0c7c2 100644
--- a/opendj-sdk/opends/src/messages/messages/schema.properties
+++ b/opendj-sdk/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
\ No newline at end of file
+ conflicting value "%d" for h(Hour) specification
diff --git a/opendj-sdk/opends/src/server/org/opends/server/api/SubtreeSpecification.java b/opendj-sdk/opends/src/server/org/opends/server/api/SubtreeSpecification.java
index d89aeff..ffebe35 100644
--- a/opendj-sdk/opends/src/server/org/opends/server/api/SubtreeSpecification.java
+++ b/opendj-sdk/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.
*
diff --git a/opendj-sdk/opends/src/server/org/opends/server/core/AbsoluteSubtreeSpecification.java b/opendj-sdk/opends/src/server/org/opends/server/core/AbsoluteSubtreeSpecification.java
index e50cb64..1e330c2 100644
--- a/opendj-sdk/opends/src/server/org/opends/server/core/AbsoluteSubtreeSpecification.java
+++ b/opendj-sdk/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;
}
diff --git a/opendj-sdk/opends/src/server/org/opends/server/core/RelativeSubtreeSpecification.java b/opendj-sdk/opends/src/server/org/opends/server/core/RelativeSubtreeSpecification.java
index 95e1319..125c65e 100644
--- a/opendj-sdk/opends/src/server/org/opends/server/core/RelativeSubtreeSpecification.java
+++ b/opendj-sdk/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;
}
diff --git a/opendj-sdk/opends/src/server/org/opends/server/core/SimpleSubtreeSpecification.java b/opendj-sdk/opends/src/server/org/opends/server/core/SimpleSubtreeSpecification.java
index 4cea53b..d303493 100644
--- a/opendj-sdk/opends/src/server/org/opends/server/core/SimpleSubtreeSpecification.java
+++ b/opendj-sdk/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;
}
diff --git a/opendj-sdk/opends/src/server/org/opends/server/core/SubentryManager.java b/opendj-sdk/opends/src/server/org/opends/server/core/SubentryManager.java
index b95f626..385c9a0 100644
--- a/opendj-sdk/opends/src/server/org/opends/server/core/SubentryManager.java
+++ b/opendj-sdk/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))
{
diff --git a/opendj-sdk/opends/src/server/org/opends/server/schema/SchemaConstants.java b/opendj-sdk/opends/src/server/org/opends/server/schema/SchemaConstants.java
index 118ac9a..727952f 100644
--- a/opendj-sdk/opends/src/server/org/opends/server/schema/SchemaConstants.java
+++ b/opendj-sdk/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;
diff --git a/opendj-sdk/opends/src/server/org/opends/server/schema/SubtreeSpecificationSyntax.java b/opendj-sdk/opends/src/server/org/opends/server/schema/SubtreeSpecificationSyntax.java
new file mode 100644
index 0000000..7e4b494
--- /dev/null
+++ b/opendj-sdk/opends/src/server/org/opends/server/schema/SubtreeSpecificationSyntax.java
@@ -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;
+ }
+}
diff --git a/opendj-sdk/opends/src/server/org/opends/server/types/SubEntry.java b/opendj-sdk/opends/src/server/org/opends/server/types/SubEntry.java
index 3001ec6..8cbfe5a 100644
--- a/opendj-sdk/opends/src/server/org/opends/server/types/SubEntry.java
+++ b/opendj-sdk/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;
}
diff --git a/opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/core/SubentryManagerTestCase.java b/opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/core/SubentryManagerTestCase.java
index e357678..84f1c4c 100644
--- a/opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/core/SubentryManagerTestCase.java
+++ b/opendj-sdk/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 =
--
Gitblit v1.10.0