From 30d5e7846b67d3432b485631f80c71be391868fb Mon Sep 17 00:00:00 2001
From: neil_a_wilson <neil_a_wilson@localhost>
Date: Tue, 25 Sep 2007 01:54:38 +0000
Subject: [PATCH] Further split up the local backend modify operation to allow it to be better optimized, and do the same for SearchFilter.matchesEntryInternal and Entry.conformsToSchema.
---
opendj-sdk/opends/src/server/org/opends/server/workflowelement/localbackend/LocalBackendAddOperation.java | 31
opendj-sdk/opends/src/server/org/opends/server/workflowelement/localbackend/LocalBackendModifyOperation.java | 232 +++---
opendj-sdk/opends/src/server/org/opends/server/workflowelement/localbackend/LocalBackendSearchOperation.java | 27
opendj-sdk/opends/src/server/org/opends/server/workflowelement/localbackend/LocalBackendModifyDNOperation.java | 31
opendj-sdk/opends/src/server/org/opends/server/types/Entry.java | 286 +++++--
opendj-sdk/opends/src/server/org/opends/server/workflowelement/localbackend/LocalBackendCompareOperation.java | 29
opendj-sdk/opends/src/server/org/opends/server/workflowelement/localbackend/LocalBackendDeleteOperation.java | 27
opendj-sdk/opends/src/server/org/opends/server/types/SearchFilter.java | 1574 +++++++++++++++++++++++-----------------
8 files changed, 1,358 insertions(+), 879 deletions(-)
diff --git a/opendj-sdk/opends/src/server/org/opends/server/types/Entry.java b/opendj-sdk/opends/src/server/org/opends/server/types/Entry.java
index 5e0fc17..461143e 100644
--- a/opendj-sdk/opends/src/server/org/opends/server/types/Entry.java
+++ b/opendj-sdk/opends/src/server/org/opends/server/types/Entry.java
@@ -2438,6 +2438,70 @@
}
+ if (! checkAttributesAndObjectClasses(ditContentRule,
+ structuralPolicy, invalidReason))
+ {
+ return false;
+ }
+
+
+ // If there is a name form for this entry, then make sure that the
+ // RDN for the entry is in compliance with it.
+ if (nameForm != null)
+ {
+ if (! checkNameForm(nameForm, structuralPolicy, invalidReason))
+ {
+ return false;
+ }
+ }
+
+
+ // If there is a DIT content rule for this entry, then make sure
+ // that the entry is in compliance with it.
+ if (ditContentRule != null)
+ {
+ if (! checkDITContentRule(ditContentRule, structuralPolicy,
+ invalidReason))
+ {
+ return false;
+ }
+ }
+
+
+ if (! checkDITStructureRule(ditStructureRule, structuralClass,
+ parentEntry, parentProvided, validateStructureRules,
+ structuralPolicy, invalidReason))
+ {
+ return false;
+ }
+
+
+ // If we've gotten here, then the entry is acceptable.
+ return true;
+ }
+
+
+
+ /**
+ * Checks the attributes and object classes contained in this entry
+ * to determine whether they conform to the server schema
+ * requirements.
+ *
+ * @param ditContentRule The DIT content rule for this entry, if
+ * any.
+ * @param structuralPolicy The policy that should be used for
+ * structural object class compliance.
+ * @param invalidReason A buffer into which an invalid reason
+ * may be added.
+ *
+ * @return {@code true} if this entry passes all of the checks, or
+ * {@code false} if there are any failures.
+ */
+ private boolean checkAttributesAndObjectClasses(
+ DITContentRule ditContentRule,
+ AcceptRejectWarn structuralPolicy,
+ MessageBuilder invalidReason)
+ {
// Make sure that we recognize all of the objectclasses, that all
// auxiliary classes are allowed by the DIT content rule, and that
// all attributes required by the object classes are present.
@@ -2579,80 +2643,42 @@
}
- // If there is a name form for this entry, then make sure that the
- // RDN for the entry is in compliance with it.
- if (nameForm != null)
+ // If we've gotten here, then things are OK.
+ return true;
+ }
+
+
+
+ /**
+ * Performs any processing needed for name form validation.
+ *
+ * @param nameForm The name form to validate against this
+ * entry.
+ * @param structuralPolicy The policy that should be used for
+ * structural object class compliance.
+ * @param invalidReason A buffer into which an invalid reason
+ * may be added.
+ *
+ * @return {@code true} if this entry passes all of the checks, or
+ * {@code false} if there are any failures.
+ */
+ private boolean checkNameForm(NameForm nameForm,
+ AcceptRejectWarn structuralPolicy,
+ MessageBuilder invalidReason)
+ {
+ RDN rdn = dn.getRDN();
+ if (rdn != null)
{
- RDN rdn = dn.getRDN();
- if (rdn != null)
+ // Make sure that all the required attributes are present.
+ for (AttributeType t : nameForm.getRequiredAttributes())
{
- // Make sure that all the required attributes are present.
- for (AttributeType t : nameForm.getRequiredAttributes())
- {
- if (! rdn.hasAttributeType(t))
- {
- Message message =
- ERR_ENTRY_SCHEMA_RDN_MISSING_REQUIRED_ATTR.get(
- String.valueOf(dn),
- t.getNameOrOID(),
- nameForm.getNameOrOID());
-
- if (structuralPolicy == AcceptRejectWarn.REJECT)
- {
- invalidReason.append(message);
- return false;
- }
- else if (structuralPolicy == AcceptRejectWarn.WARN)
- {
- logError(message);
- }
- }
- }
-
- // Make sure that all attributes in the RDN are allowed.
- int numAVAs = rdn.getNumValues();
- for (int i = 0; i < numAVAs; i++)
- {
- AttributeType t = rdn.getAttributeType(i);
- if (! nameForm.isRequiredOrOptional(t))
- {
- Message message =
- ERR_ENTRY_SCHEMA_RDN_DISALLOWED_ATTR.get(
- String.valueOf(dn),
- t.getNameOrOID(),
- nameForm.getNameOrOID());
-
- if (structuralPolicy == AcceptRejectWarn.REJECT)
- {
- invalidReason.append(message);
- return false;
- }
- else if (structuralPolicy == AcceptRejectWarn.WARN)
- {
- logError(message);
- }
- }
- }
- }
- }
-
-
- // If there is a DIT content rule for this entry, then make sure
- // that the entry is in compliance with it.
- if (ditContentRule != null)
- {
- // Make sure that all of the required attributes are present.
- for (AttributeType t : ditContentRule.getRequiredAttributes())
- {
- if (! (userAttributes.containsKey(t) ||
- operationalAttributes.containsKey(t) ||
- t.isObjectClassType()))
+ if (! rdn.hasAttributeType(t))
{
Message message =
- ERR_ENTRY_SCHEMA_MISSING_REQUIRED_ATTR_FOR_DCR.get(
+ ERR_ENTRY_SCHEMA_RDN_MISSING_REQUIRED_ATTR.get(
String.valueOf(dn),
t.getNameOrOID(),
- ditContentRule.getName());
+ nameForm.getNameOrOID());
if (structuralPolicy == AcceptRejectWarn.REJECT)
{
@@ -2666,17 +2692,18 @@
}
}
- // Make sure that none of the prohibited attributes are present.
- for (AttributeType t : ditContentRule.getProhibitedAttributes())
+ // Make sure that all attributes in the RDN are allowed.
+ int numAVAs = rdn.getNumValues();
+ for (int i = 0; i < numAVAs; i++)
{
- if (userAttributes.containsKey(t) ||
- operationalAttributes.containsKey(t))
+ AttributeType t = rdn.getAttributeType(i);
+ if (! nameForm.isRequiredOrOptional(t))
{
Message message =
- ERR_ENTRY_SCHEMA_PROHIBITED_ATTR_FOR_DCR.get(
+ ERR_ENTRY_SCHEMA_RDN_DISALLOWED_ATTR.get(
String.valueOf(dn),
t.getNameOrOID(),
- ditContentRule.getName());
+ nameForm.getNameOrOID());
if (structuralPolicy == AcceptRejectWarn.REJECT)
{
@@ -2691,7 +2718,115 @@
}
}
+ // If we've gotten here, then things are OK.
+ return true;
+ }
+
+
+ /**
+ * Performs any processing needed for DIT content rule validation.
+ *
+ * @param ditContentRule The DIT content rule to validate
+ * against this entry.
+ * @param structuralPolicy The policy that should be used for
+ * structural object class compliance.
+ * @param invalidReason A buffer into which an invalid reason
+ * may be added.
+ *
+ * @return {@code true} if this entry passes all of the checks, or
+ * {@code false} if there are any failures.
+ */
+ private boolean checkDITContentRule(DITContentRule ditContentRule,
+ AcceptRejectWarn structuralPolicy,
+ MessageBuilder invalidReason)
+ {
+ // Make sure that all of the required attributes are present.
+ for (AttributeType t : ditContentRule.getRequiredAttributes())
+ {
+ if (! (userAttributes.containsKey(t) ||
+ operationalAttributes.containsKey(t) ||
+ t.isObjectClassType()))
+ {
+ Message message =
+ ERR_ENTRY_SCHEMA_MISSING_REQUIRED_ATTR_FOR_DCR.get(
+ String.valueOf(dn),
+ t.getNameOrOID(),
+ ditContentRule.getName());
+
+ if (structuralPolicy == AcceptRejectWarn.REJECT)
+ {
+ invalidReason.append(message);
+ return false;
+ }
+ else if (structuralPolicy == AcceptRejectWarn.WARN)
+ {
+ logError(message);
+ }
+ }
+ }
+
+ // Make sure that none of the prohibited attributes are present.
+ for (AttributeType t : ditContentRule.getProhibitedAttributes())
+ {
+ if (userAttributes.containsKey(t) ||
+ operationalAttributes.containsKey(t))
+ {
+ Message message =
+ ERR_ENTRY_SCHEMA_PROHIBITED_ATTR_FOR_DCR.get(
+ String.valueOf(dn),
+ t.getNameOrOID(),
+ ditContentRule.getName());
+
+ if (structuralPolicy == AcceptRejectWarn.REJECT)
+ {
+ invalidReason.append(message);
+ return false;
+ }
+ else if (structuralPolicy == AcceptRejectWarn.WARN)
+ {
+ logError(message);
+ }
+ }
+ }
+
+ // If we've gotten here, then things are OK.
+ return true;
+ }
+
+
+
+ /**
+ * Performs any processing needed for DIT structure rule validation.
+ *
+ * @param ditStructureRule The DIT structure rule for this
+ * entry.
+ * @param structuralClass The structural object class for
+ * this entry.
+ * @param parentEntry The parent entry, if available
+ * and applicable.
+ * @param parentProvided Indicates whether the parent
+ * entry was provided.
+ * @param validateStructureRules Indicates whether to check to see
+ * if this entry violates a DIT
+ * structure rule for its parent.
+ * @param structuralPolicy The policy that should be used
+ * for structural object class
+ * compliance.
+ * @param invalidReason A buffer into which an invalid
+ * reason may be added.
+ *
+ * @return {@code true} if this entry passes all of the checks, or
+ * {@code false} if there are any failures.
+ */
+ private boolean checkDITStructureRule(
+ DITStructureRule ditStructureRule,
+ ObjectClass structuralClass,
+ Entry parentEntry, boolean parentProvided,
+ boolean validateStructureRules,
+ AcceptRejectWarn structuralPolicy,
+ MessageBuilder invalidReason)
+ {
// If there is a DIT structure rule for this entry, then make sure
// that the entry is in compliance with it.
if ((ditStructureRule != null) &&
@@ -2965,8 +3100,7 @@
}
}
-
- // If we've gotten here, then the entry is acceptable.
+ // If we've gotten here, then things are OK.
return true;
}
diff --git a/opendj-sdk/opends/src/server/org/opends/server/types/SearchFilter.java b/opendj-sdk/opends/src/server/org/opends/server/types/SearchFilter.java
index da2a3ca..e610a09 100644
--- a/opendj-sdk/opends/src/server/org/opends/server/types/SearchFilter.java
+++ b/opendj-sdk/opends/src/server/org/opends/server/types/SearchFilter.java
@@ -2331,691 +2331,31 @@
switch (filterType)
{
case AND:
- if (filterComponents == null)
- {
- // The set of subcomponents was null. This is not allowed.
- Message message =
- ERR_SEARCH_FILTER_COMPOUND_COMPONENTS_NULL.
- get(String.valueOf(entry.getDN()),
- String.valueOf(completeFilter),
- String.valueOf(filterType));
- throw new DirectoryException(
- DirectoryServer.getServerErrorResultCode(),
- message);
- }
- else if (filterComponents.isEmpty())
- {
- // An AND filter with no elements like "(&)" is specified as
- // "undefined" in RFC 2251, but is considered one of the
- // TRUE/FALSE filters in RFC 4526, in which case we should
- // always return true.
- if (debugEnabled())
- {
- TRACER.debugInfo("Returning TRUE for LDAP TRUE " +
- "filter (&)");
- }
- return ConditionResult.TRUE;
- }
- else
- {
- // We will have to evaluate one or more subcomponents. In
- // this case, first check our depth to make sure we're not
- // nesting too deep.
- if (depth >= MAX_NESTED_FILTER_DEPTH)
- {
- Message message = ERR_SEARCH_FILTER_NESTED_TOO_DEEP.
- get(String.valueOf(entry.getDN()),
- String.valueOf(completeFilter));
- throw new DirectoryException(
- DirectoryServer.getServerErrorResultCode(),
- message);
- }
-
- for (SearchFilter f : filterComponents)
- {
- ConditionResult result =
- f.matchesEntryInternal(completeFilter, entry,
- depth+1);
- switch (result)
- {
- case TRUE:
- break;
- case FALSE:
- if (debugEnabled())
- {
- TRACER.debugVerbose(
- "Returning FALSE for AND component %s in " +
- "filter %s for entry %s",
- f, completeFilter, entry.getDN());
- }
- return result;
- case UNDEFINED:
- if (debugEnabled())
- {
- TRACER.debugInfo(
- "Undefined result for AND component %s in filter " +
- "%s for entry %s", f, completeFilter, entry.getDN());
- }
- return result;
- default:
- Message message =
- ERR_SEARCH_FILTER_INVALID_RESULT_TYPE.
- get(String.valueOf(entry.getDN()),
- String.valueOf(completeFilter),
- String.valueOf(result));
- throw new
- DirectoryException(
- DirectoryServer.getServerErrorResultCode(),
- message);
- }
- }
-
- // If we have gotten here, then all the components must have
- // matched.
- if (debugEnabled())
- {
- TRACER.debugVerbose(
- "Returning TRUE for AND component %s in filter %s " +
- "for entry %s", this, completeFilter, entry.getDN());
- }
- return ConditionResult.TRUE;
- }
-
+ return processAND(completeFilter, entry, depth);
case OR:
- if (filterComponents == null)
- {
- // The set of subcomponents was null. This is not allowed.
- Message message =
- ERR_SEARCH_FILTER_COMPOUND_COMPONENTS_NULL.
- get(String.valueOf(entry.getDN()),
- String.valueOf(completeFilter),
- String.valueOf(filterType));
- throw new DirectoryException(
- DirectoryServer.getServerErrorResultCode(),
- message);
- }
- else if (filterComponents.isEmpty())
- {
- // An OR filter with no elements like "(|)" is specified as
- // "undefined" in RFC 2251, but is considered one of the
- // TRUE/FALSE filters in RFC 4526, in which case we should
- // always return false.
- if (debugEnabled())
- {
- TRACER.debugInfo("Returning FALSE for LDAP FALSE " +
- "filter (|)");
- }
- return ConditionResult.FALSE;
- }
- else
- {
- // We will have to evaluate one or more subcomponents. In
- // this case, first check our depth to make sure we're not
- // nesting too deep.
- if (depth >= MAX_NESTED_FILTER_DEPTH)
- {
- Message message = ERR_SEARCH_FILTER_NESTED_TOO_DEEP.
- get(String.valueOf(entry.getDN()),
- String.valueOf(completeFilter));
- throw new DirectoryException(
- DirectoryServer.getServerErrorResultCode(),
- message);
- }
-
- ConditionResult result = ConditionResult.FALSE;
- for (SearchFilter f : filterComponents)
- {
- switch (f.matchesEntryInternal(completeFilter, entry,
- depth+1))
- {
- case TRUE:
- if (debugEnabled())
- {
- TRACER.debugVerbose(
- "Returning TRUE for OR component %s in filter " +
- "%s for entry %s",
- f, completeFilter, entry.getDN());
- }
- return ConditionResult.TRUE;
- case FALSE:
- break;
- case UNDEFINED:
- if (debugEnabled())
- {
- TRACER.debugInfo(
- "Undefined result for OR component %s in filter " +
- "%s for entry %s",
- f, completeFilter, entry.getDN());
- }
- result = ConditionResult.UNDEFINED;
- break;
- default:
- Message message =
- ERR_SEARCH_FILTER_INVALID_RESULT_TYPE.
- get(String.valueOf(entry.getDN()),
- String.valueOf(completeFilter),
- String.valueOf(result));
- throw new
- DirectoryException(
- DirectoryServer.getServerErrorResultCode(),
- message);
- }
- }
-
-
- if (debugEnabled())
- {
- TRACER.debugVerbose(
- "Returning %s for OR component %s in filter %s for " +
- "entry %s", result, this, completeFilter,
- entry.getDN());
- }
- return result;
- }
-
+ return processOR(completeFilter, entry, depth);
case NOT:
- if (notComponent == null)
- {
- // The NOT subcomponent was null. This is not allowed.
- Message message = ERR_SEARCH_FILTER_NOT_COMPONENT_NULL.
- get(String.valueOf(entry.getDN()),
- String.valueOf(completeFilter));
- throw new DirectoryException(
- DirectoryServer.getServerErrorResultCode(),
- message);
- }
- else
- {
- // The subcomponent for the NOT filter can be an AND, OR, or
- // NOT filter that would require more nesting. Make sure
- // that we don't go too deep.
- if (depth >= MAX_NESTED_FILTER_DEPTH)
- {
- Message message = ERR_SEARCH_FILTER_NESTED_TOO_DEEP.
- get(String.valueOf(entry.getDN()),
- String.valueOf(completeFilter));
- throw new DirectoryException(
- DirectoryServer.getServerErrorResultCode(),
- message);
- }
-
- ConditionResult result =
- notComponent.matchesEntryInternal(completeFilter,
- entry, depth+1);
- switch (result)
- {
- case TRUE:
- if (debugEnabled())
- {
- TRACER.debugVerbose(
- "Returning FALSE for NOT component %s in filter " +
- "%s for entry %s",
- notComponent, completeFilter, entry.getDN());
- }
- return ConditionResult.FALSE;
- case FALSE:
- if (debugEnabled())
- {
- TRACER.debugVerbose(
- "Returning TRUE for NOT component %s in filter " +
- "%s for entry %s",
- notComponent, completeFilter, entry.getDN());
- }
- return ConditionResult.TRUE;
- case UNDEFINED:
- if (debugEnabled())
- {
- TRACER.debugInfo(
- "Undefined result for NOT component %s in filter " +
- "%s for entry %s",
- notComponent, completeFilter, entry.getDN());
- }
- return ConditionResult.UNDEFINED;
- default:
- Message message = ERR_SEARCH_FILTER_INVALID_RESULT_TYPE.
- get(String.valueOf(entry.getDN()),
- String.valueOf(completeFilter),
- String.valueOf(result));
- throw new
- DirectoryException(
- DirectoryServer.getServerErrorResultCode(),
- message);
- }
- }
-
+ return processNOT(completeFilter, entry, depth);
case EQUALITY:
- // Make sure that an attribute type has been defined.
- if (attributeType == null)
- {
- Message message =
- ERR_SEARCH_FILTER_EQUALITY_NO_ATTRIBUTE_TYPE.
- get(String.valueOf(entry.getDN()), toString());
- throw new DirectoryException(ResultCode.PROTOCOL_ERROR,
- message);
- }
-
- // Make sure that an assertion value has been defined.
- if (assertionValue == null)
- {
- Message message =
- ERR_SEARCH_FILTER_EQUALITY_NO_ASSERTION_VALUE.
- get(String.valueOf(entry.getDN()), toString(),
- attributeType.getNameOrOID());
- throw new DirectoryException(ResultCode.PROTOCOL_ERROR,
- message);
- }
-
- // See if the entry has an attribute with the requested type.
- List<Attribute> attrs = entry.getAttribute(attributeType,
- attributeOptions);
- if ((attrs == null) || (attrs.isEmpty()))
- {
- if (debugEnabled())
- {
- TRACER.debugVerbose(
- "Returning FALSE for equality component %s in " +
- "filter %s because entry %s didn't have attribute " +
- "type %s",
- this, completeFilter, entry.getDN(),
- attributeType.getNameOrOID());
- }
- return ConditionResult.FALSE;
- }
-
- // Iterate through all the attributes and see if we can find a
- // match.
- for (Attribute a : attrs)
- {
- if (a.hasValue(assertionValue))
- {
- if (debugEnabled())
- {
- TRACER.debugVerbose(
- "Returning TRUE for equality component %s in " +
- "filter %s for entry %s",
- this, completeFilter, entry.getDN());
- }
- return ConditionResult.TRUE;
- }
- }
-
- if (debugEnabled())
- {
- TRACER.debugVerbose(
- "Returning FALSE for equality component %s in filter " +
- "%s because entry %s didn't have attribute type " +
- "%s with value %s",
- this, completeFilter, entry.getDN(),
- attributeType.getNameOrOID(),
- assertionValue.getStringValue());
- }
- return ConditionResult.FALSE;
-
+ return processEquality(completeFilter, entry);
case SUBSTRING:
- // Make sure that an attribute type has been defined.
- if (attributeType == null)
- {
- Message message =
- ERR_SEARCH_FILTER_SUBSTRING_NO_ATTRIBUTE_TYPE.
- get(String.valueOf(entry.getDN()), toString());
- throw new DirectoryException(ResultCode.PROTOCOL_ERROR,
- message);
- }
-
- // Make sure that at least one substring element has been
- // defined.
- if ((subInitialElement == null) &&
- (subFinalElement == null) &&
- ((subAnyElements == null) || subAnyElements.isEmpty()))
- {
- Message message =
- ERR_SEARCH_FILTER_SUBSTRING_NO_SUBSTRING_COMPONENTS.
- get(String.valueOf(entry.getDN()), toString(),
- attributeType.getNameOrOID());
- throw new DirectoryException(ResultCode.PROTOCOL_ERROR,
- message);
- }
-
- // See if the entry has an attribute with the requested type.
- attrs = entry.getAttribute(attributeType, attributeOptions);
- if ((attrs == null) || (attrs.isEmpty()))
- {
- if (debugEnabled())
- {
- TRACER.debugVerbose(
- "Returning FALSE for substring component %s in " +
- "filter %s because entry %s didn't have attribute " +
- "type %s",
- this, completeFilter, entry.getDN(),
- attributeType.getNameOrOID());
- }
- return ConditionResult.FALSE;
- }
-
- // Iterate through all the attributes and see if we can find a
- // match.
- ConditionResult result = ConditionResult.FALSE;
- for (Attribute a : attrs)
- {
- switch (a.matchesSubstring(subInitialElement,
- subAnyElements,
- subFinalElement))
- {
- case TRUE:
- if (debugEnabled())
- {
- TRACER.debugVerbose(
- "Returning TRUE for substring component %s in " +
- "filter %s for entry %s",
- this, completeFilter, entry.getDN());
- }
- return ConditionResult.TRUE;
- case FALSE:
- break;
- case UNDEFINED:
- if (debugEnabled())
- {
- TRACER.debugVerbose(
- "Undefined result encountered for substring " +
- "component %s in filter %s for entry %s",
- this, completeFilter, entry.getDN());
- }
- result = ConditionResult.UNDEFINED;
- break;
- default:
- }
- }
-
- if (debugEnabled())
- {
- TRACER.debugVerbose(
- "Returning %s for substring component %s in filter " +
- "%s for entry %s",
- result, this, completeFilter, entry.getDN());
- }
- return result;
-
+ return processSubstring(completeFilter, entry);
case GREATER_OR_EQUAL:
- // Make sure that an attribute type has been defined.
- if (attributeType == null)
- {
- Message message =
- ERR_SEARCH_FILTER_GREATER_OR_EQUAL_NO_ATTRIBUTE_TYPE.
- get(String.valueOf(entry.getDN()), toString());
- throw new DirectoryException(ResultCode.PROTOCOL_ERROR,
- message);
- }
-
- // Make sure that an assertion value has been defined.
- if (assertionValue == null)
- {
- Message message =
- ERR_SEARCH_FILTER_GREATER_OR_EQUAL_NO_VALUE.
- get(String.valueOf(entry.getDN()), toString(),
- attributeType.getNameOrOID());
- throw new DirectoryException(ResultCode.PROTOCOL_ERROR,
- message);
- }
-
- // See if the entry has an attribute with the requested type.
- attrs = entry.getAttribute(attributeType, attributeOptions);
- if ((attrs == null) || (attrs.isEmpty()))
- {
- if (debugEnabled())
- {
- TRACER.debugVerbose("Returning FALSE for " +
- "greater-or-equal component %s in filter %s " +
- "because entry %s didn't have attribute type %s",
- this, completeFilter, entry.getDN(),
- attributeType.getNameOrOID());
- }
- return ConditionResult.FALSE;
- }
-
- // Iterate through all the attributes and see if we can find a
- // match.
- result = ConditionResult.FALSE;
- for (Attribute a : attrs)
- {
- switch (a.greaterThanOrEqualTo(assertionValue))
- {
- case TRUE:
- if (debugEnabled())
- {
- TRACER.debugVerbose(
- "Returning TRUE for greater-or-equal component " +
- "%s in filter %s for entry %s",
- this, completeFilter, entry.getDN());
- }
- return ConditionResult.TRUE;
- case FALSE:
- break;
- case UNDEFINED:
- if (debugEnabled())
- {
- TRACER.debugVerbose(
- "Undefined result encountered for " +
- "greater-or-equal component %s in filter %s " +
- "for entry %s", this, completeFilter,
- entry.getDN());
- }
- result = ConditionResult.UNDEFINED;
- break;
- default:
- }
- }
-
- if (debugEnabled())
- {
- TRACER.debugVerbose(
- "Returning %s for greater-or-equal component %s in " +
- "filter %s for entry %s",
- result, this, completeFilter, entry.getDN());
- }
- return result;
-
+ return processGreaterOrEqual(completeFilter, entry);
case LESS_OR_EQUAL:
- // Make sure that an attribute type has been defined.
- if (attributeType == null)
- {
- Message message =
- ERR_SEARCH_FILTER_LESS_OR_EQUAL_NO_ATTRIBUTE_TYPE.
- get(String.valueOf(entry.getDN()), toString());
- throw new DirectoryException(ResultCode.PROTOCOL_ERROR,
- message);
- }
-
- // Make sure that an assertion value has been defined.
- if (assertionValue == null)
- {
- Message message =
- ERR_SEARCH_FILTER_LESS_OR_EQUAL_NO_ASSERTION_VALUE.
- get(String.valueOf(entry.getDN()), toString(),
- attributeType.getNameOrOID());
- throw new DirectoryException(ResultCode.PROTOCOL_ERROR,
- message);
- }
-
- // See if the entry has an attribute with the requested type.
- attrs = entry.getAttribute(attributeType, attributeOptions);
- if ((attrs == null) || (attrs.isEmpty()))
- {
- if (debugEnabled())
- {
- TRACER.debugVerbose(
- "Returning FALSE for less-or-equal component %s in " +
- "filter %s because entry %s didn't have attribute " +
- "type %s", this, completeFilter, entry.getDN(),
- attributeType.getNameOrOID());
- }
- return ConditionResult.FALSE;
- }
-
- // Iterate through all the attributes and see if we can find a
- // match.
- result = ConditionResult.FALSE;
- for (Attribute a : attrs)
- {
- switch (a.lessThanOrEqualTo(assertionValue))
- {
- case TRUE:
- if (debugEnabled())
- {
- TRACER.debugVerbose(
- "Returning TRUE for less-or-equal component %s " +
- "in filter %s for entry %s",
- this, completeFilter, entry.getDN());
- }
- return ConditionResult.TRUE;
- case FALSE:
- break;
- case UNDEFINED:
- if (debugEnabled())
- {
- TRACER.debugVerbose(
- "Undefined result encountered for " +
- "less-or-equal component %s in filter %s " +
- "for entry %s",
- this, completeFilter, entry.getDN());
- }
- result = ConditionResult.UNDEFINED;
- break;
- default:
- }
- }
-
- if (debugEnabled())
- {
- TRACER.debugVerbose(
- "Returning %s for less-or-equal component %s in " +
- "filter %s for entry %s",
- result, this, completeFilter, entry.getDN());
- }
- return result;
-
+ return processLessOrEqual(completeFilter, entry);
case PRESENT:
- // Make sure that an attribute type has been defined.
- if (attributeType == null)
- {
- Message message =
- ERR_SEARCH_FILTER_PRESENCE_NO_ATTRIBUTE_TYPE.
- get(String.valueOf(entry.getDN()), toString());
- throw new DirectoryException(ResultCode.PROTOCOL_ERROR,
- message);
- }
-
-
- // See if the entry has an attribute with the requested type.
- // If so, then it's a match. If not, then it's not a match.
- if (entry.hasAttribute(attributeType, attributeOptions))
- {
- if (debugEnabled())
- {
- TRACER.debugVerbose(
- "Returning TRUE for presence component %s in " +
- "filter %s for entry %s",
- this, completeFilter, entry.getDN());
- }
- return ConditionResult.TRUE;
- }
- else
- {
- if (debugEnabled())
- {
- TRACER.debugVerbose(
- "Returning FALSE for presence component %s in " +
- "filter %s for entry %s",
- this, completeFilter, entry.getDN());
- }
- return ConditionResult.FALSE;
- }
-
+ return processPresent(completeFilter, entry);
case APPROXIMATE_MATCH:
- // Make sure that an attribute type has been defined.
- if (attributeType == null)
- {
- Message message =
- ERR_SEARCH_FILTER_APPROXIMATE_NO_ATTRIBUTE_TYPE.
- get(String.valueOf(entry.getDN()), toString());
- throw new DirectoryException(ResultCode.PROTOCOL_ERROR,
- message);
- }
-
- // Make sure that an assertion value has been defined.
- if (assertionValue == null)
- {
- Message message =
- ERR_SEARCH_FILTER_APPROXIMATE_NO_ASSERTION_VALUE.
- get(String.valueOf(entry.getDN()), toString(),
- attributeType.getNameOrOID());
- throw new DirectoryException(ResultCode.PROTOCOL_ERROR,
- message);
- }
-
- // See if the entry has an attribute with the requested type.
- attrs = entry.getAttribute(attributeType, attributeOptions);
- if ((attrs == null) || (attrs.isEmpty()))
- {
- if (debugEnabled())
- {
- TRACER.debugVerbose(
- "Returning FALSE for approximate component %s in " +
- "filter %s because entry %s didn't have attribute " +
- "type %s", this, completeFilter, entry.getDN(),
- attributeType.getNameOrOID());
- }
- return ConditionResult.FALSE;
- }
-
- // Iterate through all the attributes and see if we can find a
- // match.
- result = ConditionResult.FALSE;
- for (Attribute a : attrs)
- {
- switch (a.approximatelyEqualTo(assertionValue))
- {
- case TRUE:
- if (debugEnabled())
- {
- TRACER.debugVerbose(
- "Returning TRUE for approximate component %s in " +
- "filter %s for entry %s",
- this, completeFilter, entry.getDN());
- }
- return ConditionResult.TRUE;
- case FALSE:
- break;
- case UNDEFINED:
- if (debugEnabled())
- {
- TRACER.debugVerbose(
- "Undefined result encountered for approximate " +
- "component %s in filter %s for entry %s",
- this, completeFilter, entry.getDN());
- }
- result = ConditionResult.UNDEFINED;
- break;
- default:
- }
- }
-
- if (debugEnabled())
- {
- TRACER.debugVerbose(
- "Returning %s for approximate component %s in filter " +
- "%s for entry %s",
- result, this, completeFilter, entry.getDN());
- }
- return result;
-
+ return processApproximate(completeFilter, entry);
case EXTENSIBLE_MATCH:
return processExtensibleMatch(completeFilter, entry);
@@ -3034,6 +2374,902 @@
/**
+ * Indicates whether the this AND filter matches the provided entry.
+ *
+ * @param completeFilter The complete filter being checked, of
+ * which this filter may be a subset.
+ * @param entry The entry for which to make the
+ * determination.
+ * @param depth The current depth of the evaluation,
+ * which is used to prevent infinite
+ * recursion due to highly nested filters
+ * and eventually running out of stack
+ * space.
+ *
+ * @return <CODE>TRUE</CODE> if this filter matches the provided
+ * entry, <CODE>FALSE</CODE> if it does not, or
+ * <CODE>UNDEFINED</CODE> if the result is undefined.
+ *
+ * @throws DirectoryException If a problem is encountered during
+ * processing.
+ */
+ private ConditionResult processAND(SearchFilter completeFilter,
+ Entry entry, int depth)
+ throws DirectoryException
+ {
+ if (filterComponents == null)
+ {
+ // The set of subcomponents was null. This is not allowed.
+ Message message =
+ ERR_SEARCH_FILTER_COMPOUND_COMPONENTS_NULL.
+ get(String.valueOf(entry.getDN()),
+ String.valueOf(completeFilter),
+ String.valueOf(filterType));
+ throw new DirectoryException(
+ DirectoryServer.getServerErrorResultCode(),
+ message);
+ }
+ else if (filterComponents.isEmpty())
+ {
+ // An AND filter with no elements like "(&)" is specified as
+ // "undefined" in RFC 2251, but is considered one of the
+ // TRUE/FALSE filters in RFC 4526, in which case we should
+ // always return true.
+ if (debugEnabled())
+ {
+ TRACER.debugInfo("Returning TRUE for LDAP TRUE " +
+ "filter (&)");
+ }
+ return ConditionResult.TRUE;
+ }
+ else
+ {
+ // We will have to evaluate one or more subcomponents. In
+ // this case, first check our depth to make sure we're not
+ // nesting too deep.
+ if (depth >= MAX_NESTED_FILTER_DEPTH)
+ {
+ Message message = ERR_SEARCH_FILTER_NESTED_TOO_DEEP.
+ get(String.valueOf(entry.getDN()),
+ String.valueOf(completeFilter));
+ throw new DirectoryException(
+ DirectoryServer.getServerErrorResultCode(),
+ message);
+ }
+
+ for (SearchFilter f : filterComponents)
+ {
+ ConditionResult result =
+ f.matchesEntryInternal(completeFilter, entry,
+ depth+1);
+ switch (result)
+ {
+ case TRUE:
+ break;
+ case FALSE:
+ if (debugEnabled())
+ {
+ TRACER.debugVerbose(
+ "Returning FALSE for AND component %s in " +
+ "filter %s for entry %s",
+ f, completeFilter, entry.getDN());
+ }
+ return result;
+ case UNDEFINED:
+ if (debugEnabled())
+ {
+ TRACER.debugInfo(
+ "Undefined result for AND component %s in filter " +
+ "%s for entry %s", f, completeFilter, entry.getDN());
+ }
+ return result;
+ default:
+ Message message =
+ ERR_SEARCH_FILTER_INVALID_RESULT_TYPE.
+ get(String.valueOf(entry.getDN()),
+ String.valueOf(completeFilter),
+ String.valueOf(result));
+ throw new
+ DirectoryException(
+ DirectoryServer.getServerErrorResultCode(),
+ message);
+ }
+ }
+
+ // If we have gotten here, then all the components must have
+ // matched.
+ if (debugEnabled())
+ {
+ TRACER.debugVerbose(
+ "Returning TRUE for AND component %s in filter %s " +
+ "for entry %s", this, completeFilter, entry.getDN());
+ }
+ return ConditionResult.TRUE;
+ }
+ }
+
+
+
+ /**
+ * Indicates whether the this OR filter matches the provided entry.
+ *
+ * @param completeFilter The complete filter being checked, of
+ * which this filter may be a subset.
+ * @param entry The entry for which to make the
+ * determination.
+ * @param depth The current depth of the evaluation,
+ * which is used to prevent infinite
+ * recursion due to highly nested filters
+ * and eventually running out of stack
+ * space.
+ *
+ * @return <CODE>TRUE</CODE> if this filter matches the provided
+ * entry, <CODE>FALSE</CODE> if it does not, or
+ * <CODE>UNDEFINED</CODE> if the result is undefined.
+ *
+ * @throws DirectoryException If a problem is encountered during
+ * processing.
+ */
+ private ConditionResult processOR(SearchFilter completeFilter,
+ Entry entry, int depth)
+ throws DirectoryException
+ {
+ if (filterComponents == null)
+ {
+ // The set of subcomponents was null. This is not allowed.
+ Message message =
+ ERR_SEARCH_FILTER_COMPOUND_COMPONENTS_NULL.
+ get(String.valueOf(entry.getDN()),
+ String.valueOf(completeFilter),
+ String.valueOf(filterType));
+ throw new DirectoryException(
+ DirectoryServer.getServerErrorResultCode(),
+ message);
+ }
+ else if (filterComponents.isEmpty())
+ {
+ // An OR filter with no elements like "(|)" is specified as
+ // "undefined" in RFC 2251, but is considered one of the
+ // TRUE/FALSE filters in RFC 4526, in which case we should
+ // always return false.
+ if (debugEnabled())
+ {
+ TRACER.debugInfo("Returning FALSE for LDAP FALSE " +
+ "filter (|)");
+ }
+ return ConditionResult.FALSE;
+ }
+ else
+ {
+ // We will have to evaluate one or more subcomponents. In
+ // this case, first check our depth to make sure we're not
+ // nesting too deep.
+ if (depth >= MAX_NESTED_FILTER_DEPTH)
+ {
+ Message message = ERR_SEARCH_FILTER_NESTED_TOO_DEEP.
+ get(String.valueOf(entry.getDN()),
+ String.valueOf(completeFilter));
+ throw new DirectoryException(
+ DirectoryServer.getServerErrorResultCode(),
+ message);
+ }
+
+ ConditionResult result = ConditionResult.FALSE;
+ for (SearchFilter f : filterComponents)
+ {
+ switch (f.matchesEntryInternal(completeFilter, entry,
+ depth+1))
+ {
+ case TRUE:
+ if (debugEnabled())
+ {
+ TRACER.debugVerbose(
+ "Returning TRUE for OR component %s in filter " +
+ "%s for entry %s",
+ f, completeFilter, entry.getDN());
+ }
+ return ConditionResult.TRUE;
+ case FALSE:
+ break;
+ case UNDEFINED:
+ if (debugEnabled())
+ {
+ TRACER.debugInfo(
+ "Undefined result for OR component %s in filter " +
+ "%s for entry %s",
+ f, completeFilter, entry.getDN());
+ }
+ result = ConditionResult.UNDEFINED;
+ break;
+ default:
+ Message message =
+ ERR_SEARCH_FILTER_INVALID_RESULT_TYPE.
+ get(String.valueOf(entry.getDN()),
+ String.valueOf(completeFilter),
+ String.valueOf(result));
+ throw new
+ DirectoryException(
+ DirectoryServer.getServerErrorResultCode(),
+ message);
+ }
+ }
+
+
+ if (debugEnabled())
+ {
+ TRACER.debugVerbose(
+ "Returning %s for OR component %s in filter %s for " +
+ "entry %s", result, this, completeFilter,
+ entry.getDN());
+ }
+ return result;
+ }
+ }
+
+
+
+ /**
+ * Indicates whether the this NOT filter matches the provided entry.
+ *
+ * @param completeFilter The complete filter being checked, of
+ * which this filter may be a subset.
+ * @param entry The entry for which to make the
+ * determination.
+ * @param depth The current depth of the evaluation,
+ * which is used to prevent infinite
+ * recursion due to highly nested filters
+ * and eventually running out of stack
+ * space.
+ *
+ * @return <CODE>TRUE</CODE> if this filter matches the provided
+ * entry, <CODE>FALSE</CODE> if it does not, or
+ * <CODE>UNDEFINED</CODE> if the result is undefined.
+ *
+ * @throws DirectoryException If a problem is encountered during
+ * processing.
+ */
+ private ConditionResult processNOT(SearchFilter completeFilter,
+ Entry entry, int depth)
+ throws DirectoryException
+ {
+ if (notComponent == null)
+ {
+ // The NOT subcomponent was null. This is not allowed.
+ Message message = ERR_SEARCH_FILTER_NOT_COMPONENT_NULL.
+ get(String.valueOf(entry.getDN()),
+ String.valueOf(completeFilter));
+ throw new DirectoryException(
+ DirectoryServer.getServerErrorResultCode(),
+ message);
+ }
+ else
+ {
+ // The subcomponent for the NOT filter can be an AND, OR, or
+ // NOT filter that would require more nesting. Make sure
+ // that we don't go too deep.
+ if (depth >= MAX_NESTED_FILTER_DEPTH)
+ {
+ Message message = ERR_SEARCH_FILTER_NESTED_TOO_DEEP.
+ get(String.valueOf(entry.getDN()),
+ String.valueOf(completeFilter));
+ throw new DirectoryException(
+ DirectoryServer.getServerErrorResultCode(),
+ message);
+ }
+
+ ConditionResult result =
+ notComponent.matchesEntryInternal(completeFilter,
+ entry, depth+1);
+ switch (result)
+ {
+ case TRUE:
+ if (debugEnabled())
+ {
+ TRACER.debugVerbose(
+ "Returning FALSE for NOT component %s in filter " +
+ "%s for entry %s",
+ notComponent, completeFilter, entry.getDN());
+ }
+ return ConditionResult.FALSE;
+ case FALSE:
+ if (debugEnabled())
+ {
+ TRACER.debugVerbose(
+ "Returning TRUE for NOT component %s in filter " +
+ "%s for entry %s",
+ notComponent, completeFilter, entry.getDN());
+ }
+ return ConditionResult.TRUE;
+ case UNDEFINED:
+ if (debugEnabled())
+ {
+ TRACER.debugInfo(
+ "Undefined result for NOT component %s in filter " +
+ "%s for entry %s",
+ notComponent, completeFilter, entry.getDN());
+ }
+ return ConditionResult.UNDEFINED;
+ default:
+ Message message = ERR_SEARCH_FILTER_INVALID_RESULT_TYPE.
+ get(String.valueOf(entry.getDN()),
+ String.valueOf(completeFilter),
+ String.valueOf(result));
+ throw new
+ DirectoryException(
+ DirectoryServer.getServerErrorResultCode(),
+ message);
+ }
+ }
+ }
+
+
+
+ /**
+ * Indicates whether the this equality filter matches the provided
+ * entry.
+ *
+ * @param completeFilter The complete filter being checked, of
+ * which this filter may be a subset.
+ * @param entry The entry for which to make the
+ * determination.
+ *
+ * @return <CODE>TRUE</CODE> if this filter matches the provided
+ * entry, <CODE>FALSE</CODE> if it does not, or
+ * <CODE>UNDEFINED</CODE> if the result is undefined.
+ *
+ * @throws DirectoryException If a problem is encountered during
+ * processing.
+ */
+ private ConditionResult processEquality(SearchFilter completeFilter,
+ Entry entry)
+ throws DirectoryException
+ {
+ // Make sure that an attribute type has been defined.
+ if (attributeType == null)
+ {
+ Message message =
+ ERR_SEARCH_FILTER_EQUALITY_NO_ATTRIBUTE_TYPE.
+ get(String.valueOf(entry.getDN()), toString());
+ throw new DirectoryException(ResultCode.PROTOCOL_ERROR,
+ message);
+ }
+
+ // Make sure that an assertion value has been defined.
+ if (assertionValue == null)
+ {
+ Message message =
+ ERR_SEARCH_FILTER_EQUALITY_NO_ASSERTION_VALUE.
+ get(String.valueOf(entry.getDN()), toString(),
+ attributeType.getNameOrOID());
+ throw new DirectoryException(ResultCode.PROTOCOL_ERROR,
+ message);
+ }
+
+ // See if the entry has an attribute with the requested type.
+ List<Attribute> attrs = entry.getAttribute(attributeType,
+ attributeOptions);
+ if ((attrs == null) || (attrs.isEmpty()))
+ {
+ if (debugEnabled())
+ {
+ TRACER.debugVerbose(
+ "Returning FALSE for equality component %s in " +
+ "filter %s because entry %s didn't have attribute " +
+ "type %s",
+ this, completeFilter, entry.getDN(),
+ attributeType.getNameOrOID());
+ }
+ return ConditionResult.FALSE;
+ }
+
+ // Iterate through all the attributes and see if we can find a
+ // match.
+ for (Attribute a : attrs)
+ {
+ if (a.hasValue(assertionValue))
+ {
+ if (debugEnabled())
+ {
+ TRACER.debugVerbose(
+ "Returning TRUE for equality component %s in " +
+ "filter %s for entry %s",
+ this, completeFilter, entry.getDN());
+ }
+ return ConditionResult.TRUE;
+ }
+ }
+
+ if (debugEnabled())
+ {
+ TRACER.debugVerbose(
+ "Returning FALSE for equality component %s in filter " +
+ "%s because entry %s didn't have attribute type " +
+ "%s with value %s",
+ this, completeFilter, entry.getDN(),
+ attributeType.getNameOrOID(),
+ assertionValue.getStringValue());
+ }
+ return ConditionResult.FALSE;
+ }
+
+
+
+ /**
+ * Indicates whether the this substring filter matches the provided
+ * entry.
+ *
+ * @param completeFilter The complete filter being checked, of
+ * which this filter may be a subset.
+ * @param entry The entry for which to make the
+ * determination.
+ *
+ * @return <CODE>TRUE</CODE> if this filter matches the provided
+ * entry, <CODE>FALSE</CODE> if it does not, or
+ * <CODE>UNDEFINED</CODE> if the result is undefined.
+ *
+ * @throws DirectoryException If a problem is encountered during
+ * processing.
+ */
+ private ConditionResult processSubstring(
+ SearchFilter completeFilter,
+ Entry entry)
+ throws DirectoryException
+ {
+ // Make sure that an attribute type has been defined.
+ if (attributeType == null)
+ {
+ Message message =
+ ERR_SEARCH_FILTER_SUBSTRING_NO_ATTRIBUTE_TYPE.
+ get(String.valueOf(entry.getDN()), toString());
+ throw new DirectoryException(ResultCode.PROTOCOL_ERROR,
+ message);
+ }
+
+ // Make sure that at least one substring element has been
+ // defined.
+ if ((subInitialElement == null) &&
+ (subFinalElement == null) &&
+ ((subAnyElements == null) || subAnyElements.isEmpty()))
+ {
+ Message message =
+ ERR_SEARCH_FILTER_SUBSTRING_NO_SUBSTRING_COMPONENTS.
+ get(String.valueOf(entry.getDN()), toString(),
+ attributeType.getNameOrOID());
+ throw new DirectoryException(ResultCode.PROTOCOL_ERROR,
+ message);
+ }
+
+ // See if the entry has an attribute with the requested type.
+ List<Attribute> attrs =
+ entry.getAttribute(attributeType, attributeOptions);
+ if ((attrs == null) || (attrs.isEmpty()))
+ {
+ if (debugEnabled())
+ {
+ TRACER.debugVerbose(
+ "Returning FALSE for substring component %s in " +
+ "filter %s because entry %s didn't have attribute " +
+ "type %s",
+ this, completeFilter, entry.getDN(),
+ attributeType.getNameOrOID());
+ }
+ return ConditionResult.FALSE;
+ }
+
+ // Iterate through all the attributes and see if we can find a
+ // match.
+ ConditionResult result = ConditionResult.FALSE;
+ for (Attribute a : attrs)
+ {
+ switch (a.matchesSubstring(subInitialElement,
+ subAnyElements,
+ subFinalElement))
+ {
+ case TRUE:
+ if (debugEnabled())
+ {
+ TRACER.debugVerbose(
+ "Returning TRUE for substring component %s in " +
+ "filter %s for entry %s",
+ this, completeFilter, entry.getDN());
+ }
+ return ConditionResult.TRUE;
+ case FALSE:
+ break;
+ case UNDEFINED:
+ if (debugEnabled())
+ {
+ TRACER.debugVerbose(
+ "Undefined result encountered for substring " +
+ "component %s in filter %s for entry %s",
+ this, completeFilter, entry.getDN());
+ }
+ result = ConditionResult.UNDEFINED;
+ break;
+ default:
+ }
+ }
+
+ if (debugEnabled())
+ {
+ TRACER.debugVerbose(
+ "Returning %s for substring component %s in filter " +
+ "%s for entry %s",
+ result, this, completeFilter, entry.getDN());
+ }
+ return result;
+ }
+
+
+
+ /**
+ * Indicates whether the this greater-or-equal filter matches the
+ * provided entry.
+ *
+ * @param completeFilter The complete filter being checked, of
+ * which this filter may be a subset.
+ * @param entry The entry for which to make the
+ * determination.
+ *
+ * @return <CODE>TRUE</CODE> if this filter matches the provided
+ * entry, <CODE>FALSE</CODE> if it does not, or
+ * <CODE>UNDEFINED</CODE> if the result is undefined.
+ *
+ * @throws DirectoryException If a problem is encountered during
+ * processing.
+ */
+ private ConditionResult processGreaterOrEqual(
+ SearchFilter completeFilter,
+ Entry entry)
+ throws DirectoryException
+ {
+ // Make sure that an attribute type has been defined.
+ if (attributeType == null)
+ {
+ Message message =
+ ERR_SEARCH_FILTER_GREATER_OR_EQUAL_NO_ATTRIBUTE_TYPE.
+ get(String.valueOf(entry.getDN()), toString());
+ throw new DirectoryException(ResultCode.PROTOCOL_ERROR,
+ message);
+ }
+
+ // Make sure that an assertion value has been defined.
+ if (assertionValue == null)
+ {
+ Message message =
+ ERR_SEARCH_FILTER_GREATER_OR_EQUAL_NO_VALUE.
+ get(String.valueOf(entry.getDN()), toString(),
+ attributeType.getNameOrOID());
+ throw new DirectoryException(ResultCode.PROTOCOL_ERROR,
+ message);
+ }
+
+ // See if the entry has an attribute with the requested type.
+ List<Attribute> attrs =
+ entry.getAttribute(attributeType, attributeOptions);
+ if ((attrs == null) || (attrs.isEmpty()))
+ {
+ if (debugEnabled())
+ {
+ TRACER.debugVerbose("Returning FALSE for " +
+ "greater-or-equal component %s in filter %s " +
+ "because entry %s didn't have attribute type %s",
+ this, completeFilter, entry.getDN(),
+ attributeType.getNameOrOID());
+ }
+ return ConditionResult.FALSE;
+ }
+
+ // Iterate through all the attributes and see if we can find a
+ // match.
+ ConditionResult result = ConditionResult.FALSE;
+ for (Attribute a : attrs)
+ {
+ switch (a.greaterThanOrEqualTo(assertionValue))
+ {
+ case TRUE:
+ if (debugEnabled())
+ {
+ TRACER.debugVerbose(
+ "Returning TRUE for greater-or-equal component " +
+ "%s in filter %s for entry %s",
+ this, completeFilter, entry.getDN());
+ }
+ return ConditionResult.TRUE;
+ case FALSE:
+ break;
+ case UNDEFINED:
+ if (debugEnabled())
+ {
+ TRACER.debugVerbose(
+ "Undefined result encountered for " +
+ "greater-or-equal component %s in filter %s " +
+ "for entry %s", this, completeFilter,
+ entry.getDN());
+ }
+ result = ConditionResult.UNDEFINED;
+ break;
+ default:
+ }
+ }
+
+ if (debugEnabled())
+ {
+ TRACER.debugVerbose(
+ "Returning %s for greater-or-equal component %s in " +
+ "filter %s for entry %s",
+ result, this, completeFilter, entry.getDN());
+ }
+ return result;
+ }
+
+
+
+ /**
+ * Indicates whether the this less-or-equal filter matches the
+ * provided entry.
+ *
+ * @param completeFilter The complete filter being checked, of
+ * which this filter may be a subset.
+ * @param entry The entry for which to make the
+ * determination.
+ *
+ * @return <CODE>TRUE</CODE> if this filter matches the provided
+ * entry, <CODE>FALSE</CODE> if it does not, or
+ * <CODE>UNDEFINED</CODE> if the result is undefined.
+ *
+ * @throws DirectoryException If a problem is encountered during
+ * processing.
+ */
+ private ConditionResult processLessOrEqual(
+ SearchFilter completeFilter,
+ Entry entry)
+ throws DirectoryException
+ {
+ // Make sure that an attribute type has been defined.
+ if (attributeType == null)
+ {
+ Message message =
+ ERR_SEARCH_FILTER_LESS_OR_EQUAL_NO_ATTRIBUTE_TYPE.
+ get(String.valueOf(entry.getDN()), toString());
+ throw new DirectoryException(ResultCode.PROTOCOL_ERROR,
+ message);
+ }
+
+ // Make sure that an assertion value has been defined.
+ if (assertionValue == null)
+ {
+ Message message =
+ ERR_SEARCH_FILTER_LESS_OR_EQUAL_NO_ASSERTION_VALUE.
+ get(String.valueOf(entry.getDN()), toString(),
+ attributeType.getNameOrOID());
+ throw new DirectoryException(ResultCode.PROTOCOL_ERROR,
+ message);
+ }
+
+ // See if the entry has an attribute with the requested type.
+ List<Attribute> attrs =
+ entry.getAttribute(attributeType, attributeOptions);
+ if ((attrs == null) || (attrs.isEmpty()))
+ {
+ if (debugEnabled())
+ {
+ TRACER.debugVerbose(
+ "Returning FALSE for less-or-equal component %s in " +
+ "filter %s because entry %s didn't have attribute " +
+ "type %s", this, completeFilter, entry.getDN(),
+ attributeType.getNameOrOID());
+ }
+ return ConditionResult.FALSE;
+ }
+
+ // Iterate through all the attributes and see if we can find a
+ // match.
+ ConditionResult result = ConditionResult.FALSE;
+ for (Attribute a : attrs)
+ {
+ switch (a.lessThanOrEqualTo(assertionValue))
+ {
+ case TRUE:
+ if (debugEnabled())
+ {
+ TRACER.debugVerbose(
+ "Returning TRUE for less-or-equal component %s " +
+ "in filter %s for entry %s",
+ this, completeFilter, entry.getDN());
+ }
+ return ConditionResult.TRUE;
+ case FALSE:
+ break;
+ case UNDEFINED:
+ if (debugEnabled())
+ {
+ TRACER.debugVerbose(
+ "Undefined result encountered for " +
+ "less-or-equal component %s in filter %s " +
+ "for entry %s",
+ this, completeFilter, entry.getDN());
+ }
+ result = ConditionResult.UNDEFINED;
+ break;
+ default:
+ }
+ }
+
+ if (debugEnabled())
+ {
+ TRACER.debugVerbose(
+ "Returning %s for less-or-equal component %s in " +
+ "filter %s for entry %s",
+ result, this, completeFilter, entry.getDN());
+ }
+ return result;
+ }
+
+
+
+ /**
+ * Indicates whether the this present filter matches the provided
+ * entry.
+ *
+ * @param completeFilter The complete filter being checked, of
+ * which this filter may be a subset.
+ * @param entry The entry for which to make the
+ * determination.
+ *
+ * @return <CODE>TRUE</CODE> if this filter matches the provided
+ * entry, <CODE>FALSE</CODE> if it does not, or
+ * <CODE>UNDEFINED</CODE> if the result is undefined.
+ *
+ * @throws DirectoryException If a problem is encountered during
+ * processing.
+ */
+ private ConditionResult processPresent(SearchFilter completeFilter,
+ Entry entry)
+ throws DirectoryException
+ {
+ // Make sure that an attribute type has been defined.
+ if (attributeType == null)
+ {
+ Message message =
+ ERR_SEARCH_FILTER_PRESENCE_NO_ATTRIBUTE_TYPE.
+ get(String.valueOf(entry.getDN()), toString());
+ throw new DirectoryException(ResultCode.PROTOCOL_ERROR,
+ message);
+ }
+
+
+ // See if the entry has an attribute with the requested type.
+ // If so, then it's a match. If not, then it's not a match.
+ if (entry.hasAttribute(attributeType, attributeOptions))
+ {
+ if (debugEnabled())
+ {
+ TRACER.debugVerbose(
+ "Returning TRUE for presence component %s in " +
+ "filter %s for entry %s",
+ this, completeFilter, entry.getDN());
+ }
+ return ConditionResult.TRUE;
+ }
+ else
+ {
+ if (debugEnabled())
+ {
+ TRACER.debugVerbose(
+ "Returning FALSE for presence component %s in " +
+ "filter %s for entry %s",
+ this, completeFilter, entry.getDN());
+ }
+ return ConditionResult.FALSE;
+ }
+ }
+
+
+
+ /**
+ * Indicates whether the this approximate filter matches the
+ * provided entry.
+ *
+ * @param completeFilter The complete filter being checked, of
+ * which this filter may be a subset.
+ * @param entry The entry for which to make the
+ * determination.
+ *
+ * @return <CODE>TRUE</CODE> if this filter matches the provided
+ * entry, <CODE>FALSE</CODE> if it does not, or
+ * <CODE>UNDEFINED</CODE> if the result is undefined.
+ *
+ * @throws DirectoryException If a problem is encountered during
+ * processing.
+ */
+ private ConditionResult processApproximate(
+ SearchFilter completeFilter,
+ Entry entry)
+ throws DirectoryException
+ {
+ // Make sure that an attribute type has been defined.
+ if (attributeType == null)
+ {
+ Message message =
+ ERR_SEARCH_FILTER_APPROXIMATE_NO_ATTRIBUTE_TYPE.
+ get(String.valueOf(entry.getDN()), toString());
+ throw new DirectoryException(ResultCode.PROTOCOL_ERROR,
+ message);
+ }
+
+ // Make sure that an assertion value has been defined.
+ if (assertionValue == null)
+ {
+ Message message =
+ ERR_SEARCH_FILTER_APPROXIMATE_NO_ASSERTION_VALUE.
+ get(String.valueOf(entry.getDN()), toString(),
+ attributeType.getNameOrOID());
+ throw new DirectoryException(ResultCode.PROTOCOL_ERROR,
+ message);
+ }
+
+ // See if the entry has an attribute with the requested type.
+ List<Attribute> attrs =
+ entry.getAttribute(attributeType, attributeOptions);
+ if ((attrs == null) || (attrs.isEmpty()))
+ {
+ if (debugEnabled())
+ {
+ TRACER.debugVerbose(
+ "Returning FALSE for approximate component %s in " +
+ "filter %s because entry %s didn't have attribute " +
+ "type %s", this, completeFilter, entry.getDN(),
+ attributeType.getNameOrOID());
+ }
+ return ConditionResult.FALSE;
+ }
+
+ // Iterate through all the attributes and see if we can find a
+ // match.
+ ConditionResult result = ConditionResult.FALSE;
+ for (Attribute a : attrs)
+ {
+ switch (a.approximatelyEqualTo(assertionValue))
+ {
+ case TRUE:
+ if (debugEnabled())
+ {
+ TRACER.debugVerbose(
+ "Returning TRUE for approximate component %s in " +
+ "filter %s for entry %s",
+ this, completeFilter, entry.getDN());
+ }
+ return ConditionResult.TRUE;
+ case FALSE:
+ break;
+ case UNDEFINED:
+ if (debugEnabled())
+ {
+ TRACER.debugVerbose(
+ "Undefined result encountered for approximate " +
+ "component %s in filter %s for entry %s",
+ this, completeFilter, entry.getDN());
+ }
+ result = ConditionResult.UNDEFINED;
+ break;
+ default:
+ }
+ }
+
+ if (debugEnabled())
+ {
+ TRACER.debugVerbose(
+ "Returning %s for approximate component %s in filter " +
+ "%s for entry %s",
+ result, this, completeFilter, entry.getDN());
+ }
+ return result;
+ }
+
+
+
+ /**
* Indicates whether this extensibleMatch filter matches the
* provided entry.
*
diff --git a/opendj-sdk/opends/src/server/org/opends/server/workflowelement/localbackend/LocalBackendAddOperation.java b/opendj-sdk/opends/src/server/org/opends/server/workflowelement/localbackend/LocalBackendAddOperation.java
index 8207729..011d83a 100644
--- a/opendj-sdk/opends/src/server/org/opends/server/workflowelement/localbackend/LocalBackendAddOperation.java
+++ b/opendj-sdk/opends/src/server/org/opends/server/workflowelement/localbackend/LocalBackendAddOperation.java
@@ -193,7 +193,7 @@
skipPostOperation = false;
// Check for a request to cancel this operation.
- if (getCancelRequest() != null)
+ if (cancelIfRequested())
{
return;
}
@@ -222,7 +222,7 @@
}
// Check for a request to cancel this operation.
- if (getCancelRequest() != null)
+ if (cancelIfRequested())
{
return;
}
@@ -254,7 +254,7 @@
try
{
// Check for a request to cancel this operation.
- if (getCancelRequest() != null)
+ if (cancelIfRequested())
{
return;
}
@@ -596,7 +596,7 @@
}
// Check for a request to cancel this operation.
- if (getCancelRequest() != null)
+ if (cancelIfRequested())
{
return;
}
@@ -631,7 +631,7 @@
// Check for a request to cancel this operation.
- if (getCancelRequest() != null)
+ if (cancelIfRequested())
{
return;
}
@@ -855,6 +855,27 @@
/**
+ * Checks to determine whether there has been a request to cancel this
+ * operation. If so, then set the cancel result and processing stop time.
+ *
+ * @return {@code true} if there was a cancel request, or {@code false} if
+ * not.
+ */
+ private boolean cancelIfRequested()
+ {
+ if (getCancelRequest() == null)
+ {
+ return false;
+ }
+
+ indicateCancelled(getCancelRequest());
+ setProcessingStopTime();
+ return true;
+ }
+
+
+
+ /**
* Acquire a read lock on the parent of the entry to add.
*
* @return The acquired read lock.
diff --git a/opendj-sdk/opends/src/server/org/opends/server/workflowelement/localbackend/LocalBackendCompareOperation.java b/opendj-sdk/opends/src/server/org/opends/server/workflowelement/localbackend/LocalBackendCompareOperation.java
index 206ac65..b69914b 100644
--- a/opendj-sdk/opends/src/server/org/opends/server/workflowelement/localbackend/LocalBackendCompareOperation.java
+++ b/opendj-sdk/opends/src/server/org/opends/server/workflowelement/localbackend/LocalBackendCompareOperation.java
@@ -152,7 +152,7 @@
// Check for a request to cancel this operation.
- if (getCancelRequest() != null)
+ if (cancelIfRequested())
{
return;
}
@@ -185,7 +185,7 @@
// Check for a request to cancel this operation.
- if (getCancelRequest() != null)
+ if (cancelIfRequested())
{
return;
}
@@ -302,7 +302,7 @@
}
// Check for a request to cancel this operation.
- if (getCancelRequest() != null)
+ if (cancelIfRequested())
{
return;
}
@@ -415,7 +415,7 @@
// Check for a request to cancel this operation.
- if (getCancelRequest() != null)
+ if (cancelIfRequested())
{
return;
}
@@ -438,6 +438,27 @@
/**
+ * Checks to determine whether there has been a request to cancel this
+ * operation. If so, then set the cancel result and processing stop time.
+ *
+ * @return {@code true} if there was a cancel request, or {@code false} if
+ * not.
+ */
+ private boolean cancelIfRequested()
+ {
+ if (getCancelRequest() == null)
+ {
+ return false;
+ }
+
+ indicateCancelled(getCancelRequest());
+ setProcessingStopTime();
+ return true;
+ }
+
+
+
+ /**
* Performs any processing required for the controls included in the request.
*
* @throws DirectoryException If a problem occurs that should prevent the
diff --git a/opendj-sdk/opends/src/server/org/opends/server/workflowelement/localbackend/LocalBackendDeleteOperation.java b/opendj-sdk/opends/src/server/org/opends/server/workflowelement/localbackend/LocalBackendDeleteOperation.java
index 02e2887..ee4ddc1 100644
--- a/opendj-sdk/opends/src/server/org/opends/server/workflowelement/localbackend/LocalBackendDeleteOperation.java
+++ b/opendj-sdk/opends/src/server/org/opends/server/workflowelement/localbackend/LocalBackendDeleteOperation.java
@@ -163,7 +163,7 @@
skipPostOperation = false;
// Check for a request to cancel this operation.
- if (getCancelRequest() != null)
+ if (cancelIfRequested())
{
return;
}
@@ -314,7 +314,7 @@
}
// Check for a request to cancel this operation.
- if (getCancelRequest() != null)
+ if (cancelIfRequested())
{
return;
}
@@ -345,7 +345,7 @@
// Check for a request to cancel this operation.
- if (getCancelRequest() != null)
+ if (cancelIfRequested())
{
return;
}
@@ -590,6 +590,27 @@
/**
+ * Checks to determine whether there has been a request to cancel this
+ * operation. If so, then set the cancel result and processing stop time.
+ *
+ * @return {@code true} if there was a cancel request, or {@code false} if
+ * not.
+ */
+ private boolean cancelIfRequested()
+ {
+ if (getCancelRequest() == null)
+ {
+ return false;
+ }
+
+ indicateCancelled(getCancelRequest());
+ setProcessingStopTime();
+ return true;
+ }
+
+
+
+ /**
* Performs any request control processing needed for this operation.
*
* @throws DirectoryException If a problem occurs that should cause the
diff --git a/opendj-sdk/opends/src/server/org/opends/server/workflowelement/localbackend/LocalBackendModifyDNOperation.java b/opendj-sdk/opends/src/server/org/opends/server/workflowelement/localbackend/LocalBackendModifyDNOperation.java
index 8e4ec8d..a7b19b8 100644
--- a/opendj-sdk/opends/src/server/org/opends/server/workflowelement/localbackend/LocalBackendModifyDNOperation.java
+++ b/opendj-sdk/opends/src/server/org/opends/server/workflowelement/localbackend/LocalBackendModifyDNOperation.java
@@ -203,7 +203,7 @@
skipPostOperation = false;
// Check for a request to cancel this operation.
- if (getCancelRequest() != null)
+ if (cancelIfRequested())
{
return;
}
@@ -283,7 +283,7 @@
// Check for a request to cancel this operation.
- if (getCancelRequest() != null)
+ if (cancelIfRequested())
{
return;
}
@@ -359,7 +359,7 @@
try
{
// Check for a request to cancel this operation.
- if (getCancelRequest() != null)
+ if (cancelIfRequested())
{
return;
}
@@ -514,7 +514,7 @@
// Check for a request to cancel this operation.
- if (getCancelRequest() != null)
+ if (cancelIfRequested())
{
return;
}
@@ -575,7 +575,7 @@
// Check for a request to cancel this operation.
- if (getCancelRequest() != null)
+ if (cancelIfRequested())
{
return;
}
@@ -789,6 +789,27 @@
/**
+ * Checks to determine whether there has been a request to cancel this
+ * operation. If so, then set the cancel result and processing stop time.
+ *
+ * @return {@code true} if there was a cancel request, or {@code false} if
+ * not.
+ */
+ private boolean cancelIfRequested()
+ {
+ if (getCancelRequest() == null)
+ {
+ return false;
+ }
+
+ indicateCancelled(getCancelRequest());
+ setProcessingStopTime();
+ return true;
+ }
+
+
+
+ /**
* Processes the set of controls included in the request.
*
* @throws DirectoryException If a problem occurs that should cause the
diff --git a/opendj-sdk/opends/src/server/org/opends/server/workflowelement/localbackend/LocalBackendModifyOperation.java b/opendj-sdk/opends/src/server/org/opends/server/workflowelement/localbackend/LocalBackendModifyOperation.java
index 4caefd9..d38461b 100644
--- a/opendj-sdk/opends/src/server/org/opends/server/workflowelement/localbackend/LocalBackendModifyOperation.java
+++ b/opendj-sdk/opends/src/server/org/opends/server/workflowelement/localbackend/LocalBackendModifyOperation.java
@@ -366,7 +366,7 @@
// Check for a request to cancel this operation.
- if (getCancelRequest() != null)
+ if (cancelIfRequested())
{
return;
}
@@ -395,86 +395,26 @@
try
{
// Check for a request to cancel this operation.
- if (getCancelRequest() != null)
+ if (cancelIfRequested())
{
return;
}
- // Get the entry to modify. If it does not exist, then fail.
try
{
- currentEntry = backend.getEntry(entryDN);
- }
- catch (DirectoryException de)
- {
- if (debugEnabled())
- {
- TRACER.debugCaught(DebugLogLevel.ERROR, de);
- }
+ // Get the entry to modify. If it does not exist, then fail.
+ getEntryToModify();
- setResponseData(de);
- break modifyProcessing;
- }
-
- if (currentEntry == null)
- {
- setResultCode(ResultCode.NO_SUCH_OBJECT);
- appendErrorMessage(ERR_MODIFY_NO_SUCH_ENTRY.get(
- String.valueOf(entryDN)));
-
- // See if one of the entry's ancestors exists.
- DN parentDN = entryDN.getParentDNInSuffix();
- while (parentDN != null)
- {
- try
- {
- if (DirectoryServer.entryExists(parentDN))
- {
- setMatchedDN(parentDN);
- break;
- }
- }
- catch (Exception e)
- {
- if (debugEnabled())
- {
- TRACER.debugCaught(DebugLogLevel.ERROR, e);
- }
- break;
- }
-
- parentDN = parentDN.getParentDNInSuffix();
- }
-
- break modifyProcessing;
- }
-
-
- // Check to see if there are any controls in the request. If so, then
- // see if there is any special processing required.
- try
- {
+ // Check to see if there are any controls in the request. If so, then
+ // see if there is any special processing required.
processRequestControls();
- }
- catch (DirectoryException de)
- {
- if (debugEnabled())
- {
- TRACER.debugCaught(DebugLogLevel.ERROR, de);
- }
- setResponseData(de);
- break modifyProcessing;
- }
+ // Get the password policy state object for the entry that can be used
+ // to perform any appropriate password policy processing. Also, see
+ // if the entry is being updated by the end user or an administrator.
+ selfChange = entryDN.equals(getAuthorizationDN());
-
- // Get the password policy state object for the entry that can be used
- // to perform any appropriate password policy processing. Also, see if
- // the entry is being updated by the end user or an administrator.
- selfChange = entryDN.equals(getAuthorizationDN());
- try
- {
// FIXME -- Need a way to enable debug mode.
pwPolicyState = new PasswordPolicyState(currentEntry, false, false);
}
@@ -485,8 +425,7 @@
TRACER.debugCaught(DebugLogLevel.ERROR, de);
}
- setResultCode(de.getResultCode());
- appendErrorMessage(de.getMessageObject());
+ setResponseData(de);
break modifyProcessing;
}
@@ -529,6 +468,12 @@
try
{
handleInitialPasswordPolicyAndSchemaProcessing();
+
+ wasLocked = false;
+ if (passwordChanged)
+ {
+ performAdditionalPasswordChangedProcessing();
+ }
}
catch (DirectoryException de)
{
@@ -542,28 +487,6 @@
}
- // If there was a password change, then perform any additional checks
- // that may be necessary.
- wasLocked = false;
- if (passwordChanged)
- {
- try
- {
- performAdditionalPasswordChangedProcessing();
- }
- catch (DirectoryException de)
- {
- if (debugEnabled())
- {
- TRACER.debugCaught(DebugLogLevel.ERROR, de);
- }
-
- setResponseData(de);
- break modifyProcessing;
- }
- }
-
-
// Check to see if the client has permission to perform the modify.
// The access control check is not made any earlier because the handler
// needs access to the modified entry.
@@ -614,7 +537,7 @@
// Check for a request to cancel this operation.
- if (getCancelRequest() != null)
+ if (cancelIfRequested())
{
return;
}
@@ -648,7 +571,7 @@
// Check for a request to cancel this operation.
- if (getCancelRequest() != null)
+ if (cancelIfRequested())
{
return;
}
@@ -761,7 +684,7 @@
setResultCode(cancelResult.getResultCode());
Message message = coe.getMessageObject();
- if ((message != null) && (message.length() > 0))
+ if (message != null)
{
appendErrorMessage(message);
}
@@ -832,17 +755,68 @@
}
}
+
// Notify any change notification listeners that might be registered with
// the server.
if (getResultCode() == ResultCode.SUCCESS)
{
- for (ChangeNotificationListener changeListener :
- DirectoryServer.getChangeNotificationListeners())
+ notifyChangeListeners();
+ }
+
+
+ // Stop the processing timer.
+ setProcessingStopTime();
+ }
+
+
+
+ /**
+ * Checks to determine whether there has been a request to cancel this
+ * operation. If so, then set the cancel result and processing stop time.
+ *
+ * @return {@code true} if there was a cancel request, or {@code false} if
+ * not.
+ */
+ private boolean cancelIfRequested()
+ {
+ if (getCancelRequest() == null)
+ {
+ return false;
+ }
+
+ indicateCancelled(getCancelRequest());
+ setProcessingStopTime();
+ return true;
+ }
+
+
+
+ /**
+ * Gets the entry to modify.
+ *
+ * @return The entry retrieved from the backend.
+ *
+ * @throws DirectoryException If a problem occurs while trying to get the
+ * entry, or if the entry doesn't exist.
+ */
+ private void getEntryToModify()
+ throws DirectoryException
+ {
+ currentEntry = backend.getEntry(entryDN);
+ if (currentEntry == null)
+ {
+ // See if one of the entry's ancestors exists.
+ DN matchedDN = null;
+ DN parentDN = entryDN.getParentDNInSuffix();
+ while (parentDN != null)
{
try
{
- changeListener.handleModifyOperation(this, currentEntry,
- modifiedEntry);
+ if (DirectoryServer.entryExists(parentDN))
+ {
+ matchedDN = parentDN;
+ break;
+ }
}
catch (Exception e)
{
@@ -850,18 +824,16 @@
{
TRACER.debugCaught(DebugLogLevel.ERROR, e);
}
-
- Message message = ERR_MODIFY_ERROR_NOTIFYING_CHANGE_LISTENER.get(
- getExceptionMessage(e));
- logError(message);
+ break;
}
+
+ parentDN = parentDN.getParentDNInSuffix();
}
+
+ throw new DirectoryException(ResultCode.NO_SUCH_OBJECT,
+ ERR_MODIFY_NO_SUCH_ENTRY.get(String.valueOf(entryDN)),
+ matchedDN, null);
}
-
-
-
- // Stop the processing timer.
- setProcessingStopTime();
}
@@ -1584,7 +1556,8 @@
/**
- * Performs the initial schema processing for an add modification.
+ * Performs the initial schema processing for an add modification and updates
+ * the entry appropriately.
*
* @param attr The attribute being added.
*
@@ -1676,7 +1649,8 @@
/**
- * Performs the initial schema processing for a delete modification.
+ * Performs the initial schema processing for a delete modification and
+ * updates the entry appropriately.
*
* @param attr The attribute being deleted.
*
@@ -1736,7 +1710,8 @@
/**
- * Performs the initial schema processing for a replace modification.
+ * Performs the initial schema processing for a replace modification and
+ * updates the entry appropriately.
*
* @param attr The attribute being replaced.
*
@@ -1897,7 +1872,8 @@
/**
- * Performs the initial schema processing for an increment modification.
+ * Performs the initial schema processing for an increment modification and
+ * updates the entry appropriately.
*
* @param attr The attribute being incremented.
*
@@ -2408,5 +2384,33 @@
getResponseControls().add(responseControl);
}
}
+
+
+
+ /**
+ * Notify any registered change listeners about this update.
+ */
+ private void notifyChangeListeners()
+ {
+ for (ChangeNotificationListener changeListener :
+ DirectoryServer.getChangeNotificationListeners())
+ {
+ try
+ {
+ changeListener.handleModifyOperation(this, currentEntry, modifiedEntry);
+ }
+ catch (Exception e)
+ {
+ if (debugEnabled())
+ {
+ TRACER.debugCaught(DebugLogLevel.ERROR, e);
+ }
+
+ Message message = ERR_MODIFY_ERROR_NOTIFYING_CHANGE_LISTENER.get(
+ getExceptionMessage(e));
+ logError(message);
+ }
+ }
+ }
}
diff --git a/opendj-sdk/opends/src/server/org/opends/server/workflowelement/localbackend/LocalBackendSearchOperation.java b/opendj-sdk/opends/src/server/org/opends/server/workflowelement/localbackend/LocalBackendSearchOperation.java
index 15b5543..6ee6d0a 100644
--- a/opendj-sdk/opends/src/server/org/opends/server/workflowelement/localbackend/LocalBackendSearchOperation.java
+++ b/opendj-sdk/opends/src/server/org/opends/server/workflowelement/localbackend/LocalBackendSearchOperation.java
@@ -191,7 +191,7 @@
}
// Check for a request to cancel this operation.
- if (getCancelRequest() != null)
+ if (cancelIfRequested())
{
return;
}
@@ -222,7 +222,7 @@
// Check for a request to cancel this operation.
- if (getCancelRequest() != null)
+ if (cancelIfRequested())
{
return;
}
@@ -328,7 +328,7 @@
// Check for a request to cancel this operation.
- if (getCancelRequest() != null)
+ if (cancelIfRequested())
{
return;
}
@@ -352,6 +352,27 @@
/**
+ * Checks to determine whether there has been a request to cancel this
+ * operation. If so, then set the cancel result and processing stop time.
+ *
+ * @return {@code true} if there was a cancel request, or {@code false} if
+ * not.
+ */
+ private boolean cancelIfRequested()
+ {
+ if (getCancelRequest() == null)
+ {
+ return false;
+ }
+
+ indicateCancelled(getCancelRequest());
+ setProcessingStopTime();
+ return true;
+ }
+
+
+
+ /**
* Handles any controls contained in the request.
*
* @throws DirectoryException If there is a problem with any of the request
--
Gitblit v1.10.0