From 9b9e1da7fc84d1f2c93e5bb6093bd5073557f804 Mon Sep 17 00:00:00 2001
From: Matthew Swift <matthew.swift@forgerock.com>
Date: Fri, 25 Feb 2011 15:23:20 +0000
Subject: [PATCH] Fix issue OPENDJ-75: Combine RFC 3672 and relative subtree specification syntax https://bugster.forgerock.org/jira/browse/OPENDJ-75
---
opendj-sdk/opends/src/server/org/opends/server/schema/SubtreeSpecificationSyntax.java | 61 -
/dev/null | 180 ----
opendj-sdk/opends/src/server/org/opends/server/types/SubEntry.java | 30
opendj-sdk/opends/src/server/org/opends/server/types/SubtreeSpecification.java | 1836 +++++++++++++++++++++++++++++++++++++++++++++
opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/types/TestEntry.java | 15
opendj-sdk/opends/src/server/org/opends/server/types/SubtreeSpecificationSet.java | 6
opendj-sdk/opends/src/server/org/opends/server/core/SubentryManager.java | 15
opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/types/TestSubtreeSpecification.java | 198 +++-
opendj-sdk/opends/src/server/org/opends/server/schema/SchemaConstants.java | 25
opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/core/SubentryManagerTestCase.java | 9
10 files changed, 1,998 insertions(+), 377 deletions(-)
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
deleted file mode 100644
index ffebe35..0000000
--- a/opendj-sdk/opends/src/server/org/opends/server/api/SubtreeSpecification.java
+++ /dev/null
@@ -1,142 +0,0 @@
-/*
- * 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.api;
-
-
-
-import org.opends.server.types.DN;
-import org.opends.server.types.Entry;
-
-
-
-/**
- * Generic subtree specification interface.
- */
-@org.opends.server.types.PublicAPI(
- stability=org.opends.server.types.StabilityLevel.VOLATILE,
- mayInstantiate=false,
- mayExtend=true,
- mayInvoke=false)
-public abstract class SubtreeSpecification
-{
- /**
- * Create a new subtree specification.
- */
- protected SubtreeSpecification()
- {
- // No implementation required.
- }
-
-
-
- /**
- * 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.
- *
- * @param entry The entry.
- *
- * @return {@code true} if the entry is within the scope of the
- * subtree specification, or {@code false} if not.
- */
- public abstract boolean isWithinScope(Entry entry);
-
-
-
- /**
- * 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.
- *
- * @param obj The object for which to make the determination.
- *
- * @return {@code true} if the provided object is logically equal
- * to this subtree specification object, or {@code false}
- * if not.
- */
- @Override
- public abstract boolean equals(Object obj);
-
-
-
- /**
- * Retrieves the hash code for this subtree specification object.
- *
- * @return The hash code for this subtree specification object.
- */
- @Override
- public abstract int hashCode();
-
-
-
- /**
- * Append the string representation of the subtree specification to
- * the provided string builder.
- *
- * @param builder The string builder.
- * @return The string builder.
- */
- public abstract StringBuilder toString(StringBuilder builder);
-
-
-
- /**
- * Retrieves a string representation of this subtree specification
- * object.
- *
- * @return A string representation of this subtree specification
- * object.
- */
- @Override
- public final String toString()
- {
- StringBuilder builder = new StringBuilder();
- return toString(builder).toString();
- }
-}
-
diff --git a/opendj-sdk/opends/src/server/org/opends/server/core/RFC3672SubtreeSpecification.java b/opendj-sdk/opends/src/server/org/opends/server/core/RFC3672SubtreeSpecification.java
deleted file mode 100644
index 2d2adf8..0000000
--- a/opendj-sdk/opends/src/server/org/opends/server/core/RFC3672SubtreeSpecification.java
+++ /dev/null
@@ -1,873 +0,0 @@
-/*
- * 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-2008 Sun Microsystems, Inc.
- */
-package org.opends.server.core;
-import org.opends.messages.Message;
-
-import static org.opends.messages.SchemaMessages.*;
-
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.HashSet;
-import java.util.InputMismatchException;
-import java.util.Iterator;
-import java.util.NoSuchElementException;
-
-import org.opends.server.types.DirectoryException;
-import org.opends.server.types.DN;
-import org.opends.server.types.Entry;
-import org.opends.server.types.ObjectClass;
-import org.opends.server.types.ResultCode;
-import org.opends.server.util.StaticUtils;
-
-/**
- * An RFC 3672 subtree specification.
- * <p>
- * Refer to RFC 3672 for a detailed definition of the subtree
- * specification string representation.
- */
-public final class RFC3672SubtreeSpecification extends
- SimpleSubtreeSpecification {
-
- // The root DN.
- private DN rootDN;
-
- // The optional relative base DN.
- private DN relativeBaseDN;
-
- // The optional specification filter refinements.
- private Refinement refinements;
-
- /**
- * Abstract interface for RFC3672 specification filter refinements.
- */
- public static abstract class Refinement {
- /**
- * Create a new RFC3672 specification filter refinement.
- */
- protected Refinement() {
- // No implementation required.
- }
-
- /**
- * Check if the refinement matches the given entry.
- *
- * @param entry
- * The filterable entry.
- * @return Returns <code>true</code> if the entry matches the
- * refinement, or <code>false</code> otherwise.
- */
- public abstract boolean matches(Entry entry);
-
- /**
- * {@inheritDoc}
- */
- @Override
- public final String toString() {
- StringBuilder builder = new StringBuilder();
-
- return toString(builder).toString();
- }
-
- /**
- * Append the string representation of the refinement to the
- * provided string builder.
- *
- * @param builder
- * The string builder.
- * @return The string builder.
- */
- public abstract StringBuilder toString(StringBuilder builder);
-
- /**
- * {@inheritDoc}
- */
- @Override
- public abstract boolean equals(Object obj);
-
- /**
- * {@inheritDoc}
- */
- @Override
- public abstract int hashCode();
- }
-
- /**
- * RFC 3672 subtree specification Item refinement. This type of
- * refinement filters entries based on the presence of a specified
- * object class.
- */
- public static final class ItemRefinement extends Refinement {
- // The item's object class.
- private String objectClass;
-
- // The item's normalized object class.
- private String normalizedObjectClass;
-
- /**
- * Create a new item refinement.
- *
- * @param objectClass
- * The item's object class.
- */
- public ItemRefinement(String objectClass) {
-
- this.objectClass = objectClass;
- this.normalizedObjectClass = StaticUtils.toLowerCase(objectClass
- .trim());
- }
-
- /**
- * {@inheritDoc}
- */
- @Override
- public boolean matches(Entry entry) {
- ObjectClass oc = DirectoryServer
- .getObjectClass(normalizedObjectClass);
-
- if (oc == null) {
- return false;
- } else {
- return entry.hasObjectClass(oc);
- }
- }
-
- /**
- * {@inheritDoc}
- */
- @Override
- public StringBuilder toString(StringBuilder builder) {
- builder.append("item:");
- builder.append(objectClass);
- return builder;
- }
-
- /**
- * {@inheritDoc}
- */
- @Override
- public boolean equals(Object obj) {
-
- if (this == obj) {
- return true;
- }
-
- if (obj instanceof ItemRefinement) {
- ItemRefinement other = (ItemRefinement) obj;
-
- return normalizedObjectClass.equals(other.normalizedObjectClass);
- }
-
- return false;
- }
-
- /**
- * {@inheritDoc}
- */
- @Override
- public int hashCode() {
-
- return normalizedObjectClass.hashCode();
- }
- }
-
- /**
- * RFC 3672 subtree specification NOT refinement. This type of
- * refinement filters entries based on the underlying refinement being
- * <code>false</code>.
- */
- public static final class NotRefinement extends Refinement {
- // The inverted refinement.
- private Refinement refinement;
-
- /**
- * Create a new NOT refinement.
- *
- * @param refinement
- * The refinement which must be <code>false</code>.
- */
- public NotRefinement(Refinement refinement) {
-
- this.refinement = refinement;
- }
-
- /**
- * {@inheritDoc}
- */
- @Override
- public boolean matches(Entry entry) {
- return !refinement.matches(entry);
- }
-
- /**
- * {@inheritDoc}
- */
- @Override
- public StringBuilder toString(StringBuilder builder) {
- builder.append("not:");
- return refinement.toString(builder);
- }
-
- /**
- * {@inheritDoc}
- */
- @Override
- public boolean equals(Object obj) {
-
- if (this == obj) {
- return true;
- }
-
- if (obj instanceof NotRefinement) {
- NotRefinement other = (NotRefinement) obj;
-
- return refinement.equals(other.refinement);
- }
-
- return false;
- }
-
- /**
- * {@inheritDoc}
- */
- @Override
- public int hashCode() {
-
- return refinement.hashCode();
- }
- }
-
- /**
- * RFC 3672 subtree specification AND refinement. This type of
- * refinement filters entries based on all of the underlying
- * refinements being <code>true</code>.
- */
- public static final class AndRefinement extends Refinement {
- // The set of refinements which must all be true.
- private Collection<Refinement> refinementSet;
-
- /**
- * Create a new AND refinement.
- *
- * @param refinementSet
- * The set of refinements which must all be
- * <code>true</code>.
- */
- public AndRefinement(Collection<Refinement> refinementSet) {
-
- this.refinementSet = refinementSet;
- }
-
- /**
- * {@inheritDoc}
- */
- @Override
- public boolean matches(Entry entry) {
- for (Refinement refinement : refinementSet) {
- if (refinement.matches(entry) == false) {
- return false;
- }
- }
-
- // All sub-refinements matched.
- return true;
- }
-
- /**
- * {@inheritDoc}
- */
- @Override
- public StringBuilder toString(StringBuilder builder) {
- switch (refinementSet.size()) {
- case 0:
- // Do nothing.
- break;
- case 1:
- refinementSet.iterator().next().toString(builder);
- break;
- default:
- builder.append("and:{");
- Iterator<Refinement> iterator = refinementSet.iterator();
- iterator.next().toString(builder);
- while (iterator.hasNext()) {
- builder.append(", ");
- iterator.next().toString(builder);
- }
- builder.append("}");
- break;
- }
-
- return builder;
- }
-
- /**
- * {@inheritDoc}
- */
- @Override
- public boolean equals(Object obj) {
-
- if (this == obj) {
- return true;
- }
-
- if (obj instanceof AndRefinement) {
- AndRefinement other = (AndRefinement) obj;
-
- return refinementSet.equals(other.refinementSet);
- }
-
- return false;
- }
-
- /**
- * {@inheritDoc}
- */
- @Override
- public int hashCode() {
-
- return refinementSet.hashCode();
- }
- }
-
- /**
- * RFC 3672 subtree specification OR refinement. This type of
- * refinement filters entries based on at least one of the underlying
- * refinements being <code>true</code>.
- */
- public static final class OrRefinement extends Refinement {
- // The set of refinements of which at least one must be true.
- private Collection<Refinement> refinementSet;
-
- /**
- * Create a new OR refinement.
- *
- * @param refinementSet
- * The set of refinements of which at least one must be
- * <code>true</code>.
- */
- public OrRefinement(Collection<Refinement> refinementSet) {
-
- this.refinementSet = refinementSet;
- }
-
- /**
- * {@inheritDoc}
- */
- @Override
- public boolean matches(Entry entry) {
- for (Refinement refinement : refinementSet) {
- if (refinement.matches(entry) == true) {
- return true;
- }
- }
-
- // No sub-refinements matched.
- return false;
- }
-
- /**
- * {@inheritDoc}
- */
- @Override
- public StringBuilder toString(StringBuilder builder) {
- switch (refinementSet.size()) {
- case 0:
- // Do nothing.
- break;
- case 1:
- refinementSet.iterator().next().toString(builder);
- break;
- default:
- builder.append("or:{");
- Iterator<Refinement> iterator = refinementSet.iterator();
- iterator.next().toString(builder);
- while (iterator.hasNext()) {
- builder.append(", ");
- iterator.next().toString(builder);
- }
- builder.append("}");
- break;
- }
-
- return builder;
- }
-
- /**
- * {@inheritDoc}
- */
- @Override
- public boolean equals(Object obj) {
-
- if (this == obj) {
- return true;
- }
-
- if (obj instanceof AndRefinement) {
- AndRefinement other = (AndRefinement) obj;
-
- return refinementSet.equals(other.refinementSet);
- }
-
- return false;
- }
-
- /**
- * {@inheritDoc}
- */
- @Override
- public int hashCode() {
-
- return refinementSet.hashCode();
- }
- }
-
- /**
- * Parses the string argument as an RFC3672 subtree specification.
- *
- * @param rootDN
- * The DN of the subtree specification's base entry.
- * @param s
- * The string to be parsed.
- * @return The RFC3672 subtree specification represented by the string
- * argument.
- * @throws DirectoryException
- * If the string does not contain a parsable relative
- * subtree specification.
- */
- public static RFC3672SubtreeSpecification valueOf(DN rootDN, String s)
- throws DirectoryException {
-
- // Default values.
- DN relativeBaseDN = null;
-
- int minimum = -1;
- int maximum = -1;
-
- HashSet<DN> chopBefore = new HashSet<DN>();
- HashSet<DN> chopAfter = new HashSet<DN>();
-
- Refinement refinement = null;
-
- // Value must have an opening left brace.
- Parser parser = new Parser(s);
- boolean isValid = true;
-
- try {
- parser.skipLeftBrace();
-
- // Parse each element of the value sequence.
- boolean isFirst = true;
-
- while (true) {
- if (parser.hasNextRightBrace()) {
- // Make sure that there is a closing brace and no trailing
- // text.
- parser.skipRightBrace();
-
- if (parser.hasNext()) {
- throw new java.util.InputMismatchException();
- }
- break;
- }
-
- // Make sure that there is a comma separator if this is not the
- // first element.
- if (!isFirst) {
- parser.skipSeparator();
- } else {
- isFirst = false;
- }
-
- String key = parser.nextKey();
- if (key.equals("base")) {
- if (relativeBaseDN != null) {
- // Relative base DN specified more than once.
- throw new InputMismatchException();
- }
- relativeBaseDN = DN.decode(parser.nextStringValue());
- } else if (key.equals("minimum")) {
- if (minimum != -1) {
- // Minimum specified more than once.
- throw new InputMismatchException();
- }
- minimum = parser.nextInt();
- } else if (key.equals("maximum")) {
- if (maximum != -1) {
- // Maximum specified more than once.
- throw new InputMismatchException();
- }
- maximum = parser.nextInt();
- } else if (key.equals("specificationfilter")) {
- if (refinement != null) {
- // Refinements specified more than once.
- throw new InputMismatchException();
- }
-
- refinement = parseRefinement(parser);
- } else if (key.equals("specificexclusions")) {
- if (!chopBefore.isEmpty() || !chopAfter.isEmpty()) {
- // Specific exclusions specified more than once.
- throw new InputMismatchException();
- }
-
- parser.nextSpecificExclusions(chopBefore, chopAfter);
- } else {
- throw new InputMismatchException();
- }
- }
-
- // Make default minimum value is 0.
- if (minimum < 0) {
- minimum = 0;
- }
-
- // Check that the maximum, if specified, is gte the minimum.
- if (maximum >= 0 && maximum < minimum) {
- isValid = false;
- }
- } catch (InputMismatchException e) {
- isValid = false;
- } catch (NoSuchElementException e) {
- isValid = false;
- }
-
- if (isValid) {
- return new RFC3672SubtreeSpecification(rootDN, relativeBaseDN,
- minimum, maximum, chopBefore, chopAfter, refinement);
- } else {
- Message message =
- ERR_ATTR_SYNTAX_RFC3672_SUBTREE_SPECIFICATION_INVALID.get(s);
- throw new DirectoryException(ResultCode.INVALID_ATTRIBUTE_SYNTAX,
- message);
- }
- }
-
- /**
- * Parse a single refinement.
- *
- * @param parser
- * The active subtree specification parser.
- * @return The parsed refinement.
- * @throws InputMismatchException
- * If the common component did not have a valid syntax.
- * @throws NoSuchElementException
- * If input is exhausted.
- */
- private static Refinement parseRefinement(Parser parser)
- throws InputMismatchException, NoSuchElementException {
- // Get the type of refinement.
- String type = StaticUtils.toLowerCase(parser.nextName());
-
- // Skip the colon separator.
- parser.skipColon();
-
- if (type.equals("item")) {
- return new ItemRefinement(parser.nextName());
- } else if (type.equals("not")) {
- Refinement refinement = parseRefinement(parser);
- return new NotRefinement(refinement);
- } else if (type.equals("and")) {
- ArrayList<Refinement> refinements = parseRefinementSet(parser);
- return new AndRefinement(refinements);
- } else if (type.equals("or")) {
- ArrayList<Refinement> refinements = parseRefinementSet(parser);
- return new OrRefinement(refinements);
- } else {
- // Unknown refinement type.
- throw new InputMismatchException();
- }
- }
-
- /**
- * Parse a list of refinements.
- *
- * @param parser
- * The active subtree specification parser.
- * @return The parsed refinement list.
- * @throws InputMismatchException
- * If the common component did not have a valid syntax.
- * @throws NoSuchElementException
- * If input is exhausted.
- */
- private static ArrayList<Refinement> parseRefinementSet(Parser parser)
- throws InputMismatchException, NoSuchElementException {
- ArrayList<Refinement> refinements = new ArrayList<Refinement>();
-
- // Skip leading open-brace.
- parser.skipLeftBrace();
-
- // Parse each chop DN in the sequence.
- boolean isFirstValue = true;
- while (true) {
- // Make sure that there is a closing brace.
- if (parser.hasNextRightBrace()) {
- parser.skipRightBrace();
- break;
- }
-
- // Make sure that there is a comma separator if this is not
- // the first element.
- if (!isFirstValue) {
- parser.skipSeparator();
- } else {
- isFirstValue = false;
- }
-
- // Parse each sub-refinement.
- Refinement refinement = parseRefinement(parser);
- refinements.add(refinement);
- }
-
- return refinements;
- }
-
- /**
- * Create a new RFC3672 subtree specification.
- *
- * @param rootDN
- * The root DN of the subtree.
- * @param relativeBaseDN
- * The relative base DN (or <code>null</code> if not
- * specified).
- * @param minimumDepth
- * The minimum depth (<=0 means unlimited).
- * @param maximumDepth
- * The maximum depth (<0 means unlimited).
- * @param chopBefore
- * The set of chop before local names (relative to the
- * relative base DN), or <code>null</code> if there are
- * none.
- * @param chopAfter
- * The set of chop after local names (relative to the
- * relative base DN), or <code>null</code> if there are
- * none.
- * @param refinements
- * The optional specification filter refinements, or
- * <code>null</code> if there are none.
- */
- public RFC3672SubtreeSpecification(DN rootDN, DN relativeBaseDN,
- int minimumDepth, int maximumDepth, Iterable<DN> chopBefore,
- Iterable<DN> chopAfter, Refinement refinements) {
- super(relativeBaseDN == null ? rootDN : rootDN.concat(relativeBaseDN),
- minimumDepth, maximumDepth, chopBefore, chopAfter);
-
-
- this.rootDN = rootDN;
- this.relativeBaseDN = relativeBaseDN;
- this.refinements = refinements;
- }
-
- /**
- * Get the root DN.
- *
- * @return Returns the root DN.
- */
- public DN getRootDN() {
- return rootDN;
- }
-
- /**
- * Get the relative base DN.
- *
- * @return Returns the relative base DN or <code>null</code> if none
- * was specified.
- */
- public DN getRelativeBaseDN() {
- return relativeBaseDN;
- }
-
- /**
- * Get the specification filter refinements.
- *
- * @return Returns the specification filter refinements, or
- * <code>null</code> if none were specified.
- */
- public Refinement getRefinements() {
- return refinements;
- }
-
- /**
- * {@inheritDoc}
- */
- @Override
- public boolean isWithinScope(Entry entry) {
-
- if (isDNWithinScope(entry.getDN())) {
- if (refinements != null) {
- return refinements.matches(entry);
- } else {
- return true;
- }
- } else {
- return false;
- }
- }
-
- /**
- * {@inheritDoc}
- */
- @Override
- public StringBuilder toString(StringBuilder builder) {
-
- boolean isFirstElement = true;
-
- // Output the optional base DN.
- builder.append("{");
- if (relativeBaseDN != null && !relativeBaseDN.isNullDN()) {
- builder.append(" base ");
- StaticUtils.toRFC3641StringValue(builder, relativeBaseDN.toString());
- isFirstElement = false;
- }
-
- // Output the optional specific exclusions.
- Iterable<DN> chopBefore = getChopBefore();
- Iterable<DN> chopAfter = getChopAfter();
-
- if ((chopBefore != null && chopBefore.iterator().hasNext())
- || (chopAfter != null && chopAfter.iterator().hasNext())) {
-
- if (!isFirstElement) {
- builder.append(",");
- } else {
- isFirstElement = false;
- }
- builder.append(" specificExclusions { ");
-
- boolean isFirst = true;
-
- if (chopBefore != null) {
- for (DN dn : chopBefore) {
- if (!isFirst) {
- builder.append(", chopBefore:");
- } else {
- builder.append("chopBefore:");
- isFirst = false;
- }
- StaticUtils.toRFC3641StringValue(builder, dn.toString());
- }
- }
-
- if (chopAfter != null) {
- for (DN dn : chopAfter) {
- if (!isFirst) {
- builder.append(", chopAfter:");
- } else {
- builder.append("chopAfter:");
- isFirst = false;
- }
- StaticUtils.toRFC3641StringValue(builder, dn.toString());
- }
- }
-
- builder.append(" }");
- }
-
- // Output the optional minimum depth.
- if (getMinimumDepth() > 0) {
- if (!isFirstElement) {
- builder.append(",");
- } else {
- isFirstElement = false;
- }
- builder.append(" minimum ");
- builder.append(getMinimumDepth());
- }
-
- // Output the optional maximum depth.
- if (getMaximumDepth() >= 0) {
- if (!isFirstElement) {
- builder.append(",");
- } else {
- isFirstElement = false;
- }
- builder.append(" maximum ");
- builder.append(getMaximumDepth());
- }
-
- // Output the optional refinements.
- if (refinements != null) {
- if (!isFirstElement) {
- builder.append(",");
- } else {
- isFirstElement = false;
- }
- builder.append(" specificationFilter ");
- refinements.toString(builder);
- }
-
- builder.append(" }");
-
- return builder;
- }
-
- /**
- * {@inheritDoc}
- */
- @Override
- public boolean equals(Object obj) {
-
- if (this == obj) {
- return true;
- }
-
- if (obj instanceof RFC3672SubtreeSpecification) {
- RFC3672SubtreeSpecification other = (RFC3672SubtreeSpecification) obj;
-
- if (!commonComponentsEquals(other)) {
- return false;
- }
-
- if (!getBaseDN().equals(other.getBaseDN())) {
- return false;
- }
-
- if (refinements != null) {
- return refinements.equals(other.refinements);
- } else {
- return refinements == other.refinements;
- }
- }
-
- return false;
- }
-
- /**
- * {@inheritDoc}
- */
- @Override
- public int hashCode() {
-
- int hash = commonComponentsHashCode();
-
- hash = hash * 31 + getBaseDN().hashCode();
-
- if (refinements != null) {
- hash = hash * 31 + refinements.hashCode();
- }
-
- return hash;
- }
-}
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
deleted file mode 100644
index 125c65e..0000000
--- a/opendj-sdk/opends/src/server/org/opends/server/core/RelativeSubtreeSpecification.java
+++ /dev/null
@@ -1,449 +0,0 @@
-/*
- * 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.core;
-import org.opends.messages.Message;
-
-import static org.opends.messages.SchemaMessages.*;
-
-import java.util.HashSet;
-import java.util.InputMismatchException;
-import java.util.NoSuchElementException;
-
-import org.opends.server.types.DirectoryException;
-import org.opends.server.types.DN;
-import org.opends.server.types.Entry;
-import org.opends.server.types.ResultCode;
-import org.opends.server.types.SearchFilter;
-import org.opends.server.util.StaticUtils;
-
-/**
- * A relative subtree specification.
- * <p>
- * Relative subtree specifications are very similar toRFC 3672 subtree
- * specifications with the only difference being that the specification
- * filter is not a set of refinements, but an LDAP search filter.
- * <p>
- * The string representation of a relative subtree specification is
- * defined by the following grammar:
- *
- * <pre>
- * SubtreeSpecification = "{"
- * [ sp ss-relative-base ]
- * [ sep sp ss-specificExclusions ]
- * [ sep sp ss-minimum ]
- * [ sep sp ss-maximum ]
- * [ sep sp ss-specificationFilter ]
- * sp "}"
- *
- * ss-relative-base = "relativeBase&quot msp DistinguishedName
- *
- * ss-specificExclusions = "specificExclusions&quot
- * msp SpecificExclusions
- *
- * ss-minimum = "minimum&quot msp BaseDistance
- *
- * ss-maximum = "maximum&quot msp BaseDistance
- *
- * ss-specificationFilter = "specificationFilter&quot msp Filter
- *
- * SpecificExclusions = "{"
- * [ sp SpecificExclusion
- * ( "," sp SpecificExclusion ) ]
- * sp "}"
- *
- * SpecificExclusion = chopBefore / chopAfter
- *
- * chopBefore = "chopBefore&quot ":" LocalName
- *
- * chopAfter = "chopAfter&quot ":" LocalName
- *
- * Filter = dquote *SafeUTF8Character dquote
- * </pre>
- */
-public final class RelativeSubtreeSpecification extends
- SimpleSubtreeSpecification {
-
- // The root DN.
- private DN rootDN;
-
- // The optional relative base DN.
- private DN relativeBaseDN;
-
- // The optional search filter.
- private SearchFilter filter;
-
- /**
- * Parses the string argument as a relative subtree specification.
- *
- * @param rootDN
- * The DN of the subtree specification's base entry.
- * @param s
- * The string to be parsed.
- * @return The relative subtree specification represented by the
- * string argument.
- * @throws DirectoryException
- * If the string does not contain a parsable relative
- * subtree specification.
- */
- public static RelativeSubtreeSpecification valueOf(DN rootDN, String s)
- throws DirectoryException {
-
- // Default values.
- DN relativeBaseDN = null;
-
- int minimum = -1;
- int maximum = -1;
-
- HashSet<DN> chopBefore = new HashSet<DN>();
- HashSet<DN> chopAfter = new HashSet<DN>();
-
- SearchFilter filter = null;
-
- // Value must have an opening left brace.
- Parser parser = new Parser(s);
- boolean isValid = true;
-
- try {
- parser.skipLeftBrace();
-
- // Parse each element of the value sequence.
- boolean isFirst = true;
-
- while (true) {
- if (parser.hasNextRightBrace()) {
- // Make sure that there is a closing brace and no trailing
- // text.
- parser.skipRightBrace();
-
- if (parser.hasNext()) {
- throw new java.util.InputMismatchException();
- }
- break;
- }
-
- // Make sure that there is a comma separator if this is not the
- // first element.
- if (!isFirst) {
- parser.skipSeparator();
- } else {
- isFirst = false;
- }
-
- String key = parser.nextKey();
- if (key.equals("relativebase")) {
- if (relativeBaseDN != null) {
- // Relative base DN specified more than once.
- throw new InputMismatchException();
- }
- relativeBaseDN = DN.decode(parser.nextStringValue());
- } else if (key.equals("minimum")) {
- if (minimum != -1) {
- // Minimum specified more than once.
- throw new InputMismatchException();
- }
- minimum = parser.nextInt();
- } else if (key.equals("maximum")) {
- if (maximum != -1) {
- // Maximum specified more than once.
- throw new InputMismatchException();
- }
- maximum = parser.nextInt();
- } else if (key.equals("specificationfilter")) {
- if (filter != null) {
- // Filter specified more than once.
- throw new InputMismatchException();
- }
- filter = SearchFilter.createFilterFromString(parser
- .nextStringValue());
- } else if (key.equals("specificexclusions")) {
- if (!chopBefore.isEmpty() || !chopAfter.isEmpty()) {
- // Specific exclusions specified more than once.
- throw new InputMismatchException();
- }
-
- parser.nextSpecificExclusions(chopBefore, chopAfter);
- } else {
- throw new InputMismatchException();
- }
- }
-
- // Make default minimum value is 0.
- if (minimum < 0) {
- minimum = 0;
- }
-
- // Check that the maximum, if specified, is gte the minimum.
- if (maximum >= 0 && maximum < minimum) {
- isValid = false;
- }
- } catch (InputMismatchException e) {
- isValid = false;
- } catch (NoSuchElementException e) {
- isValid = false;
- }
-
- if (isValid) {
- return new RelativeSubtreeSpecification(rootDN, relativeBaseDN,
- minimum, maximum, chopBefore, chopAfter, filter);
- } else {
- Message message =
- ERR_ATTR_SYNTAX_RELATIVE_SUBTREE_SPECIFICATION_INVALID.get(s);
- throw new DirectoryException(ResultCode.INVALID_ATTRIBUTE_SYNTAX,
- message);
- }
- }
-
- /**
- * Create a new relative subtree specification.
- *
- * @param rootDN
- * The root DN of the subtree.
- * @param relativeBaseDN
- * The relative base DN (or <code>null</code> if not
- * specified).
- * @param minimumDepth
- * The minimum depth (<=0 means unlimited).
- * @param maximumDepth
- * The maximum depth (<0 means unlimited).
- * @param chopBefore
- * The set of chop before local names (relative to the base
- * DN), or <code>null</code> if there are none.
- * @param chopAfter
- * The set of chop after local names (relative to the base
- * DN), or <code>null</code> if there are none.
- * @param filter
- * The optional search filter (<code>null</code> if there
- * is no filter).
- */
- public RelativeSubtreeSpecification(DN rootDN, DN relativeBaseDN,
- int minimumDepth, int maximumDepth, Iterable<DN> chopBefore,
- Iterable<DN> chopAfter, SearchFilter filter) {
- super(relativeBaseDN == null ? rootDN : rootDN.concat(relativeBaseDN),
- minimumDepth, maximumDepth, chopBefore, chopAfter);
-
-
- this.rootDN = rootDN;
- this.relativeBaseDN = relativeBaseDN;
- this.filter = filter;
- }
-
- /**
- * Get the root DN.
- *
- * @return Returns the root DN.
- */
- public DN getRootDN() {
- return rootDN;
- }
-
- /**
- * Get the relative base DN.
- *
- * @return Returns the relative base DN or <code>null</code> if none
- * was specified.
- */
- public DN getRelativeBaseDN() {
- return relativeBaseDN;
- }
-
- /**
- * Get the specification filter.
- *
- * @return Returns the search filter, or <code>null</code> if there
- * is no filter.
- */
- public SearchFilter getFilter() {
- return filter;
- }
-
- /**
- * {@inheritDoc}
- */
- @Override
- public boolean isWithinScope(Entry entry) {
-
- if (isDNWithinScope(entry.getDN())) {
- 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;
- }
- }
-
- /**
- * {@inheritDoc}
- */
- @Override
- public StringBuilder toString(StringBuilder builder) {
-
- boolean isFirstElement = true;
-
- // Output the optional base DN.
- builder.append("{");
- if (relativeBaseDN != null && !relativeBaseDN.isNullDN()) {
- builder.append(" relativeBase ");
- StaticUtils.toRFC3641StringValue(builder, relativeBaseDN.toString());
- isFirstElement = false;
- }
-
- // Output the optional specific exclusions.
- Iterable<DN> chopBefore = getChopBefore();
- Iterable<DN> chopAfter = getChopAfter();
-
- if ((chopBefore != null && chopBefore.iterator().hasNext())
- || (chopAfter != null && chopAfter.iterator().hasNext())) {
-
- if (!isFirstElement) {
- builder.append(",");
- } else {
- isFirstElement = false;
- }
- builder.append(" specificExclusions { ");
-
- boolean isFirst = true;
-
- if (chopBefore != null) {
- for (DN dn : chopBefore) {
- if (!isFirst) {
- builder.append(", chopBefore:");
- } else {
- builder.append("chopBefore:");
- isFirst = false;
- }
- StaticUtils.toRFC3641StringValue(builder, dn.toString());
- }
- }
-
- if (chopAfter != null) {
- for (DN dn : chopAfter) {
- if (!isFirst) {
- builder.append(", chopAfter:");
- } else {
- builder.append("chopAfter:");
- isFirst = false;
- }
- StaticUtils.toRFC3641StringValue(builder, dn.toString());
- }
- }
-
- builder.append(" }");
- }
-
- // Output the optional minimum depth.
- if (getMinimumDepth() > 0) {
- if (!isFirstElement) {
- builder.append(",");
- } else {
- isFirstElement = false;
- }
- builder.append(" minimum ");
- builder.append(getMinimumDepth());
- }
-
- // Output the optional maximum depth.
- if (getMaximumDepth() >= 0) {
- if (!isFirstElement) {
- builder.append(",");
- } else {
- isFirstElement = false;
- }
- builder.append(" maximum ");
- builder.append(getMaximumDepth());
- }
-
- // Output the optional filter.
- if (filter != null) {
- if (!isFirstElement) {
- builder.append(",");
- } else {
- isFirstElement = false;
- }
- builder.append(" specificationFilter ");
- StaticUtils.toRFC3641StringValue(builder, filter.toString());
- }
-
- builder.append(" }");
-
- return builder;
- }
-
- /**
- * {@inheritDoc}
- */
- @Override
- public boolean equals(Object obj) {
-
- if (this == obj) {
- return true;
- }
-
- if (obj instanceof RelativeSubtreeSpecification) {
- RelativeSubtreeSpecification other = (RelativeSubtreeSpecification) obj;
-
- if (!commonComponentsEquals(other)) {
- return false;
- }
-
- if (!getBaseDN().equals(other.getBaseDN())) {
- return false;
- }
-
- if (filter != null) {
- return filter.equals(other.filter);
- } else {
- return filter == other.filter;
- }
- }
-
- return false;
- }
-
- /**
- * {@inheritDoc}
- */
- @Override
- public int hashCode() {
-
- int hash = commonComponentsHashCode();
-
- hash = hash * 31 + getBaseDN().hashCode();
-
- if (filter != null) {
- hash = hash * 31 + filter.hashCode();
- }
-
- return hash;
- }
-}
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
deleted file mode 100644
index d303493..0000000
--- a/opendj-sdk/opends/src/server/org/opends/server/core/SimpleSubtreeSpecification.java
+++ /dev/null
@@ -1,571 +0,0 @@
-/*
- * 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.core;
-
-import java.util.InputMismatchException;
-import java.util.NoSuchElementException;
-import java.util.Scanner;
-import java.util.Set;
-import java.util.TreeMap;
-import java.util.regex.Pattern;
-
-import org.opends.server.api.SubtreeSpecification;
-import org.opends.server.types.DirectoryException;
-import org.opends.server.types.DN;
-import org.opends.server.util.StaticUtils;
-
-/**
- * A simple subtree specification implementation that has a subtree
- * base, optional minimum and maximum depths, and a set of chop
- * specifications.
- */
-public abstract class SimpleSubtreeSpecification extends
- SubtreeSpecification {
-
-
- // The absolute base of the subtree.
- private DN baseDN;
-
- // Optional minimum depth (<=0 means unlimited).
- private int minimumDepth;
-
- // Optional maximum depth (<0 means unlimited).
- private int maximumDepth;
-
- // Optional set of chop before absolute DNs (mapping to their
- // local-names).
- private TreeMap<DN, DN> chopBefore;
-
- // Optional set of chop after absolute DNs (mapping to their
- // local-names).
- private TreeMap<DN, DN> chopAfter;
-
- /**
- * Internal utility class which can be used by sub-classes to help
- * parse string representations.
- */
- protected static final class Parser {
- // Text scanner used to parse the string value.
- private Scanner scanner;
-
- // Pattern used to detect left braces.
- private static Pattern LBRACE = Pattern.compile("\\{.*");
-
- // Pattern used to parse left braces.
- private static Pattern LBRACE_TOKEN = Pattern.compile("\\{");
-
- // Pattern used to detect right braces.
- private static Pattern RBRACE = Pattern.compile("\\}.*");
-
- // Pattern used to parse right braces.
- private static Pattern RBRACE_TOKEN = Pattern.compile("\\}");
-
- // Pattern used to detect comma separators.
- private static Pattern SEP = Pattern.compile(",.*");
-
- // Pattern used to parse comma separators.
- private static Pattern SEP_TOKEN = Pattern.compile(",");
-
- // Pattern used to detect colon separators.
- private static Pattern COLON = Pattern.compile(":.*");
-
- // Pattern used to parse colon separators.
- private static Pattern COLON_TOKEN = Pattern.compile(":");
-
- // Pattern used to detect integer values.
- private static Pattern INT = Pattern.compile("\\d.*");
-
- // Pattern used to parse integer values.
- private static Pattern INT_TOKEN = Pattern.compile("\\d+");
-
- // Pattern used to detect name values.
- private static Pattern NAME = Pattern.compile("[\\w_;-].*");
-
- // Pattern used to parse name values.
- private static Pattern NAME_TOKEN = Pattern.compile("[\\w_;-]+");
-
- // Pattern used to detect RFC3641 string values.
- private static Pattern STRING_VALUE = Pattern.compile("\".*");
-
- // Pattern used to parse RFC3641 string values.
- private static Pattern STRING_VALUE_TOKEN = Pattern
- .compile("\"([^\"]|(\"\"))*\"");
-
- /**
- * Create a new parser for a subtree specification string value.
- *
- * @param value
- * The subtree specification string value.
- */
- public Parser(String value) {
- this.scanner = new Scanner(value);
- }
-
- /**
- * Skip a left-brace character.
- *
- * @throws InputMismatchException
- * If the next token is not a left-brace character.
- * @throws NoSuchElementException
- * If input is exhausted.
- */
- public void skipLeftBrace() throws InputMismatchException,
- NoSuchElementException {
- nextValue(LBRACE, LBRACE_TOKEN);
- }
-
- /**
- * Skip a right-brace character.
- *
- * @throws InputMismatchException
- * If the next token is not a right-brace character.
- * @throws NoSuchElementException
- * If input is exhausted.
- */
- public void skipRightBrace() throws InputMismatchException,
- NoSuchElementException {
- nextValue(RBRACE, RBRACE_TOKEN);
- }
-
- /**
- * Skip a comma separator.
- *
- * @throws InputMismatchException
- * If the next token is not a comma separator character.
- * @throws NoSuchElementException
- * If input is exhausted.
- */
- public void skipSeparator() throws InputMismatchException,
- NoSuchElementException {
- nextValue(SEP, SEP_TOKEN);
- }
-
- /**
- * Skip a colon separator.
- *
- * @throws InputMismatchException
- * If the next token is not a colon separator character.
- * @throws NoSuchElementException
- * If input is exhausted.
- */
- public void skipColon() throws InputMismatchException,
- NoSuchElementException {
- nextValue(COLON, COLON_TOKEN);
- }
-
- /**
- * Determine if the next token is a right-brace character.
- *
- * @return <code>true</code> if and only if the next token is a
- * valid right brace character.
- */
- public boolean hasNextRightBrace() {
- return scanner.hasNext(RBRACE);
- }
-
- /**
- * Determine if there are remaining tokens.
- *
- * @return <code>true</code> if and only if there are remaining
- * tokens.
- */
- public boolean hasNext() {
- return scanner.hasNext();
- }
-
- /**
- * Scans the next token of the input as a key value.
- *
- * @return The lower-case key value scanned from the input.
- * @throws InputMismatchException
- * If the next token is not a valid key string.
- * @throws NoSuchElementException
- * If input is exhausted.
- */
- public String nextKey() throws InputMismatchException,
- NoSuchElementException {
- return StaticUtils.toLowerCase(scanner.next());
- }
-
- /**
- * Scans the next token of the input as a name value.
- * <p>
- * A name is any string containing only alpha-numeric characters or
- * hyphens, semi-colons, or underscores.
- *
- * @return The name value scanned from the input.
- * @throws InputMismatchException
- * If the next token is not a valid name string.
- * @throws NoSuchElementException
- * If input is exhausted.
- */
- public String nextName() throws InputMismatchException,
- NoSuchElementException {
- return nextValue(NAME, NAME_TOKEN);
- }
-
- /**
- * Scans the next token of the input as a non-negative
- * <code>int</code> value.
- *
- * @return The name value scanned from the input.
- * @throws InputMismatchException
- * If the next token is not a valid non-negative integer
- * string.
- * @throws NoSuchElementException
- * If input is exhausted.
- */
- public int nextInt() throws InputMismatchException,
- NoSuchElementException {
- String s = nextValue(INT, INT_TOKEN);
- return Integer.parseInt(s);
- }
-
- /**
- * Scans the next token of the input as a string quoted according to
- * the StringValue production in RFC 3641.
- * <p>
- * The return string has its outer double quotes removed and any
- * escaped inner double quotes unescaped.
- *
- * @return The string value scanned from the input.
- * @throws InputMismatchException
- * If the next token is not a valid string.
- * @throws NoSuchElementException
- * If input is exhausted.
- */
- public String nextStringValue() throws InputMismatchException,
- NoSuchElementException {
- String s = nextValue(STRING_VALUE, STRING_VALUE_TOKEN);
- return s.substring(1, s.length() - 1).replace("\"\"", "\"");
- }
-
- /**
- * Scans the next tokens of the input as a set of specific
- * exclusions encoded according to the SpecificExclusion production
- * in RFC 3672.
- *
- * @param chopBefore
- * The set of chop before local names.
- * @param chopAfter
- * The set of chop after local names.
- * @throws InputMismatchException
- * If the common component did not have a valid syntax.
- * @throws NoSuchElementException
- * If input is exhausted.
- * @throws DirectoryException
- * If an error occurred when attempting to parse a DN
- * value.
- */
- public void nextSpecificExclusions(Set<DN> chopBefore, Set<DN> chopAfter)
- throws InputMismatchException, NoSuchElementException,
- DirectoryException {
-
- // Skip leading open-brace.
- skipLeftBrace();
-
- // Parse each chop DN in the sequence.
- boolean isFirstValue = true;
- while (true) {
- // Make sure that there is a closing brace.
- if (hasNextRightBrace()) {
- skipRightBrace();
- break;
- }
-
- // Make sure that there is a comma separator if this is not
- // the first element.
- if (!isFirstValue) {
- skipSeparator();
- } else {
- isFirstValue = false;
- }
-
- // Parse each chop specification which is of the form
- // <type>:<value>.
- String type = StaticUtils.toLowerCase(nextName());
- skipColon();
- if (type.equals("chopbefore")) {
- chopBefore.add(DN.decode(nextStringValue()));
- } else if (type.equals("chopafter")) {
- chopAfter.add(DN.decode(nextStringValue()));
- } else {
- throw new java.util.InputMismatchException();
- }
- }
- }
-
- /**
- * Parse the next token from the string using the specified
- * patterns.
- *
- * @param head
- * The pattern used to determine if the next token is a
- * possible match.
- * @param content
- * The pattern used to parse the token content.
- * @return The next token matching the <code>content</code>
- * pattern.
- * @throws InputMismatchException
- * If the next token does not match the
- * <code>content</code> pattern.
- * @throws NoSuchElementException
- * If input is exhausted.
- */
- private String nextValue(Pattern head, Pattern content)
- throws InputMismatchException, NoSuchElementException {
- if (!scanner.hasNext()) {
- throw new java.util.NoSuchElementException();
- }
-
- if (!scanner.hasNext(head)) {
- throw new java.util.InputMismatchException();
- }
-
- String s = scanner.findInLine(content);
- if (s == null) {
- throw new java.util.InputMismatchException();
- }
-
- return s;
- }
- }
-
- /**
- * Create a new simple subtree specification.
- *
- * @param baseDN
- * The absolute base DN of the subtree.
- * @param minimumDepth
- * The minimum depth (<=0 means unlimited).
- * @param maximumDepth
- * The maximum depth (<0 means unlimited).
- * @param chopBefore
- * The set of chop before local names (relative to the base
- * DN), or <code>null</code> if there are none.
- * @param chopAfter
- * The set of chop after local names (relative to the base
- * DN), or <code>null</code> if there are none.
- */
- protected SimpleSubtreeSpecification(DN baseDN, int minimumDepth,
- int maximumDepth, Iterable<DN> chopBefore, Iterable<DN> chopAfter) {
-
- this.baseDN = baseDN;
- this.minimumDepth = minimumDepth;
- this.maximumDepth = maximumDepth;
-
- if (chopBefore != null && chopBefore.iterator().hasNext()) {
- // Calculate the absolute DNs.
- this.chopBefore = new TreeMap<DN, DN>();
-
- for (DN localName : chopBefore) {
- this.chopBefore.put(baseDN.concat(localName), localName);
- }
- } else {
- // No chop before specifications.
- this.chopBefore = null;
- }
-
- if (chopAfter != null && chopAfter.iterator().hasNext()) {
- // Calculate the absolute DNs.
- this.chopAfter = new TreeMap<DN, DN>();
-
- for (DN localName : chopAfter) {
- this.chopAfter.put(baseDN.concat(localName), localName);
- }
- } else {
- // No chop after specifications.
- this.chopAfter = null;
- }
- }
-
- /**
- * {@inheritDoc}
- */
- public final boolean isDNWithinScope(DN dn) {
-
- if (!dn.isDescendantOf(baseDN)) {
- return false;
- }
-
- // Check minimum and maximum depths.
- int baseRDNCount = baseDN.getNumComponents();
-
- if (minimumDepth > 0) {
- int entryRDNCount = dn.getNumComponents();
-
- if (entryRDNCount - baseRDNCount < minimumDepth) {
- return false;
- }
- }
-
- if (maximumDepth >= 0) {
- int entryRDNCount = dn.getNumComponents();
-
- if (entryRDNCount - baseRDNCount > maximumDepth) {
- return false;
- }
- }
-
- // Check exclusions.
- if (chopBefore != null) {
- for (DN chopBeforeDN : chopBefore.keySet()) {
- if (dn.isDescendantOf(chopBeforeDN)) {
- return false;
- }
- }
- }
-
- if (chopAfter != null) {
- for (DN chopAfterDN : chopAfter.keySet()) {
- if (!dn.equals(chopAfterDN) && dn.isDescendantOf(chopAfterDN)) {
- return false;
- }
- }
- }
-
- // Everything seemed to match.
- return true;
- }
-
- /**
- * {@inheritDoc}
- */
- public final DN getBaseDN() {
- return baseDN;
- }
-
- /**
- * Determine if the common components of this subtree specification
- * are equal to the common components of another subtre specification.
- *
- * @param other
- * The other subtree specification.
- * @return Returns <code>true</code> if they are equal.
- */
- protected final boolean commonComponentsEquals(
- SimpleSubtreeSpecification other) {
-
- if (this == other) {
- return true;
- }
-
- if (minimumDepth != other.minimumDepth) {
- return false;
- }
-
- if (maximumDepth != other.maximumDepth) {
- return false;
- }
-
- if (chopBefore != null && other.chopBefore != null) {
- if (!chopBefore.values().equals(other.chopBefore.values())) {
- return false;
- }
- } else if (chopBefore != other.chopBefore) {
- return false;
- }
-
- if (chopAfter != null && other.chopAfter != null) {
- if (!chopAfter.values().equals(other.chopAfter.values())) {
- return false;
- }
- } else if (chopAfter != other.chopAfter) {
- return false;
- }
-
- return true;
- }
-
- /**
- * Get a hash code of the subtree specification's common components.
- *
- * @return The computed hash code.
- */
- protected final int commonComponentsHashCode() {
-
- int hash = minimumDepth * 31 + maximumDepth;
-
- if (chopBefore != null) {
- hash = hash * 31 + chopBefore.values().hashCode();
- }
-
- if (chopAfter != null) {
- hash = hash * 31 + chopAfter.values().hashCode();
- }
-
- return hash;
- }
-
- /**
- * Get the set of chop after relative DNs.
- *
- * @return Returns the set of chop after relative DNs, or
- * <code>null</code> if there are not any.
- */
- public final Iterable<DN> getChopAfter() {
-
- if (chopAfter != null) {
- return chopAfter.values();
- } else {
- return null;
- }
- }
-
- /**
- * Get the set of chop before relative DNs.
- *
- * @return Returns the set of chop before relative DNs, or
- * <code>null</code> if there are not any.
- */
- public final Iterable<DN> getChopBefore() {
-
- if (chopBefore != null) {
- return chopBefore.values();
- } else {
- return null;
- }
- }
-
- /**
- * Get the maximum depth of the subtree specification.
- *
- * @return Returns the maximum depth (<0 indicates unlimited depth).
- */
- public final int getMaximumDepth() {
- return maximumDepth;
- }
-
- /**
- * Get the minimum depth of the subtree specification.
- *
- * @return Returns the minimum depth (<=0 indicates unlimited depth).
- */
- public final int getMinimumDepth() {
- return minimumDepth;
- }
-}
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 b94f46a..df7d46c 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
@@ -23,13 +23,13 @@
*
*
* Copyright 2009-2010 Sun Microsystems, Inc.
+ * Portions copyright 2011 ForgeRock AS
*/
package org.opends.server.core;
import org.opends.server.api.ClientConnection;
-import org.opends.server.api.SubtreeSpecification;
import java.util.*;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.concurrent.locks.ReentrantReadWriteLock;
@@ -47,18 +47,7 @@
import org.opends.server.loggers.debug.DebugTracer;
import org.opends.server.protocols.internal.InternalClientConnection;
import org.opends.server.protocols.internal.InternalSearchOperation;
-import org.opends.server.types.Control;
-import org.opends.server.types.DebugLogLevel;
-import org.opends.server.types.DereferencePolicy;
-import org.opends.server.types.DN;
-import org.opends.server.types.DirectoryException;
-import org.opends.server.types.Entry;
-import org.opends.server.types.Privilege;
-import org.opends.server.types.ResultCode;
-import org.opends.server.types.SearchResultEntry;
-import org.opends.server.types.SearchScope;
-import org.opends.server.types.SearchFilter;
-import org.opends.server.types.SubEntry;
+import org.opends.server.types.*;
import org.opends.server.types.operation.PostOperationAddOperation;
import org.opends.server.types.operation.PostOperationDeleteOperation;
import org.opends.server.types.operation.PostOperationModifyDNOperation;
diff --git a/opendj-sdk/opends/src/server/org/opends/server/schema/RFC3672SubtreeSpecificationSyntax.java b/opendj-sdk/opends/src/server/org/opends/server/schema/RFC3672SubtreeSpecificationSyntax.java
deleted file mode 100644
index 3328aad..0000000
--- a/opendj-sdk/opends/src/server/org/opends/server/schema/RFC3672SubtreeSpecificationSyntax.java
+++ /dev/null
@@ -1,280 +0,0 @@
-/*
- * 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-2008 Sun Microsystems, Inc.
- */
-package org.opends.server.schema;
-
-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.config.ConfigException;
-import org.opends.server.core.DirectoryServer;
-import org.opends.server.core.RFC3672SubtreeSpecification;
-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). Equality will
- * be allowed eventually, although it's not implemented yet.
- */
-public final class RFC3672SubtreeSpecificationSyntax
- 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<RFC3672SubtreeSpecification>
- createAttributeValueDecoder(DN rootDN) {
- return new Decoder(rootDN);
- }
-
- /**
- * Internal class implementing an attribute value decoder.
- */
- private static class Decoder implements
- AttributeValueDecoder<RFC3672SubtreeSpecification> {
-
- // 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 RFC3672SubtreeSpecification decode(AttributeValue value)
- throws DirectoryException {
- return RFC3672SubtreeSpecification.valueOf(rootDN, value
- .getValue().toString());
- }
- }
-
- /**
- * 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 RFC3672SubtreeSpecificationSyntax() {
- // 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_RFC3672_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_RFC3672_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_RFC3672_SUBTREE_SPECIFICATION_NAME));
- }
- }
-
- /**
- * Retrieves the common name for this attribute syntax.
- *
- * @return The common name for this attribute syntax.
- */
- public String getSyntaxName() {
-
- return SYNTAX_RFC3672_SUBTREE_SPECIFICATION_NAME;
- }
-
- /**
- * Retrieves the OID for this attribute syntax.
- *
- * @return The OID for this attribute syntax.
- */
- public String getOID() {
-
- return SYNTAX_RFC3672_SUBTREE_SPECIFICATION_OID;
- }
-
- /**
- * Retrieves a description for this attribute syntax.
- *
- * @return A description for this attribute syntax.
- */
- public String getDescription() {
-
- return SYNTAX_RFC3672_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 {
- RFC3672SubtreeSpecification.valueOf(DN.nullDN(), value.toString());
-
- return true;
- } catch (DirectoryException e) {
- if (debugEnabled())
- {
- TRACER.debugCaught(DebugLogLevel.ERROR, e);
- }
-
- invalidReason.append(e.getMessageObject());
- return false;
- }
- }
-
-
-
- /**
- * {@inheritDoc}
- */
- public boolean isBinary()
- {
- return false;
- }
-}
diff --git a/opendj-sdk/opends/src/server/org/opends/server/schema/RelativeSubtreeSpecificationSyntax.java b/opendj-sdk/opends/src/server/org/opends/server/schema/RelativeSubtreeSpecificationSyntax.java
deleted file mode 100644
index 2442d14..0000000
--- a/opendj-sdk/opends/src/server/org/opends/server/schema/RelativeSubtreeSpecificationSyntax.java
+++ /dev/null
@@ -1,283 +0,0 @@
-/*
- * 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-2008 Sun Microsystems, Inc.
- */
-package org.opends.server.schema;
-
-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.config.ConfigException;
-import org.opends.server.core.DirectoryServer;
-import org.opends.server.core.RelativeSubtreeSpecification;
-import org.opends.server.types.*;
-
-
-/**
- * This class defines the relative subtree specification attribute
- * syntax, which is used to specify the scope of access controls and
- * their parameters.
- */
-public final class RelativeSubtreeSpecificationSyntax
- 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 relative subtree
- * specifications.
- * @return The attribute value decoder.
- */
- public static AttributeValueDecoder<RelativeSubtreeSpecification>
- createAttributeValueDecoder(DN rootDN) {
- return new Decoder(rootDN);
- }
-
- /**
- * Internal class implementing an attribute value decoder.
- */
- private static class Decoder implements
- AttributeValueDecoder<RelativeSubtreeSpecification> {
-
- // 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 RelativeSubtreeSpecification decode(AttributeValue value)
- throws DirectoryException {
- return RelativeSubtreeSpecification.valueOf(rootDN, value
- .getValue().toString());
- }
- }
-
- /**
- * 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 RelativeSubtreeSpecificationSyntax() {
- // 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_RELATIVE_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_RELATIVE_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_RELATIVE_SUBTREE_SPECIFICATION_NAME));
- }
- }
-
- /**
- * Retrieves the common name for this attribute syntax.
- *
- * @return The common name for this attribute syntax.
- */
- public String getSyntaxName() {
-
- return SYNTAX_RELATIVE_SUBTREE_SPECIFICATION_NAME;
- }
-
- /**
- * Retrieves the OID for this attribute syntax.
- *
- * @return The OID for this attribute syntax.
- */
- public String getOID() {
-
- return SYNTAX_RELATIVE_SUBTREE_SPECIFICATION_OID;
- }
-
- /**
- * Retrieves a description for this attribute syntax.
- *
- * @return A description for this attribute syntax.
- */
- public String getDescription() {
-
- return SYNTAX_RELATIVE_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 {
- RelativeSubtreeSpecification.valueOf(DN.nullDN(), value.toString());
-
- return true;
- } catch (DirectoryException e) {
- if (debugEnabled())
- {
- TRACER.debugCaught(DebugLogLevel.ERROR, e);
- }
-
- invalidReason.append(e.getMessageObject());
- return false;
- }
- }
-
-
-
- /**
- * {@inheritDoc}
- */
- public boolean isBinary()
- {
- return false;
- }
-}
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 ad1987f..1ee117c 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
@@ -23,6 +23,7 @@
*
*
* Copyright 2006-2010 Sun Microsystems, Inc.
+ * Portions copyright 2011 ForgeRock AS
*/
package org.opends.server.schema;
@@ -1668,30 +1669,6 @@
/**
- * The OID for the RFC3672 subtree specification attribute syntax.
- */
- public static final String SYNTAX_RFC3672_SUBTREE_SPECIFICATION_OID =
- SYNTAX_SUBTREE_SPECIFICATION_OID;
-
-
-
- /**
- * The description for the RFC3672 subtree specification attribute syntax.
- */
- public static final String SYNTAX_RFC3672_SUBTREE_SPECIFICATION_DESCRIPTION =
- "RFC3672 Subtree Specification";
-
-
-
- /**
- * The name for the RFC3672 subtree specification attribute syntax.
- */
- public static final String SYNTAX_RFC3672_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 =
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
index b747ba6..17f5893 100644
--- a/opendj-sdk/opends/src/server/org/opends/server/schema/SubtreeSpecificationSyntax.java
+++ b/opendj-sdk/opends/src/server/org/opends/server/schema/SubtreeSpecificationSyntax.java
@@ -23,11 +23,12 @@
*
*
* Copyright 2006-2010 Sun Microsystems, Inc.
+ * Portions copyright 2011 ForgeRock AS
*/
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.*;
@@ -41,11 +42,8 @@
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.DirectoryServer;
-import org.opends.server.core.RFC3672SubtreeSpecification;
-import org.opends.server.core.RelativeSubtreeSpecification;
import org.opends.server.types.*;
@@ -107,30 +105,8 @@
*/
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) {}
-
- if (subTreeSpec == null) {
- Message message =
- ERR_ATTR_SYNTAX_SUBTREE_SPECIFICATION_INVALID.get(
- specString);
- throw new DirectoryException(
- ResultCode.INVALID_ATTRIBUTE_SYNTAX, message);
- }
-
- return subTreeSpec;
+ return SubtreeSpecification.valueOf(rootDN, value
+ .getValue().toString());
}
}
@@ -275,28 +251,19 @@
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) {}
+ SubtreeSpecification.valueOf(DN.nullDN(), value.toString());
- if (subTreeSpec == null) {
- Message message =
- ERR_ATTR_SYNTAX_SUBTREE_SPECIFICATION_INVALID.get(
- specString);
- invalidReason.append(message);
+ return true;
+ } catch (DirectoryException e) {
+ if (debugEnabled())
+ {
+ TRACER.debugCaught(DebugLogLevel.ERROR, e);
+ }
+
+ invalidReason.append(e.getMessageObject());
+ return false;
}
-
- 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 e916f12..86944a3 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
@@ -23,23 +23,19 @@
*
*
* Copyright 2009-2010 Sun Microsystems, Inc.
+ * Portions copyright 2011 ForgeRock AS
*/
package org.opends.server.types;
import org.opends.messages.Message;
-import org.opends.server.core.RelativeSubtreeSpecification;
-import org.opends.server.api.SubtreeSpecification;
import java.util.List;
import java.util.ArrayList;
import java.util.Set;
import java.util.LinkedHashSet;
-import org.opends.server.loggers.debug.DebugTracer;
import org.opends.server.core.DirectoryServer;
-import org.opends.server.core.RFC3672SubtreeSpecification;
import static org.opends.server.util.ServerConstants.*;
-import static org.opends.server.loggers.debug.DebugLogger.*;
import static org.opends.messages.SchemaMessages.*;
/**
@@ -48,11 +44,6 @@
*/
public class SubEntry {
/**
- * The tracer object for the debug logger.
- */
- private static final DebugTracer TRACER = getTracer();
-
- /**
* Defines the set of permissable values for the conflict behavior.
* Specifies the behavior that the server is to exhibit for entries
* that already contain one or more real values for the associated
@@ -216,25 +207,10 @@
{
for (AttributeValue value : attr)
{
- // 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(
+ this.subTreeSpec = SubtreeSpecification.valueOf(
entry.getDN().getParent(), specString);
isValidSpec = true;
}
@@ -270,7 +246,7 @@
{
// There is none for some reason eg this could be
// old Draft based ldapSubEntry so create a dummy.
- this.subTreeSpec = new RFC3672SubtreeSpecification(
+ this.subTreeSpec = new SubtreeSpecification(
DN.NULL_DN, null, -1, -1,
null, null, null);
}
diff --git a/opendj-sdk/opends/src/server/org/opends/server/types/SubtreeSpecification.java b/opendj-sdk/opends/src/server/org/opends/server/types/SubtreeSpecification.java
new file mode 100644
index 0000000..103a880
--- /dev/null
+++ b/opendj-sdk/opends/src/server/org/opends/server/types/SubtreeSpecification.java
@@ -0,0 +1,1836 @@
+/*
+ * 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.
+ * Portions copyright 2011 ForgeRock AS
+ */
+package org.opends.server.types;
+
+
+
+import static org.opends.messages.SchemaMessages.*;
+
+import java.util.*;
+import java.util.regex.Pattern;
+
+import org.opends.messages.Message;
+import org.opends.server.core.DirectoryServer;
+import org.opends.server.util.StaticUtils;
+
+
+
+/**
+ * An RFC 3672 subtree specification.
+ * <p>
+ * This implementation extends RFC 3672 by supporting search filters
+ * for specification filters. More specifically, the
+ * {@code Refinement} product has been extended as follows:
+ *
+ * <pre>
+ * Refinement = item / and / or / not / Filter
+ *
+ * Filter = dquote *SafeUTF8Character dquote
+ * </pre>
+ *
+ * @see <a href="http://tools.ietf.org/html/rfc3672">RFC 3672 -
+ * Subentries inthe Lightweight Directory Access Protocol (LDAP)
+ * </a>
+ */
+@org.opends.server.types.PublicAPI(
+ stability = org.opends.server.types.StabilityLevel.VOLATILE,
+ mayInstantiate = false,
+ mayExtend = true,
+ mayInvoke = false)
+public final class SubtreeSpecification
+{
+
+ /**
+ * RFC 3672 subtree specification AND refinement. This type of
+ * refinement filters entries based on all of the underlying
+ * refinements being <code>true</code>.
+ */
+ public static final class AndRefinement extends Refinement
+ {
+ // The set of refinements which must all be true.
+ private final Collection<Refinement> refinementSet;
+
+
+
+ /**
+ * Create a new AND refinement.
+ *
+ * @param refinementSet
+ * The set of refinements which must all be
+ * <code>true</code>.
+ */
+ public AndRefinement(final Collection<Refinement> refinementSet)
+ {
+
+ this.refinementSet = refinementSet;
+ }
+
+
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public boolean equals(final Object obj)
+ {
+
+ if (this == obj)
+ {
+ return true;
+ }
+
+ if (obj instanceof AndRefinement)
+ {
+ final AndRefinement other = (AndRefinement) obj;
+
+ return refinementSet.equals(other.refinementSet);
+ }
+
+ return false;
+ }
+
+
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public int hashCode()
+ {
+
+ return refinementSet.hashCode();
+ }
+
+
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public boolean matches(final Entry entry)
+ {
+ for (final Refinement refinement : refinementSet)
+ {
+ if (refinement.matches(entry) == false)
+ {
+ return false;
+ }
+ }
+
+ // All sub-refinements matched.
+ return true;
+ }
+
+
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public StringBuilder toString(final StringBuilder builder)
+ {
+ switch (refinementSet.size())
+ {
+ case 0:
+ // Do nothing.
+ break;
+ case 1:
+ refinementSet.iterator().next().toString(builder);
+ break;
+ default:
+ builder.append("and:{");
+ final Iterator<Refinement> iterator = refinementSet
+ .iterator();
+ iterator.next().toString(builder);
+ while (iterator.hasNext())
+ {
+ builder.append(", ");
+ iterator.next().toString(builder);
+ }
+ builder.append("}");
+ break;
+ }
+
+ return builder;
+ }
+ }
+
+
+
+ /**
+ * A refinement which uses a search filter.
+ */
+ public static final class FilterRefinement extends Refinement
+ {
+ // The search filter.
+ private final SearchFilter filter;
+
+
+
+ /**
+ * Create a new filter refinement.
+ *
+ * @param filter
+ * The search filter.
+ */
+ public FilterRefinement(final SearchFilter filter)
+ {
+
+ this.filter = filter;
+ }
+
+
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public boolean equals(final Object obj)
+ {
+
+ if (this == obj)
+ {
+ return true;
+ }
+
+ if (obj instanceof FilterRefinement)
+ {
+ final FilterRefinement other = (FilterRefinement) obj;
+ return filter.equals(other.filter);
+ }
+
+ return false;
+ }
+
+
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public int hashCode()
+ {
+
+ return filter.hashCode();
+ }
+
+
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public boolean matches(final Entry entry)
+ {
+ try
+ {
+ return filter.matchesEntry(entry);
+ }
+ catch (final 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;
+ }
+ }
+
+
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public StringBuilder toString(final StringBuilder builder)
+ {
+ StaticUtils.toRFC3641StringValue(builder, filter.toString());
+ return builder;
+ }
+ }
+
+
+
+ /**
+ * RFC 3672 subtree specification Item refinement. This type of
+ * refinement filters entries based on the presence of a specified
+ * object class.
+ */
+ public static final class ItemRefinement extends Refinement
+ {
+ // The item's object class.
+ private final String objectClass;
+
+ // The item's normalized object class.
+ private final String normalizedObjectClass;
+
+
+
+ /**
+ * Create a new item refinement.
+ *
+ * @param objectClass
+ * The item's object class.
+ */
+ public ItemRefinement(final String objectClass)
+ {
+
+ this.objectClass = objectClass;
+ this.normalizedObjectClass = StaticUtils
+ .toLowerCase(objectClass.trim());
+ }
+
+
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public boolean equals(final Object obj)
+ {
+
+ if (this == obj)
+ {
+ return true;
+ }
+
+ if (obj instanceof ItemRefinement)
+ {
+ final ItemRefinement other = (ItemRefinement) obj;
+
+ return normalizedObjectClass
+ .equals(other.normalizedObjectClass);
+ }
+
+ return false;
+ }
+
+
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public int hashCode()
+ {
+
+ return normalizedObjectClass.hashCode();
+ }
+
+
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public boolean matches(final Entry entry)
+ {
+ final ObjectClass oc = DirectoryServer
+ .getObjectClass(normalizedObjectClass);
+
+ if (oc == null)
+ {
+ return false;
+ }
+ else
+ {
+ return entry.hasObjectClass(oc);
+ }
+ }
+
+
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public StringBuilder toString(final StringBuilder builder)
+ {
+ builder.append("item:");
+ builder.append(objectClass);
+ return builder;
+ }
+ }
+
+
+
+ /**
+ * RFC 3672 subtree specification NOT refinement. This type of
+ * refinement filters entries based on the underlying refinement
+ * being <code>false</code>
+ * .
+ */
+ public static final class NotRefinement extends Refinement
+ {
+ // The inverted refinement.
+ private final Refinement refinement;
+
+
+
+ /**
+ * Create a new NOT refinement.
+ *
+ * @param refinement
+ * The refinement which must be <code>false</code>.
+ */
+ public NotRefinement(final Refinement refinement)
+ {
+
+ this.refinement = refinement;
+ }
+
+
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public boolean equals(final Object obj)
+ {
+
+ if (this == obj)
+ {
+ return true;
+ }
+
+ if (obj instanceof NotRefinement)
+ {
+ final NotRefinement other = (NotRefinement) obj;
+
+ return refinement.equals(other.refinement);
+ }
+
+ return false;
+ }
+
+
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public int hashCode()
+ {
+
+ return refinement.hashCode();
+ }
+
+
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public boolean matches(final Entry entry)
+ {
+ return !refinement.matches(entry);
+ }
+
+
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public StringBuilder toString(final StringBuilder builder)
+ {
+ builder.append("not:");
+ return refinement.toString(builder);
+ }
+ }
+
+
+
+ /**
+ * RFC 3672 subtree specification OR refinement. This type of
+ * refinement filters entries based on at least one of the
+ * underlying refinements being <code>true</code>.
+ */
+ public static final class OrRefinement extends Refinement
+ {
+ // The set of refinements of which at least one must be true.
+ private final Collection<Refinement> refinementSet;
+
+
+
+ /**
+ * Create a new OR refinement.
+ *
+ * @param refinementSet
+ * The set of refinements of which at least one must be
+ * <code>true</code>.
+ */
+ public OrRefinement(final Collection<Refinement> refinementSet)
+ {
+
+ this.refinementSet = refinementSet;
+ }
+
+
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public boolean equals(final Object obj)
+ {
+
+ if (this == obj)
+ {
+ return true;
+ }
+
+ if (obj instanceof AndRefinement)
+ {
+ final AndRefinement other = (AndRefinement) obj;
+
+ return refinementSet.equals(other.refinementSet);
+ }
+
+ return false;
+ }
+
+
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public int hashCode()
+ {
+
+ return refinementSet.hashCode();
+ }
+
+
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public boolean matches(final Entry entry)
+ {
+ for (final Refinement refinement : refinementSet)
+ {
+ if (refinement.matches(entry) == true)
+ {
+ return true;
+ }
+ }
+
+ // No sub-refinements matched.
+ return false;
+ }
+
+
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public StringBuilder toString(final StringBuilder builder)
+ {
+ switch (refinementSet.size())
+ {
+ case 0:
+ // Do nothing.
+ break;
+ case 1:
+ refinementSet.iterator().next().toString(builder);
+ break;
+ default:
+ builder.append("or:{");
+ final Iterator<Refinement> iterator = refinementSet
+ .iterator();
+ iterator.next().toString(builder);
+ while (iterator.hasNext())
+ {
+ builder.append(", ");
+ iterator.next().toString(builder);
+ }
+ builder.append("}");
+ break;
+ }
+
+ return builder;
+ }
+ }
+
+
+
+ /**
+ * Abstract interface for RFC3672 specification filter refinements.
+ */
+ public static abstract class Refinement
+ {
+ /**
+ * Create a new RFC3672 specification filter refinement.
+ */
+ protected Refinement()
+ {
+ // No implementation required.
+ }
+
+
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public abstract boolean equals(Object obj);
+
+
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public abstract int hashCode();
+
+
+
+ /**
+ * Check if the refinement matches the given entry.
+ *
+ * @param entry
+ * The filterable entry.
+ * @return Returns <code>true</code> if the entry matches the
+ * refinement, or <code>false</code> otherwise.
+ */
+ public abstract boolean matches(Entry entry);
+
+
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public final String toString()
+ {
+ final StringBuilder builder = new StringBuilder();
+
+ return toString(builder).toString();
+ }
+
+
+
+ /**
+ * Append the string representation of the refinement to the
+ * provided strin builder.
+ *
+ * @param builder
+ * The string builder.
+ * @return The string builder.
+ */
+ public abstract StringBuilder toString(StringBuilder builder);
+ }
+
+
+
+ /**
+ * Internal utility class which can be used by sub-classes to help
+ * parse string representations.
+ */
+ protected static final class Parser
+ {
+ // Text scanner used to parse the string value.
+ private final Scanner scanner;
+
+ // Pattern used to detect left braces.
+ private static Pattern LBRACE = Pattern.compile("\\{.*");
+
+ // Pattern used to parse left braces.
+ private static Pattern LBRACE_TOKEN = Pattern.compile("\\{");
+
+ // Pattern used to detect right braces.
+ private static Pattern RBRACE = Pattern.compile("\\}.*");
+
+ // Pattern used to parse right braces.
+ private static Pattern RBRACE_TOKEN = Pattern.compile("\\}");
+
+ // Pattern used to detect comma separators.
+ private static Pattern SEP = Pattern.compile(",.*");
+
+ // Pattern used to parse comma separators.
+ private static Pattern SEP_TOKEN = Pattern.compile(",");
+
+ // Pattern used to detect colon separators.
+ private static Pattern COLON = Pattern.compile(":.*");
+
+ // Pattern used to parse colon separators.
+ private static Pattern COLON_TOKEN = Pattern.compile(":");
+
+ // Pattern used to detect integer values.
+ private static Pattern INT = Pattern.compile("\\d.*");
+
+ // Pattern used to parse integer values.
+ private static Pattern INT_TOKEN = Pattern.compile("\\d+");
+
+ // Pattern used to detect name values.
+ private static Pattern NAME = Pattern.compile("[\\w_;-].*");
+
+ // Pattern used to parse name values.
+ private static Pattern NAME_TOKEN = Pattern.compile("[\\w_;-]+");
+
+ // Pattern used to detect RFC3641 string values.
+ private static Pattern STRING_VALUE = Pattern.compile("\".*");
+
+ // Pattern used to parse RFC3641 string values.
+ private static Pattern STRING_VALUE_TOKEN = Pattern
+ .compile("\"([^\"]|(\"\"))*\"");
+
+
+
+ /**
+ * Create a new parser for a subtree specification string value.
+ *
+ * @param value
+ * The subtree specification string value.
+ */
+ public Parser(final String value)
+ {
+ this.scanner = new Scanner(value);
+ }
+
+
+
+ /**
+ * Determine if there are remaining tokens.
+ *
+ * @return <code>true</code> if and only if there are remaining
+ * tokens.
+ */
+ public boolean hasNext()
+ {
+ return scanner.hasNext();
+ }
+
+
+
+ /**
+ * Determine if the next token is a right-brace character.
+ *
+ * @return <code>true</code> if and only if the next token is a
+ * valid right brace character.
+ */
+ public boolean hasNextRightBrace()
+ {
+ return scanner.hasNext(RBRACE);
+ }
+
+
+
+ /**
+ * Scans the next token of the input as a non-negative
+ * <code>int</code> value.
+ *
+ * @return The name value scanned from the input.
+ * @throws InputMismatchException
+ * If the next token is not a valid non-negative integer
+ * string.
+ * @throws NoSuchElementException
+ * If input is exhausted.
+ */
+ public int nextInt() throws InputMismatchException,
+ NoSuchElementException
+ {
+ final String s = nextValue(INT, INT_TOKEN);
+ return Integer.parseInt(s);
+ }
+
+
+
+ /**
+ * Scans the next token of the input as a key value.
+ *
+ * @return The lower-case key value scanned from the input.
+ * @throws InputMismatchException
+ * If the next token is not a valid key string.
+ * @throws NoSuchElementException
+ * If input is exhausted.
+ */
+ public String nextKey() throws InputMismatchException,
+ NoSuchElementException
+ {
+ return StaticUtils.toLowerCase(scanner.next());
+ }
+
+
+
+ /**
+ * Scans the next token of the input as a name value.
+ * <p>
+ * A name is any string containing only alpha-numeric characters
+ * or hyphens, semi-colons, or underscores.
+ *
+ * @return The name value scanned from the input.
+ * @throws InputMismatchException
+ * If the next token is not a valid name string.
+ * @throws NoSuchElementException
+ * If input is exhausted.
+ */
+ public String nextName() throws InputMismatchException,
+ NoSuchElementException
+ {
+ return nextValue(NAME, NAME_TOKEN);
+ }
+
+
+
+ /**
+ * Scans the next tokens of the input as a set of specific
+ * exclusions encoded according to the SpecificExclusion
+ * production in RFC 3672.
+ *
+ * @param chopBefore
+ * The set of chop before local names.
+ * @param chopAfter
+ * The set of chop after local names.
+ * @throws InputMismatchException
+ * If the common component did not have a valid syntax.
+ * @throws NoSuchElementException
+ * If input is exhausted.
+ * @throws DirectoryException
+ * If an error occurred when attempting to parse a
+ * DN value.
+ */
+ public void nextSpecificExclusions(final Set<DN> chopBefore,
+ final Set<DN> chopAfter) throws InputMismatchException,
+ NoSuchElementException, DirectoryException
+ {
+
+ // Skip leading open-brace.
+ skipLeftBrace();
+
+ // Parse each chop DN in the sequence.
+ boolean isFirstValue = true;
+ while (true)
+ {
+ // Make sure that there is a closing brace.
+ if (hasNextRightBrace())
+ {
+ skipRightBrace();
+ break;
+ }
+
+ // Make sure that there is a comma separator if this is not
+ // the first element.
+ if (!isFirstValue)
+ {
+ skipSeparator();
+ }
+ else
+ {
+ isFirstValue = false;
+ }
+
+ // Parse each chop specification which is of the form
+ // <type>:<value>.
+ final String type = StaticUtils.toLowerCase(nextName());
+ skipColon();
+ if (type.equals("chopbefore"))
+ {
+ chopBefore.add(DN.decode(nextStringValue()));
+ }
+ else if (type.equals("chopafter"))
+ {
+ chopAfter.add(DN.decode(nextStringValue()));
+ }
+ else
+ {
+ throw new java.util.InputMismatchException();
+ }
+ }
+ }
+
+
+
+ /**
+ * Scans the next token of the input as a string quoted according
+ * to the StringValue production in RFC 3641.
+ * <p>
+ * The return string has its outer double quotes removed and any
+ * escape inner double quotes unescaped.
+ *
+ * @return The string value scanned from the input.
+ * @throws InputMismatchException
+ * If the next token is not a valid string.
+ * @throws NoSuchElementException
+ * If input is exhausted.
+ */
+ public String nextStringValue() throws InputMismatchException,
+ NoSuchElementException
+ {
+ final String s = nextValue(STRING_VALUE, STRING_VALUE_TOKEN);
+ return s.substring(1, s.length() - 1).replace("\"\"", "\"");
+ }
+
+
+
+ /**
+ * Skip a colon separator.
+ *
+ * @throws InputMismatchException
+ * If the next token is not a colon separator character.
+ * @throws NoSuchElementException
+ * If input is exhausted.
+ */
+ public void skipColon() throws InputMismatchException,
+ NoSuchElementException
+ {
+ nextValue(COLON, COLON_TOKEN);
+ }
+
+
+
+ /**
+ * Skip a left-brace character.
+ *
+ * @throws InputMismatchException
+ * If the next token is not a left-brace character.
+ * @throws NoSuchElementException
+ * If input is exhausted.
+ */
+ public void skipLeftBrace() throws InputMismatchException,
+ NoSuchElementException
+ {
+ nextValue(LBRACE, LBRACE_TOKEN);
+ }
+
+
+
+ /**
+ * Skip a right-brace character.
+ *
+ * @throws InputMismatchException
+ * If the next token is not a right-brace character.
+ * @throws NoSuchElementException
+ * If input is exhausted.
+ */
+ public void skipRightBrace() throws InputMismatchException,
+ NoSuchElementException
+ {
+ nextValue(RBRACE, RBRACE_TOKEN);
+ }
+
+
+
+ /**
+ * Skip a comma separator.
+ *
+ * @throws InputMismatchException
+ * If the next token is not a comma separator character.
+ * @throws NoSuchElementException
+ * If input is exhausted.
+ */
+ public void skipSeparator() throws InputMismatchException,
+ NoSuchElementException
+ {
+ nextValue(SEP, SEP_TOKEN);
+ }
+
+
+
+ /**
+ * Parse the next token from the string using the specified
+ * patterns.
+ *
+ * @param head
+ * The pattern used to determine if the next token is a
+ * possible match.
+ * @param content
+ * The pattern used to parse the token content.
+ * @return The next token matching the <code>content</code>
+ * pattern.
+ * @throws InputMismatchException
+ * If the next token does not match the
+ * <code>content</code> pattern.
+ * @throws NoSuchElementException
+ * If input is exhausted.
+ */
+ private String nextValue(final Pattern head,
+ final Pattern content)
+ throws InputMismatchException, NoSuchElementException
+ {
+ if (!scanner.hasNext())
+ {
+ throw new java.util.NoSuchElementException();
+ }
+
+ if (!scanner.hasNext(head))
+ {
+ throw new java.util.InputMismatchException();
+ }
+
+ final String s = scanner.findInLine(content);
+ if (s == null)
+ {
+ throw new java.util.InputMismatchException();
+ }
+
+ return s;
+ }
+ }
+
+
+
+ /**
+ * Parses the string argument as an RFC3672 subtree specification.
+ *
+ * @param rootDN
+ * The DN of the subtree specification's base entry.
+ * @param s
+ * The string to be parsed.
+ * @return The RFC3672 subtree specification represented by the
+ * string argument.
+ * @throws DirectoryException
+ * If the string does not contain a parsable relative
+ * subtree specification.
+ */
+ public static SubtreeSpecification valueOf(final DN rootDN,
+ final String s) throws DirectoryException
+ {
+
+ // Default values.
+ DN relativeBaseDN = null;
+
+ int minimum = -1;
+ int maximum = -1;
+
+ final HashSet<DN> chopBefore = new HashSet<DN>();
+ final HashSet<DN> chopAfter = new HashSet<DN>();
+
+ Refinement refinement = null;
+
+ // Value must have an opening left brace.
+ final Parser parser = new Parser(s);
+ boolean isValid = true;
+
+ try
+ {
+ parser.skipLeftBrace();
+
+ // Parse each element of the value sequence.
+ boolean isFirst = true;
+
+ while (true)
+ {
+ if (parser.hasNextRightBrace())
+ {
+ // Make sure that there is a closing brace and no trailing
+ // text.
+ parser.skipRightBrace();
+
+ if (parser.hasNext())
+ {
+ throw new java.util.InputMismatchException();
+ }
+ break;
+ }
+
+ // Make sure that there is a comma separator if this is not
+ // the first element.
+ if (!isFirst)
+ {
+ parser.skipSeparator();
+ }
+ else
+ {
+ isFirst = false;
+ }
+
+ final String key = parser.nextKey();
+ if (key.equals("base"))
+ {
+ if (relativeBaseDN != null)
+ {
+ // Relative base DN specified more than once.
+ throw new InputMismatchException();
+ }
+ relativeBaseDN = DN.decode(parser.nextStringValue());
+ }
+ else if (key.equals("minimum"))
+ {
+ if (minimum != -1)
+ {
+ // Minimum specified more than once.
+ throw new InputMismatchException();
+ }
+ minimum = parser.nextInt();
+ }
+ else if (key.equals("maximum"))
+ {
+ if (maximum != -1)
+ {
+ // Maximum specified more than once.
+ throw new InputMismatchException();
+ }
+ maximum = parser.nextInt();
+ }
+ else if (key.equals("specificationfilter"))
+ {
+ if (refinement != null)
+ {
+ // Refinements specified more than once.
+ throw new InputMismatchException();
+ }
+
+ // First try normal search filter before RFC3672
+ // refinements.
+ try
+ {
+ final SearchFilter filter = SearchFilter
+ .createFilterFromString(parser.nextStringValue());
+ refinement = new FilterRefinement(filter);
+ }
+ catch (final InputMismatchException e)
+ {
+ refinement = parseRefinement(parser);
+ }
+ }
+ else if (key.equals("specificexclusions"))
+ {
+ if (!chopBefore.isEmpty() || !chopAfter.isEmpty())
+ {
+ // Specific exclusions specified more than once.
+ throw new InputMismatchException();
+ }
+
+ parser.nextSpecificExclusions(chopBefore, chopAfter);
+ }
+ else
+ {
+ throw new InputMismatchException();
+ }
+ }
+
+ // Make default minimum value is 0.
+ if (minimum < 0)
+ {
+ minimum = 0;
+ }
+
+ // Check that the maximum, if specified, is gte the minimum.
+ if (maximum >= 0 && maximum < minimum)
+ {
+ isValid = false;
+ }
+ }
+ catch (final InputMismatchException e)
+ {
+ isValid = false;
+ }
+ catch (final NoSuchElementException e)
+ {
+ isValid = false;
+ }
+
+ if (isValid)
+ {
+ return new SubtreeSpecification(rootDN, relativeBaseDN,
+ minimum, maximum, chopBefore, chopAfter, refinement);
+ }
+ else
+ {
+ final Message message =
+ ERR_ATTR_SYNTAX_RFC3672_SUBTREE_SPECIFICATION_INVALID.get(s);
+ throw new DirectoryException(
+ ResultCode.INVALID_ATTRIBUTE_SYNTAX, message);
+ }
+ }
+
+
+
+ /**
+ * Parse a single refinement.
+ *
+ * @param parser
+ * The active subtree specification parser.
+ * @return The parsed refinement.
+ * @throws InputMismatchException
+ * If the common component did not have a valid syntax.
+ * @throws NoSuchElementException
+ * If input is exhausted.
+ */
+ private static Refinement parseRefinement(final Parser parser)
+ throws InputMismatchException, NoSuchElementException
+ {
+ // Get the type of refinement.
+ final String type = StaticUtils.toLowerCase(parser.nextName());
+
+ // Skip the colon separator.
+ parser.skipColon();
+
+ if (type.equals("item"))
+ {
+ return new ItemRefinement(parser.nextName());
+ }
+ else if (type.equals("not"))
+ {
+ final Refinement refinement = parseRefinement(parser);
+ return new NotRefinement(refinement);
+ }
+ else if (type.equals("and"))
+ {
+ final ArrayList<Refinement> refinements =
+ parseRefinementSet(parser);
+ return new AndRefinement(refinements);
+ }
+ else if (type.equals("or"))
+ {
+ final ArrayList<Refinement> refinements =
+ parseRefinementSet(parser);
+ return new OrRefinement(refinements);
+ }
+ else
+ {
+ // Unknown refinement type.
+ throw new InputMismatchException();
+ }
+ }
+
+
+
+ /**
+ * Parse a list of refinements.
+ *
+ * @param parser
+ * The active subtree specification parser.
+ * @return The parsed refinement list.
+ * @throws InputMismatchException
+ * If the common component did not have a valid syntax.
+ * @throws NoSuchElementException
+ * If input is exhausted.
+ */
+ private static ArrayList<Refinement> parseRefinementSet(
+ final Parser parser) throws InputMismatchException,
+ NoSuchElementException
+ {
+ final ArrayList<Refinement> refinements =
+ new ArrayList<Refinement>();
+
+ // Skip leading open-brace.
+ parser.skipLeftBrace();
+
+ // Parse each chop DN in the sequence.
+ boolean isFirstValue = true;
+ while (true)
+ {
+ // Make sure that there is a closing brace.
+ if (parser.hasNextRightBrace())
+ {
+ parser.skipRightBrace();
+ break;
+ }
+
+ // Make sure that there is a comma separator if this is not
+ // the first element.
+ if (!isFirstValue)
+ {
+ parser.skipSeparator();
+ }
+ else
+ {
+ isFirstValue = false;
+ }
+
+ // Parse each sub-refinement.
+ final Refinement refinement = parseRefinement(parser);
+ refinements.add(refinement);
+ }
+
+ return refinements;
+ }
+
+
+
+ // The absolute base of the subtree.
+ private final DN baseDN;
+
+ // Optional minimum depth (<=0 means unlimited).
+ private final int minimumDepth;
+
+ // Optional maximum depth (<0 means unlimited).
+ private final int maximumDepth;
+
+ // Optional set of chop before absolute DNs (mapping to their
+ // local-names).
+ private final Map<DN, DN> chopBefore;
+
+ // Optional set of chop after absolute DNs (mapping to their
+ // local-names).
+ private final Map<DN, DN> chopAfter;
+
+ // The root DN.
+ private final DN rootDN;
+
+ // The optional relative base DN.
+ private final DN relativeBaseDN;
+
+ // The optional specification filter refinements.
+ private final Refinement refinements;
+
+
+
+ /**
+ * Create a new RFC3672 subtree specification.
+ *
+ * @param rootDN
+ * The root DN of the subtree.
+ * @param relativeBaseDN
+ * The relative base DN (or <code>null</code> if not
+ * specified).
+ * @param minimumDepth
+ * The minimum depth (<=0 means unlimited).
+ * @param maximumDepth
+ * The maximum depth (<0 means unlimited).
+ * @param chopBefore
+ * The set of chop before local names (relative to the
+ * relative base DN), or <code>null</code> if there are
+ * none.
+ * @param chopAfter
+ * The set of chop after local names (relative to the
+ * relative base DN), or <code>null</code> if there are
+ * none.
+ * @param refinements
+ * The optional specification filter refinements, or
+ * <code>null</code> if there are none.
+ */
+ public SubtreeSpecification(final DN rootDN,
+ final DN relativeBaseDN, final int minimumDepth,
+ final int maximumDepth, final Iterable<DN> chopBefore,
+ final Iterable<DN> chopAfter, final Refinement refinements)
+ {
+ this.baseDN = relativeBaseDN == null ? rootDN : rootDN
+ .concat(relativeBaseDN);
+ this.minimumDepth = minimumDepth;
+ this.maximumDepth = maximumDepth;
+
+ if (chopBefore != null && chopBefore.iterator().hasNext())
+ {
+ // Calculate the absolute DNs.
+ final TreeMap<DN, DN> map = new TreeMap<DN, DN>();
+ for (final DN localName : chopBefore)
+ {
+ map.put(baseDN.concat(localName), localName);
+ }
+ this.chopBefore = Collections.unmodifiableMap(map);
+ }
+ else
+ {
+ // No chop before specifications.
+ this.chopBefore = Collections.emptyMap();
+ }
+
+ if (chopAfter != null && chopAfter.iterator().hasNext())
+ {
+ // Calculate the absolute DNs.
+ final TreeMap<DN, DN> map = new TreeMap<DN, DN>();
+ for (final DN localName : chopAfter)
+ {
+ map.put(baseDN.concat(localName), localName);
+ }
+ this.chopAfter = Collections.unmodifiableMap(map);
+ }
+ else
+ {
+ // No chop after specifications.
+ this.chopAfter = Collections.emptyMap();
+ }
+
+ this.rootDN = rootDN;
+ this.relativeBaseDN = relativeBaseDN;
+ this.refinements = refinements;
+ }
+
+
+
+ /**
+ * Indicates whether the provided object is logically equal to this
+ * subtree specification object.
+ *
+ * @param obj
+ * The object for which to make the determination.
+ * @return {@code true} if the provided object is logically equal
+ * to this subtree specification object, or {@code false}
+ * if not.
+ */
+ @Override
+ public boolean equals(final Object obj)
+ {
+
+ if (this == obj)
+ {
+ return true;
+ }
+
+ if (obj instanceof SubtreeSpecification)
+ {
+ final SubtreeSpecification other = (SubtreeSpecification) obj;
+
+ if (!commonComponentsEquals(other))
+ {
+ return false;
+ }
+
+ if (!getBaseDN().equals(other.getBaseDN()))
+ {
+ return false;
+ }
+
+ if (refinements != null)
+ {
+ return refinements.equals(other.refinements);
+ }
+ else
+ {
+ return refinements == other.refinements;
+ }
+ }
+
+ return false;
+ }
+
+
+
+ /**
+ * Get the absolute base DN of the subtree specification.
+ *
+ * @return Returns the absolute base DN of the subtree
+ * specification.
+ */
+ public DN getBaseDN()
+ {
+ return baseDN;
+ }
+
+
+
+ /**
+ * Get the set of chop after relative DNs.
+ *
+ * @return Returns the set of chop after relative DNs.
+ */
+ public Iterable<DN> getChopAfter()
+ {
+
+ return chopAfter.values();
+ }
+
+
+
+ /**
+ * Get the set of chop before relative DNs.
+ *
+ * @return Returns the set of chop before relative DNs.
+ */
+ public Iterable<DN> getChopBefore()
+ {
+
+ return chopBefore.values();
+ }
+
+
+
+ /**
+ * Get the maximum depth of the subtree specification.
+ *
+ * @return Returns the maximum depth (<0 indicates unlimited depth).
+ */
+ public int getMaximumDepth()
+ {
+ return maximumDepth;
+ }
+
+
+
+ /**
+ * Get the minimum depth of the subtree specification.
+ *
+ * @return Returns the minimum depth (<=0 indicates unlimited
+ * depth).
+ */
+ public int getMinimumDepth()
+ {
+ return minimumDepth;
+ }
+
+
+
+ /**
+ * Get the specification filter refinements.
+ *
+ * @return Returns the specification filter refinements, or
+ * <code>null</code> if none were specified.
+ */
+ public Refinement getRefinements()
+ {
+ return refinements;
+ }
+
+
+
+ /**
+ * Get the relative base DN.
+ *
+ * @return Returns the relative base DN or <code>null</code> if
+ * none was specified.
+ */
+ public DN getRelativeBaseDN()
+ {
+ return relativeBaseDN;
+ }
+
+
+
+ /**
+ * Get the root DN.
+ *
+ * @return Returns the root DN.
+ */
+ public DN getRootDN()
+ {
+ return rootDN;
+ }
+
+
+
+ /**
+ * Retrieves the hash code for this subtree specification object.
+ *
+ * @return The hash code for this subtree specification object.
+ */
+ @Override
+ public int hashCode()
+ {
+
+ int hash = commonComponentsHashCode();
+
+ hash = hash * 31 + getBaseDN().hashCode();
+
+ if (refinements != null)
+ {
+ hash = hash * 31 + refinements.hashCode();
+ }
+
+ return hash;
+ }
+
+
+
+ /**
+ * 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 boolean isDNWithinScope(final DN dn)
+ {
+
+ if (!dn.isDescendantOf(baseDN))
+ {
+ return false;
+ }
+
+ // Check minimum and maximum depths.
+ final int baseRDNCount = baseDN.getNumComponents();
+
+ if (minimumDepth > 0)
+ {
+ final int entryRDNCount = dn.getNumComponents();
+
+ if (entryRDNCount - baseRDNCount < minimumDepth)
+ {
+ return false;
+ }
+ }
+
+ if (maximumDepth >= 0)
+ {
+ final int entryRDNCount = dn.getNumComponents();
+
+ if (entryRDNCount - baseRDNCount > maximumDepth)
+ {
+ return false;
+ }
+ }
+
+ // Check exclusions.
+ for (final DN chopBeforeDN : chopBefore.keySet())
+ {
+ if (dn.isDescendantOf(chopBeforeDN))
+ {
+ return false;
+ }
+ }
+
+ for (final DN chopAfterDN : chopAfter.keySet())
+ {
+ if (!dn.equals(chopAfterDN) && dn.isDescendantOf(chopAfterDN))
+ {
+ return false;
+ }
+ }
+
+ // Everything seemed to match.
+ return true;
+ }
+
+
+
+ /**
+ * Determine if an entry is within the scope of the subtree
+ * specification.
+ *
+ * @param entry
+ * The entry.
+ * @return {@code true} if the entry is within the scope of the
+ * subtree specification, or {@code false} if not.
+ */
+ public boolean isWithinScope(final Entry entry)
+ {
+
+ if (isDNWithinScope(entry.getDN()))
+ {
+ if (refinements != null)
+ {
+ return refinements.matches(entry);
+ }
+ else
+ {
+ return true;
+ }
+ }
+ else
+ {
+ return false;
+ }
+ }
+
+
+
+ /**
+ * Retrieves a string representation of this subtree specification
+ * object.
+ *
+ * @return A string representation of this subtree specification
+ * object.
+ */
+ @Override
+ public String toString()
+ {
+ final StringBuilder builder = new StringBuilder();
+ return toString(builder).toString();
+ }
+
+
+
+ /**
+ * Append the string representation of the subtree specification to
+ * the provided string builder.
+ *
+ * @param builder
+ * The string builder.
+ * @return The string builder.
+ */
+ public StringBuilder toString(final StringBuilder builder)
+ {
+
+ boolean isFirstElement = true;
+
+ // Output the optional base DN.
+ builder.append("{");
+ if (relativeBaseDN != null && !relativeBaseDN.isNullDN())
+ {
+ builder.append(" base ");
+ StaticUtils.toRFC3641StringValue(builder,
+ relativeBaseDN.toString());
+ isFirstElement = false;
+ }
+
+ // Output the optional specific exclusions.
+ final Iterable<DN> chopBefore = getChopBefore();
+ final Iterable<DN> chopAfter = getChopAfter();
+
+ if ((chopBefore.iterator().hasNext())
+ || (chopAfter.iterator().hasNext()))
+ {
+
+ if (!isFirstElement)
+ {
+ builder.append(",");
+ }
+ else
+ {
+ isFirstElement = false;
+ }
+ builder.append(" specificExclusions { ");
+
+ boolean isFirst = true;
+
+ for (final DN dn : chopBefore)
+ {
+ if (!isFirst)
+ {
+ builder.append(", chopBefore:");
+ }
+ else
+ {
+ builder.append("chopBefore:");
+ isFirst = false;
+ }
+ StaticUtils.toRFC3641StringValue(builder, dn.toString());
+ }
+
+ for (final DN dn : chopAfter)
+ {
+ if (!isFirst)
+ {
+ builder.append(", chopAfter:");
+ }
+ else
+ {
+ builder.append("chopAfter:");
+ isFirst = false;
+ }
+ StaticUtils.toRFC3641StringValue(builder, dn.toString());
+ }
+
+ builder.append(" }");
+ }
+
+ // Output the optional minimum depth.
+ if (getMinimumDepth() > 0)
+ {
+ if (!isFirstElement)
+ {
+ builder.append(",");
+ }
+ else
+ {
+ isFirstElement = false;
+ }
+ builder.append(" minimum ");
+ builder.append(getMinimumDepth());
+ }
+
+ // Output the optional maximum depth.
+ if (getMaximumDepth() >= 0)
+ {
+ if (!isFirstElement)
+ {
+ builder.append(",");
+ }
+ else
+ {
+ isFirstElement = false;
+ }
+ builder.append(" maximum ");
+ builder.append(getMaximumDepth());
+ }
+
+ // Output the optional refinements.
+ if (refinements != null)
+ {
+ if (!isFirstElement)
+ {
+ builder.append(",");
+ }
+ else
+ {
+ isFirstElement = false;
+ }
+ builder.append(" specificationFilter ");
+ refinements.toString(builder);
+ }
+
+ builder.append(" }");
+
+ return builder;
+ }
+
+
+
+ /**
+ * Determine if the common components of this subtree specification
+ * are equal to the common components of another subtree
+ * specification.
+ *
+ * @param other
+ * The other subtree specification.
+ * @return Returns <code>true</code> if they are equal.
+ */
+ private boolean commonComponentsEquals(
+ final SubtreeSpecification other)
+ {
+
+ if (this == other)
+ {
+ return true;
+ }
+
+ if (minimumDepth != other.minimumDepth)
+ {
+ return false;
+ }
+
+ if (maximumDepth != other.maximumDepth)
+ {
+ return false;
+ }
+
+ if (!chopBefore.values().equals(other.chopBefore.values()))
+ {
+ return false;
+ }
+
+ if (!chopAfter.values().equals(other.chopAfter.values()))
+ {
+ return false;
+ }
+
+ return true;
+ }
+
+
+
+ /**
+ * Get a hash code of the subtree specification's common components.
+ *
+ * @return The computed hash code.
+ */
+ private int commonComponentsHashCode()
+ {
+ int hash = minimumDepth * 31 + maximumDepth;
+ hash = hash * 31 + chopBefore.values().hashCode();
+ hash = hash * 31 + chopAfter.values().hashCode();
+ return hash;
+ }
+}
diff --git a/opendj-sdk/opends/src/server/org/opends/server/api/SubtreeSpecificationSet.java b/opendj-sdk/opends/src/server/org/opends/server/types/SubtreeSpecificationSet.java
similarity index 96%
rename from opendj-sdk/opends/src/server/org/opends/server/api/SubtreeSpecificationSet.java
rename to opendj-sdk/opends/src/server/org/opends/server/types/SubtreeSpecificationSet.java
index 5f3dab9..bcc982a 100644
--- a/opendj-sdk/opends/src/server/org/opends/server/api/SubtreeSpecificationSet.java
+++ b/opendj-sdk/opends/src/server/org/opends/server/types/SubtreeSpecificationSet.java
@@ -23,8 +23,9 @@
*
*
* Copyright 2006-2008 Sun Microsystems, Inc.
+ * Portions copyright 2011 ForgeRock AS
*/
-package org.opends.server.api;
+package org.opends.server.types;
@@ -33,13 +34,12 @@
import java.util.HashSet;
import java.util.Iterator;
-import org.opends.server.types.Entry;
/**
* This class implements the {@code Set} interface for
- * {@link org.opends.server.api.SubtreeSpecification}s.
+ * {@link org.opends.server.types.SubtreeSpecification}s.
* <p>
* It is backed by a {@code HashSet} but provides additional
* functionality, {@link #isWithinScope(Entry)}, for determining
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 70ee499..8f8fb61 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
@@ -28,7 +28,6 @@
package org.opends.server.core;
-import org.opends.server.api.SubtreeSpecification;
import java.util.ArrayList;
import java.util.LinkedHashSet;
import java.util.List;
@@ -175,7 +174,7 @@
"objectClass: subentry",
"objectClass: collectiveAttributeSubentry",
"objectClass: extensibleObject",
- "subtreeSpecification: {relativebase \"\", specificationFilter \"(isMemberOf=cn=collective users,ou=people,o=test)\"}",
+ "subtreeSpecification: {base \"\", specificationFilter \"(isMemberOf=cn=collective users,ou=people,o=test)\"}",
"cn: description collective attribute",
"description;collective: inherited description",
"",
@@ -615,7 +614,7 @@
if (subentry.getDN().equals(ldapSubentry.getDN()))
{
SubtreeSpecification spec = subentry.getSubTreeSpecification();
- assertTrue(spec instanceof RFC3672SubtreeSpecification);
+ assertNull(spec.getRefinements());
}
}
@@ -627,7 +626,7 @@
"dn: cn=Relative Subentry," + SUFFIX,
"objectClass: top",
"objectclass: subentry",
- "subtreeSpecification: {relativeBase \"ou=Test SubEntry Manager\"}",
+ "subtreeSpecification: {base \"ou=Test SubEntry Manager\", specificationFilter \"(objectClass=*)\"}",
"cn: Subentry");
AddOperation addOperation =
connection.processAdd(relativeSubentry.getDN(),
@@ -644,7 +643,7 @@
if (subentry.getDN().equals(relativeSubentry.getDN()))
{
SubtreeSpecification spec = subentry.getSubTreeSpecification();
- assertTrue(spec instanceof RelativeSubtreeSpecification);
+ assertTrue(spec.getRefinements() instanceof SubtreeSpecification.FilterRefinement);
}
}
diff --git a/opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/core/TestRelativeSubtreeSpecification.java b/opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/core/TestRelativeSubtreeSpecification.java
deleted file mode 100644
index 34d726a..0000000
--- a/opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/core/TestRelativeSubtreeSpecification.java
+++ /dev/null
@@ -1,180 +0,0 @@
-/*
- * 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-2008 Sun Microsystems, Inc.
- */
-package org.opends.server.core;
-
-import static org.testng.AssertJUnit.assertEquals;
-
-import org.opends.server.api.SubtreeSpecification;
-import org.opends.server.types.DN;
-import org.testng.annotations.Test;
-
-/**
- * This class defines a set of tests for the
- * {@link org.opends.server.core.RelativeSubtreeSpecification} class.
- * <p>
- * This test suite is shorter than the RFC 3672 test suite because it
- * focuses on testing only the pieces of functionality that are specific
- * to the syntax.
- */
-public final class TestRelativeSubtreeSpecification extends
- SubtreeSpecificationTestCase {
-
- // Cached root DN.
- private DN rootDN = DN.nullDN();
-
- /**
- * Tests the {@link RelativeSubtreeSpecification#valueOf(DN, String)}
- * method.
- *
- * @throws Exception
- * If the test failed unexpectedly.
- */
- @Test
- public void testValueOf1() throws Exception {
-
- String input = "{}";
- String output = "{ }";
-
- SubtreeSpecification ss = RelativeSubtreeSpecification.valueOf(rootDN,
- input);
- assertEquals(output, ss.toString());
- }
-
- /**
- * Tests the {@link RelativeSubtreeSpecification#valueOf(DN, String)}
- * method.
- *
- * @throws Exception
- * If the test failed unexpectedly.
- */
- @Test
- public void testValueOf2() throws Exception {
-
- String input = " { } ";
- String output = "{ }";
-
- SubtreeSpecification ss = RelativeSubtreeSpecification.valueOf(rootDN,
- input);
- assertEquals(output, ss.toString());
- }
-
- /**
- * Tests the {@link RelativeSubtreeSpecification#valueOf(DN, String)}
- * method.
- *
- * @throws Exception
- * If the test failed unexpectedly.
- */
- @Test
- public void testValueOf3() throws Exception {
-
- String input = "{ relativeBase \"dc=sun, dc=com\" }";
- String output = "{ relativeBase \"dc=sun,dc=com\" }";
-
- SubtreeSpecification ss = RelativeSubtreeSpecification.valueOf(rootDN,
- input);
- assertEquals(output, ss.toString());
- }
-
- /**
- * Tests the {@link RelativeSubtreeSpecification#valueOf(DN, String)}
- * method.
- *
- * @throws Exception
- * If the test failed unexpectedly.
- */
- @Test
- public void testValueOf4() throws Exception {
-
- String input = "{relativeBase \"dc=sun, dc=com\"}";
- String output = "{ relativeBase \"dc=sun,dc=com\" }";
-
- SubtreeSpecification ss = RelativeSubtreeSpecification.valueOf(rootDN,
- input);
- assertEquals(output, ss.toString());
- }
-
- /**
- * Tests the {@link RelativeSubtreeSpecification#valueOf(DN, String)}
- * method.
- *
- * @throws Exception
- * If the test failed unexpectedly.
- */
- @Test
- public void testValueOf5() throws Exception {
-
- String input = "{ relativeBase \"dc=sun, dc=com\", "
- + "specificationFilter \"(objectClass=*)\" }";
- String output = "{ relativeBase \"dc=sun,dc=com\", "
- + "specificationFilter \"(objectClass=*)\" }";
-
- SubtreeSpecification ss = RelativeSubtreeSpecification.valueOf(rootDN,
- input);
- assertEquals(output, ss.toString());
- }
-
- /**
- * Tests the {@link RelativeSubtreeSpecification#isWithinScope(Entry)}
- * method.
- *
- * @throws Exception
- * If the test failed unexpectedly.
- */
- @Test
- public void testMatches1() throws Exception {
- DN dn = DN.decode("dc=abc, dc=sun, dc=com");
-
- String value = "{ relativeBase \"dc=sun, dc=com\", "
- + "specificationFilter \"(objectClass=person)\" }";
- SubtreeSpecification ss = RelativeSubtreeSpecification.valueOf(rootDN,
- value);
-
- assertEquals(true, ss
- .isWithinScope(createEntry(dn, getObjectClasses())));
- }
-
- /**
- * Tests the {@link RelativeSubtreeSpecification#isWithinScope(Entry)}
- * method.
- *
- * @throws Exception
- * If the test failed unexpectedly.
- */
- @Test
- public void testMatches2() throws Exception {
- DN dn = DN.decode("dc=abc, dc=sun, dc=com");
-
- String value = "{ relativeBase \"dc=sun, dc=com\", "
- + "specificationFilter \"(objectClass=organization)\" }";
- SubtreeSpecification ss = RelativeSubtreeSpecification.valueOf(rootDN,
- value);
-
- assertEquals(false, ss
- .isWithinScope(createEntry(dn, getObjectClasses())));
- }
-}
diff --git a/opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/types/TestEntry.java b/opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/types/TestEntry.java
index a02d6a0..303b64a 100644
--- a/opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/types/TestEntry.java
+++ b/opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/types/TestEntry.java
@@ -23,6 +23,7 @@
*
*
* Copyright 2006-2008 Sun Microsystems, Inc.
+ * Portions copyright 2011 ForgeRock AS
*/
package org.opends.server.types;
@@ -35,15 +36,9 @@
import java.util.List;
import org.opends.server.TestCaseUtils;
-import org.opends.server.util.StaticUtils;
import org.opends.messages.MessageBuilder;
-import org.opends.server.api.SubtreeSpecificationSet;
import org.opends.server.core.DirectoryServer;
-import org.opends.server.core.RFC3672SubtreeSpecification;
-import org.opends.server.schema.AttributeTypeSyntax;
-import org.opends.server.schema.BooleanSyntax;
-import org.opends.server.schema.IntegerSyntax;
-import org.opends.server.schema.RFC3672SubtreeSpecificationSyntax;
+import org.opends.server.schema.*;
import org.testng.annotations.Test;
import org.testng.annotations.BeforeClass;
@@ -264,7 +259,7 @@
* If the test failed unexpectedly.
*/
@Test
- public void testGetAttributeValuesRFC3672SubtreeSpecification()
+ public void testGetAttributeValuesSubtreeSpecification()
throws Exception {
// Define a dummy attribute type, in case there is not one already
// in the core schema.
@@ -286,12 +281,12 @@
SubtreeSpecificationSet expected = new SubtreeSpecificationSet();
for (String value : values) {
- expected.add(RFC3672SubtreeSpecification.valueOf(rootDN, value));
+ expected.add(SubtreeSpecification.valueOf(rootDN, value));
}
Entry entry = createTestEntry(type, values);
SubtreeSpecificationSet result = new SubtreeSpecificationSet();
- entry.getAttributeValues(type, RFC3672SubtreeSpecificationSyntax
+ entry.getAttributeValues(type, SubtreeSpecificationSyntax
.createAttributeValueDecoder(rootDN), result);
assertEquals(expected, result);
diff --git a/opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/core/TestRFC3672SubtreeSpecification.java b/opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/types/TestSubtreeSpecification.java
similarity index 69%
rename from opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/core/TestRFC3672SubtreeSpecification.java
rename to opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/types/TestSubtreeSpecification.java
index 686ead3..a2ed15d 100644
--- a/opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/core/TestRFC3672SubtreeSpecification.java
+++ b/opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/types/TestSubtreeSpecification.java
@@ -23,27 +23,29 @@
*
*
* Copyright 2006-2008 Sun Microsystems, Inc.
+ * Portions copyright 2011 ForgeRock AS
*/
-package org.opends.server.core;
+package org.opends.server.types;
import static org.testng.AssertJUnit.assertEquals;
-import org.opends.server.api.SubtreeSpecification;
+import org.opends.server.core.SubtreeSpecificationTestCase;
import org.opends.server.types.DN;
+import org.opends.server.types.SubtreeSpecification;
import org.testng.annotations.Test;
/**
* This class defines a set of tests for the
- * {@link org.opends.server.core.RFC3672SubtreeSpecification} class.
+ * {@link org.opends.server.types.SubtreeSpecification} class.
*/
-public final class TestRFC3672SubtreeSpecification extends
+public final class TestSubtreeSpecification extends
SubtreeSpecificationTestCase {
// Cached root DN.
private DN rootDN = DN.nullDN();
/**
- * Tests the {@link RFC3672SubtreeSpecification#valueOf(DN, String)}
+ * Tests the {@link SubtreeSpecification#valueOf(DN, String)}
* method.
*
* @throws Exception
@@ -55,13 +57,13 @@
String input = "{}";
String output = "{ }";
- SubtreeSpecification ss = RFC3672SubtreeSpecification.valueOf(rootDN,
+ SubtreeSpecification ss = SubtreeSpecification.valueOf(rootDN,
input);
assertEquals(output, ss.toString());
}
/**
- * Tests the {@link RFC3672SubtreeSpecification#valueOf(DN, String)}
+ * Tests the {@link SubtreeSpecification#valueOf(DN, String)}
* method.
*
* @throws Exception
@@ -73,13 +75,13 @@
String input = " { } ";
String output = "{ }";
- SubtreeSpecification ss = RFC3672SubtreeSpecification.valueOf(rootDN,
+ SubtreeSpecification ss = SubtreeSpecification.valueOf(rootDN,
input);
assertEquals(output, ss.toString());
}
/**
- * Tests the {@link RFC3672SubtreeSpecification#valueOf(DN, String)}
+ * Tests the {@link SubtreeSpecification#valueOf(DN, String)}
* method.
*
* @throws Exception
@@ -91,13 +93,13 @@
String input = "{ base \"dc=sun, dc=com\" }";
String output = "{ base \"dc=sun,dc=com\" }";
- SubtreeSpecification ss = RFC3672SubtreeSpecification.valueOf(rootDN,
+ SubtreeSpecification ss = SubtreeSpecification.valueOf(rootDN,
input);
assertEquals(output, ss.toString());
}
/**
- * Tests the {@link RFC3672SubtreeSpecification#valueOf(DN, String)}
+ * Tests the {@link SubtreeSpecification#valueOf(DN, String)}
* method.
*
* @throws Exception
@@ -109,13 +111,13 @@
String input = "{base \"dc=sun, dc=com\"}";
String output = "{ base \"dc=sun,dc=com\" }";
- SubtreeSpecification ss = RFC3672SubtreeSpecification.valueOf(rootDN,
+ SubtreeSpecification ss = SubtreeSpecification.valueOf(rootDN,
input);
assertEquals(output, ss.toString());
}
/**
- * Tests the {@link RFC3672SubtreeSpecification#valueOf(DN, String)}
+ * Tests the {@link SubtreeSpecification#valueOf(DN, String)}
* method.
*
* @throws Exception
@@ -129,13 +131,13 @@
String output = "{ base \"dc=sun,dc=com\", "
+ "specificationFilter item:ds-config-rootDN }";
- SubtreeSpecification ss = RFC3672SubtreeSpecification.valueOf(rootDN,
+ SubtreeSpecification ss = SubtreeSpecification.valueOf(rootDN,
input);
assertEquals(output, ss.toString());
}
/**
- * Tests the {@link RFC3672SubtreeSpecification#valueOf(DN, String)}
+ * Tests the {@link SubtreeSpecification#valueOf(DN, String)}
* method.
*
* @throws Exception
@@ -152,13 +154,13 @@
+ "chopAfter:\"o=xyz\" }, maximum 10, specificationFilter "
+ "not:not:item:foo }";
- SubtreeSpecification ss = RFC3672SubtreeSpecification.valueOf(rootDN,
+ SubtreeSpecification ss = SubtreeSpecification.valueOf(rootDN,
input);
assertEquals(output, ss.toString());
}
/**
- * Tests the {@link RFC3672SubtreeSpecification#valueOf(DN, String)}
+ * Tests the {@link SubtreeSpecification#valueOf(DN, String)}
* method.
*
* @throws Exception
@@ -174,13 +176,13 @@
+ "chopAfter:\"o=xyz\" }, "
+ "maximum 10, specificationFilter not:not:item:foo }";
- SubtreeSpecification ss = RFC3672SubtreeSpecification.valueOf(rootDN,
+ SubtreeSpecification ss = SubtreeSpecification.valueOf(rootDN,
input);
assertEquals(output, ss.toString());
}
/**
- * Tests the {@link RFC3672SubtreeSpecification#valueOf(DN, String)}
+ * Tests the {@link SubtreeSpecification#valueOf(DN, String)}
* method.
*
* @throws Exception
@@ -192,13 +194,13 @@
String input = "{ specificationFilter and:{item:top, item:person} }";
String output = "{ specificationFilter and:{item:top, item:person} }";
- SubtreeSpecification ss = RFC3672SubtreeSpecification.valueOf(rootDN,
+ SubtreeSpecification ss = SubtreeSpecification.valueOf(rootDN,
input);
assertEquals(output, ss.toString());
}
/**
- * Tests the {@link RFC3672SubtreeSpecification#valueOf(DN, String)}
+ * Tests the {@link SubtreeSpecification#valueOf(DN, String)}
* method.
*
* @throws Exception
@@ -210,13 +212,13 @@
String input = "{ specificationFilter or:{item:top, item:person} }";
String output = "{ specificationFilter or:{item:top, item:person} }";
- SubtreeSpecification ss = RFC3672SubtreeSpecification.valueOf(rootDN,
+ SubtreeSpecification ss = SubtreeSpecification.valueOf(rootDN,
input);
assertEquals(output, ss.toString());
}
/**
- * Tests the {@link RFC3672SubtreeSpecification#valueOf(DN, String)}
+ * Tests the {@link SubtreeSpecification#valueOf(DN, String)}
* method.
*
* @throws Exception
@@ -230,13 +232,33 @@
String output = "{ specificationFilter "
+ "or:{item:top, item:foo, and:{item:one, item:two}} }";
- SubtreeSpecification ss = RFC3672SubtreeSpecification.valueOf(rootDN,
+ SubtreeSpecification ss = SubtreeSpecification.valueOf(rootDN,
input);
assertEquals(output, ss.toString());
}
/**
- * Tests the {@link RFC3672SubtreeSpecification#isWithinScope(Entry)}
+ * Tests the {@link SubtreeSpecification#valueOf(DN, String)}
+ * method.
+ *
+ * @throws Exception
+ * If the test failed unexpectedly.
+ */
+ @Test
+ public void testValueOf11() throws Exception {
+
+ String input = "{ base \"dc=sun, dc=com\", "
+ + "specificationFilter \"(objectClass=*)\" }";
+ String output = "{ base \"dc=sun,dc=com\", "
+ + "specificationFilter \"(objectClass=*)\" }";
+
+ SubtreeSpecification ss = SubtreeSpecification.valueOf(rootDN,
+ input);
+ assertEquals(output, ss.toString());
+ }
+
+ /**
+ * Tests the {@link SubtreeSpecification#isWithinScope(Entry)}
* method.
*
* @throws Exception
@@ -247,7 +269,7 @@
DN dn = DN.decode("dc=sun, dc=com");
String value = "{ base \"dc=sun, dc=com\" }";
- SubtreeSpecification ss = RFC3672SubtreeSpecification.valueOf(rootDN,
+ SubtreeSpecification ss = SubtreeSpecification.valueOf(rootDN,
value);
assertEquals(true, ss
@@ -255,7 +277,7 @@
}
/**
- * Tests the {@link RFC3672SubtreeSpecification#isWithinScope(Entry)}
+ * Tests the {@link SubtreeSpecification#isWithinScope(Entry)}
* method.
*
* @throws Exception
@@ -266,7 +288,7 @@
DN dn = DN.decode("dc=com");
String value = "{ base \"dc=sun, dc=com\" }";
- SubtreeSpecification ss = RFC3672SubtreeSpecification.valueOf(rootDN,
+ SubtreeSpecification ss = SubtreeSpecification.valueOf(rootDN,
value);
assertEquals(false, ss
@@ -274,7 +296,7 @@
}
/**
- * Tests the {@link RFC3672SubtreeSpecification#isWithinScope(Entry)}
+ * Tests the {@link SubtreeSpecification#isWithinScope(Entry)}
* method.
*
* @throws Exception
@@ -285,7 +307,7 @@
DN dn = DN.decode("dc=foo, dc=sun, dc=com");
String value = "{ base \"dc=sun, dc=com\" }";
- SubtreeSpecification ss = RFC3672SubtreeSpecification.valueOf(rootDN,
+ SubtreeSpecification ss = SubtreeSpecification.valueOf(rootDN,
value);
assertEquals(true, ss
@@ -293,7 +315,7 @@
}
/**
- * Tests the {@link RFC3672SubtreeSpecification#isWithinScope(Entry)}
+ * Tests the {@link SubtreeSpecification#isWithinScope(Entry)}
* method.
*
* @throws Exception
@@ -304,7 +326,7 @@
DN dn = DN.decode("dc=foo, dc=bar, dc=com");
String value = "{ base \"dc=sun, dc=com\" }";
- SubtreeSpecification ss = RFC3672SubtreeSpecification.valueOf(rootDN,
+ SubtreeSpecification ss = SubtreeSpecification.valueOf(rootDN,
value);
assertEquals(false, ss
@@ -312,7 +334,7 @@
}
/**
- * Tests the {@link RFC3672SubtreeSpecification#isWithinScope(Entry)}
+ * Tests the {@link SubtreeSpecification#isWithinScope(Entry)}
* method.
*
* @throws Exception
@@ -323,7 +345,7 @@
DN dn = DN.decode("dc=sun, dc=com");
String value = "{ base \"dc=sun, dc=com\", minimum 1 }";
- SubtreeSpecification ss = RFC3672SubtreeSpecification.valueOf(rootDN,
+ SubtreeSpecification ss = SubtreeSpecification.valueOf(rootDN,
value);
assertEquals(false, ss
@@ -331,7 +353,7 @@
}
/**
- * Tests the {@link RFC3672SubtreeSpecification#isWithinScope(Entry)}
+ * Tests the {@link SubtreeSpecification#isWithinScope(Entry)}
* method.
*
* @throws Exception
@@ -342,7 +364,7 @@
DN dn = DN.decode("dc=abc, dc=sun, dc=com");
String value = "{ base \"dc=sun, dc=com\", minimum 1 }";
- SubtreeSpecification ss = RFC3672SubtreeSpecification.valueOf(rootDN,
+ SubtreeSpecification ss = SubtreeSpecification.valueOf(rootDN,
value);
assertEquals(true, ss
@@ -350,7 +372,7 @@
}
/**
- * Tests the {@link RFC3672SubtreeSpecification#isWithinScope(Entry)}
+ * Tests the {@link SubtreeSpecification#isWithinScope(Entry)}
* method.
*
* @throws Exception
@@ -361,7 +383,7 @@
DN dn = DN.decode("dc=xyz, dc=abc, dc=sun, dc=com");
String value = "{ base \"dc=sun, dc=com\", minimum 1 }";
- SubtreeSpecification ss = RFC3672SubtreeSpecification.valueOf(rootDN,
+ SubtreeSpecification ss = SubtreeSpecification.valueOf(rootDN,
value);
assertEquals(true, ss
@@ -369,7 +391,7 @@
}
/**
- * Tests the {@link RFC3672SubtreeSpecification#isWithinScope(Entry)}
+ * Tests the {@link SubtreeSpecification#isWithinScope(Entry)}
* method.
*
* @throws Exception
@@ -380,7 +402,7 @@
DN dn = DN.decode("dc=sun, dc=com");
String value = "{ base \"dc=sun, dc=com\", maximum 0 }";
- SubtreeSpecification ss = RFC3672SubtreeSpecification.valueOf(rootDN,
+ SubtreeSpecification ss = SubtreeSpecification.valueOf(rootDN,
value);
assertEquals(true, ss
@@ -388,7 +410,7 @@
}
/**
- * Tests the {@link RFC3672SubtreeSpecification#isWithinScope(Entry)}
+ * Tests the {@link SubtreeSpecification#isWithinScope(Entry)}
* method.
*
* @throws Exception
@@ -399,7 +421,7 @@
DN dn = DN.decode("dc=foo, dc=sun, dc=com");
String value = "{ base \"dc=sun, dc=com\", maximum 0 }";
- SubtreeSpecification ss = RFC3672SubtreeSpecification.valueOf(rootDN,
+ SubtreeSpecification ss = SubtreeSpecification.valueOf(rootDN,
value);
assertEquals(false, ss
@@ -407,7 +429,7 @@
}
/**
- * Tests the {@link RFC3672SubtreeSpecification#isWithinScope(Entry)}
+ * Tests the {@link SubtreeSpecification#isWithinScope(Entry)}
* method.
*
* @throws Exception
@@ -418,7 +440,7 @@
DN dn = DN.decode("dc=bar, dc=foo, dc=sun, dc=com");
String value = "{ base \"dc=sun, dc=com\", maximum 1 }";
- SubtreeSpecification ss = RFC3672SubtreeSpecification.valueOf(rootDN,
+ SubtreeSpecification ss = SubtreeSpecification.valueOf(rootDN,
value);
assertEquals(false, ss
@@ -426,7 +448,7 @@
}
/**
- * Tests the {@link RFC3672SubtreeSpecification#isWithinScope(Entry)}
+ * Tests the {@link SubtreeSpecification#isWithinScope(Entry)}
* method.
*
* @throws Exception
@@ -437,7 +459,7 @@
DN dn = DN.decode("dc=bar, dc=foo, dc=sun, dc=com");
String value = "{ base \"dc=sun, dc=com\", maximum 2 }";
- SubtreeSpecification ss = RFC3672SubtreeSpecification.valueOf(rootDN,
+ SubtreeSpecification ss = SubtreeSpecification.valueOf(rootDN,
value);
assertEquals(true, ss
@@ -445,7 +467,7 @@
}
/**
- * Tests the {@link RFC3672SubtreeSpecification#isWithinScope(Entry)}
+ * Tests the {@link SubtreeSpecification#isWithinScope(Entry)}
* method.
*
* @throws Exception
@@ -457,7 +479,7 @@
String value = "{ base \"dc=sun, dc=com\", "
+ "specificExclusions { chopAfter:\"\" } }";
- SubtreeSpecification ss = RFC3672SubtreeSpecification.valueOf(rootDN,
+ SubtreeSpecification ss = SubtreeSpecification.valueOf(rootDN,
value);
assertEquals(true, ss
@@ -465,7 +487,7 @@
}
/**
- * Tests the {@link RFC3672SubtreeSpecification#isWithinScope(Entry)}
+ * Tests the {@link SubtreeSpecification#isWithinScope(Entry)}
* method.
*
* @throws Exception
@@ -477,7 +499,7 @@
String value = "{ base \"dc=sun, dc=com\", "
+ "specificExclusions { chopAfter:\"\" } }";
- SubtreeSpecification ss = RFC3672SubtreeSpecification.valueOf(rootDN,
+ SubtreeSpecification ss = SubtreeSpecification.valueOf(rootDN,
value);
assertEquals(false, ss
@@ -485,7 +507,7 @@
}
/**
- * Tests the {@link RFC3672SubtreeSpecification#isWithinScope(Entry)}
+ * Tests the {@link SubtreeSpecification#isWithinScope(Entry)}
* method.
*
* @throws Exception
@@ -497,7 +519,7 @@
String value = "{ base \"dc=sun, dc=com\", "
+ "specificExclusions { chopAfter:\"dc=foo\" } }";
- SubtreeSpecification ss = RFC3672SubtreeSpecification.valueOf(rootDN,
+ SubtreeSpecification ss = SubtreeSpecification.valueOf(rootDN,
value);
assertEquals(true, ss
@@ -505,7 +527,7 @@
}
/**
- * Tests the {@link RFC3672SubtreeSpecification#isWithinScope(Entry)}
+ * Tests the {@link SubtreeSpecification#isWithinScope(Entry)}
* method.
*
* @throws Exception
@@ -517,7 +539,7 @@
String value = "{ base \"dc=sun, dc=com\", "
+ "specificExclusions { chopAfter:\"dc=foo\" } }";
- SubtreeSpecification ss = RFC3672SubtreeSpecification.valueOf(rootDN,
+ SubtreeSpecification ss = SubtreeSpecification.valueOf(rootDN,
value);
assertEquals(false, ss
@@ -525,7 +547,7 @@
}
/**
- * Tests the {@link RFC3672SubtreeSpecification#isWithinScope(Entry)}
+ * Tests the {@link SubtreeSpecification#isWithinScope(Entry)}
* method.
*
* @throws Exception
@@ -537,7 +559,7 @@
String value = "{ base \"dc=sun, dc=com\", "
+ "specificExclusions { chopBefore:\"dc=foo\" } }";
- SubtreeSpecification ss = RFC3672SubtreeSpecification.valueOf(rootDN,
+ SubtreeSpecification ss = SubtreeSpecification.valueOf(rootDN,
value);
assertEquals(false, ss
@@ -545,7 +567,7 @@
}
/**
- * Tests the {@link RFC3672SubtreeSpecification#isWithinScope(Entry)}
+ * Tests the {@link SubtreeSpecification#isWithinScope(Entry)}
* method.
*
* @throws Exception
@@ -557,7 +579,7 @@
String value = "{ base \"dc=sun, dc=com\", "
+ "specificExclusions { chopBefore:\"dc=foo\" } }";
- SubtreeSpecification ss = RFC3672SubtreeSpecification.valueOf(rootDN,
+ SubtreeSpecification ss = SubtreeSpecification.valueOf(rootDN,
value);
assertEquals(false, ss
@@ -565,7 +587,7 @@
}
/**
- * Tests the {@link RFC3672SubtreeSpecification#isWithinScope(Entry)}
+ * Tests the {@link SubtreeSpecification#isWithinScope(Entry)}
* method.
*
* @throws Exception
@@ -577,7 +599,7 @@
String value = "{ base \"dc=sun, dc=com\", "
+ "specificExclusions { chopBefore:\"dc=foo\" } }";
- SubtreeSpecification ss = RFC3672SubtreeSpecification.valueOf(rootDN,
+ SubtreeSpecification ss = SubtreeSpecification.valueOf(rootDN,
value);
assertEquals(true, ss
@@ -585,7 +607,7 @@
}
/**
- * Tests the {@link RFC3672SubtreeSpecification#isWithinScope(Entry)}
+ * Tests the {@link SubtreeSpecification#isWithinScope(Entry)}
* method.
*
* @throws Exception
@@ -597,7 +619,7 @@
String value = "{ base \"dc=sun, dc=com\", "
+ "specificationFilter item:person }";
- SubtreeSpecification ss = RFC3672SubtreeSpecification.valueOf(rootDN,
+ SubtreeSpecification ss = SubtreeSpecification.valueOf(rootDN,
value);
assertEquals(true, ss
@@ -605,7 +627,7 @@
}
/**
- * Tests the {@link RFC3672SubtreeSpecification#isWithinScope(Entry)}
+ * Tests the {@link SubtreeSpecification#isWithinScope(Entry)}
* method.
*
* @throws Exception
@@ -617,7 +639,7 @@
String value = "{ base \"dc=sun, dc=com\", "
+ "specificationFilter item:organization }";
- SubtreeSpecification ss = RFC3672SubtreeSpecification.valueOf(rootDN,
+ SubtreeSpecification ss = SubtreeSpecification.valueOf(rootDN,
value);
assertEquals(false, ss
@@ -625,7 +647,7 @@
}
/**
- * Tests the {@link RFC3672SubtreeSpecification#isWithinScope(Entry)}
+ * Tests the {@link SubtreeSpecification#isWithinScope(Entry)}
* method.
*
* @throws Exception
@@ -637,7 +659,7 @@
String value = "{ base \"dc=sun, dc=com\", "
+ "specificationFilter not:item:person }";
- SubtreeSpecification ss = RFC3672SubtreeSpecification.valueOf(rootDN,
+ SubtreeSpecification ss = SubtreeSpecification.valueOf(rootDN,
value);
assertEquals(false, ss
@@ -645,7 +667,7 @@
}
/**
- * Tests the {@link RFC3672SubtreeSpecification#isWithinScope(Entry)}
+ * Tests the {@link SubtreeSpecification#isWithinScope(Entry)}
* method.
*
* @throws Exception
@@ -657,10 +679,50 @@
String value = "{ base \"dc=sun, dc=com\", "
+ "specificationFilter not:item:organization }";
- SubtreeSpecification ss = RFC3672SubtreeSpecification.valueOf(rootDN,
+ SubtreeSpecification ss = SubtreeSpecification.valueOf(rootDN,
value);
assertEquals(true, ss
.isWithinScope(createEntry(dn, getObjectClasses())));
}
+
+ /**
+ * Tests the {@code SubtreeSpecification#isWithinScope(Entry)}
+ * method.
+ *
+ * @throws Exception
+ * If the test failed unexpectedly.
+ */
+ @Test
+ public void testMatches23() throws Exception {
+ DN dn = DN.decode("dc=abc, dc=sun, dc=com");
+
+ String value = "{ base \"dc=sun, dc=com\", "
+ + "specificationFilter \"(objectClass=person)\" }";
+ SubtreeSpecification ss = SubtreeSpecification.valueOf(rootDN,
+ value);
+
+ assertEquals(true, ss
+ .isWithinScope(createEntry(dn, getObjectClasses())));
+ }
+
+ /**
+ * Tests the {@code SubtreeSpecification#isWithinScope(Entry)}
+ * method.
+ *
+ * @throws Exception
+ * If the test failed unexpectedly.
+ */
+ @Test
+ public void testMatches24() throws Exception {
+ DN dn = DN.decode("dc=abc, dc=sun, dc=com");
+
+ String value = "{ base \"dc=sun, dc=com\", "
+ + "specificationFilter \"(objectClass=organization)\" }";
+ SubtreeSpecification ss = SubtreeSpecification.valueOf(rootDN,
+ value);
+
+ assertEquals(false, ss
+ .isWithinScope(createEntry(dn, getObjectClasses())));
+ }
}
--
Gitblit v1.10.0