From 59685c84348f8d71dc3bbd3513c5eb10cc738a8e Mon Sep 17 00:00:00 2001
From: matthew_swift <matthew_swift@localhost>
Date: Fri, 03 Nov 2006 16:39:22 +0000
Subject: [PATCH] Refactor DN and RDN classes and improve their test coverage.
---
opends/src/server/org/opends/server/types/AttributeValue.java | 116
opends/src/server/org/opends/server/core/EntryCacheConfigManager.java | 6
opends/src/server/org/opends/server/tools/LDIFSearch.java | 2
opends/tests/unit-tests-testng/src/server/org/opends/server/extensions/DigestMD5SASLMechanismHandlerTestCase.java | 6
opends/src/server/org/opends/server/types/SearchFilter.java | 16
opends/src/server/org/opends/server/messages/CoreMessages.java | 13
opends/tests/unit-tests-testng/src/server/org/opends/server/extensions/CRAMMD5SASLMechanismHandlerTestCase.java | 14
opends/src/server/org/opends/server/core/KeyManagerProviderConfigManager.java | 8
opends/src/server/org/opends/server/protocols/jmx/JmxConnectionHandler.java | 4
opends/src/server/org/opends/server/synchronization/MultimasterSynchronization.java | 2
opends/tests/unit-tests-testng/src/server/org/opends/server/core/TestModifyDNOperation.java | 72
opends/tests/unit-tests-testng/src/server/org/opends/server/util/TestModifyDNChangeRecordEntry.java | 21
opends/src/server/org/opends/server/core/RelativeSubtreeSpecification.java | 2
opends/src/server/org/opends/server/tools/makeldif/UnderscoreParentDNTag.java | 8
opends/tests/unit-tests-testng/src/server/org/opends/server/backends/jeb/JebTestCase.java | 4
opends/tests/unit-tests-testng/src/server/org/opends/server/monitors/InternalSearchMonitorTestCase.java | 8
opends/tests/unit-tests-testng/src/server/org/opends/server/protocols/internal/InternalClientConnectionTestCase.java | 8
opends/src/server/org/opends/server/core/AddOperation.java | 37
opends/src/server/org/opends/server/types/DN.java | 3162 +++-----------------
opends/src/server/org/opends/server/core/ModifyOperation.java | 4
opends/src/server/org/opends/server/backends/RootDSEBackend.java | 3
opends/tests/unit-tests-testng/src/server/org/opends/server/core/BindOperationTestCase.java | 34
opends/tests/unit-tests-testng/src/server/org/opends/server/util/TestModifyChangeRecordEntry.java | 13
opends/tests/unit-tests-testng/src/server/org/opends/server/util/TestStaticUtils.java | 59
opends/src/server/org/opends/server/tools/LDIFDiff.java | 10
opends/src/server/org/opends/server/tools/makeldif/TemplateEntry.java | 31
opends/tests/unit-tests-testng/src/server/org/opends/server/util/TestDeleteChangeRecordEntry.java | 8
opends/tests/unit-tests-testng/src/server/org/opends/server/util/TestAddChangeRecordEntry.java | 12
opends/src/server/org/opends/server/backends/MemoryBackend.java | 6
opends/src/server/org/opends/server/backends/MonitorBackend.java | 14
opends/src/server/org/opends/server/backends/jeb/EntryContainer.java | 34
opends/src/server/org/opends/server/schema/RFC3672SubtreeSpecificationSyntax.java | 2
opends/src/server/org/opends/server/schema/RelativeSubtreeSpecificationSyntax.java | 2
opends/src/server/org/opends/server/util/LDIFReader.java | 2
opends/tests/unit-tests-testng/src/server/org/opends/server/protocols/ldap/TestDeleteResponseProtocolOp.java | 9
opends/src/server/org/opends/server/backends/task/TaskBackend.java | 10
opends/src/server/org/opends/server/schema/OctetStringOrderingMatchingRule.java | 35
opends/tests/unit-tests-testng/src/server/org/opends/server/protocols/ldap/TestCompareResponseProtocolOp.java | 9
opends/tests/unit-tests-testng/src/server/org/opends/server/types/TestRDN.java | 869 +++++
opends/src/server/org/opends/server/types/RDN.java | 2539 +++++++++------
opends/tests/unit-tests-testng/src/server/org/opends/server/protocols/internal/InternalSearchOperationTestCase.java | 4
opends/src/server/org/opends/server/backends/task/TaskScheduler.java | 2
opends/tests/unit-tests-testng/src/server/org/opends/server/protocols/ldap/TestAddResponseProtocolOp.java | 10
opends/src/server/org/opends/server/types/LDAPURL.java | 2
opends/src/server/org/opends/server/tools/makeldif/DNTag.java | 20
opends/src/server/org/opends/server/core/Operation.java | 3
opends/tests/unit-tests-testng/src/server/org/opends/server/core/DeleteOperationTestCase.java | 4
opends/src/server/org/opends/server/backends/jeb/VerifyJob.java | 6
opends/tests/unit-tests-testng/src/server/org/opends/server/protocols/ldap/TestModifyResponseProtocolOp.java | 9
opends/src/server/org/opends/server/backends/SchemaBackend.java | 15
opends/tests/unit-tests-testng/src/server/org/opends/server/core/TestRFC3672SubtreeSpecification.java | 2
opends/src/server/org/opends/server/core/SimpleSubtreeSpecification.java | 10
opends/src/server/org/opends/server/util/StaticUtils.java | 103
opends/src/server/org/opends/server/core/CertificateMapperConfigManager.java | 7
opends/tests/unit-tests-testng/src/server/org/opends/server/core/TestRelativeSubtreeSpecification.java | 2
opends/src/server/org/opends/server/backends/BackupBackend.java | 30
opends/src/server/org/opends/server/types/Entry.java | 24
opends/src/server/org/opends/server/core/PersistentSearch.java | 10
opends/src/server/org/opends/server/backends/jeb/ImportJob.java | 4
opends/tests/unit-tests-testng/src/server/org/opends/server/types/TestDN.java | 1383 +++++++-
opends/src/server/org/opends/server/core/TrustManagerProviderConfigManager.java | 8
opends/tests/unit-tests-testng/src/server/org/opends/server/extensions/AnonymousSASLMechanismHandlerTestCase.java | 6
opends/tests/unit-tests-testng/src/server/org/opends/server/core/ModifyOperationTestCase.java | 24
opends/src/server/org/opends/server/controls/ProxiedAuthV2Control.java | 4
opends/src/server/org/opends/server/core/DirectoryServer.java | 33
opends/src/server/org/opends/server/extensions/PasswordModifyExtendedOperation.java | 4
opends/src/server/org/opends/server/tools/LDIFModify.java | 10
opends/src/server/org/opends/server/backends/jeb/RootContainer.java | 2
/dev/null | 132
opends/src/server/org/opends/server/core/CompareOperation.java | 4
opends/tests/unit-tests-testng/src/server/org/opends/server/protocols/ldap/TestModifyDNResponseProtocolOp.java | 9
opends/tests/unit-tests-testng/src/server/org/opends/server/types/TestEntry.java | 2
opends/src/server/org/opends/server/core/ModifyDNOperation.java | 27
opends/src/server/org/opends/server/synchronization/SynchronizationDomain.java | 10
opends/src/server/org/opends/server/core/RFC3672SubtreeSpecification.java | 2
opends/tests/unit-tests-testng/src/server/org/opends/server/util/TestChangeRecordEntry.java | 7
opends/src/server/org/opends/server/core/DeleteOperation.java | 4
opends/src/server/org/opends/server/tools/makeldif/UnderscoreDNTag.java | 29
opends/src/server/org/opends/server/backends/jeb/DN2URI.java | 6
79 files changed, 4,607 insertions(+), 4,580 deletions(-)
diff --git a/opends/src/server/org/opends/server/backends/BackupBackend.java b/opends/src/server/org/opends/server/backends/BackupBackend.java
index 46b7195..fda38ea 100644
--- a/opends/src/server/org/opends/server/backends/BackupBackend.java
+++ b/opends/src/server/org/opends/server/backends/BackupBackend.java
@@ -245,19 +245,20 @@
LinkedHashMap<AttributeType,List<Attribute>> userAttrs =
new LinkedHashMap<AttributeType,List<Attribute>>(1);
- AttributeType[] attrTypes = backupBaseDN.getRDN().getAttributeTypes();
- AttributeValue[] attrValues = backupBaseDN.getRDN().getAttributeValues();
- for (int i=0; i < attrTypes.length; i++)
+ RDN rdn = backupBaseDN.getRDN();
+ int numAVAs = rdn.getNumValues();
+ for (int i=0; i < numAVAs; i++)
{
LinkedHashSet<AttributeValue> valueSet =
new LinkedHashSet<AttributeValue>(1);
- valueSet.add(attrValues[i]);
+ valueSet.add(rdn.getAttributeValue(i));
+ AttributeType attrType = rdn.getAttributeType(i);
ArrayList<Attribute> attrList = new ArrayList<Attribute>(1);
- attrList.add(new Attribute(attrTypes[i], attrTypes[i].getNameOrOID(),
+ attrList.add(new Attribute(attrType, attrType.getNameOrOID(),
valueSet));
- userAttrs.put(attrTypes[i], attrList);
+ userAttrs.put(attrType, attrList);
}
backupBaseEntry = new Entry(backupBaseDN, objectClasses, userAttrs,
@@ -370,7 +371,7 @@
// If so, then it must point to a backup directory. Otherwise, it must be
// two levels below the backup base entry and must point to a specific
// backup.
- DN parentDN = entryDN.getParent();
+ DN parentDN = entryDN.getParentDNInSuffix();
if (parentDN == null)
{
int msgID = MSGID_BACKUP_INVALID_BASE;
@@ -381,7 +382,7 @@
{
return getBackupDirectoryEntry(entryDN);
}
- else if (backupBaseDN.equals(parentDN.getParent()))
+ else if (backupBaseDN.equals(parentDN.getParentDNInSuffix()))
{
return getBackupEntry(entryDN);
}
@@ -528,7 +529,7 @@
// Next, get the backup directory from the parent DN.
- DN parentDN = entryDN.getParent();
+ DN parentDN = entryDN.getParentDNInSuffix();
if (parentDN == null)
{
int msgID = MSGID_BACKUP_NO_BACKUP_PARENT_DN;
@@ -929,7 +930,7 @@
}
}
}
- else if (backupBaseDN.equals(parentDN = baseDN.getParent()))
+ else if (backupBaseDN.equals(parentDN = baseDN.getParentDNInSuffix()))
{
Entry backupDirEntry = getBackupDirectoryEntry(baseDN);
@@ -983,7 +984,8 @@
}
else
{
- if ((parentDN == null) || (! backupBaseDN.equals(parentDN.getParent())))
+ if ((parentDN == null)
+ || (! backupBaseDN.equals(parentDN.getParentDNInSuffix())))
{
int msgID = MSGID_BACKUP_NO_SUCH_ENTRY;
String message = getMessage(msgID);
@@ -1475,13 +1477,9 @@
public static DN makeChildDN(DN parentDN, AttributeType rdnAttrType,
String rdnStringValue)
{
- RDN[] baseComponents = parentDN.getRDNComponents();
- RDN[] components = new RDN[baseComponents.length+1];
AttributeValue attrValue =
new AttributeValue(rdnAttrType, rdnStringValue);
- components[0] = new RDN(rdnAttrType, attrValue);
- System.arraycopy(baseComponents, 0, components, 1, baseComponents.length);
- return new DN(components);
+ return parentDN.concat(RDN.create(rdnAttrType, attrValue));
}
}
diff --git a/opends/src/server/org/opends/server/backends/MemoryBackend.java b/opends/src/server/org/opends/server/backends/MemoryBackend.java
index 8bc12d4..5b5f8e8 100644
--- a/opends/src/server/org/opends/server/backends/MemoryBackend.java
+++ b/opends/src/server/org/opends/server/backends/MemoryBackend.java
@@ -292,7 +292,7 @@
// Get the parent DN and ensure that it exists in the backend.
- DN parentDN = entryDN.getParent();
+ DN parentDN = entryDN.getParentDNInSuffix();
if (parentDN == null)
{
int msgID = MSGID_MEMORYBACKEND_ENTRY_DOESNT_BELONG;
@@ -393,7 +393,7 @@
childDNs.remove(entryDN);
entryMap.remove(entryDN);
- DN parentDN = entryDN.getParent();
+ DN parentDN = entryDN.getParentDNInSuffix();
if (parentDN != null)
{
HashSet<DN> parentsChildren = childDNs.get(parentDN);
@@ -505,7 +505,7 @@
// Make sure that the parent of the new entry exists.
- DN parentDN = entry.getDN().getParent();
+ DN parentDN = entry.getDN().getParentDNInSuffix();
if ((parentDN == null) || (! entryMap.containsKey(parentDN)))
{
int msgID = MSGID_MEMORYBACKEND_RENAME_PARENT_DOESNT_EXIST;
diff --git a/opends/src/server/org/opends/server/backends/MonitorBackend.java b/opends/src/server/org/opends/server/backends/MonitorBackend.java
index 9f84e20..206a778 100644
--- a/opends/src/server/org/opends/server/backends/MonitorBackend.java
+++ b/opends/src/server/org/opends/server/backends/MonitorBackend.java
@@ -371,7 +371,7 @@
// See if the monitor base entry is the immediate parent for the requested
// entry. If not, then throw an exception.
- DN parentDN = entryDN.getParent();
+ DN parentDN = entryDN.getParentDNInSuffix();
if ((parentDN == null) || (! parentDN.equals(baseMonitorDN)))
{
if (baseMonitorDN.isAncestorOf(entryDN))
@@ -405,7 +405,7 @@
// Get the RDN value and see if it matches the instance name for one of
// the directory server monitor providers.
- String rdnValue = entryRDN.getAttributeValues()[0].getStringValue();
+ String rdnValue = entryRDN.getAttributeValue(0).getStringValue();
MonitorProvider monitorProvider =
DirectoryServer.getMonitorProvider(rdnValue.toLowerCase());
if (monitorProvider == null)
@@ -448,7 +448,7 @@
return true;
}
- DN parentDN = entryDN.getParent();
+ DN parentDN = entryDN.getParentDNInSuffix();
if ((parentDN == null) || (! parentDN.equals(baseMonitorDN)))
{
return false;
@@ -460,7 +460,7 @@
return false;
}
- String rdnValue = rdn.getAttributeValues()[0].getStringValue();
+ String rdnValue = rdn.getAttributeValue(0).getStringValue();
MonitorProvider monitorProvider =
DirectoryServer.getMonitorProvider(toLowerCase(rdnValue));
return (monitorProvider != null);
@@ -654,14 +654,14 @@
// Make sure to include the RDN attribute.
RDN entryRDN = entryDN.getRDN();
- AttributeType rdnType = entryRDN.getAttributeTypes()[0];
- AttributeValue rdnValue = entryRDN.getAttributeValues()[0];
+ AttributeType rdnType = entryRDN.getAttributeType(0);
+ AttributeValue rdnValue = entryRDN.getAttributeValue(0);
LinkedHashSet<AttributeValue> rdnValues =
new LinkedHashSet<AttributeValue>(1);
rdnValues.add(rdnValue);
- Attribute rdnAttr = new Attribute(rdnType, entryRDN.getAttributeNames()[0],
+ Attribute rdnAttr = new Attribute(rdnType, entryRDN.getAttributeName(0),
rdnValues);
ArrayList<Attribute> rdnList = new ArrayList<Attribute>(1);
rdnList.add(rdnAttr);
diff --git a/opends/src/server/org/opends/server/backends/RootDSEBackend.java b/opends/src/server/org/opends/server/backends/RootDSEBackend.java
index ee96da1..5611e60 100644
--- a/opends/src/server/org/opends/server/backends/RootDSEBackend.java
+++ b/opends/src/server/org/opends/server/backends/RootDSEBackend.java
@@ -72,7 +72,6 @@
import org.opends.server.types.LDIFExportConfig;
import org.opends.server.types.LDIFImportConfig;
import org.opends.server.types.ObjectClass;
-import org.opends.server.types.RDN;
import org.opends.server.types.RestoreConfig;
import org.opends.server.types.ResultCode;
import org.opends.server.types.SearchFilter;
@@ -230,7 +229,7 @@
// Create the set of base DNs that we will handle. In this case, it's just
// the root DSE.
- rootDSEDN = new DN(new ArrayList<RDN>(0));
+ rootDSEDN = DN.nullDN();
this.baseDNs = new DN[] { rootDSEDN };
diff --git a/opends/src/server/org/opends/server/backends/SchemaBackend.java b/opends/src/server/org/opends/server/backends/SchemaBackend.java
index f70eda6..9e0bc7b 100644
--- a/opends/src/server/org/opends/server/backends/SchemaBackend.java
+++ b/opends/src/server/org/opends/server/backends/SchemaBackend.java
@@ -399,19 +399,16 @@
RDN rdn = entryDN.getRDN();
if (rdn != null)
{
- String[] rdnNames = rdn.getAttributeNames();
- AttributeType[] rdnTypes = rdn.getAttributeTypes();
- AttributeValue[] rdnValues = rdn.getAttributeValues();
-
- int numRDNs = rdnTypes.length;
- for (int i=0; i < numRDNs; i++)
+ int numAVAs = rdn.getNumValues();
+ for (int i=0; i < numAVAs; i++)
{
LinkedHashSet<AttributeValue> valueSet =
new LinkedHashSet<AttributeValue>(1);
- valueSet.add(rdnValues[i]);
+ valueSet.add(rdn.getAttributeValue(i));
- AttributeType attrType = rdnTypes[i];
- Attribute a = new Attribute(attrType, rdnNames[i], valueSet);
+ AttributeType attrType = rdn.getAttributeType(i);
+ String attrName = rdn.getAttributeName(i);
+ Attribute a = new Attribute(attrType, attrName, valueSet);
ArrayList<Attribute> attrList = new ArrayList<Attribute>(1);
attrList.add(a);
diff --git a/opends/src/server/org/opends/server/backends/jeb/DN2URI.java b/opends/src/server/org/opends/server/backends/jeb/DN2URI.java
index 7cb76a9..d349e1e 100644
--- a/opends/src/server/org/opends/server/backends/jeb/DN2URI.java
+++ b/opends/src/server/org/opends/server/backends/jeb/DN2URI.java
@@ -445,7 +445,7 @@
{
urlBaseDN =
EntryContainer.modDN(targetDN,
- referralDN.getRDNComponents().length,
+ referralDN.getNumComponents(),
ldapurl.getBaseDN());
}
ldapurl.setBaseDN(urlBaseDN);
@@ -616,8 +616,8 @@
// Make sure the referral is within scope.
if (searchOp.getScope() == SearchScope.SINGLE_LEVEL)
{
- if ((dn.getRDNComponents().length !=
- baseDN.getRDNComponents().length + 1))
+ if ((dn.getNumComponents() !=
+ baseDN.getNumComponents() + 1))
{
continue;
}
diff --git a/opends/src/server/org/opends/server/backends/jeb/EntryContainer.java b/opends/src/server/org/opends/server/backends/jeb/EntryContainer.java
index 006f7c7..9363442 100644
--- a/opends/src/server/org/opends/server/backends/jeb/EntryContainer.java
+++ b/opends/src/server/org/opends/server/backends/jeb/EntryContainer.java
@@ -53,7 +53,6 @@
import org.opends.server.types.Entry;
import org.opends.server.types.LockType;
import org.opends.server.types.Modification;
-import org.opends.server.types.RDN;
import org.opends.server.types.ResultCode;
import org.opends.server.types.SearchScope;
import org.opends.server.util.StaticUtils;
@@ -903,8 +902,8 @@
if (searchScope == SearchScope.SINGLE_LEVEL)
{
// Check if this entry is an immediate child.
- if ((dn.getRDNComponents().length !=
- baseDN.getRDNComponents().length + 1))
+ if ((dn.getNumComponents() !=
+ baseDN.getNumComponents() + 1))
{
isInScope = false;
}
@@ -1131,8 +1130,8 @@
else if (searchScope == SearchScope.SINGLE_LEVEL)
{
// Check if this entry is an immediate child.
- if ((entryDN.getRDNComponents().length ==
- baseDN.getRDNComponents().length + 1) &&
+ if ((entryDN.getNumComponents() ==
+ baseDN.getNumComponents() + 1) &&
entryDN.isDescendantOf(baseDN))
{
isInScope = true;
@@ -1147,8 +1146,8 @@
}
else if (searchScope == SearchScope.SUBORDINATE_SUBTREE)
{
- if ((entryDN.getRDNComponents().length >
- baseDN.getRDNComponents().length) &&
+ if ((entryDN.getNumComponents() >
+ baseDN.getNumComponents()) &&
entryDN.isDescendantOf(baseDN))
{
isInScope = true;
@@ -2702,7 +2701,7 @@
// Construct the new DN of the entry.
DN newDN = modDN(oldEntry.getDN(),
- oldApexDN.getRDNComponents().length,
+ oldApexDN.getNumComponents(),
newApexEntry.getDN());
if (requestedNewSuperiorDN != null)
@@ -3078,23 +3077,8 @@
*/
public static DN modDN(DN oldDN, int oldSuffixLen, DN newSuffixDN)
{
- RDN[] oldRDNs = oldDN.getRDNComponents();
- RDN[] suffixRDNs = newSuffixDN.getRDNComponents();
-
- int prefixLen = oldRDNs.length - oldSuffixLen;
- RDN[] newRDNs = new RDN[prefixLen + suffixRDNs.length];
-
- // Copy the unchanged prefix.
- System.arraycopy(oldRDNs, 0,
- newRDNs, 0,
- prefixLen);
-
- // Copy the new suffix.
- System.arraycopy(suffixRDNs, 0,
- newRDNs, prefixLen,
- suffixRDNs.length);
-
- return new DN(newRDNs);
+ DN localName = oldDN.getLocalName(oldSuffixLen);
+ return newSuffixDN.concat(localName);
}
/**
diff --git a/opends/src/server/org/opends/server/backends/jeb/ImportJob.java b/opends/src/server/org/opends/server/backends/jeb/ImportJob.java
index 5508dcd..ae9fc55 100644
--- a/opends/src/server/org/opends/server/backends/jeb/ImportJob.java
+++ b/opends/src/server/org/opends/server/backends/jeb/ImportJob.java
@@ -705,7 +705,7 @@
}
else
{
- IDs = new ArrayList<EntryID>(entryDN.getRDNComponents().length);
+ IDs = new ArrayList<EntryID>(entryDN.getNumComponents());
IDs.add(entryID);
if (parentID != null)
{
@@ -838,7 +838,7 @@
importContext = importMap.get(nodeDN);
if (importContext == null)
{
- nodeDN = nodeDN.getParent();
+ nodeDN = nodeDN.getParentDNInSuffix();
}
}
diff --git a/opends/src/server/org/opends/server/backends/jeb/RootContainer.java b/opends/src/server/org/opends/server/backends/jeb/RootContainer.java
index 0f76e75..efeb9d3 100644
--- a/opends/src/server/org/opends/server/backends/jeb/RootContainer.java
+++ b/opends/src/server/org/opends/server/backends/jeb/RootContainer.java
@@ -524,7 +524,7 @@
ec = entryContainers.get(nodeDN);
if (ec == null)
{
- nodeDN = nodeDN.getParent();
+ nodeDN = nodeDN.getParentDNInSuffix();
}
}
diff --git a/opends/src/server/org/opends/server/backends/jeb/VerifyJob.java b/opends/src/server/org/opends/server/backends/jeb/VerifyJob.java
index ec35008..6a2ff16 100644
--- a/opends/src/server/org/opends/server/backends/jeb/VerifyJob.java
+++ b/opends/src/server/org/opends/server/backends/jeb/VerifyJob.java
@@ -734,8 +734,8 @@
}
if (!childEntry.getDN().isDescendantOf(entry.getDN()) ||
- childEntry.getDN().getRDNComponents().length !=
- entry.getDN().getRDNComponents().length + 1)
+ childEntry.getDN().getNumComponents() !=
+ entry.getDN().getNumComponents() + 1)
{
errorCount++;
System.err.printf("File id2children has ID %d with DN <%s> " +
@@ -1512,7 +1512,7 @@
{
return null;
}
- return dn.getParent();
+ return dn.getParentDNInSuffix();
}
/**
diff --git a/opends/src/server/org/opends/server/backends/task/TaskBackend.java b/opends/src/server/org/opends/server/backends/task/TaskBackend.java
index 79e4181..8e4783d 100644
--- a/opends/src/server/org/opends/server/backends/task/TaskBackend.java
+++ b/opends/src/server/org/opends/server/backends/task/TaskBackend.java
@@ -453,7 +453,7 @@
return taskScheduler.getRecurringTaskParentEntry();
}
- DN parentDN = entryDN.getParent();
+ DN parentDN = entryDN.getParentDNInSuffix();
if (parentDN == null)
{
return null;
@@ -509,7 +509,7 @@
return true;
}
- DN parentDN = entryDN.getParent();
+ DN parentDN = entryDN.getParentDNInSuffix();
if (parentDN == null)
{
return false;
@@ -553,7 +553,7 @@
// Get the DN for the entry and then get its parent.
DN entryDN = entry.getDN();
- DN parentDN = entryDN.getParent();
+ DN parentDN = entryDN.getParentDNInSuffix();
if (parentDN == null)
{
@@ -618,7 +618,7 @@
// Get the parent for the provided entry DN. It must be either the
// scheduled or recurring task parent DN.
- DN parentDN = entryDN.getParent();
+ DN parentDN = entryDN.getParentDNInSuffix();
if (parentDN == null)
{
int msgID = MSGID_TASKBE_DELETE_INVALID_ENTRY;
@@ -841,7 +841,7 @@
}
else
{
- DN parentDN = baseDN.getParent();
+ DN parentDN = baseDN.getParentDNInSuffix();
if (parentDN == null)
{
int msgID = MSGID_TASKBE_SEARCH_INVALID_BASE;
diff --git a/opends/src/server/org/opends/server/backends/task/TaskScheduler.java b/opends/src/server/org/opends/server/backends/task/TaskScheduler.java
index edd9a3a..13a0de4 100644
--- a/opends/src/server/org/opends/server/backends/task/TaskScheduler.java
+++ b/opends/src/server/org/opends/server/backends/task/TaskScheduler.java
@@ -1009,7 +1009,7 @@
}
else
{
- DN parentDN = entryDN.getParent();
+ DN parentDN = entryDN.getParentDNInSuffix();
if (parentDN == null)
{
int msgID = MSGID_TASKSCHED_ENTRY_HAS_NO_PARENT;
diff --git a/opends/src/server/org/opends/server/controls/ProxiedAuthV2Control.java b/opends/src/server/org/opends/server/controls/ProxiedAuthV2Control.java
index 1814727..02b2912 100644
--- a/opends/src/server/org/opends/server/controls/ProxiedAuthV2Control.java
+++ b/opends/src/server/org/opends/server/controls/ProxiedAuthV2Control.java
@@ -266,7 +266,7 @@
// Check for a zero-length value, which would be for an anonymous user.
if (authorizationID.value().length == 0)
{
- return new DN();
+ return DN.nullDN();
}
@@ -346,7 +346,7 @@
// If the authorization ID is just "u:", then it's an anonymous request.
if (lowerAuthzID.length() == 2)
{
- return new DN();
+ return DN.nullDN();
}
diff --git a/opends/src/server/org/opends/server/core/AddOperation.java b/opends/src/server/org/opends/server/core/AddOperation.java
index f07fdc6..8ca91ba 100644
--- a/opends/src/server/org/opends/server/core/AddOperation.java
+++ b/opends/src/server/org/opends/server/core/AddOperation.java
@@ -1014,11 +1014,11 @@
Lock parentLock = null;
Lock entryLock = null;
- DN parentDN = entryDN.getParent();
+ DN parentDN = entryDN.getParentDNInSuffix();
if (parentDN == null)
{
// Either this entry is a suffix or doesn't belong in the directory.
- if (entryDN.isSuffix())
+ if (DirectoryServer.isSuffix(entryDN))
{
// This is fine. This entry is one of the configured suffixes.
parentLock = null;
@@ -1166,7 +1166,7 @@
if (parentEntry == null)
{
- DN matchedDN = parentDN.getParent();
+ DN matchedDN = parentDN.getParentDNInSuffix();
while (matchedDN != null)
{
try
@@ -1183,7 +1183,7 @@
break;
}
- matchedDN = matchedDN.getParent();
+ matchedDN = matchedDN.getParentDNInSuffix();
}
@@ -1211,15 +1211,12 @@
// Check to make sure that all of the RDN attributes are included as
// attribute values. If not, then either add them or report an error.
RDN rdn = entryDN.getRDN();
- AttributeType[] rdnTypes = rdn.getAttributeTypes();
- AttributeValue[] rdnValues = rdn.getAttributeValues();
- String[] rdnNames = rdn.getAttributeNames();
-
- for (int i=0; i < rdnTypes.length; i++)
+ int numAVAs = rdn.getNumValues();
+ for (int i=0; i < numAVAs; i++)
{
- AttributeType t = rdnTypes[i];
- AttributeValue v = rdnValues[i];
-
+ AttributeType t = rdn.getAttributeType(i);
+ AttributeValue v = rdn.getAttributeValue(i);
+ String n = rdn.getAttributeName(i);
if (t.isOperational())
{
List<Attribute> attrList = operationalAttributes.get(t);
@@ -1233,7 +1230,7 @@
valueList.add(v);
attrList = new ArrayList<Attribute>();
- attrList.add(new Attribute(t, rdnNames[i], valueList));
+ attrList.add(new Attribute(t, n, valueList));
operationalAttributes.put(t, attrList);
}
@@ -1243,7 +1240,7 @@
int msgID = MSGID_ADD_MISSING_RDN_ATTRIBUTE;
appendErrorMessage(getMessage(msgID, String.valueOf(entryDN),
- rdnNames[i]));
+ n));
break addProcessing;
}
@@ -1277,7 +1274,7 @@
LinkedHashSet<AttributeValue> valueList =
new LinkedHashSet<AttributeValue>(1);
valueList.add(v);
- attrList.add(new Attribute(t, rdnNames[i], valueList));
+ attrList.add(new Attribute(t, n, valueList));
}
else
{
@@ -1285,7 +1282,7 @@
int msgID = MSGID_ADD_MISSING_RDN_ATTRIBUTE;
appendErrorMessage(getMessage(msgID, String.valueOf(entryDN),
- rdnNames[i]));
+ n));
break addProcessing;
}
@@ -1305,7 +1302,7 @@
valueList.add(v);
attrList = new ArrayList<Attribute>();
- attrList.add(new Attribute(t, rdnNames[i], valueList));
+ attrList.add(new Attribute(t, n, valueList));
userAttributes.put(t, attrList);
}
@@ -1315,7 +1312,7 @@
int msgID = MSGID_ADD_MISSING_RDN_ATTRIBUTE;
appendErrorMessage(getMessage(msgID, String.valueOf(entryDN),
- rdnNames[i]));
+ n));
break addProcessing;
}
@@ -1349,7 +1346,7 @@
LinkedHashSet<AttributeValue> valueList =
new LinkedHashSet<AttributeValue>(1);
valueList.add(v);
- attrList.add(new Attribute(t, rdnNames[i], valueList));
+ attrList.add(new Attribute(t, n, valueList));
}
else
{
@@ -1357,7 +1354,7 @@
int msgID = MSGID_ADD_MISSING_RDN_ATTRIBUTE;
appendErrorMessage(getMessage(msgID, String.valueOf(entryDN),
- rdnNames[i]));
+ n));
break addProcessing;
}
diff --git a/opends/src/server/org/opends/server/core/CertificateMapperConfigManager.java b/opends/src/server/org/opends/server/core/CertificateMapperConfigManager.java
index 1ffe6f6..30957dd 100644
--- a/opends/src/server/org/opends/server/core/CertificateMapperConfigManager.java
+++ b/opends/src/server/org/opends/server/core/CertificateMapperConfigManager.java
@@ -146,7 +146,8 @@
try
{
ConfigEntry parentEntry =
- DirectoryServer.getConfigEntry(configEntryDN.getParent());
+ DirectoryServer
+ .getConfigEntry(configEntryDN.getParentDNInSuffix());
if (parentEntry != null)
{
parentEntry.registerAddListener(this);
@@ -172,7 +173,7 @@
configEntry.registerChangeListener(this);
try
{
- DN parentDN = configEntryDN.getParent();
+ DN parentDN = configEntryDN.getParentDNInSuffix();
ConfigEntry parentEntry = DirectoryServer.getConfigEntry(parentDN);
if (parentEntry != null)
{
@@ -860,7 +861,7 @@
configEntry.registerChangeListener(this);
try
{
- DN parentDN = configEntry.getDN().getParent();
+ DN parentDN = configEntry.getDN().getParentDNInSuffix();
ConfigEntry parentEntry = DirectoryServer.getConfigEntry(parentDN);
if (parentEntry != null)
{
diff --git a/opends/src/server/org/opends/server/core/CompareOperation.java b/opends/src/server/org/opends/server/core/CompareOperation.java
index ab312d8..3ad3fba 100644
--- a/opends/src/server/org/opends/server/core/CompareOperation.java
+++ b/opends/src/server/org/opends/server/core/CompareOperation.java
@@ -697,7 +697,7 @@
String.valueOf(entryDN)));
// See if one of the entry's ancestors exists.
- DN parentDN = entryDN.getParent();
+ DN parentDN = entryDN.getParentDNInSuffix();
while (parentDN != null)
{
try
@@ -714,7 +714,7 @@
break;
}
- parentDN = parentDN.getParent();
+ parentDN = parentDN.getParentDNInSuffix();
}
break compareProcessing;
diff --git a/opends/src/server/org/opends/server/core/DeleteOperation.java b/opends/src/server/org/opends/server/core/DeleteOperation.java
index 230ef40..70d034c 100644
--- a/opends/src/server/org/opends/server/core/DeleteOperation.java
+++ b/opends/src/server/org/opends/server/core/DeleteOperation.java
@@ -617,7 +617,7 @@
try
{
- DN parentDN = entryDN.getParent();
+ DN parentDN = entryDN.getParentDNInSuffix();
while (parentDN != null)
{
if (DirectoryServer.entryExists(parentDN))
@@ -626,7 +626,7 @@
break;
}
- parentDN = parentDN.getParent();
+ parentDN = parentDN.getParentDNInSuffix();
}
}
catch (Exception e)
diff --git a/opends/src/server/org/opends/server/core/DirectoryServer.java b/opends/src/server/org/opends/server/core/DirectoryServer.java
index 94e6740..caf5bb0 100644
--- a/opends/src/server/org/opends/server/core/DirectoryServer.java
+++ b/opends/src/server/org/opends/server/core/DirectoryServer.java
@@ -31,7 +31,6 @@
import java.io.FileOutputStream;
import java.io.PrintStream;
import java.net.InetAddress;
-import java.util.ArrayList;
import java.util.Collections;
import java.util.LinkedHashMap;
import java.util.LinkedHashSet;
@@ -1926,7 +1925,7 @@
throw new InitializationException(msgID, message, e);
}
- DN[] baseDNs = { new DN(new RDN[0]) };
+ DN[] baseDNs = { DN.nullDN() };
rootDSEBackend = new RootDSEBackend();
rootDSEBackend.initializeBackend(rootDSEConfigEntry, baseDNs);
}
@@ -5372,7 +5371,7 @@
while (backend == null)
{
- dn = dn.getParent();
+ dn = dn.getParentDNInSuffix();
if (dn == null)
{
break;
@@ -5422,7 +5421,7 @@
}
boolean found = false;
- DN parentDN = suffixDN.getParent();
+ DN parentDN = suffixDN.getParentDNInSuffix();
while (parentDN != null)
{
b = directoryServer.suffixes.get(suffixDN);
@@ -5444,7 +5443,7 @@
}
}
- parentDN = parentDN.getParent();
+ parentDN = parentDN.getParentDNInSuffix();
}
@@ -5513,7 +5512,7 @@
throw new ConfigException(msgID, message);
}
- DN parentDN = suffixDN.getParent();
+ DN parentDN = suffixDN.getParentDNInSuffix();
while (parentDN != null)
{
b = directoryServer.suffixes.get(suffixDN);
@@ -5525,7 +5524,7 @@
throw new ConfigException(msgID, message);
}
- parentDN = suffixDN.getParent();
+ parentDN = suffixDN.getParentDNInSuffix();
}
}
@@ -5542,7 +5541,7 @@
throw new ConfigException(msgID, message);
}
- DN parentDN = suffixDN.getParent();
+ DN parentDN = suffixDN.getParentDNInSuffix();
while (parentDN != null)
{
b = directoryServer.privateSuffixes.get(suffixDN);
@@ -5563,7 +5562,7 @@
}
}
- parentDN = suffixDN.getParent();
+ parentDN = suffixDN.getParentDNInSuffix();
}
@@ -5599,7 +5598,7 @@
return;
}
- DN parentDN = suffixDN.getParent();
+ DN parentDN = suffixDN.getParentDNInSuffix();
while (parentDN != null)
{
b = directoryServer.suffixes.get(parentDN);
@@ -5625,7 +5624,7 @@
return;
}
- DN parentDN = suffixDN.getParent();
+ DN parentDN = suffixDN.getParentDNInSuffix();
while (parentDN != null)
{
b = directoryServer.privateSuffixes.get(parentDN);
@@ -7328,7 +7327,7 @@
{
// The config handler hasn't been initialized yet. Just return the DN
// of the root DSE.
- return new DN(new ArrayList<RDN>(0));
+ return DN.nullDN();
}
return configHandler.getConfigRootEntry().getDN();
@@ -7339,7 +7338,7 @@
// This could theoretically happen if an alert needs to be sent before the
// configuration is initialized. In that case, just return an empty DN.
- return new DN(new ArrayList<RDN>(0));
+ return DN.nullDN();
}
}
@@ -7782,11 +7781,9 @@
// Cannot reach this point.
throw new RuntimeException();
}
- RDN[] baseRDNs = monitorRootDN.getRDNComponents();
- RDN[] rdns = new RDN[baseRDNs.length+1];
- rdns[0] = new RDN(cnType, new AttributeValue(cnType, monitorName));
- System.arraycopy(baseRDNs, 0, rdns, 1, baseRDNs.length);
- return new DN(rdns);
+
+ RDN rdn = RDN.create(cnType, new AttributeValue(cnType, monitorName));
+ return monitorRootDN.concat(rdn);
}
}
diff --git a/opends/src/server/org/opends/server/core/EntryCacheConfigManager.java b/opends/src/server/org/opends/server/core/EntryCacheConfigManager.java
index fb85891..8c2c8eb 100644
--- a/opends/src/server/org/opends/server/core/EntryCacheConfigManager.java
+++ b/opends/src/server/org/opends/server/core/EntryCacheConfigManager.java
@@ -141,8 +141,8 @@
try
{
- ConfigEntry parentEntry =
- DirectoryServer.getConfigEntry(configEntryDN.getParent());
+ ConfigEntry parentEntry = DirectoryServer
+ .getConfigEntry(configEntryDN.getParentDNInSuffix());
if (parentEntry != null)
{
parentEntry.registerAddListener(this);
@@ -168,7 +168,7 @@
configEntry.registerChangeListener(this);
try
{
- DN parentDN = configEntryDN.getParent();
+ DN parentDN = configEntryDN.getParentDNInSuffix();
ConfigEntry parentEntry = DirectoryServer.getConfigEntry(parentDN);
if (parentEntry != null)
{
diff --git a/opends/src/server/org/opends/server/core/KeyManagerProviderConfigManager.java b/opends/src/server/org/opends/server/core/KeyManagerProviderConfigManager.java
index f36c5ce..064bcd6 100644
--- a/opends/src/server/org/opends/server/core/KeyManagerProviderConfigManager.java
+++ b/opends/src/server/org/opends/server/core/KeyManagerProviderConfigManager.java
@@ -143,8 +143,8 @@
try
{
- ConfigEntry parentEntry =
- DirectoryServer.getConfigEntry(configEntryDN.getParent());
+ ConfigEntry parentEntry = DirectoryServer
+ .getConfigEntry(configEntryDN.getParentDNInSuffix());
if (parentEntry != null)
{
parentEntry.registerAddListener(this);
@@ -170,7 +170,7 @@
configEntry.registerChangeListener(this);
try
{
- DN parentDN = configEntryDN.getParent();
+ DN parentDN = configEntryDN.getParentDNInSuffix();
ConfigEntry parentEntry = DirectoryServer.getConfigEntry(parentDN);
if (parentEntry != null)
{
@@ -857,7 +857,7 @@
configEntry.registerChangeListener(this);
try
{
- DN parentDN = configEntry.getDN().getParent();
+ DN parentDN = configEntry.getDN().getParentDNInSuffix();
ConfigEntry parentEntry = DirectoryServer.getConfigEntry(parentDN);
if (parentEntry != null)
{
diff --git a/opends/src/server/org/opends/server/core/ModifyDNOperation.java b/opends/src/server/org/opends/server/core/ModifyDNOperation.java
index 7c275e4..978870d 100644
--- a/opends/src/server/org/opends/server/core/ModifyDNOperation.java
+++ b/opends/src/server/org/opends/server/core/ModifyDNOperation.java
@@ -927,7 +927,7 @@
DN parentDN;
if (newSuperior == null)
{
- parentDN = entryDN.getParent();
+ parentDN = entryDN.getParentDNInSuffix();
}
else
{
@@ -942,14 +942,7 @@
break modifyDNProcessing;
}
- RDN[] parentComponents = parentDN.getRDNComponents();
- RDN[] newComponents = new RDN[parentComponents.length+1];
- System.arraycopy(parentComponents, 0, newComponents, 1,
- parentComponents.length);
- newComponents[0] = newRDN;
-
- DN newDN = new DN(newComponents);
-
+ DN newDN = parentDN.concat(newRDN);
// Get the backend for the current entry, and the backend for the new
// entry. If either is null, or if they are different, then fail.
@@ -1092,7 +1085,7 @@
if (currentEntry == null)
{
// See if one of the entry's ancestors exists.
- parentDN = entryDN.getParent();
+ parentDN = entryDN.getParentDNInSuffix();
while (parentDN != null)
{
try
@@ -1109,7 +1102,7 @@
break;
}
- parentDN = parentDN.getParent();
+ parentDN = parentDN.getParentDNInSuffix();
}
setResultCode(ResultCode.NO_SUCH_OBJECT);
@@ -1416,10 +1409,10 @@
{
LinkedHashSet<AttributeValue> valueSet =
new LinkedHashSet<AttributeValue>(1);
- valueSet.add(currentRDN.getAttributeValues()[i]);
+ valueSet.add(currentRDN.getAttributeValue(i));
- Attribute a = new Attribute(currentRDN.getAttributeTypes()[i],
- currentRDN.getAttributeNames()[i],
+ Attribute a = new Attribute(currentRDN.getAttributeType(i),
+ currentRDN.getAttributeName(i),
valueSet);
// If the associated attribute type is marked NO-USER-MODIFICATION,
@@ -1455,10 +1448,10 @@
{
LinkedHashSet<AttributeValue> valueSet =
new LinkedHashSet<AttributeValue>(1);
- valueSet.add(newRDN.getAttributeValues()[i]);
+ valueSet.add(newRDN.getAttributeValue(i));
- Attribute a = new Attribute(newRDN.getAttributeTypes()[i],
- newRDN.getAttributeNames()[i],
+ Attribute a = new Attribute(newRDN.getAttributeType(i),
+ newRDN.getAttributeName(i),
valueSet);
LinkedList<AttributeValue> duplicateValues =
diff --git a/opends/src/server/org/opends/server/core/ModifyOperation.java b/opends/src/server/org/opends/server/core/ModifyOperation.java
index 4767e51..c46d128 100644
--- a/opends/src/server/org/opends/server/core/ModifyOperation.java
+++ b/opends/src/server/org/opends/server/core/ModifyOperation.java
@@ -923,7 +923,7 @@
String.valueOf(entryDN)));
// See if one of the entry's ancestors exists.
- DN parentDN = entryDN.getParent();
+ DN parentDN = entryDN.getParentDNInSuffix();
while (parentDN != null)
{
try
@@ -940,7 +940,7 @@
break;
}
- parentDN = parentDN.getParent();
+ parentDN = parentDN.getParentDNInSuffix();
}
break modifyProcessing;
diff --git a/opends/src/server/org/opends/server/core/Operation.java b/opends/src/server/org/opends/server/core/Operation.java
index 0d85d66..fd81051 100644
--- a/opends/src/server/org/opends/server/core/Operation.java
+++ b/opends/src/server/org/opends/server/core/Operation.java
@@ -42,7 +42,6 @@
import org.opends.server.types.DN;
import org.opends.server.types.DirectoryException;
import org.opends.server.types.OperationType;
-import org.opends.server.types.RDN;
import org.opends.server.types.ResultCode;
import org.opends.server.types.operation.PostOperationOperation;
import org.opends.server.types.operation.PostResponseOperation;
@@ -752,7 +751,7 @@
AuthenticationInfo authInfo = clientConnection.getAuthenticationInfo();
if (authInfo == null)
{
- return new DN(new RDN[0]);
+ return DN.nullDN();
}
else
{
diff --git a/opends/src/server/org/opends/server/core/PersistentSearch.java b/opends/src/server/org/opends/server/core/PersistentSearch.java
index 63c343a..2ae86ec 100644
--- a/opends/src/server/org/opends/server/core/PersistentSearch.java
+++ b/opends/src/server/org/opends/server/core/PersistentSearch.java
@@ -221,7 +221,7 @@
}
break;
case SINGLE_LEVEL:
- if (! baseDN.equals(entry.getDN().getParent()))
+ if (! baseDN.equals(entry.getDN().getParentDNInSuffix()))
{
return;
}
@@ -331,7 +331,7 @@
}
break;
case SINGLE_LEVEL:
- if (! baseDN.equals(entry.getDN().getParent()))
+ if (! baseDN.equals(entry.getDN().getParentDNInSuffix()))
{
return;
}
@@ -444,7 +444,7 @@
}
break;
case SINGLE_LEVEL:
- if (! baseDN.equals(oldEntry.getDN().getParent()))
+ if (! baseDN.equals(oldEntry.getDN().getParentDNInSuffix()))
{
return;
}
@@ -567,8 +567,8 @@
break;
case SINGLE_LEVEL:
- oldMatches = baseDN.equals(oldEntry.getDN().getParent());
- newMatches = baseDN.equals(newEntry.getDN().getParent());
+ oldMatches = baseDN.equals(oldEntry.getDN().getParentDNInSuffix());
+ newMatches = baseDN.equals(newEntry.getDN().getParentDNInSuffix());
if (! (oldMatches || newMatches))
{
diff --git a/opends/src/server/org/opends/server/core/RFC3672SubtreeSpecification.java b/opends/src/server/org/opends/server/core/RFC3672SubtreeSpecification.java
index a964219..011032e 100644
--- a/opends/src/server/org/opends/server/core/RFC3672SubtreeSpecification.java
+++ b/opends/src/server/org/opends/server/core/RFC3672SubtreeSpecification.java
@@ -689,7 +689,7 @@
public RFC3672SubtreeSpecification(DN rootDN, DN relativeBaseDN,
int minimumDepth, int maximumDepth, Iterable<DN> chopBefore,
Iterable<DN> chopAfter, Refinement refinements) {
- super(relativeBaseDN == null ? rootDN : new DN(rootDN, relativeBaseDN),
+ super(relativeBaseDN == null ? rootDN : rootDN.concat(relativeBaseDN),
minimumDepth, maximumDepth, chopBefore, chopAfter);
assert debugConstructor(CLASS_NAME);
diff --git a/opends/src/server/org/opends/server/core/RelativeSubtreeSpecification.java b/opends/src/server/org/opends/server/core/RelativeSubtreeSpecification.java
index 5f58344..f53de92 100644
--- a/opends/src/server/org/opends/server/core/RelativeSubtreeSpecification.java
+++ b/opends/src/server/org/opends/server/core/RelativeSubtreeSpecification.java
@@ -248,7 +248,7 @@
public RelativeSubtreeSpecification(DN rootDN, DN relativeBaseDN,
int minimumDepth, int maximumDepth, Iterable<DN> chopBefore,
Iterable<DN> chopAfter, SearchFilter filter) {
- super(relativeBaseDN == null ? rootDN : new DN(rootDN, relativeBaseDN),
+ super(relativeBaseDN == null ? rootDN : rootDN.concat(relativeBaseDN),
minimumDepth, maximumDepth, chopBefore, chopAfter);
assert debugConstructor(CLASS_NAME);
diff --git a/opends/src/server/org/opends/server/core/SimpleSubtreeSpecification.java b/opends/src/server/org/opends/server/core/SimpleSubtreeSpecification.java
index cfb7673..b548c3d 100644
--- a/opends/src/server/org/opends/server/core/SimpleSubtreeSpecification.java
+++ b/opends/src/server/org/opends/server/core/SimpleSubtreeSpecification.java
@@ -390,7 +390,7 @@
this.chopBefore = new TreeMap<DN, DN>();
for (DN localName : chopBefore) {
- this.chopBefore.put(new DN(baseDN, localName), localName);
+ this.chopBefore.put(baseDN.concat(localName), localName);
}
} else {
// No chop before specifications.
@@ -402,7 +402,7 @@
this.chopAfter = new TreeMap<DN, DN>();
for (DN localName : chopAfter) {
- this.chopAfter.put(new DN(baseDN, localName), localName);
+ this.chopAfter.put(baseDN.concat(localName), localName);
}
} else {
// No chop after specifications.
@@ -428,10 +428,10 @@
}
// Check minimum and maximum depths.
- int baseRDNCount = baseDN.getRDNComponents().length;
+ int baseRDNCount = baseDN.getNumComponents();
if (minimumDepth > 0) {
- int entryRDNCount = dn.getRDNComponents().length;
+ int entryRDNCount = dn.getNumComponents();
if (entryRDNCount - baseRDNCount < minimumDepth) {
return false;
@@ -439,7 +439,7 @@
}
if (maximumDepth >= 0) {
- int entryRDNCount = dn.getRDNComponents().length;
+ int entryRDNCount = dn.getNumComponents();
if (entryRDNCount - baseRDNCount > maximumDepth) {
return false;
diff --git a/opends/src/server/org/opends/server/core/TrustManagerProviderConfigManager.java b/opends/src/server/org/opends/server/core/TrustManagerProviderConfigManager.java
index 50fa8d3..04a12fb 100644
--- a/opends/src/server/org/opends/server/core/TrustManagerProviderConfigManager.java
+++ b/opends/src/server/org/opends/server/core/TrustManagerProviderConfigManager.java
@@ -144,8 +144,8 @@
try
{
- ConfigEntry parentEntry =
- DirectoryServer.getConfigEntry(configEntryDN.getParent());
+ ConfigEntry parentEntry = DirectoryServer
+ .getConfigEntry(configEntryDN.getParentDNInSuffix());
if (parentEntry != null)
{
parentEntry.registerAddListener(this);
@@ -171,7 +171,7 @@
configEntry.registerChangeListener(this);
try
{
- DN parentDN = configEntryDN.getParent();
+ DN parentDN = configEntryDN.getParentDNInSuffix();
ConfigEntry parentEntry = DirectoryServer.getConfigEntry(parentDN);
if (parentEntry != null)
{
@@ -861,7 +861,7 @@
configEntry.registerChangeListener(this);
try
{
- DN parentDN = configEntry.getDN().getParent();
+ DN parentDN = configEntry.getDN().getParentDNInSuffix();
ConfigEntry parentEntry = DirectoryServer.getConfigEntry(parentDN);
if (parentEntry != null)
{
diff --git a/opends/src/server/org/opends/server/extensions/PasswordModifyExtendedOperation.java b/opends/src/server/org/opends/server/extensions/PasswordModifyExtendedOperation.java
index 82f4b81..50c6c8e 100644
--- a/opends/src/server/org/opends/server/extensions/PasswordModifyExtendedOperation.java
+++ b/opends/src/server/org/opends/server/extensions/PasswordModifyExtendedOperation.java
@@ -1015,7 +1015,7 @@
String.valueOf(entryDN)));
// See if one of the entry's ancestors exists.
- DN parentDN = entryDN.getParent();
+ DN parentDN = entryDN.getParentDNInSuffix();
while (parentDN != null)
{
try
@@ -1032,7 +1032,7 @@
break;
}
- parentDN = parentDN.getParent();
+ parentDN = parentDN.getParentDNInSuffix();
}
return null;
diff --git a/opends/src/server/org/opends/server/messages/CoreMessages.java b/opends/src/server/org/opends/server/messages/CoreMessages.java
index f4d0c07..a7357e7 100644
--- a/opends/src/server/org/opends/server/messages/CoreMessages.java
+++ b/opends/src/server/org/opends/server/messages/CoreMessages.java
@@ -1754,10 +1754,11 @@
/**
- * The message ID for the string that will be used if an attempt is made to
- * decode a string as an RDN but that string contained an unexpected comma or
- * semicolon. This takes two arguments, which are the RDN string to decode
- * and the position of the illegal comma or semicolon.
+ * The message ID for the string that will be used if an attempt is
+ * made to decode a string as an RDN but that string contained an
+ * unexpected plus, comma, or semicolon. This takes two arguments,
+ * which are the RDN string to decode and the position of the
+ * illegal plus, comma, or semicolon.
*/
public static final int MSGID_RDN_UNEXPECTED_COMMA =
CATEGORY_MASK_CORE | SEVERITY_MASK_MILD_ERROR | 174;
@@ -6572,8 +6573,8 @@
registerMessage(MSGID_RDN_UNEXPECTED_COMMA,
"Unable to decode the provided string \"%s\" as a " +
"relative distinguished name because it contained an " +
- "unexpected comma or semicolon at position %d, which is " +
- "not allowed in an RDN.");
+ "unexpected plus, comma, or semicolon at position %d, "+
+ "which is not allowed in an RDN.");
registerMessage(MSGID_RDN_ILLEGAL_CHARACTER,
"Unable to decode the provided string \"%s\" as a " +
"relative distinguished name because an illegal " +
diff --git a/opends/src/server/org/opends/server/protocols/jmx/JmxConnectionHandler.java b/opends/src/server/org/opends/server/protocols/jmx/JmxConnectionHandler.java
index 99238fc..bbfe835 100644
--- a/opends/src/server/org/opends/server/protocols/jmx/JmxConnectionHandler.java
+++ b/opends/src/server/org/opends/server/protocols/jmx/JmxConnectionHandler.java
@@ -337,7 +337,7 @@
// in the current entry.
// Always return true as the check will be performed by the
// hasAcceptableConfiguration call
- if (configEntry.getDN().compareTo(configEntryDN) == 0)
+ if (configEntry.getDN().equals(configEntryDN))
{
return true;
}
@@ -370,7 +370,7 @@
//
// We are checking first if we are dealing with a change
// in the current entry.
- if (configEntry.getDN().compareTo(configEntryDN) == 0)
+ if (configEntry.getDN().equals(configEntryDN))
{
ArrayList<String> messages = new ArrayList<String>();
return new ConfigChangeResult(ResultCode.SUCCESS, false, messages);
diff --git a/opends/src/server/org/opends/server/schema/OctetStringOrderingMatchingRule.java b/opends/src/server/org/opends/server/schema/OctetStringOrderingMatchingRule.java
index 29ca439..0ff9913 100644
--- a/opends/src/server/org/opends/server/schema/OctetStringOrderingMatchingRule.java
+++ b/opends/src/server/org/opends/server/schema/OctetStringOrderingMatchingRule.java
@@ -35,12 +35,10 @@
import org.opends.server.types.ByteString;
import org.opends.server.types.DirectoryException;
import org.opends.server.types.InitializationException;
+import org.opends.server.util.StaticUtils;
import static org.opends.server.loggers.Debug.*;
-import static org.opends.server.messages.MessageHandler.*;
-import static org.opends.server.messages.SchemaMessages.*;
import static org.opends.server.schema.SchemaConstants.*;
-import static org.opends.server.util.StaticUtils.*;
@@ -229,36 +227,7 @@
assert debugEnter(CLASS_NAME, "compareValues", String.valueOf(b1),
String.valueOf(b2));
- int minLength = Math.min(b1.length, b2.length);
-
- for (int i=0; i < minLength; i++)
- {
- if (b1[i] == b2[i])
- {
- continue;
- }
- else if (b1[i] < b2[i])
- {
- return -1;
- }
- else if (b1[i] > b2[i])
- {
- return 1;
- }
- }
-
- if (b1.length == b2.length)
- {
- return 0;
- }
- else if (b1.length < b2.length)
- {
- return -1;
- }
- else
- {
- return 1;
- }
+ return StaticUtils.compare(b1, b2);
}
}
diff --git a/opends/src/server/org/opends/server/schema/RFC3672SubtreeSpecificationSyntax.java b/opends/src/server/org/opends/server/schema/RFC3672SubtreeSpecificationSyntax.java
index 73d5480..227f3b7 100644
--- a/opends/src/server/org/opends/server/schema/RFC3672SubtreeSpecificationSyntax.java
+++ b/opends/src/server/org/opends/server/schema/RFC3672SubtreeSpecificationSyntax.java
@@ -277,7 +277,7 @@
// Use the subtree specification code to make this determination.
try {
- RFC3672SubtreeSpecification.valueOf(new DN(), value.stringValue());
+ RFC3672SubtreeSpecification.valueOf(DN.nullDN(), value.stringValue());
return true;
} catch (DirectoryException e) {
diff --git a/opends/src/server/org/opends/server/schema/RelativeSubtreeSpecificationSyntax.java b/opends/src/server/org/opends/server/schema/RelativeSubtreeSpecificationSyntax.java
index b92910a..57e0aa6 100644
--- a/opends/src/server/org/opends/server/schema/RelativeSubtreeSpecificationSyntax.java
+++ b/opends/src/server/org/opends/server/schema/RelativeSubtreeSpecificationSyntax.java
@@ -278,7 +278,7 @@
// Use the subtree specification code to make this determination.
try {
- RelativeSubtreeSpecification.valueOf(new DN(), value.stringValue());
+ RelativeSubtreeSpecification.valueOf(DN.nullDN(), value.stringValue());
return true;
} catch (DirectoryException e) {
diff --git a/opends/src/server/org/opends/server/synchronization/MultimasterSynchronization.java b/opends/src/server/org/opends/server/synchronization/MultimasterSynchronization.java
index bd7f70e..d354f23 100644
--- a/opends/src/server/org/opends/server/synchronization/MultimasterSynchronization.java
+++ b/opends/src/server/org/opends/server/synchronization/MultimasterSynchronization.java
@@ -462,7 +462,7 @@
do
{
domain = domains.get(temp);
- temp = temp.getParent();
+ temp = temp.getParentDNInSuffix();
if (temp == null)
{
break;
diff --git a/opends/src/server/org/opends/server/synchronization/SynchronizationDomain.java b/opends/src/server/org/opends/server/synchronization/SynchronizationDomain.java
index 922bfe6..7b401b2 100644
--- a/opends/src/server/org/opends/server/synchronization/SynchronizationDomain.java
+++ b/opends/src/server/org/opends/server/synchronization/SynchronizationDomain.java
@@ -662,7 +662,7 @@
{
AddContext ctx = new AddContext(generateChangeNumber(addOperation),
Historical.getEntryUuid(addOperation),
- findEntryId(addOperation.getEntryDN().getParent()));
+ findEntryId(addOperation.getEntryDN().getParentDNInSuffix()));
addOperation.setAttachment(SYNCHROCONTEXT, ctx);
}
@@ -1491,13 +1491,7 @@
throw new Exception("operation parameters are invalid");
}
- RDN[] parentComponents = parentDN.getRDNComponents();
- RDN[] newComponents = new RDN[parentComponents.length+1];
- System.arraycopy(parentComponents, 0, newComponents, 1,
- parentComponents.length);
- newComponents[0] = newRDN;
-
- DN newDN = new DN(newComponents);
+ DN newDN = parentDN.concat(newRDN);
// get the current DN of this entry in the database.
DN currentDN = findEntryDN(entryUid);
diff --git a/opends/src/server/org/opends/server/tools/LDIFDiff.java b/opends/src/server/org/opends/server/tools/LDIFDiff.java
index c1e65ab..4739c33 100644
--- a/opends/src/server/org/opends/server/tools/LDIFDiff.java
+++ b/opends/src/server/org/opends/server/tools/LDIFDiff.java
@@ -42,7 +42,6 @@
import org.opends.server.types.AttributeType;
import org.opends.server.types.AttributeValue;
import org.opends.server.types.DN;
-import org.opends.server.types.DNComparator;
import org.opends.server.types.Entry;
import org.opends.server.types.ExistingFileBehavior;
import org.opends.server.types.LDIFImportConfig;
@@ -277,8 +276,7 @@
return 1;
}
- DNComparator comparator = new DNComparator();
- TreeMap<DN,Entry> sourceMap = new TreeMap<DN,Entry>(comparator);
+ TreeMap<DN,Entry> sourceMap = new TreeMap<DN,Entry>();
try
{
while (true)
@@ -324,7 +322,7 @@
return 1;
}
- TreeMap<DN,Entry> targetMap = new TreeMap<DN,Entry>(comparator);
+ TreeMap<DN,Entry> targetMap = new TreeMap<DN,Entry>();
try
{
while (true)
@@ -437,9 +435,9 @@
while (true)
{
- // Use the DN comparator to determine the relative order of the
+ // Compare the DNs to determine the relative order of the
// entries.
- int comparatorValue = comparator.compare(sourceDN, targetDN);
+ int comparatorValue = sourceDN.compareTo(targetDN);
if (comparatorValue < 0)
{
// The source entry should be before the target entry, which means
diff --git a/opends/src/server/org/opends/server/tools/LDIFModify.java b/opends/src/server/org/opends/server/tools/LDIFModify.java
index 425219d..8f51f98 100644
--- a/opends/src/server/org/opends/server/tools/LDIFModify.java
+++ b/opends/src/server/org/opends/server/tools/LDIFModify.java
@@ -45,7 +45,6 @@
import org.opends.server.types.Attribute;
import org.opends.server.types.AttributeType;
import org.opends.server.types.AttributeValue;
-import org.opends.server.types.DNComparator;
import org.opends.server.types.DirectoryException;
import org.opends.server.types.DN;
import org.opends.server.types.Entry;
@@ -126,11 +125,10 @@
throws IOException, LDIFException
{
// Read the changes into memory.
- DNComparator comparator = new DNComparator();
- TreeMap<DN,AddChangeRecordEntry> adds =
- new TreeMap<DN,AddChangeRecordEntry>(comparator);
- TreeMap<DN,Entry> ldifEntries =
- new TreeMap<DN,Entry>(comparator);
+ TreeMap<DN,AddChangeRecordEntry> adds =
+ new TreeMap<DN,AddChangeRecordEntry>();
+ TreeMap<DN,Entry> ldifEntries =
+ new TreeMap<DN,Entry>();
HashMap<DN,DeleteChangeRecordEntry> deletes =
new HashMap<DN,DeleteChangeRecordEntry>();
HashMap<DN,LinkedList<Modification>> modifications =
diff --git a/opends/src/server/org/opends/server/tools/LDIFSearch.java b/opends/src/server/org/opends/server/tools/LDIFSearch.java
index ae48bb6..ff60b5e 100644
--- a/opends/src/server/org/opends/server/tools/LDIFSearch.java
+++ b/opends/src/server/org/opends/server/tools/LDIFSearch.java
@@ -521,7 +521,7 @@
}
else
{
- baseDNs.add(new DN());
+ baseDNs.add(DN.nullDN());
}
diff --git a/opends/src/server/org/opends/server/tools/makeldif/DNTag.java b/opends/src/server/org/opends/server/tools/makeldif/DNTag.java
index be051e7..235f44b 100644
--- a/opends/src/server/org/opends/server/tools/makeldif/DNTag.java
+++ b/opends/src/server/org/opends/server/tools/makeldif/DNTag.java
@@ -32,7 +32,6 @@
import org.opends.server.types.DN;
import org.opends.server.types.InitializationException;
-import org.opends.server.types.RDN;
import static org.opends.server.messages.MessageHandler.*;
import static org.opends.server.messages.ToolMessages.*;
@@ -205,26 +204,25 @@
}
else if (numComponents > 0)
{
- RDN[] rdnComps = dn.getRDNComponents();
- int count = Math.min(numComponents, rdnComps.length);
+ int count = Math.min(numComponents, dn.getNumComponents());
- rdnComps[0].toString(templateValue.getValue());
- for (int i=1; i < count; i++)
+ dn.getRDN(0).toString(templateValue.getValue());
+ for (int i = 1; i < count; i++)
{
templateValue.append(",");
- rdnComps[i].toString(templateValue.getValue());
+ dn.getRDN(i).toString(templateValue.getValue());
}
}
else
{
- RDN[] rdnComps = dn.getRDNComponents();
- int count = Math.min(Math.abs(numComponents), rdnComps.length);
+ int sz = dn.getNumComponents();
+ int count = Math.min(Math.abs(numComponents), sz);
- rdnComps[rdnComps.length-count].toString(templateValue.getValue());
- for (int i=1; i < count; i++)
+ dn.getRDN(sz - count).toString(templateValue.getValue());
+ for (int i = 1; i < count; i++)
{
templateValue.append(",");
- rdnComps[rdnComps.length-count+i].toString(templateValue.getValue());
+ dn.getRDN(sz - count + i).toString(templateValue.getValue());
}
}
diff --git a/opends/src/server/org/opends/server/tools/makeldif/TemplateEntry.java b/opends/src/server/org/opends/server/tools/makeldif/TemplateEntry.java
index 339f942..fa4c9be 100644
--- a/opends/src/server/org/opends/server/tools/makeldif/TemplateEntry.java
+++ b/opends/src/server/org/opends/server/tools/makeldif/TemplateEntry.java
@@ -155,33 +155,22 @@
*/
public DN getDN()
{
- if (dn == null)
- {
- AttributeType[] rdnAttributes = template.getRDNAttributes();
- String[] rdnNames = new String[rdnAttributes.length];
- AttributeValue[] rdnValues = new AttributeValue[rdnAttributes.length];
+ if (dn == null) {
+ RDN.Builder builder = RDN.createBuilder();
- for (int i=0; i < rdnAttributes.length; i++)
- {
- TemplateValue v = getValue(rdnAttributes[i]);
- if (v == null)
- {
+ for (AttributeType type : template.getRDNAttributes()) {
+ TemplateValue v = getValue(type);
+ if (v == null) {
return null;
}
- rdnNames[i] = rdnAttributes[i].getNameOrOID();
- rdnValues[i] = new AttributeValue(rdnAttributes[i],
- v.getValue().toString());
+ AttributeValue value = new AttributeValue(type,
+ v.getValue().toString());
+
+ builder.append(type, value);
}
- RDN[] parentComponents = parentDN.getRDNComponents();
- RDN[] dnComponents = new RDN[parentComponents.length+1];
-
- dnComponents[0] = new RDN(rdnAttributes, rdnNames, rdnValues);
- System.arraycopy(parentComponents, 0, dnComponents, 1,
- parentComponents.length);
-
- dn = new DN(dnComponents);
+ dn = parentDN.concat(builder.getInstance());
}
return dn;
diff --git a/opends/src/server/org/opends/server/tools/makeldif/UnderscoreDNTag.java b/opends/src/server/org/opends/server/tools/makeldif/UnderscoreDNTag.java
index 631c379..3702b24 100644
--- a/opends/src/server/org/opends/server/tools/makeldif/UnderscoreDNTag.java
+++ b/opends/src/server/org/opends/server/tools/makeldif/UnderscoreDNTag.java
@@ -32,7 +32,6 @@
import org.opends.server.types.DN;
import org.opends.server.types.InitializationException;
-import org.opends.server.types.RDN;
import static org.opends.server.messages.MessageHandler.*;
import static org.opends.server.messages.ToolMessages.*;
@@ -201,37 +200,33 @@
if (numComponents == 0)
{
- RDN[] rdnComps = dn.getRDNComponents();
-
- rdnComps[0].toString(templateValue.getValue());
- for (int i=1; i < rdnComps.length; i++)
+ dn.getRDN(0).toString(templateValue.getValue());
+ for (int i=1; i < dn.getNumComponents(); i++)
{
templateValue.append("_");
- rdnComps[i].toString(templateValue.getValue());
+ dn.getRDN(i).toString(templateValue.getValue());
}
}
else if (numComponents > 0)
{
- RDN[] rdnComps = dn.getRDNComponents();
- int count = Math.min(numComponents, rdnComps.length);
+ int count = Math.min(numComponents, dn.getNumComponents());
- rdnComps[0].toString(templateValue.getValue());
- for (int i=1; i < count; i++)
+ dn.getRDN(0).toString(templateValue.getValue());
+ for (int i = 1; i < count; i++)
{
templateValue.append("_");
- rdnComps[i].toString(templateValue.getValue());
+ dn.getRDN(i).toString(templateValue.getValue());
}
}
else
{
- RDN[] rdnComps = dn.getRDNComponents();
- int count = Math.min(Math.abs(numComponents), rdnComps.length);
+ int sz = dn.getNumComponents();
+ int count = Math.min(Math.abs(numComponents), sz);
- rdnComps[rdnComps.length-count].toString(templateValue.getValue());
- for (int i=1; i < count; i++)
- {
+ dn.getRDN(sz - count).toString(templateValue.getValue());
+ for (int i = 1; i < count; i++) {
templateValue.append("_");
- rdnComps[rdnComps.length-count+i].toString(templateValue.getValue());
+ dn.getRDN(sz - count + i).toString(templateValue.getValue());
}
}
diff --git a/opends/src/server/org/opends/server/tools/makeldif/UnderscoreParentDNTag.java b/opends/src/server/org/opends/server/tools/makeldif/UnderscoreParentDNTag.java
index 8ac2344..39b3a84 100644
--- a/opends/src/server/org/opends/server/tools/makeldif/UnderscoreParentDNTag.java
+++ b/opends/src/server/org/opends/server/tools/makeldif/UnderscoreParentDNTag.java
@@ -32,7 +32,6 @@
import org.opends.server.types.DN;
import org.opends.server.types.InitializationException;
-import org.opends.server.types.RDN;
import static org.opends.server.messages.MessageHandler.*;
import static org.opends.server.messages.ToolMessages.*;
@@ -132,12 +131,11 @@
return TagResult.SUCCESS_RESULT;
}
- RDN[] rdnComps = parentDN.getRDNComponents();
- rdnComps[0].toString(templateValue.getValue());
- for (int i=1; i < rdnComps.length; i++)
+ parentDN.getRDN(0).toString(templateValue.getValue());
+ for (int i=1; i < parentDN.getNumComponents(); i++)
{
templateValue.append("_");
- rdnComps[i].toString(templateValue.getValue());
+ parentDN.getRDN(i).toString(templateValue.getValue());
}
return TagResult.SUCCESS_RESULT;
diff --git a/opends/src/server/org/opends/server/types/AttributeValue.java b/opends/src/server/org/opends/server/types/AttributeValue.java
index a9d992e..7d454a7 100644
--- a/opends/src/server/org/opends/server/types/AttributeValue.java
+++ b/opends/src/server/org/opends/server/types/AttributeValue.java
@@ -32,7 +32,6 @@
import org.opends.server.protocols.asn1.ASN1OctetString;
import static org.opends.server.loggers.Debug.*;
-import static org.opends.server.util.StaticUtils.*;
@@ -173,22 +172,6 @@
/**
- * Retrieves a string representation of the user-defined form of
- * this attribute value in a form suitable for use in a DN.
- *
- * @return A string representation of the user-defined form of this
- * attribute value in a form suitable for use in a DN.
- */
- public String getDNStringValue()
- {
- assert debugEnter(CLASS_NAME, "getDNStringValue");
-
- return getDNValue(getStringValue());
- }
-
-
-
- /**
* Retrieves the normalized form of this attribute value.
*
* @return The normalized form of this attribute value.
@@ -263,105 +246,6 @@
/**
- * Retrieves a string representation of the normalized form of this
- * attribute value in a form suitable for use in a DN.
- *
- * @return A string representation of the normalized form of this
- * attribute value in a form suitable for use in a DN.
- *
- * @throws DirectoryException If an error occurs while trying to
- * normalize the value (e.g., if it is
- * not acceptable for use with the
- * associated equality matching rule).
- */
- public String getNormalizedDNStringValue()
- throws DirectoryException
- {
- assert debugEnter(CLASS_NAME, "getNormalizedDNStringValue");
-
- return getDNValue(getNormalizedStringValue());
- }
-
-
-
- /**
- * Retrieves a version of the provided value in a form that is
- * properly escaped for use in a DN or RDN.
- *
- * @param value The value to be represented in a DN-safe form.
- *
- * @return A version of the provided value in a form that is
- * properly escaped for use in a DN or RDN.
- */
- private static String getDNValue(String value)
- {
- assert debugEnter(CLASS_NAME, "getDNValue",
- String.valueOf(value));
-
- if ((value == null) || (value.length() == 0))
- {
- return "";
- }
-
- StringBuilder buffer = new StringBuilder(value);
-
- int length = buffer.length();
- for (int i=0; i < length; i++)
- {
- char c = buffer.charAt(i);
-
- if ((c < ' ') || (c > '~'))
- {
- buffer.deleteCharAt(i);
- length -= 1;
-
- for (byte b : getBytes(String.valueOf(c)))
- {
- buffer.insert(i++, "\\");
- buffer.insert(i++, byteToLowerHex(b));
- i++;
-
- length += 3;
- }
-
- i -= 1;
- }
- else
- {
- switch (buffer.charAt(i))
- {
- case ',':
- case '+':
- case '"':
- case '\\':
- case '<':
- case '>':
- case ';':
- buffer.insert(i++, '\\');
- length++;
- }
- }
- }
-
- char c = buffer.charAt(0);
- if ((c == ' ') || (c == '#'))
- {
- buffer.insert(0, '\\');
- length++;
- }
-
- if (buffer.charAt(length-1) == ' ')
- {
- buffer.insert(length-1, '\\');
- length++;
- }
-
- return buffer.toString();
- }
-
-
-
- /**
* Determines whether this attribute value is equal to the provided
* object.
*
diff --git a/opends/src/server/org/opends/server/types/AttributeValueComparator.java b/opends/src/server/org/opends/server/types/AttributeValueComparator.java
deleted file mode 100644
index 0d4f4c0..0000000
--- a/opends/src/server/org/opends/server/types/AttributeValueComparator.java
+++ /dev/null
@@ -1,181 +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
- *
- *
- * Portions Copyright 2006 Sun Microsystems, Inc.
- */
-package org.opends.server.types;
-
-
-
-import java.util.Comparator;
-
-import org.opends.server.api.OrderingMatchingRule;
-
-import static org.opends.server.loggers.Debug.*;
-
-
-
-/**
- * This class defines a <CODE>Comparator</CODE> object that may be
- * used to compare attribute values, particularly for inclusion in a
- * sorted list. The values must share the same attribute type, and if
- * possible the ordering matching rule for that attribute type will be
- * used to make the determination. If there is no ordering matching
- * rule, then a bytewise comparison of the normalized values (from
- * left to right) will be used.
- */
-public class AttributeValueComparator
- implements Comparator<AttributeValue>
-{
- /**
- * The fully-qualified name of this class for debugging purposes.
- */
- private static final String CLASS_NAME =
- "org.opends.server.types.AttributeValueComparator";
-
-
-
- // The attribute type with which this comparator is associated.
- private AttributeType attributeType;
-
- // The ordering matching rule for the attribute type, if any.
- private OrderingMatchingRule matchingRule;
-
-
-
- /**
- * Creates a new instance of this attribute value comparator that
- * may be used with values of the provided attribute type.
- *
- * @param attributeType The attribute type that should be used for
- * this attribute value comparator.
- */
- public AttributeValueComparator(AttributeType attributeType)
- {
- assert debugConstructor(CLASS_NAME,
- String.valueOf(attributeType));
-
- this.attributeType = attributeType;
- this.matchingRule = attributeType.getOrderingMatchingRule();
- }
-
-
-
- /**
- * Compares the provided attribute values and returns an integer
- * value that reflects the relative order between them.
- *
- * @param value1 The first attribute value to compare.
- * @param value2 The second attribute value to compare.
- *
- * @return A negative value if the first value should come before
- * the second in an ordered list, a positive value if they
- * first value should come after the second in an ordered
- * list, or zero if there is no difference between their
- * order (i.e., the values are equal).
- */
- public int compare(AttributeValue value1, AttributeValue value2)
- {
- assert debugEnter(CLASS_NAME, "compare", String.valueOf(value1),
- String.valueOf(value2));
-
- try
- {
- if (matchingRule == null)
- {
- return compareValues(value1.getNormalizedValue(),
- value2.getNormalizedValue());
- }
- else
- {
- return matchingRule.compare(value1.getNormalizedValueBytes(),
- value2.getNormalizedValueBytes());
- }
- }
- catch (Exception e)
- {
- assert debugException(CLASS_NAME, "compare", e);
-
- // Just get the raw values and do a comparison between them.
- return compareValues(value1.getValue(), value2.getValue());
- }
- }
-
-
-
- /**
- * Compares the provided values using a simple bytewise comparison
- * and returns an integer value that reflects the relative order
- * between them.
- *
- * @param value1 The first byte string to compare.
- * @param value2 The second byte string to compare.
- *
- * @return A negative value if the first byte string should come
- * before the second in an ordered list, a positive value
- * if the first byte string should come after the second in
- * an ordered list, or zero if there is no difference
- * between them (i.e., the values are equal).
- */
- public static int compareValues(ByteString value1,
- ByteString value2)
- {
- assert debugEnter(CLASS_NAME, "compareValues",
- String.valueOf(value1), String.valueOf(value2));
-
- byte[] value1Bytes = value1.value();
- byte[] value2Bytes = value2.value();
-
- int index = 0;
- while (true)
- {
- if (index < value1Bytes.length)
- {
- if (index < value2Bytes.length)
- {
- int value = value1Bytes[index] - value2Bytes[index];
- if (value != 0)
- {
- return value;
- }
- }
- else
- {
- return 1;
- }
- }
- else if (index < value2Bytes.length)
- {
- return -1;
- }
- else
- {
- return 0;
- }
-
- index++;
- }
- }
-}
-
diff --git a/opends/src/server/org/opends/server/types/DN.java b/opends/src/server/org/opends/server/types/DN.java
index 857c8f2..45de88c 100644
--- a/opends/src/server/org/opends/server/types/DN.java
+++ b/opends/src/server/org/opends/server/types/DN.java
@@ -28,17 +28,14 @@
+import static org.opends.server.loggers.Debug.*;
+import static org.opends.server.util.Validator.ensureNotNull;
+
import java.io.Serializable;
import java.util.ArrayList;
+import java.util.List;
import org.opends.server.core.DirectoryServer;
-import org.opends.server.protocols.asn1.ASN1OctetString;
-
-import static org.opends.server.config.ConfigConstants.*;
-import static org.opends.server.loggers.Debug.*;
-import static org.opends.server.messages.MessageHandler.*;
-import static org.opends.server.messages.SchemaMessages.*;
-import static org.opends.server.util.StaticUtils.*;
@@ -46,51 +43,196 @@
* This class defines a data structure for storing and interacting
* with the distinguished names associated with entries in the
* Directory Server.
+ * <p>
+ * All the methods in this class will throw a
+ * <code>NullPointerException</code> when provided with
+ * <code>null</code> reference parameters unless otherwise stated.
*/
-public class DN
- implements Comparable<DN>, Serializable
-{
+public final class DN implements Comparable<DN>, Serializable {
+ // FIXME: Don't store the normalized form and define equals(),
+ // hashCode(), and compareTo() in terms of RDN components (which
+ // cache their normalized form). This could potentially lead to less
+ // memory utilization for very little performance loss.
+
+ // FIXME: Optimize normalization for common use-cases. E.g.
+ // concat(DN) can simply join the two normalized forms together.
+ // Similarly, getParent() and getLocalName() can avoid
+ // recalculating the normalized form and take a substring from the
+ // source DN's normalized form (this requires parsing commas, but
+ // could save memory).
+
/**
* The fully-qualified name of this class for debugging purposes.
*/
private static final String CLASS_NAME =
- "org.opends.server.types.DN";
-
-
+ "org.opends.server.types.DN";
/**
* The serial version identifier required to satisfy the compiler
* because this class implements the
- * <CODE>java.io.Serializable</CODE> interface. This value was
- * generated using the <CODE>serialver</CODE> command-line utility
+ * <code>java.io.Serializable</code> interface. This value was
+ * generated using the <code>serialver</code> command-line utility
* included with the Java SDK.
*/
private static final long serialVersionUID = 1184263456768819888L;
-
-
// The number of RDN components that comprise this DN.
- private int numComponents;
+ private final int numComponents;
+
+ // The index of the first RDN component (furthest from the root) in
+ // this DN.
+ private final int offset;
// The set of RDN components that comprise this DN, arranged with
// the suffix as the last element.
- private RDN[] rdnComponents;
+ private final RDN[] rdnComponents;
- // The string representation of this DN.
- private String dnString;
+ // The cached normalized string representation of this DN.
+ private final String normalizedDN;
- // The normalized string representation of this DN.
- private String normalizedDN;
+ // A DN comprising of zero RDN components.
+ private static final DN EMPTY_DN = new DN(new RDN[0], 0, 0);
/**
- * Creates a new DN with no RDN components (i.e., a null DN or root
- * DSE).
+ * Creates a new DN comprising of zero RDN components (a null DN or
+ * root DSE).
+ *
+ * @return Returns a new DN comprising of zero RDN components.
*/
- public DN()
- {
- this(new RDN[0]);
+ public static DN nullDN() {
+ return EMPTY_DN;
+ }
+
+
+
+ /**
+ * Creates a new <code>DN</code> containing the specified RDN
+ * sequence.
+ * <p>
+ * If the argument RDN sequence is empty, then the effect is the
+ * same as if {@link #nullDN()} had been called.
+ *
+ * @param rdns
+ * The RDN sequence that the new DN will represent.
+ * @return Returns a DN that represents the specified RDN sequence
+ * onto the end of this DN.
+ */
+ public static DN create(RDN... rdns) {
+ ensureNotNull(rdns);
+
+ if (rdns.length == 0) {
+ return nullDN();
+ }
+
+ RDN[] allRDNs = new RDN[rdns.length];
+ System.arraycopy(rdns, 0, allRDNs, 0, rdns.length);
+ return new DN(allRDNs, 0, rdns.length);
+ }
+
+
+
+ /**
+ * Returns a <code>DN</code> object holding the value of the
+ * specified <code>String</code>. The argument is interpreted as
+ * representing the LDAP string representation of a DN.
+ * <p>
+ * This method is identical to {@link #decode(String)}.
+ *
+ * @param s
+ * The string to be parsed, or <code>null</code> in
+ * which case a <code>nullDN</code> will be returned.
+ * @return Returns a <code>DN</code> holding the value represented
+ * by the <code>string</code> argument.
+ * @throws DirectoryException
+ * If a problem occurs while trying to decode the provided
+ * string as a DN.
+ */
+ public static DN valueOf(String s) throws DirectoryException {
+ return decode(s);
+ }
+
+
+
+ /**
+ * Decodes the provided ASN.1 octet string as a DN.
+ *
+ * @param dnString
+ * The ASN.1 octet string to decode as a DN, or
+ * <code>null</code> in which case a <code>nullDN</code>
+ * will be returned.
+ * @return The decoded DN.
+ * @throws DirectoryException
+ * If a problem occurs while trying to decode the provided
+ * ASN.1 octet string as a DN.
+ */
+ public static DN decode(ByteString dnString)
+ throws DirectoryException {
+ assert debugEnter(CLASS_NAME, "decode", String.valueOf(dnString));
+
+ // A null or empty DN is acceptable.
+ if (dnString == null) {
+ return nullDN();
+ }
+
+ byte[] dnBytes = dnString.value();
+ int length = dnBytes.length;
+ if (length == 0) {
+ return nullDN();
+ }
+
+ // Use string-based decoder.
+ return decode(dnString.stringValue());
+ }
+
+
+
+ /**
+ * Decodes the provided string as a DN.
+ *
+ * @param dnString
+ * The string to decode as a DN, or <code>null</code> in
+ * which case a <code>nullDN</code> will be returned.
+ * @return The decoded DN.
+ * @throws DirectoryException
+ * If a problem occurs while trying to decode the provided
+ * string as a DN.
+ */
+ public static DN decode(String dnString) throws DirectoryException {
+ assert debugEnter(CLASS_NAME, "decode", String.valueOf(dnString));
+
+ // A null or empty DN is acceptable.
+ if (dnString == null || dnString.length() == 0) {
+ return nullDN();
+ }
+
+ // Parse the first RDN.
+ int pos = 0;
+ RDN.Builder builder = RDN.createBuilder();
+ pos = builder.parse(dnString, pos, true);
+
+ if (builder.isEmpty()) {
+ return nullDN();
+ } else {
+ // Parse the remaining RDNs.
+ List<RDN> rdns = new ArrayList<RDN>(10);
+ rdns.add(builder.getInstance());
+
+ while (pos >= 0) {
+ // Skip the RDN separator.
+ pos++;
+
+ // Parse the next RDN.
+ builder.clear();
+ pos = builder.parse(dnString, pos, false);
+ rdns.add(builder.getInstance());
+ }
+
+ // Parse successful - create the DN.
+ int sz = rdns.size();
+ return new DN(rdns.toArray(new RDN[sz]), 0, sz);
+ }
}
@@ -99,203 +241,255 @@
* Creates a new DN with the provided set of RDNs, arranged with the
* suffix as the last element.
*
- * @param rdnComponents The set of RDN components that make up
- * this DN.
+ * @param rdnComponents
+ * The set of RDN components that make up this DN.
+ * @param offset
+ * The index of the first RDN component (furthest from the
+ * root) in this DN.
+ * @param count
+ * The number of RDNs to include in this DN.
*/
- public DN(RDN[] rdnComponents)
- {
+ private DN(RDN[] rdnComponents, int offset, int count) {
assert debugConstructor(CLASS_NAME,
- String.valueOf(rdnComponents));
+ String.valueOf(rdnComponents), String.valueOf(offset));
- if (rdnComponents == null)
- {
- this.rdnComponents = new RDN[0];
- }
- else
- {
- this.rdnComponents = rdnComponents;
- }
-
- numComponents = this.rdnComponents.length;
- dnString = null;
- normalizedDN = toNormalizedString();
+ this.rdnComponents = rdnComponents;
+ this.offset = offset;
+ this.numComponents = count;
+ this.normalizedDN = normalize();
}
/**
- * Creates a new DN with the provided set of RDNs, arranged with the
- * suffix as the last element.
+ * Concatenates the specified DN to the end of this DN.
+ * <p>
+ * If the argument DN is the null DN, then this DN is returned.
+ * Conversely, if this DN is the null DN then the argument DN will
+ * be returned. Otherwise, the returned DN will be a descendent of
+ * this DN.
*
- * @param rdnComponents The set of RDN components that make up
- * this DN.
+ * @param localName
+ * The DN that will be concatenated to the end of this DN.
+ * @return Returns a DN that represents the concatenation of the
+ * specified DN onto the end of this DN.
*/
- public DN(ArrayList<RDN> rdnComponents)
- {
- assert debugConstructor(CLASS_NAME,
- String.valueOf(rdnComponents));
+ public DN concat(DN localName) {
+ ensureNotNull(localName);
- if ((rdnComponents == null) || rdnComponents.isEmpty())
- {
- this.rdnComponents = new RDN[0];
- }
- else
- {
- this.rdnComponents = new RDN[rdnComponents.size()];
- rdnComponents.toArray(this.rdnComponents);
+ if (localName.isNullDN()) {
+ return this;
}
- numComponents = this.rdnComponents.length;
- dnString = null;
- normalizedDN = toNormalizedString();
+ if (isNullDN()) {
+ return localName;
+ }
+
+ RDN[] allRDNs = new RDN[numComponents + localName.numComponents];
+ System.arraycopy(localName.rdnComponents, localName.offset,
+ allRDNs, 0, localName.numComponents);
+ System.arraycopy(rdnComponents, offset, allRDNs,
+ localName.numComponents, numComponents);
+
+ return new DN(allRDNs, 0, allRDNs.length);
}
/**
- * Constructs a new DN which is the concatenation of a base DN and a
- * relative DN. The constructed DN has the following property:
+ * Concatenates the specified RDN sequence to the end of this DN.
+ * <p>
+ * If the argument RDN sequence is empty, then this DN is returned.
+ * Otherwise, the returned DN will be a descendent of this DN.
+ *
+ * @param rdns
+ * The RDN sequence that will be concatenated to the end of
+ * this DN.
+ * @return Returns a DN that represents the concatenation of the
+ * specified RDN sequence onto the end of this DN.
+ */
+ public DN concat(RDN... rdns) {
+ ensureNotNull(rdns);
+
+ if (rdns.length == 0) {
+ return this;
+ }
+
+ // Don't check if this is a nullDN, because were going to copy the
+ // RDN sequence anyway.
+
+ RDN[] allRDNs = new RDN[rdns.length + numComponents];
+
+ System.arraycopy(rdns, 0, allRDNs, 0, rdns.length);
+ System.arraycopy(rdnComponents, offset, allRDNs,
+ rdns.length, numComponents);
+
+ return new DN(allRDNs, 0, allRDNs.length);
+ }
+
+
+
+ /**
+ * Get the parent DN of this DN.
+ *
+ * @return Returns the parent DN of this DN, or <code>null</code>
+ * if this DN does not have a parent (i.e. it is a DN having
+ * a single RDN component, or the null DN).
+ */
+ public DN getParent() {
+ if (numComponents <= 1) {
+ return null;
+ } else {
+ return new DN(rdnComponents, offset + 1, numComponents - 1);
+ }
+ }
+
+
+
+ /**
+ * Create a local name (a relative DN) from this DN.
+ * <p>
+ * Examples: <blockquote>
*
* <pre>
- * DN suffix;
- * DN localName;
+ * DN dn = DN.decode("cn=john,o=example,c=us");
*
- * suffix.isAncestorOf(new DN(suffix, localName)) == true;
+ * dn.getLocalName(0) returns "cn=john,o=example,c=us"
+ * dn.getLocalName(1) returns "cn=john,o=example"
+ * dn.getLocalName(3) returns "" (null DN).
* </pre>
*
- * @param baseDN
- * The base DN.
- * @param localName
- * The relative DN.
+ * </blockquote>
+ *
+ * @param beginIndex
+ * The index of the first RDN component (nearest the root),
+ * inclusive.
+ * @return Returns the specified local name.
+ * @throws IndexOutOfBoundsException
+ * If <code>beginIndex</code> is negative, or greater
+ * than the number of RDN components in this DN.
*/
- public DN(DN baseDN, DN localName)
- {
- this(baseDN, localName.rdnComponents);
+ public DN getLocalName(int beginIndex)
+ throws IndexOutOfBoundsException {
+ return getLocalName(beginIndex, numComponents);
}
/**
- * Constructs a new DN which is the concatenation of a base DN and
- * an RDN sequence.
+ * Create a local name (a relative DN) from this DN.
+ * <p>
+ * Examples: <blockquote>
*
- * @param baseDN The base DN.
- * @param rdnSequence The RDN sequence which will become the
- * outermost RDNs of the concatenated DN.
+ * <pre>
+ * DN dn = DN.decode("cn=john,o=example,c=us");
+ *
+ * dn.getLocalName(0, 3) returns "cn=john,o=example,c=us"
+ * dn.getLocalName(1, 2) returns "o=example"
+ * dn.getLocalName(2, 2) returns "" (null DN).
+ * </pre>
+ *
+ * </blockquote>
+ *
+ * @param beginIndex
+ * The index of the first RDN component (nearest the root),
+ * inclusive.
+ * @param endIndex
+ * The index of the last RDN component (furthest from the
+ * root), exclusive.
+ * @return Returns the specified local name.
+ * @throws IndexOutOfBoundsException
+ * If <code>beginIndex</code> is negative, or
+ * <code>endIndex</code> is larger than the number of
+ * RDN components in this DN, or <code>beginIndex</code>
+ * is larger than <code>endIndex</code>.
*/
- public DN(DN baseDN, RDN[] rdnSequence)
- {
- assert debugConstructor(CLASS_NAME, String.valueOf(baseDN),
- String.valueOf(rdnSequence));
+ public DN getLocalName(int beginIndex, int endIndex)
+ throws IndexOutOfBoundsException {
+ if (beginIndex < 0) {
+ throw new IndexOutOfBoundsException("beginIndex out of range: "
+ + beginIndex);
+ }
- RDN[] allRDNs = new RDN[rdnSequence.length+baseDN.numComponents];
+ if (endIndex > numComponents) {
+ throw new IndexOutOfBoundsException("endIndex out of range: "
+ + endIndex);
+ }
- System.arraycopy(rdnSequence, 0, allRDNs, 0, rdnSequence.length);
- System.arraycopy(baseDN.rdnComponents, 0, allRDNs,
- rdnSequence.length, baseDN.numComponents);
+ if (beginIndex > endIndex) {
+ throw new IndexOutOfBoundsException(
+ "beginIndex greater than endIndex");
+ }
- this.rdnComponents = allRDNs;
- this.numComponents = allRDNs.length;
- this.dnString = null;
- this.normalizedDN = toNormalizedString();
+ if (beginIndex == 0 && endIndex == numComponents) {
+ return this;
+ } else {
+ int i = offset + numComponents - endIndex;
+ return new DN(rdnComponents, i, endIndex - beginIndex);
+ }
}
/**
- * Retrieves the set of RDN components that make up this DN,
- * arranged with the suffix as the last element. The caller must not
- * modify the contents of the returned list.
+ * Get the number of RDN components that make up this DN.
*
- * @return The set of RDN components that make up this DN.
+ * @return Returns the number of RDN components that make up this
+ * DN.
*/
- public RDN[] getRDNComponents()
- {
- assert debugEnter(CLASS_NAME, "getRDNComponents");
+ public int getNumComponents() {
+ assert debugEnter(CLASS_NAME, "getNumComponents");
- return rdnComponents;
- }
-
-
-
- /**
- * Specifies the set of RDN components that make up this DN.
- *
- * @param rdnComponents The set of RDN components that make up
- * this DN arranged with the suffix as the
- * last element.
- */
- public void setRDNComponents(RDN[] rdnComponents)
- {
- assert debugEnter(CLASS_NAME, "setRDNComponents",
- String.valueOf(rdnComponents));
-
- if (rdnComponents == null)
- {
- this.rdnComponents = new RDN[0];
- }
- else
- {
- this.rdnComponents = rdnComponents;
- }
-
- numComponents = this.rdnComponents.length;
- dnString = null;
- normalizedDN = null; // Get rid of the old cached value.
- normalizedDN = toNormalizedString();
- }
-
-
-
- /**
- * Specifies the set of RDN components that make up this DN.
- *
- * @param rdnComponents The set of RDN components that make up
- * this DN, arranged with the suffix as the
- * last element.
- */
- public void setRDNComponents(ArrayList<RDN> rdnComponents)
- {
- assert debugEnter(CLASS_NAME, "setRDNComponents",
- String.valueOf(rdnComponents));
-
- if (rdnComponents == null)
- {
- this.rdnComponents = new RDN[0];
- }
- else
- {
- this.rdnComponents = new RDN[rdnComponents.size()];
- rdnComponents.toArray(this.rdnComponents);
- }
-
- numComponents = this.rdnComponents.length;
- dnString = null;
- normalizedDN = toNormalizedString();
+ return numComponents;
}
/**
* Retrieves the outermost RDN component for this DN (i.e., the one
- * that is furthest from the suffix).
+ * that is furthest from the suffix). This method is equivalent to
+ * calling <code>getRDN(0)</code> for non-null DNs.
*
- * @return The outermost RDN component for this DN, or
- * <CODE>null</CODE> if there are no RDN components in the
- * DN.
+ * @return The outermost RDN component for this DN, or
+ * <code>null</code> if there are no RDN components in the
+ * DN.
*/
- public RDN getRDN()
- {
+ public RDN getRDN() {
assert debugEnter(CLASS_NAME, "getRDN");
- if (numComponents == 0)
- {
+ if (numComponents == 0) {
return null;
+ } else {
+ return getRDN(0);
}
- else
- {
- return rdnComponents[0];
+ }
+
+
+
+ /**
+ * Get the RDN at the specified index.
+ *
+ * @param index
+ * The index of the RDN to retrieve, where <code>0</code>
+ * indicates the outermost RDN component (i.e. the one that
+ * is furthest from the suffix).
+ * @return Returns the RDN at the specified index.
+ * @throws IndexOutOfBoundsException
+ * If <code>index</code> is negative, or greater than or
+ * equal to the number of RDN components in this DN.
+ */
+ public RDN getRDN(int index) throws IndexOutOfBoundsException {
+ if (index < 0) {
+ throw new IndexOutOfBoundsException("index out of range: "
+ + index);
}
+
+ if (index >= numComponents) {
+ throw new IndexOutOfBoundsException("index out of range: "
+ + index);
+ }
+
+ return rdnComponents[offset + index];
}
@@ -304,39 +498,33 @@
* Retrieves the DN of the entry that is the immediate parent for
* this entry.
*
- * @return The DN of the entry that is the immediate parent for
- * this entry, or <CODE>null</CODE> if the entry with this
- * DN does not have a parent (either because there is only
- * a single RDN component or because this DN is a suffix
- * defined in the server).
+ * @return The DN of the entry that is the immediate parent for this
+ * entry, or <code>null</code> if the entry with this DN
+ * does not have a parent (either because there is only a
+ * single RDN component or because this DN is a suffix
+ * defined in the server).
*/
- public DN getParent()
- {
- assert debugEnter(CLASS_NAME, "getParent");
+ public DN getParentDNInSuffix() {
+ assert debugEnter(CLASS_NAME, "getParentDNInSuffix");
- if ((numComponents <= 1) || (DirectoryServer.isSuffix(this)))
- {
+ if ((numComponents <= 1) || (DirectoryServer.isSuffix(this))) {
return null;
}
- RDN[] parentComponents = new RDN[numComponents-1];
- System.arraycopy(rdnComponents, 1, parentComponents, 0,
- numComponents-1);
- return new DN(parentComponents);
+ return getParent();
}
/**
- * Indicates whether this represents a null DN. This could target
+ * Indicates whether this represents a null DN. This could target
* the root DSE for the Directory Server, or the authorization DN
* for an anonymous or unauthenticated client.
*
- * @return <CODE>true</CODE> if this does represent a null DN, or
- * <CODE>false</CODE> if it does not.
+ * @return <code>true</code> if this does represent a null DN, or
+ * <code>false</code> if it does not.
*/
- public boolean isNullDN()
- {
+ public boolean isNullDN() {
assert debugEnter(CLASS_NAME, "isNullDN");
return (numComponents == 0);
@@ -345,47 +533,28 @@
/**
- * Indicates whether this DN is one of the suffixes defined in the
- * Directory Server.
- *
- * @return <CODE>true</CODE> if this DN is one of the suffixes
- * defined in the Directory Server, or <CODE>false</CODE>
- * if not.
- */
- public boolean isSuffix()
- {
- assert debugEnter(CLASS_NAME, "isSuffix");
-
- return DirectoryServer.isSuffix(this);
- }
-
-
-
- /**
* Indicates whether this DN is a descendant of the provided DN
* (i.e., that the RDN components of the provided DN are the same as
* the last RDN components for this DN).
*
- * @param dn The DN for which to make the determination.
- *
- * @return <CODE>true</CODE> if this DN is a descendant of the
- * provided DN, or <CODE>false</CODE> if not.
+ * @param dn
+ * The DN for which to make the determination.
+ * @return <code>true</code> if this DN is a descendant of the
+ * provided DN, or <code>false</code> if not.
*/
- public boolean isDescendantOf(DN dn)
- {
- assert debugEnter(CLASS_NAME, "isDescendantOf",
- String.valueOf(dn));
+ public boolean isDescendantOf(DN dn) {
+ assert debugEnter(CLASS_NAME, "isDescendantOf", String
+ .valueOf(dn));
- int offset = numComponents - dn.numComponents;
- if (offset < 0)
- {
+ ensureNotNull(dn);
+
+ int diff = numComponents - dn.numComponents;
+ if (diff < 0) {
return false;
}
- for (int i=0; i < dn.numComponents; i++)
- {
- if (! rdnComponents[i+offset].equals(dn.rdnComponents[i]))
- {
+ for (int i = 0; i < dn.numComponents; i++) {
+ if (!getRDN(i + diff).equals(dn.getRDN(i))) {
return false;
}
}
@@ -400,25 +569,23 @@
* (i.e., that the RDN components of this DN are the same as the
* last RDN components for the provided DN).
*
- * @param dn The DN for which to make the determination.
- *
- * @return <CODE>true</CODE> if this DN is an ancestor of the
- * provided DN, or <CODE>false</CODE> if not.
+ * @param dn
+ * The DN for which to make the determination.
+ * @return <code>true</code> if this DN is an ancestor of the
+ * provided DN, or <code>false</code> if not.
*/
- public boolean isAncestorOf(DN dn)
- {
+ public boolean isAncestorOf(DN dn) {
assert debugEnter(CLASS_NAME, "isAncestorOf", String.valueOf(dn));
- int offset = dn.numComponents - numComponents;
- if (offset < 0)
- {
+ ensureNotNull(dn);
+
+ int diff = dn.numComponents - numComponents;
+ if (diff < 0) {
return false;
}
- for (int i=0; i < numComponents; i++)
- {
- if (! rdnComponents[i].equals(dn.rdnComponents[i+offset]))
- {
+ for (int i = 0; i < numComponents; i++) {
+ if (!getRDN(i).equals(dn.getRDN(i + diff))) {
return false;
}
}
@@ -429,2334 +596,26 @@
/**
- * Decodes the provided ASN.1 octet string as a DN.
- *
- * @param dnString The ASN.1 octet string to decode as a DN.
- *
- * @return The decoded DN.
- *
- * @throws DirectoryException If a problem occurs while trying to
- * decode the provided ASN.1 octet
- * string as a DN.
- */
- public static DN decode(ByteString dnString)
- throws DirectoryException
- {
- assert debugEnter(CLASS_NAME, "decode", String.valueOf(dnString));
-
-
- // A null or empty DN is acceptable.
- if (dnString == null)
- {
- return new DN(new ArrayList<RDN>(0));
- }
-
- byte[] dnBytes = dnString.value();
- int length = dnBytes.length;
- if (length == 0)
- {
- return new DN(new ArrayList<RDN>(0));
- }
-
-
- // See if we are dealing with any non-ASCII characters, or any
- // escaped characters. If so, then the easiest and safest
- // approach is to convert the DN to a string and decode it that
- // way.
- for (byte b : dnBytes)
- {
- if (((b & 0x7F) != b) || (b == '\\'))
- {
- return decode(dnString.stringValue());
- }
- }
-
-
- // Iterate through the DN string. The first thing to do is to get
- // rid of any leading spaces.
- int pos = 0;
- byte b = dnBytes[pos];
- while (b == ' ')
- {
- pos++;
- if (pos == length)
- {
- // This means that the DN was completely comprised of spaces
- // and therefore should be considered the same as a null or
- // empty DN.
- return new DN(new ArrayList<RDN>(0));
- }
- else
- {
- b = dnBytes[pos];
- }
- }
-
-
- // We know that it's not an empty DN, so we can do the real
- // processing. Create a loop and iterate through all the RDN
- // components.
- boolean allowExceptions =
- DirectoryServer.allowAttributeNameExceptions();
- ArrayList<RDN> rdnComponents = new ArrayList<RDN>();
- while (true)
- {
- StringBuilder attributeName = new StringBuilder();
- pos = parseAttributeName(dnBytes, pos, attributeName,
- allowExceptions);
-
-
- // Make sure that we're not at the end of the DN string because
- // that would be invalid.
- if (pos >= length)
- {
- int msgID = MSGID_ATTR_SYNTAX_DN_END_WITH_ATTR_NAME;
- String message = getMessage(msgID, dnString.stringValue(),
- attributeName.toString());
- throw new DirectoryException(ResultCode.INVALID_DN_SYNTAX,
- message, msgID);
- }
-
-
- // Skip over any spaces between the attribute name and its
- // value.
- b = dnBytes[pos];
- while (b == ' ')
- {
- pos++;
- if (pos >= length)
- {
- // This means that we hit the end of the value before
- // finding a '='. This is illegal because there is no
- // attribute-value separator.
- int msgID = MSGID_ATTR_SYNTAX_DN_END_WITH_ATTR_NAME;
- String message = getMessage(msgID, dnString.stringValue(),
- attributeName.toString());
- throw new DirectoryException(ResultCode.INVALID_DN_SYNTAX,
- message, msgID);
- }
- else
- {
- b = dnBytes[pos];
- }
- }
-
-
- // The next character must be an equal sign. If it is not,
- // then that's an error.
- if (b == '=')
- {
- pos++;
- }
- else
- {
- int msgID = MSGID_ATTR_SYNTAX_DN_NO_EQUAL;
- String message = getMessage(msgID, dnString.stringValue(),
- attributeName.toString(),
- (char) b);
- throw new DirectoryException(ResultCode.INVALID_DN_SYNTAX,
- message, msgID);
- }
-
-
- // Skip over any spaces after the equal sign.
- while ((pos < length) && ((b = dnBytes[pos]) == ' '))
- {
- pos++;
- }
-
-
- // If we are at the end of the DN string, then that must mean
- // that the attribute value was empty. This will probably never
- // happen in a real-world environment, but technically isn't
- // illegal. If it does happen, then go ahead and create the RDN
- // component and return the DN.
- if (pos >= length)
- {
- String name = attributeName.toString();
- String lowerName = toLowerCase(name);
- AttributeType attrType =
- DirectoryServer.getAttributeType(lowerName);
-
- if (attrType == null)
- {
- // This must be an attribute type that we don't know about.
- // In that case, we'll create a new attribute using the
- // default syntax. If this is a problem, it will be caught
- // later either by not finding the target entry or by not
- // allowing the entry to be added.
- attrType = DirectoryServer.getDefaultAttributeType(name);
- }
-
- AttributeValue value =
- new AttributeValue(new ASN1OctetString(),
- new ASN1OctetString());
- rdnComponents.add(new RDN(attrType, name, value));
- return new DN(rdnComponents);
- }
-
-
- // Parse the value for this RDN component.
- ByteString parsedValue = new ASN1OctetString();
- pos = parseAttributeValue(dnBytes, pos, parsedValue);
-
-
- // Create the new RDN with the provided information.
- String name = attributeName.toString();
- String lowerName = toLowerCase(name);
- AttributeType attrType =
- DirectoryServer.getAttributeType(lowerName);
- if (attrType == null)
- {
- // This must be an attribute type that we don't know about.
- // In that case, we'll create a new attribute using the
- // default syntax. If this is a problem, it will be caught
- // later either by not finding the target entry or by not
- // allowing the entry to be added.
- attrType = DirectoryServer.getDefaultAttributeType(name);
- }
-
- AttributeValue value =
- new AttributeValue(attrType, parsedValue);
- RDN rdn = new RDN(attrType, name, value);
-
-
- // Skip over any spaces that might be after the attribute value.
- while ((pos < length) && ((b = dnBytes[pos]) == ' '))
- {
- pos++;
- }
-
-
- // Most likely, we will be at either the end of the RDN
- // component or the end of the DN. If so, then handle that
- // appropriately.
- if (pos >= length)
- {
- // We're at the end of the DN string and should have a valid
- // DN so return it.
- rdnComponents.add(rdn);
- return new DN(rdnComponents);
- }
- else if ((b == ',') || (b == ';'))
- {
- // We're at the end of the RDN component, so add it to the
- // list, skip over the comma/semicolon, and start on the next
- // component.
- rdnComponents.add(rdn);
- pos++;
- continue;
- }
- else if (b != '+')
- {
- // This should not happen. At any rate, it's an illegal
- // character, so throw an exception.
- int msgID = MSGID_ATTR_SYNTAX_DN_INVALID_CHAR;
- String message = getMessage(msgID, new String(dnBytes),
- (char) b, pos);
- throw new DirectoryException(ResultCode.INVALID_DN_SYNTAX,
- message, msgID);
- }
-
-
- // If we have gotten here, then this must be a multi-valued RDN.
- // In that case, parse the remaining attribute/value pairs and
- // add them to the RDN that we've already created.
- while (true)
- {
- // Skip over the plus sign and any spaces that may follow it
- // before the next attribute name.
- pos++;
- while ((pos < length) && (dnBytes[pos] == ' '))
- {
- pos++;
- }
-
-
- // Parse the attribute name from the DN string.
- attributeName = new StringBuilder();
- pos = parseAttributeName(dnBytes, pos, attributeName,
- allowExceptions);
-
-
- // Make sure that we're not at the end of the DN string
- // because that would be invalid.
- if (pos >= length)
- {
- int msgID = MSGID_ATTR_SYNTAX_DN_END_WITH_ATTR_NAME;
- String message = getMessage(msgID, dnString.stringValue(),
- attributeName.toString());
- throw new DirectoryException(ResultCode.INVALID_DN_SYNTAX,
- message, msgID);
- }
-
-
- // Skip over any spaces between the attribute name and its
- // value.
- b = dnBytes[pos];
- while (b == ' ')
- {
- pos++;
- if (pos >= length)
- {
- // This means that we hit the end of the value before
- // finding a '='. This is illegal because there is no
- // attribute-value separator.
- int msgID = MSGID_ATTR_SYNTAX_DN_END_WITH_ATTR_NAME;
- String message = getMessage(msgID, dnString.stringValue(),
- attributeName.toString());
- throw new DirectoryException(ResultCode.INVALID_DN_SYNTAX,
- message, msgID);
- }
- else
- {
- b = dnBytes[pos];
- }
- }
-
-
- // The next character must be an equal sign. If it is not,
- // then that's an error.
- if (b == '=')
- {
- pos++;
- }
- else
- {
- int msgID = MSGID_ATTR_SYNTAX_DN_NO_EQUAL;
- String message = getMessage(msgID, dnString.stringValue(),
- attributeName.toString(),
- (char) b);
- throw new DirectoryException(ResultCode.INVALID_DN_SYNTAX,
- message, msgID);
- }
-
-
- // Skip over any spaces after the equal sign.
- while ((pos < length) && ((b = dnBytes[pos]) == ' '))
- {
- pos++;
- }
-
-
- // If we are at the end of the DN string, then that must mean
- // that the attribute value was empty. This will probably
- // never happen in a real-world environment, but technically
- // isn't illegal. If it does happen, then go ahead and create
- // the RDN component and return the DN.
- if (pos >= length)
- {
- name = attributeName.toString();
- lowerName = toLowerCase(name);
- attrType = DirectoryServer.getAttributeType(lowerName);
-
- if (attrType == null)
- {
- // This must be an attribute type that we don't know
- // about. In that case, we'll create a new attribute
- // using the default syntax. If this is a problem, it
- // will be caught later either by not finding the target
- // entry or by not allowing the entry to be added.
- attrType = DirectoryServer.getDefaultAttributeType(name);
- }
-
- value = new AttributeValue(new ASN1OctetString(),
- new ASN1OctetString());
- rdn.addValue(attrType, name, value);
- rdnComponents.add(rdn);
- return new DN(rdnComponents);
- }
-
-
- // Parse the value for this RDN component.
- parsedValue = new ASN1OctetString();
- pos = parseAttributeValue(dnBytes, pos, parsedValue);
-
-
- // Create the new RDN with the provided information.
- name = attributeName.toString();
- lowerName = toLowerCase(name);
- attrType = DirectoryServer.getAttributeType(lowerName);
- if (attrType == null)
- {
- // This must be an attribute type that we don't know about.
- // In that case, we'll create a new attribute using the
- // default syntax. If this is a problem, it will be caught
- // later either by not finding the target entry or by not
- // allowing the entry to be added.
- attrType = DirectoryServer.getDefaultAttributeType(name);
- }
-
- value = new AttributeValue(attrType, parsedValue);
- rdn.addValue(attrType, name, value);
-
-
- // Skip over any spaces that might be after the attribute
- // value.
- while ((pos < length) && ((b = dnBytes[pos]) == ' '))
- {
- pos++;
- }
-
-
- // Most likely, we will be at either the end of the RDN
- // component or the end of the DN. If so, then handle that
- // appropriately.
- if (pos >= length)
- {
- // We're at the end of the DN string and should have a valid
- // DN so return it.
- rdnComponents.add(rdn);
- return new DN(rdnComponents);
- }
- else if ((b == ',') || (b == ';'))
- {
- // We're at the end of the RDN component, so add it to the
- // list, skip over the comma/semicolon, and start on the
- // next component.
- rdnComponents.add(rdn);
- pos++;
- break;
- }
- else if (b != '+')
- {
- // This should not happen. At any rate, it's an illegal
- // character, so throw an exception.
- int msgID = MSGID_ATTR_SYNTAX_DN_INVALID_CHAR;
- String message = getMessage(msgID, dnString.stringValue(),
- (char) b, pos);
- throw new DirectoryException(ResultCode.INVALID_DN_SYNTAX,
- message, msgID);
- }
- }
- }
- }
-
-
-
- /**
- * Decodes the provided string as a DN.
- *
- * @param dnString The string to decode as a DN.
- *
- * @return The decoded DN.
- *
- * @throws DirectoryException If a problem occurs while trying to
- * decode the provided string as a DN.
- */
- public static DN decode(String dnString)
- throws DirectoryException
- {
- assert debugEnter(CLASS_NAME, "decode", String.valueOf(dnString));
-
-
- // A null or empty DN is acceptable.
- if (dnString == null)
- {
- return new DN(new ArrayList<RDN>(0));
- }
-
- int length = dnString.length();
- if (length == 0)
- {
- return new DN(new ArrayList<RDN>(0));
- }
-
-
- // Iterate through the DN string. The first thing to do is to get
- // rid of any leading spaces.
- int pos = 0;
- char c = dnString.charAt(pos);
- while (c == ' ')
- {
- pos++;
- if (pos == length)
- {
- // This means that the DN was completely comprised of spaces
- // and therefore should be considered the same as a null or
- // empty DN.
- return new DN(new ArrayList<RDN>(0));
- }
- else
- {
- c = dnString.charAt(pos);
- }
- }
-
-
- // We know that it's not an empty DN, so we can do the real
- // processing. Create a loop and iterate through all the RDN
- // components.
- boolean allowExceptions =
- DirectoryServer.allowAttributeNameExceptions();
- ArrayList<RDN> rdnComponents = new ArrayList<RDN>();
- while (true)
- {
- StringBuilder attributeName = new StringBuilder();
- pos = parseAttributeName(dnString, pos, attributeName,
- allowExceptions);
-
-
- // Make sure that we're not at the end of the DN string because
- // that would be invalid.
- if (pos >= length)
- {
- int msgID = MSGID_ATTR_SYNTAX_DN_END_WITH_ATTR_NAME;
- String message = getMessage(msgID, dnString,
- attributeName.toString());
- throw new DirectoryException(ResultCode.INVALID_DN_SYNTAX,
- message, msgID);
- }
-
-
- // Skip over any spaces between the attribute name and its
- // value.
- c = dnString.charAt(pos);
- while (c == ' ')
- {
- pos++;
- if (pos >= length)
- {
- // This means that we hit the end of the value before
- // finding a '='. This is illegal because there is no
- // attribute-value separator.
- int msgID = MSGID_ATTR_SYNTAX_DN_END_WITH_ATTR_NAME;
- String message = getMessage(msgID, dnString,
- attributeName.toString());
- throw new DirectoryException(ResultCode.INVALID_DN_SYNTAX,
- message, msgID);
- }
- else
- {
- c = dnString.charAt(pos);
- }
- }
-
-
- // The next character must be an equal sign. If it is not, then
- // that's an error.
- if (c == '=')
- {
- pos++;
- }
- else
- {
- int msgID = MSGID_ATTR_SYNTAX_DN_NO_EQUAL;
- String message = getMessage(msgID, dnString,
- attributeName.toString(), c);
- throw new DirectoryException(ResultCode.INVALID_DN_SYNTAX,
- message, msgID);
- }
-
-
- // Skip over any spaces after the equal sign.
- while ((pos < length) && ((c = dnString.charAt(pos)) == ' '))
- {
- pos++;
- }
-
-
- // If we are at the end of the DN string, then that must mean
- // that the attribute value was empty. This will probably never
- // happen in a real-world environment, but technically isn't
- // illegal. If it does happen, then go ahead and create the
- // RDN component and return the DN.
- if (pos >= length)
- {
- String name = attributeName.toString();
- String lowerName = toLowerCase(name);
- AttributeType attrType =
- DirectoryServer.getAttributeType(lowerName);
-
- if (attrType == null)
- {
- // This must be an attribute type that we don't know about.
- // In that case, we'll create a new attribute using the
- // default syntax. If this is a problem, it will be caught
- // later either by not finding the target entry or by not
- // allowing the entry to be added.
- attrType = DirectoryServer.getDefaultAttributeType(name);
- }
-
- AttributeValue value =
- new AttributeValue(new ASN1OctetString(),
- new ASN1OctetString());
- rdnComponents.add(new RDN(attrType, name, value));
- return new DN(rdnComponents);
- }
-
-
- // Parse the value for this RDN component.
- ByteString parsedValue = new ASN1OctetString();
- pos = parseAttributeValue(dnString, pos, parsedValue);
-
-
- // Create the new RDN with the provided information.
- String name = attributeName.toString();
- String lowerName = toLowerCase(name);
- AttributeType attrType =
- DirectoryServer.getAttributeType(lowerName);
- if (attrType == null)
- {
- // This must be an attribute type that we don't know about.
- // In that case, we'll create a new attribute using the
- // default syntax. If this is a problem, it will be caught
- // later either by not finding the target entry or by not
- // allowing the entry to be added.
- attrType = DirectoryServer.getDefaultAttributeType(name);
- }
-
- AttributeValue value =
- new AttributeValue(attrType, parsedValue);
- RDN rdn = new RDN(attrType, name, value);
-
-
- // Skip over any spaces that might be after the attribute value.
- while ((pos < length) && ((c = dnString.charAt(pos)) == ' '))
- {
- pos++;
- }
-
-
- // Most likely, we will be at either the end of the RDN
- // component or the end of the DN. If so, then handle that
- // appropriately.
- if (pos >= length)
- {
- // We're at the end of the DN string and should have a valid
- // DN so return it.
- rdnComponents.add(rdn);
- return new DN(rdnComponents);
- }
- else if ((c == ',') || (c == ';'))
- {
- // We're at the end of the RDN component, so add it to the
- // list, skip over the comma/semicolon, and start on the next
- // component.
- rdnComponents.add(rdn);
- pos++;
- continue;
- }
- else if (c != '+')
- {
- // This should not happen. At any rate, it's an illegal
- // character, so throw an exception.
- int msgID = MSGID_ATTR_SYNTAX_DN_INVALID_CHAR;
- String message = getMessage(msgID, dnString, c, pos);
- throw new DirectoryException(ResultCode.INVALID_DN_SYNTAX,
- message, msgID);
- }
-
-
- // If we have gotten here, then this must be a multi-valued RDN.
- // In that case, parse the remaining attribute/value pairs and
- // add them to the RDN that we've already created.
- while (true)
- {
- // Skip over the plus sign and any spaces that may follow it
- // before the next attribute name.
- pos++;
- while ((pos < length) && (dnString.charAt(pos) == ' '))
- {
- pos++;
- }
-
-
- // Parse the attribute name from the DN string.
- attributeName = new StringBuilder();
- pos = parseAttributeName(dnString, pos, attributeName,
- allowExceptions);
-
-
- // Make sure that we're not at the end of the DN string
- // because that would be invalid.
- if (pos >= length)
- {
- int msgID = MSGID_ATTR_SYNTAX_DN_END_WITH_ATTR_NAME;
- String message = getMessage(msgID, dnString,
- attributeName.toString());
- throw new DirectoryException(ResultCode.INVALID_DN_SYNTAX,
- message, msgID);
- }
-
-
- // Skip over any spaces between the attribute name and its
- // value.
- c = dnString.charAt(pos);
- while (c == ' ')
- {
- pos++;
- if (pos >= length)
- {
- // This means that we hit the end of the value before
- // finding a '='. This is illegal because there is no
- // attribute-value separator.
- int msgID = MSGID_ATTR_SYNTAX_DN_END_WITH_ATTR_NAME;
- String message = getMessage(msgID, dnString,
- attributeName.toString());
- throw new DirectoryException(ResultCode.INVALID_DN_SYNTAX,
- message, msgID);
- }
- else
- {
- c = dnString.charAt(pos);
- }
- }
-
-
- // The next character must be an equal sign. If it is not,
- // then that's an error.
- if (c == '=')
- {
- pos++;
- }
- else
- {
- int msgID = MSGID_ATTR_SYNTAX_DN_NO_EQUAL;
- String message = getMessage(msgID, dnString,
- attributeName.toString(), c);
- throw new DirectoryException(ResultCode.INVALID_DN_SYNTAX,
- message, msgID);
- }
-
-
- // Skip over any spaces after the equal sign.
- while ((pos < length) && ((c = dnString.charAt(pos)) == ' '))
- {
- pos++;
- }
-
-
- // If we are at the end of the DN string, then that must mean
- // that the attribute value was empty. This will probably
- // never happen in a real-world environment, but technically
- // isn't illegal. If it does happen, then go ahead and create
- // the RDN component and return the DN.
- if (pos >= length)
- {
- name = attributeName.toString();
- lowerName = toLowerCase(name);
- attrType = DirectoryServer.getAttributeType(lowerName);
-
- if (attrType == null)
- {
- // This must be an attribute type that we don't know
- // about. In that case, we'll create a new attribute
- // using the default syntax. If this is a problem, it
- // will be caught later either by not finding the target
- // entry or by not allowing the entry to be added.
- attrType = DirectoryServer.getDefaultAttributeType(name);
- }
-
- value = new AttributeValue(new ASN1OctetString(),
- new ASN1OctetString());
- rdn.addValue(attrType, name, value);
- rdnComponents.add(rdn);
- return new DN(rdnComponents);
- }
-
-
- // Parse the value for this RDN component.
- parsedValue = new ASN1OctetString();
- pos = parseAttributeValue(dnString, pos, parsedValue);
-
-
- // Create the new RDN with the provided information.
- name = attributeName.toString();
- lowerName = toLowerCase(name);
- attrType = DirectoryServer.getAttributeType(lowerName);
- if (attrType == null)
- {
- // This must be an attribute type that we don't know about.
- // In that case, we'll create a new attribute using the
- // default syntax. If this is a problem, it will be caught
- // later either by not finding the target entry or by not
- // allowing the entry to be added.
- attrType = DirectoryServer.getDefaultAttributeType(name);
- }
-
- value = new AttributeValue(attrType, parsedValue);
- rdn.addValue(attrType, name, value);
-
-
- // Skip over any spaces that might be after the attribute
- // value.
- while ((pos < length) && ((c = dnString.charAt(pos)) == ' '))
- {
- pos++;
- }
-
-
- // Most likely, we will be at either the end of the RDN
- // component or the end of the DN. If so, then handle that
- // appropriately.
- if (pos >= length)
- {
- // We're at the end of the DN string and should have a valid
- // DN so return it.
- rdnComponents.add(rdn);
- return new DN(rdnComponents);
- }
- else if ((c == ',') || (c == ';'))
- {
- // We're at the end of the RDN component, so add it to the
- // list, skip over the comma/semicolon, and start on the
- // next component.
- rdnComponents.add(rdn);
- pos++;
- break;
- }
- else if (c != '+')
- {
- // This should not happen. At any rate, it's an illegal
- // character, so throw an exception.
- int msgID = MSGID_ATTR_SYNTAX_DN_INVALID_CHAR;
- String message = getMessage(msgID, dnString, c, pos);
- throw new DirectoryException(ResultCode.INVALID_DN_SYNTAX,
- message, msgID);
- }
- }
- }
- }
-
-
-
- /**
- * Parses an attribute name from the provided DN string starting at
- * the specified location.
- *
- * @param dnBytes The byte array containing the DN to
- * parse.
- * @param pos The position at which to start parsing
- * the attribute name.
- * @param attributeName The buffer to which to append the parsed
- * attribute name.
- * @param allowExceptions Indicates whether to allow certain
- * exceptions to the strict requirements
- * for attribute names.
- *
- * @return The position of the first character that is not part of
- * the attribute name.
- *
- * @throws DirectoryException If it was not possible to parse a
- * valid attribute name from the
- * provided DN string.
- */
- public static int parseAttributeName(byte[] dnBytes, int pos,
- StringBuilder attributeName,
- boolean allowExceptions)
- throws DirectoryException
- {
- assert debugEnter(CLASS_NAME, "parseAttributeName",
- String.valueOf(dnBytes), String.valueOf(pos),
- "java.lang.StringBuilder");
-
- int length = dnBytes.length;
-
-
- // Skip over any leading spaces.
- if (pos < length)
- {
- while (dnBytes[pos] == ' ')
- {
- pos++;
- if (pos == length)
- {
- // This means that the remainder of the DN was completely
- // comprised of spaces. If we have gotten here, then we
- // know that there is at least one RDN component, and
- // therefore the last non-space character of the DN must
- // have been a comma. This is not acceptable.
- int msgID = MSGID_ATTR_SYNTAX_DN_END_WITH_COMMA;
- String message = getMessage(msgID, new String(dnBytes));
- throw new DirectoryException(ResultCode.INVALID_DN_SYNTAX,
- message, msgID);
- }
- }
- }
-
-
- // Next, we should find the attribute name for this RDN component.
- // It may either be a name (with only letters, digits, and dashes
- // and starting with a letter) or an OID (with only digits and
- // periods, optionally prefixed with "oid."), and there is also a
- // special case in which we will allow underscores. Because of
- // the complexity involved, read the entire name first with
- // minimal validation and then do more thorough validation later.
- boolean checkForOID = false;
- boolean endOfName = false;
- while (pos < length)
- {
- // To make the switch more efficient, we'll include all ASCII
- // characters in the range of allowed values and then reject the
- // ones that aren't allowed.
- byte b = dnBytes[pos];
- switch (b)
- {
- case ' ':
- // This should denote the end of the attribute name.
- endOfName = true;
- break;
-
-
- case '!':
- case '"':
- case '#':
- case '$':
- case '%':
- case '&':
- case '\'':
- case '(':
- case ')':
- case '*':
- case '+':
- case ',':
- // None of these are allowed in an attribute name or any
- // character immediately following it.
- int msgID = MSGID_ATTR_SYNTAX_DN_ATTR_ILLEGAL_CHAR;
- String message = getMessage(msgID, new String(dnBytes),
- (char) b, pos);
- throw new DirectoryException(ResultCode.INVALID_DN_SYNTAX,
- message, msgID);
-
-
- case '-':
- // This will be allowed as long as it isn't the first
- // character in the attribute name.
- if (attributeName.length() > 0)
- {
- attributeName.append((char) b);
- }
- else
- {
- msgID = MSGID_ATTR_SYNTAX_DN_ATTR_ILLEGAL_INITIAL_DASH;
- message = getMessage(msgID, new String(dnBytes),
- (char) b);
- throw new DirectoryException(ResultCode.INVALID_DN_SYNTAX,
- message, msgID);
- }
- break;
-
-
- case '.':
- // The period could be allowed if the attribute name is
- // actually expressed as an OID. We'll accept it for now,
- // but make sure to check it later.
- attributeName.append((char) b);
- checkForOID = true;
- break;
-
-
- case '/':
- // This is not allowed in an attribute name or any character
- // immediately following it.
- msgID = MSGID_ATTR_SYNTAX_DN_ATTR_ILLEGAL_CHAR;
- message = getMessage(msgID, new String(dnBytes),
- (char) b, pos);
- throw new DirectoryException(ResultCode.INVALID_DN_SYNTAX,
- message, msgID);
-
-
- case '0':
- case '1':
- case '2':
- case '3':
- case '4':
- case '5':
- case '6':
- case '7':
- case '8':
- case '9':
- // Digits are always allowed if they are not the first
- // character. However, they may be allowed if they are the
- // first character if the valid is an OID or if the
- // attribute name exceptions option is enabled. Therefore,
- // we'll accept it now and check it later.
- attributeName.append((char) b);
- break;
-
-
- case ':':
- case ';': // NOTE: attribute options are not allowed in a DN.
- case '<':
- // None of these are allowed in an attribute name or any
- // character immediately following it.
- msgID = MSGID_ATTR_SYNTAX_DN_ATTR_ILLEGAL_CHAR;
- message = getMessage(msgID, new String(dnBytes),
- (char) b, pos);
- throw new DirectoryException(ResultCode.INVALID_DN_SYNTAX,
- message, msgID);
-
-
- case '=':
- // This should denote the end of the attribute name.
- endOfName = true;
- break;
-
-
- case '>':
- case '?':
- case '@':
- // None of these are allowed in an attribute name or any
- // character immediately following it.
- msgID = MSGID_ATTR_SYNTAX_DN_ATTR_ILLEGAL_CHAR;
- message = getMessage(msgID, new String(dnBytes),
- (char) b, pos);
- throw new DirectoryException(ResultCode.INVALID_DN_SYNTAX,
- message, msgID);
-
-
- case 'A':
- case 'B':
- case 'C':
- case 'D':
- case 'E':
- case 'F':
- case 'G':
- case 'H':
- case 'I':
- case 'J':
- case 'K':
- case 'L':
- case 'M':
- case 'N':
- case 'O':
- case 'P':
- case 'Q':
- case 'R':
- case 'S':
- case 'T':
- case 'U':
- case 'V':
- case 'W':
- case 'X':
- case 'Y':
- case 'Z':
- // These will always be allowed.
- attributeName.append((char) b);
- break;
-
-
- case '[':
- case '\\':
- case ']':
- case '^':
- // None of these are allowed in an attribute name or any
- // character immediately following it.
- msgID = MSGID_ATTR_SYNTAX_DN_ATTR_ILLEGAL_CHAR;
- message = getMessage(msgID, new String(dnBytes),
- (char) b, pos);
- throw new DirectoryException(ResultCode.INVALID_DN_SYNTAX,
- message, msgID);
-
-
- case '_':
- // This will never be allowed as the first character. It
- // may be allowed for subsequent characters if the attribute
- // name exceptions option is enabled.
- if (attributeName.length() == 0)
- {
- msgID =
- MSGID_ATTR_SYNTAX_DN_ATTR_ILLEGAL_INITIAL_UNDERSCORE;
- message = getMessage(msgID, new String(dnBytes),
- ATTR_ALLOW_ATTRIBUTE_NAME_EXCEPTIONS);
- throw new DirectoryException(ResultCode.INVALID_DN_SYNTAX,
- message, msgID);
- }
- else if (allowExceptions)
- {
- attributeName.append((char) b);
- }
- else
- {
- msgID = MSGID_ATTR_SYNTAX_DN_ATTR_ILLEGAL_UNDERSCORE_CHAR;
- message = getMessage(msgID, new String(dnBytes),
- ATTR_ALLOW_ATTRIBUTE_NAME_EXCEPTIONS);
- throw new DirectoryException(ResultCode.INVALID_DN_SYNTAX,
- message, msgID);
- }
- break;
-
-
- case '`':
- // This is not allowed in an attribute name or any character
- // immediately following it.
- msgID = MSGID_ATTR_SYNTAX_DN_ATTR_ILLEGAL_CHAR;
- message = getMessage(msgID, new String(dnBytes),
- (char) b, pos);
- throw new DirectoryException(ResultCode.INVALID_DN_SYNTAX,
- message, msgID);
-
-
- case 'a':
- case 'b':
- case 'c':
- case 'd':
- case 'e':
- case 'f':
- case 'g':
- case 'h':
- case 'i':
- case 'j':
- case 'k':
- case 'l':
- case 'm':
- case 'n':
- case 'o':
- case 'p':
- case 'q':
- case 'r':
- case 's':
- case 't':
- case 'u':
- case 'v':
- case 'w':
- case 'x':
- case 'y':
- case 'z':
- // These will always be allowed.
- attributeName.append((char) b);
- break;
-
-
- default:
- // This is not allowed in an attribute name or any character
- // immediately following it.
- msgID = MSGID_ATTR_SYNTAX_DN_ATTR_ILLEGAL_CHAR;
- message = getMessage(msgID, new String(dnBytes),
- (char) b, pos);
- throw new DirectoryException(ResultCode.INVALID_DN_SYNTAX,
- message, msgID);
- }
-
-
- if (endOfName)
- {
- break;
- }
-
- pos++;
- }
-
-
- // We should now have the full attribute name. However, we may
- // still need to perform some validation, particularly if the name
- // contains a period or starts with a digit. It must also have at
- // least one character.
- if (attributeName.length() == 0)
- {
- int msgID = MSGID_ATTR_SYNTAX_DN_ATTR_NO_NAME;
- String message = getMessage(msgID, new String(dnBytes));
- throw new DirectoryException(ResultCode.INVALID_DN_SYNTAX,
- message, msgID);
- }
- else if (checkForOID)
- {
- boolean validOID = true;
-
- int namePos = 0;
- int nameLength = attributeName.length();
- char ch = attributeName.charAt(0);
- if ((ch == 'o') || (ch == 'O'))
- {
- if (nameLength <= 4)
- {
- validOID = false;
- }
- else
- {
- if ((((ch = attributeName.charAt(1)) == 'i') ||
- (ch == 'I')) &&
- (((ch = attributeName.charAt(2)) == 'd') ||
- (ch == 'D')) &&
- (attributeName.charAt(3) == '.'))
- {
- attributeName.delete(0, 4);
- nameLength -= 4;
- }
- else
- {
- validOID = false;
- }
- }
- }
-
- while (validOID && (namePos < nameLength))
- {
- ch = attributeName.charAt(namePos++);
- if (isDigit(ch))
- {
- while (validOID && (namePos < nameLength) &&
- isDigit(attributeName.charAt(namePos)))
- {
- namePos++;
- }
-
- if ((namePos < nameLength) &&
- (attributeName.charAt(namePos) != '.'))
- {
- validOID = false;
- }
- }
- else if (ch == '.')
- {
- if ((namePos == 1) ||
- (attributeName.charAt(namePos-2) == '.'))
- {
- validOID = false;
- }
- }
- else
- {
- validOID = false;
- }
- }
-
-
- if (validOID && (attributeName.charAt(nameLength-1) == '.'))
- {
- validOID = false;
- }
-
-
- if (! validOID)
- {
- int msgID = MSGID_ATTR_SYNTAX_DN_ATTR_ILLEGAL_PERIOD;
- String message = getMessage(msgID, new String(dnBytes),
- attributeName.toString());
- throw new DirectoryException(ResultCode.INVALID_DN_SYNTAX,
- message, msgID);
- }
- }
- else if (isDigit(attributeName.charAt(0)) && (! allowExceptions))
- {
- int msgID = MSGID_ATTR_SYNTAX_DN_ATTR_ILLEGAL_INITIAL_DIGIT;
- String message = getMessage(msgID, new String(dnBytes),
- attributeName.charAt(0),
- ATTR_ALLOW_ATTRIBUTE_NAME_EXCEPTIONS);
- throw new DirectoryException(ResultCode.INVALID_DN_SYNTAX,
- message, msgID);
- }
-
-
- return pos;
- }
-
-
-
- /**
- * Parses an attribute name from the provided DN string starting at
- * the specified location.
- *
- * @param dnString The DN string to be parsed.
- * @param pos The position at which to start parsing
- * the attribute name.
- * @param attributeName The buffer to which to append the parsed
- * attribute name.
- * @param allowExceptions Indicates whether to allow certain
- * exceptions to the strict requirements
- * for attribute names.
- *
- * @return The position of the first character that is not part of
- * the attribute name.
- *
- * @throws DirectoryException If it was not possible to parse a
- * valid attribute name from the
- * provided DN string.
- */
- public static int parseAttributeName(String dnString, int pos,
- StringBuilder attributeName,
- boolean allowExceptions)
- throws DirectoryException
- {
- assert debugEnter(CLASS_NAME, "parseAttributeName",
- String.valueOf(dnString), String.valueOf(pos),
- "java.lang.StringBuilder");
-
- int length = dnString.length();
-
-
- // Skip over any leading spaces.
- if (pos < length)
- {
- while (dnString.charAt(pos) == ' ')
- {
- pos++;
- if (pos == length)
- {
- // This means that the remainder of the DN was completely
- // comprised of spaces. If we have gotten here, then we
- // know that there is at least one RDN component, and
- // therefore the last non-space character of the DN must
- // have been a comma. This is not acceptable.
- int msgID = MSGID_ATTR_SYNTAX_DN_END_WITH_COMMA;
- String message = getMessage(msgID, dnString);
- throw new DirectoryException(ResultCode.INVALID_DN_SYNTAX,
- message, msgID);
- }
- }
- }
-
- // Next, we should find the attribute name for this RDN component.
- // It may either be a name (with only letters, digits, and dashes
- // and starting with a letter) or an OID (with only digits and
- // periods, optionally prefixed with "oid."), and there is also a
- // special case in which we will allow underscores. Because of
- // the complexity involved, read the entire name first with
- // minimal validation and then do more thorough validation later.
- boolean checkForOID = false;
- boolean endOfName = false;
- while (pos < length)
- {
- // To make the switch more efficient, we'll include all ASCII
- // characters in the range of allowed values and then reject the
- // ones that aren't allowed.
- char c = dnString.charAt(pos);
- switch (c)
- {
- case ' ':
- // This should denote the end of the attribute name.
- endOfName = true;
- break;
-
-
- case '!':
- case '"':
- case '#':
- case '$':
- case '%':
- case '&':
- case '\'':
- case '(':
- case ')':
- case '*':
- case '+':
- case ',':
- // None of these are allowed in an attribute name or any
- // character immediately following it.
- int msgID = MSGID_ATTR_SYNTAX_DN_ATTR_ILLEGAL_CHAR;
- String message = getMessage(msgID, dnString, c, pos);
- throw new DirectoryException(ResultCode.INVALID_DN_SYNTAX,
- message, msgID);
-
-
- case '-':
- // This will be allowed as long as it isn't the first
- // character in the attribute name.
- if (attributeName.length() > 0)
- {
- attributeName.append(c);
- }
- else
- {
- msgID = MSGID_ATTR_SYNTAX_DN_ATTR_ILLEGAL_INITIAL_DASH;
- message = getMessage(msgID, dnString, c);
- throw new DirectoryException(ResultCode.INVALID_DN_SYNTAX,
- message, msgID);
- }
- break;
-
-
- case '.':
- // The period could be allowed if the attribute name is
- // actually expressed as an OID. We'll accept it for now,
- // but make sure to check it later.
- attributeName.append(c);
- checkForOID = true;
- break;
-
-
- case '/':
- // This is not allowed in an attribute name or any character
- // immediately following it.
- msgID = MSGID_ATTR_SYNTAX_DN_ATTR_ILLEGAL_CHAR;
- message = getMessage(msgID, dnString, c, pos);
- throw new DirectoryException(ResultCode.INVALID_DN_SYNTAX,
- message, msgID);
-
-
- case '0':
- case '1':
- case '2':
- case '3':
- case '4':
- case '5':
- case '6':
- case '7':
- case '8':
- case '9':
- // Digits are always allowed if they are not the first
- // character. However, they may be allowed if they are the
- // first character if the valid is an OID or if the
- // attribute name exceptions option is enabled. Therefore,
- // we'll accept it now and check it later.
- attributeName.append(c);
- break;
-
-
- case ':':
- case ';': // NOTE: attribute options are not allowed in a DN.
- case '<':
- // None of these are allowed in an attribute name or any
- // character immediately following it.
- msgID = MSGID_ATTR_SYNTAX_DN_ATTR_ILLEGAL_CHAR;
- message = getMessage(msgID, dnString, c, pos);
- throw new DirectoryException(ResultCode.INVALID_DN_SYNTAX,
- message, msgID);
-
-
- case '=':
- // This should denote the end of the attribute name.
- endOfName = true;
- break;
-
-
- case '>':
- case '?':
- case '@':
- // None of these are allowed in an attribute name or any
- // character immediately following it.
- msgID = MSGID_ATTR_SYNTAX_DN_ATTR_ILLEGAL_CHAR;
- message = getMessage(msgID, dnString, c, pos);
- throw new DirectoryException(ResultCode.INVALID_DN_SYNTAX,
- message, msgID);
-
-
- case 'A':
- case 'B':
- case 'C':
- case 'D':
- case 'E':
- case 'F':
- case 'G':
- case 'H':
- case 'I':
- case 'J':
- case 'K':
- case 'L':
- case 'M':
- case 'N':
- case 'O':
- case 'P':
- case 'Q':
- case 'R':
- case 'S':
- case 'T':
- case 'U':
- case 'V':
- case 'W':
- case 'X':
- case 'Y':
- case 'Z':
- // These will always be allowed.
- attributeName.append(c);
- break;
-
-
- case '[':
- case '\\':
- case ']':
- case '^':
- // None of these are allowed in an attribute name or any
- // character immediately following it.
- msgID = MSGID_ATTR_SYNTAX_DN_ATTR_ILLEGAL_CHAR;
- message = getMessage(msgID, dnString, c, pos);
- throw new DirectoryException(ResultCode.INVALID_DN_SYNTAX,
- message, msgID);
-
-
- case '_':
- // This will never be allowed as the first character. It
- // may be allowed for subsequent characters if the attribute
- // name exceptions option is enabled.
- if (attributeName.length() == 0)
- {
- msgID =
- MSGID_ATTR_SYNTAX_DN_ATTR_ILLEGAL_INITIAL_UNDERSCORE;
- message = getMessage(msgID, dnString,
- ATTR_ALLOW_ATTRIBUTE_NAME_EXCEPTIONS);
- throw new DirectoryException(ResultCode.INVALID_DN_SYNTAX,
- message, msgID);
- }
- else if (allowExceptions)
- {
- attributeName.append(c);
- }
- else
- {
- msgID = MSGID_ATTR_SYNTAX_DN_ATTR_ILLEGAL_UNDERSCORE_CHAR;
- message = getMessage(msgID, dnString,
- ATTR_ALLOW_ATTRIBUTE_NAME_EXCEPTIONS);
- throw new DirectoryException(ResultCode.INVALID_DN_SYNTAX,
- message, msgID);
- }
- break;
-
-
- case '`':
- // This is not allowed in an attribute name or any character
- // immediately following it.
- msgID = MSGID_ATTR_SYNTAX_DN_ATTR_ILLEGAL_CHAR;
- message = getMessage(msgID, dnString, c, pos);
- throw new DirectoryException(ResultCode.INVALID_DN_SYNTAX,
- message, msgID);
-
-
- case 'a':
- case 'b':
- case 'c':
- case 'd':
- case 'e':
- case 'f':
- case 'g':
- case 'h':
- case 'i':
- case 'j':
- case 'k':
- case 'l':
- case 'm':
- case 'n':
- case 'o':
- case 'p':
- case 'q':
- case 'r':
- case 's':
- case 't':
- case 'u':
- case 'v':
- case 'w':
- case 'x':
- case 'y':
- case 'z':
- // These will always be allowed.
- attributeName.append(c);
- break;
-
-
- default:
- // This is not allowed in an attribute name or any character
- // immediately following it.
- msgID = MSGID_ATTR_SYNTAX_DN_ATTR_ILLEGAL_CHAR;
- message = getMessage(msgID, dnString, c, pos);
- throw new DirectoryException(ResultCode.INVALID_DN_SYNTAX,
- message, msgID);
- }
-
-
- if (endOfName)
- {
- break;
- }
-
- pos++;
- }
-
-
- // We should now have the full attribute name. However, we may
- // still need to perform some validation, particularly if the
- // name contains a period or starts with a digit. It must also
- // have at least one character.
- if (attributeName.length() == 0)
- {
- int msgID = MSGID_ATTR_SYNTAX_DN_ATTR_NO_NAME;
- String message = getMessage(msgID, dnString);
- throw new DirectoryException(ResultCode.INVALID_DN_SYNTAX,
- message, msgID);
- }
- else if (checkForOID)
- {
- boolean validOID = true;
-
- int namePos = 0;
- int nameLength = attributeName.length();
- char ch = attributeName.charAt(0);
- if ((ch == 'o') || (ch == 'O'))
- {
- if (nameLength <= 4)
- {
- validOID = false;
- }
- else
- {
- if ((((ch = attributeName.charAt(1)) == 'i') ||
- (ch == 'I')) &&
- (((ch = attributeName.charAt(2)) == 'd') ||
- (ch == 'D')) &&
- (attributeName.charAt(3) == '.'))
- {
- attributeName.delete(0, 4);
- nameLength -= 4;
- }
- else
- {
- validOID = false;
- }
- }
- }
-
- while (validOID && (namePos < nameLength))
- {
- ch = attributeName.charAt(namePos++);
- if (isDigit(ch))
- {
- while (validOID && (namePos < nameLength) &&
- isDigit(attributeName.charAt(namePos)))
- {
- namePos++;
- }
-
- if ((namePos < nameLength) &&
- (attributeName.charAt(namePos) != '.'))
- {
- validOID = false;
- }
- }
- else if (ch == '.')
- {
- if ((namePos == 1) ||
- (attributeName.charAt(namePos-2) == '.'))
- {
- validOID = false;
- }
- }
- else
- {
- validOID = false;
- }
- }
-
-
- if (validOID && (attributeName.charAt(nameLength-1) == '.'))
- {
- validOID = false;
- }
-
-
- if (! validOID)
- {
- int msgID = MSGID_ATTR_SYNTAX_DN_ATTR_ILLEGAL_PERIOD;
- String message = getMessage(msgID, dnString,
- attributeName.toString());
- throw new DirectoryException(ResultCode.INVALID_DN_SYNTAX,
- message, msgID);
- }
- }
- else if (isDigit(attributeName.charAt(0)) &&
- (! allowExceptions))
- {
- int msgID = MSGID_ATTR_SYNTAX_DN_ATTR_ILLEGAL_INITIAL_DIGIT;
- String message = getMessage(msgID, dnString,
- attributeName.charAt(0),
- ATTR_ALLOW_ATTRIBUTE_NAME_EXCEPTIONS);
- throw new DirectoryException(ResultCode.INVALID_DN_SYNTAX,
- message, msgID);
- }
-
-
- return pos;
- }
-
-
-
- /**
- * Parses the attribute value from the provided DN string starting
- * at the specified location. When the value has been parsed, it
- * will be assigned to the provided ASN.1 octet string.
- *
- * @param dnBytes The byte array containing the DN to be
- * parsed.
- * @param pos The position of the first character in
- * the attribute value to parse.
- * @param attributeValue The ASN.1 octet string whose value should
- * be set to the parsed attribute value when
- * this method completes successfully.
- *
- * @return The position of the first character that is not part of
- * the attribute value.
- *
- * @throws DirectoryException If it was not possible to parse a
- * valid attribute value from the
- * provided DN string.
- */
- public static int parseAttributeValue(byte[] dnBytes, int pos,
- ByteString attributeValue)
- throws DirectoryException
- {
- assert debugEnter(CLASS_NAME, "parseAttributeValue",
- String.valueOf(dnBytes), String.valueOf(pos),
- "java.lang.StringBuilder");
-
-
- // All leading spaces have already been stripped so we can start
- // reading the value. However, it may be empty so check for that.
- int length = dnBytes.length;
- if (pos >= length)
- {
- attributeValue.setValue("");
- return pos;
- }
-
-
- // Look at the first character. If it is an octothorpe (#), then
- // that means that the value should be a hex string.
- byte b = dnBytes[pos++];
- if (b == '#')
- {
- // The first two characters must be hex characters.
- StringBuilder hexString = new StringBuilder();
- if ((pos+2) > length)
- {
- int msgID = MSGID_ATTR_SYNTAX_DN_HEX_VALUE_TOO_SHORT;
- String message = getMessage(msgID, new String(dnBytes));
- throw new DirectoryException(ResultCode.INVALID_DN_SYNTAX,
- message, msgID);
- }
-
- for (int i=0; i < 2; i++)
- {
- b = dnBytes[pos++];
- if (isHexDigit(b))
- {
- hexString.append((char) b);
- }
- else
- {
- int msgID = MSGID_ATTR_SYNTAX_DN_INVALID_HEX_DIGIT;
- String message = getMessage(msgID, new String(dnBytes),
- (char) b);
- throw new DirectoryException(ResultCode.INVALID_DN_SYNTAX,
- message, msgID);
- }
- }
-
-
- // The rest of the value must be a multiple of two hex
- // characters. The end of the value may be designated by the
- // end of the DN, a comma or semicolon, a plus sign, or a space.
- while (pos < length)
- {
- b = dnBytes[pos++];
- if (isHexDigit(b))
- {
- hexString.append((char) b);
-
- if (pos < length)
- {
- b = dnBytes[pos++];
- if (isHexDigit(b))
- {
- hexString.append((char) b);
- }
- else
- {
- int msgID = MSGID_ATTR_SYNTAX_DN_INVALID_HEX_DIGIT;
- String message = getMessage(msgID, new String(dnBytes),
- (char) b);
- throw new DirectoryException(
- ResultCode.INVALID_DN_SYNTAX, message,
- msgID);
- }
- }
- else
- {
- int msgID = MSGID_ATTR_SYNTAX_DN_HEX_VALUE_TOO_SHORT;
- String message = getMessage(msgID, new String(dnBytes));
- throw new DirectoryException(ResultCode.INVALID_DN_SYNTAX,
- message, msgID);
- }
- }
- else if ((b == ' ') || (b == ',') || (b == ';') || (b == '+'))
- {
- // This denotes the end of the value.
- pos--;
- break;
- }
- else
- {
- int msgID = MSGID_ATTR_SYNTAX_DN_INVALID_HEX_DIGIT;
- String message = getMessage(msgID, new String(dnBytes),
- (char) b);
- throw new DirectoryException(ResultCode.INVALID_DN_SYNTAX,
- message, msgID);
- }
- }
-
-
- // At this point, we should have a valid hex string. Convert it
- // to a byte array and set that as the value of the provided
- // octet string.
- try
- {
- attributeValue.setValue(hexStringToByteArray(
- hexString.toString()));
- return pos;
- }
- catch (Exception e)
- {
- assert debugException(CLASS_NAME, "parseAttributeValue", e);
-
- int msgID = MSGID_ATTR_SYNTAX_DN_ATTR_VALUE_DECODE_FAILURE;
- String message = getMessage(msgID, new String(dnBytes),
- String.valueOf(e));
- throw new DirectoryException(ResultCode.INVALID_DN_SYNTAX,
- message, msgID);
- }
- }
-
-
- // If the first character is a quotation mark, then the value
- // should continue until the corresponding closing quotation mark.
- else if (b == '"')
- {
- int valueStartPos = pos;
-
- // Keep reading until we find a closing quotation mark.
- while (true)
- {
- if (pos >= length)
- {
- // We hit the end of the DN before the closing quote.
- // That's an error.
- int msgID = MSGID_ATTR_SYNTAX_DN_UNMATCHED_QUOTE;
- String message = getMessage(msgID, new String(dnBytes));
- throw new DirectoryException(ResultCode.INVALID_DN_SYNTAX,
- message, msgID);
- }
-
- if (dnBytes[pos++] == '"')
- {
- // This is the end of the value.
- break;
- }
- }
-
- byte[] valueBytes = new byte[pos - valueStartPos - 1];
- System.arraycopy(dnBytes, valueStartPos, valueBytes, 0,
- valueBytes.length);
-
- try
- {
- attributeValue.setValue(valueBytes);
- }
- catch (Exception e)
- {
- assert debugException(CLASS_NAME, "parseAttributeValue", e);
-
- // This should never happen. Just in case, work around it by
- // converting to a string and back.
- String valueStr = new String(valueBytes);
- attributeValue.setValue(valueStr);
- }
- return pos;
- }
-
-
- // Otherwise, use general parsing to find the end of the value.
- else
- {
- // Keep reading until we find a comma/semicolon, a plus sign, or
- // the end of the DN.
- int valueStartPos = pos - 1;
-
- while (true)
- {
- if (pos >= length)
- {
- // This is the end of the DN and therefore the end of the
- // value.
- break;
- }
-
- b = dnBytes[pos++];
- if ((b == ',') || (b == ';') || (b == '+'))
- {
- pos--;
- break;
- }
- }
-
-
- // Convert the byte buffer to an array.
- byte[] valueBytes = new byte[pos - valueStartPos];
- System.arraycopy(dnBytes, valueStartPos, valueBytes, 0,
- valueBytes.length);
-
-
- // Strip off any unescaped spaces that may be at the end of the
- // value.
- boolean extraSpaces = false;
- int lastPos = valueBytes.length - 1;
- while (lastPos > 0)
- {
- if (valueBytes[lastPos] == ' ')
- {
- extraSpaces = true;
- lastPos--;
- }
- else
- {
- break;
- }
- }
-
- if (extraSpaces)
- {
- byte[] newValueBytes = new byte[lastPos+1];
- System.arraycopy(valueBytes, 0, newValueBytes, 0, lastPos+1);
- valueBytes = newValueBytes;
- }
-
-
- try
- {
- attributeValue.setValue(valueBytes);
- }
- catch (Exception e)
- {
- assert debugException(CLASS_NAME, "parseAttributeValue", e);
-
- // This should never happen. Just in case, work around it by
- // converting to a string and back.
- String valueStr = new String(valueBytes);
- attributeValue.setValue(valueStr);
- }
- return pos;
- }
- }
-
-
-
- /**
- * Parses the attribute value from the provided DN string starting
- * at the specified location. When the value has been parsed, it
- * will be assigned to the provided ASN.1 octet string.
- *
- * @param dnString The DN string to be parsed.
- * @param pos The position of the first character in
- * the attribute value to parse.
- * @param attributeValue The ASN.1 octet string whose value should
- * be set to the parsed attribute value when
- * this method completes successfully.
- *
- * @return The position of the first character that is not part of
- * the attribute value.
- *
- * @throws DirectoryException If it was not possible to parse a
- * valid attribute value from the
- * provided DN string.
- */
- public static int parseAttributeValue(String dnString, int pos,
- ByteString attributeValue)
- throws DirectoryException
- {
- assert debugEnter(CLASS_NAME, "parseAttributeValue",
- String.valueOf(dnString), String.valueOf(pos),
- "java.lang.StringBuilder");
-
-
- // All leading spaces have already been stripped so we can start
- // reading the value. However, it may be empty so check for that.
- int length = dnString.length();
- if (pos >= length)
- {
- attributeValue.setValue("");
- return pos;
- }
-
-
- // Look at the first character. If it is an octothorpe (#), then
- // that means that the value should be a hex string.
- char c = dnString.charAt(pos++);
- if (c == '#')
- {
- // The first two characters must be hex characters.
- StringBuilder hexString = new StringBuilder();
- if ((pos+2) > length)
- {
- int msgID = MSGID_ATTR_SYNTAX_DN_HEX_VALUE_TOO_SHORT;
- String message = getMessage(msgID, dnString);
- throw new DirectoryException(ResultCode.INVALID_DN_SYNTAX,
- message, msgID);
- }
-
- for (int i=0; i < 2; i++)
- {
- c = dnString.charAt(pos++);
- if (isHexDigit(c))
- {
- hexString.append(c);
- }
- else
- {
- int msgID = MSGID_ATTR_SYNTAX_DN_INVALID_HEX_DIGIT;
- String message = getMessage(msgID, dnString, c);
- throw new DirectoryException(ResultCode.INVALID_DN_SYNTAX,
- message, msgID);
- }
- }
-
-
- // The rest of the value must be a multiple of two hex
- // characters. The end of the value may be designated by the
- // end of the DN, a comma or semicolon, or a space.
- while (pos < length)
- {
- c = dnString.charAt(pos++);
- if (isHexDigit(c))
- {
- hexString.append(c);
-
- if (pos < length)
- {
- c = dnString.charAt(pos++);
- if (isHexDigit(c))
- {
- hexString.append(c);
- }
- else
- {
- int msgID = MSGID_ATTR_SYNTAX_DN_INVALID_HEX_DIGIT;
- String message = getMessage(msgID, dnString, c);
- throw new DirectoryException(
- ResultCode.INVALID_DN_SYNTAX, message,
- msgID);
- }
- }
- else
- {
- int msgID = MSGID_ATTR_SYNTAX_DN_HEX_VALUE_TOO_SHORT;
- String message = getMessage(msgID, dnString);
- throw new DirectoryException(ResultCode.INVALID_DN_SYNTAX,
- message, msgID);
- }
- }
- else if ((c == ' ') || (c == ',') || (c == ';'))
- {
- // This denotes the end of the value.
- pos--;
- break;
- }
- else
- {
- int msgID = MSGID_ATTR_SYNTAX_DN_INVALID_HEX_DIGIT;
- String message = getMessage(msgID, dnString, c);
- throw new DirectoryException(ResultCode.INVALID_DN_SYNTAX,
- message, msgID);
- }
- }
-
-
- // At this point, we should have a valid hex string. Convert it
- // to a byte array and set that as the value of the provided
- // octet string.
- try
- {
- attributeValue.setValue(hexStringToByteArray(
- hexString.toString()));
- return pos;
- }
- catch (Exception e)
- {
- assert debugException(CLASS_NAME, "parseAttributeValue", e);
-
- int msgID = MSGID_ATTR_SYNTAX_DN_ATTR_VALUE_DECODE_FAILURE;
- String message = getMessage(msgID, dnString,
- String.valueOf(e));
- throw new DirectoryException(ResultCode.INVALID_DN_SYNTAX,
- message, msgID);
- }
- }
-
-
- // If the first character is a quotation mark, then the value
- // should continue until the corresponding closing quotation mark.
- else if (c == '"')
- {
- // Keep reading until we find an unescaped closing quotation
- // mark.
- boolean escaped = false;
- StringBuilder valueString = new StringBuilder();
- while (true)
- {
- if (pos >= length)
- {
- // We hit the end of the DN before the closing quote.
- // That's an error.
- int msgID = MSGID_ATTR_SYNTAX_DN_UNMATCHED_QUOTE;
- String message = getMessage(msgID, dnString);
- throw new DirectoryException(ResultCode.INVALID_DN_SYNTAX,
- message, msgID);
- }
-
- c = dnString.charAt(pos++);
- if (escaped)
- {
- // The previous character was an escape, so we'll take this
- // one no matter what.
- valueString.append(c);
- escaped = false;
- }
- else if (c == '\\')
- {
- // The next character is escaped. Set a flag to denote
- // this, but don't include the backslash.
- escaped = true;
- }
- else if (c == '"')
- {
- // This is the end of the value.
- break;
- }
- else
- {
- // This is just a regular character that should be in the
- // value.
- valueString.append(c);
- }
- }
-
- attributeValue.setValue(valueString.toString());
- return pos;
- }
-
-
- // Otherwise, use general parsing to find the end of the value.
- else
- {
- boolean escaped;
- StringBuilder valueString = new StringBuilder();
- StringBuilder hexChars = new StringBuilder();
-
- if (c == '\\')
- {
- escaped = true;
- }
- else
- {
- escaped = false;
- valueString.append(c);
- }
-
-
- // Keep reading until we find an unescaped comma or plus sign or
- // the end of the DN.
- while (true)
- {
- if (pos >= length)
- {
- // This is the end of the DN and therefore the end of the
- // value. If there are any hex characters, then we need to
- // deal with them accordingly.
- appendHexChars(dnString, valueString, hexChars);
- break;
- }
-
- c = dnString.charAt(pos++);
- if (escaped)
- {
- // The previous character was an escape, so we'll take this
- // one. However, this could be a hex digit, and if that's
- // the case then the escape would actually be in front of
- // two hex digits that should be treated as a special
- // character.
- if (isHexDigit(c))
- {
- // It is a hexadecimal digit, so the next digit must be
- // one too. However, this could be just one in a series
- // of escaped hex pairs that is used in a string
- // containing one or more multi-byte UTF-8 characters so
- // we can't just treat this byte in isolation. Collect
- // all the bytes together and make sure to take care of
- // these hex bytes before appending anything else to the
- // value.
- if (pos >= length)
- {
- int msgID =
- MSGID_ATTR_SYNTAX_DN_ESCAPED_HEX_VALUE_INVALID;
- String message = getMessage(msgID, dnString);
- throw new DirectoryException(
- ResultCode.INVALID_DN_SYNTAX, message,
- msgID);
- }
- else
- {
- char c2 = dnString.charAt(pos++);
- if (isHexDigit(c2))
- {
- hexChars.append(c);
- hexChars.append(c2);
- }
- else
- {
- int msgID =
- MSGID_ATTR_SYNTAX_DN_ESCAPED_HEX_VALUE_INVALID;
- String message = getMessage(msgID, dnString);
- throw new DirectoryException(
- ResultCode.INVALID_DN_SYNTAX, message,
- msgID);
- }
- }
- }
- else
- {
- appendHexChars(dnString, valueString, hexChars);
- valueString.append(c);
- }
-
- escaped = false;
- }
- else if (c == '\\')
- {
- escaped = true;
- }
- else if ((c == ',') || (c == ';'))
- {
- appendHexChars(dnString, valueString, hexChars);
- pos--;
- break;
- }
- else if (c == '+')
- {
- appendHexChars(dnString, valueString, hexChars);
- pos--;
- break;
- }
- else
- {
- appendHexChars(dnString, valueString, hexChars);
- valueString.append(c);
- }
- }
-
-
- // Strip off any unescaped spaces that may be at the end of the
- // value.
- if (pos > 2 && dnString.charAt(pos-1) == ' ' &&
- dnString.charAt(pos-2) != '\\')
- {
- int lastPos = valueString.length() - 1;
- while (lastPos > 0)
- {
- if (valueString.charAt(lastPos) == ' ')
- {
- valueString.delete(lastPos, lastPos+1);
- lastPos--;
- }
- else
- {
- break;
- }
- }
- }
-
-
- attributeValue.setValue(valueString.toString());
- return pos;
- }
- }
-
-
-
- /**
- * Decodes a hexadecimal string from the provided
- * <CODE>hexChars</CODE> buffer, converts it to a byte array, and
- * then converts that to a UTF-8 string. The resulting UTF-8 string
- * will be appended to the provided <CODE>valueString</CODE> buffer,
- * and the <CODE>hexChars</CODE> buffer will be cleared.
- *
- * @param dnString The DN string that is being decoded.
- * @param valueString The buffer containing the value to which the
- * decoded string should be appended.
- * @param hexChars The buffer containing the hexadecimal
- * characters to decode to a UTF-8 string.
- *
- * @throws DirectoryException If any problem occurs during the
- * decoding process.
- */
- public static void appendHexChars(String dnString,
- StringBuilder valueString,
- StringBuilder hexChars)
- throws DirectoryException
- {
- try
- {
- byte[] hexBytes = hexStringToByteArray(hexChars.toString());
- valueString.append(new String(hexBytes, "UTF-8"));
- hexChars.delete(0, hexChars.length());
- }
- catch (Exception e)
- {
- assert debugException(CLASS_NAME, "appendHexChars", e);
-
- int msgID = MSGID_ATTR_SYNTAX_DN_ATTR_VALUE_DECODE_FAILURE;
- String message = getMessage(msgID, dnString, String.valueOf(e));
- throw new DirectoryException(ResultCode.INVALID_DN_SYNTAX,
- message, msgID);
- }
- }
-
-
-
- /**
- * Creates a duplicate of this DN that can be modified without
- * impacting this DN.
- *
- * @return A duplicate of this DN that can be modified without
- * impacting this DN.
- */
- public DN duplicate()
- {
- assert debugEnter(CLASS_NAME, "duplicate");
-
- RDN[] rdnCopy = new RDN[numComponents];
- for (int i=0; i < numComponents; i++)
- {
- rdnCopy[i] = rdnComponents[i].duplicate();
- }
-
- return new DN(rdnCopy);
- }
-
-
-
- /**
- * Indicates whether the provided object is equal to this DN. In
+ * Indicates whether the provided object is equal to this DN. In
* order for the object to be considered equal, it must be a DN with
* the same number of RDN components and each corresponding RDN
* component must be equal.
*
- * @param o The object for which to make the determination.
- *
- * @return <CODE>true</CODE> if the provided object is a DN that is
- * equal to this DN, or <CODE>false</CODE> if it is not.
+ * @param o
+ * The object for which to make the determination.
+ * @return <code>true</code> if the provided object is a DN that
+ * is equal to this DN, or <code>false</code> if it is
+ * not.
*/
- public boolean equals(Object o)
- {
+ public boolean equals(Object o) {
assert debugEnter(CLASS_NAME, "equals", String.valueOf(o));
- if (this == o)
- {
+ if (this == o) {
return true;
- }
-
- if (o == null)
- {
- return false;
- }
-
- try
- {
- return (normalizedDN.equals(((DN) o).normalizedDN));
- }
- catch (Exception e)
- {
- // This most likely means that the object was null or wasn't a
- // DN. In either case, it's faster to assume that it is and
- // return false on an exception than to perform the checks to
- // see if it meets the appropriate
- // conditions.
- assert debugException(CLASS_NAME, "equals", e);
-
+ } else if (o instanceof DN) {
+ DN other = (DN) o;
+ return normalizedDN.equals(other.normalizedDN);
+ } else {
return false;
}
}
@@ -2764,13 +623,12 @@
/**
- * Retrieves the hash code for this DN. The hash code will be the
+ * Retrieves the hash code for this DN. The hash code will be the
* sum of the hash codes for all the RDN components.
*
- * @return The hash code for this DN.
+ * @return The hash code for this DN.
*/
- public int hashCode()
- {
+ public int hashCode() {
assert debugEnter(CLASS_NAME, "hashCode");
return normalizedDN.hashCode();
@@ -2781,34 +639,14 @@
/**
* Retrieves a string representation of this DN.
*
- * @return A string representation of this DN.
+ * @return A string representation of this DN.
*/
- public String toString()
- {
+ public String toString() {
assert debugEnter(CLASS_NAME, "toString");
- if (dnString == null)
- {
- if (numComponents == 0)
- {
- dnString = "";
- }
- else
- {
- StringBuilder buffer = new StringBuilder();
- rdnComponents[0].toString(buffer);
-
- for (int i=1; i < numComponents; i++)
- {
- buffer.append(",");
- rdnComponents[i].toString(buffer);
- }
-
- dnString = buffer.toString();
- }
- }
-
- return dnString;
+ StringBuilder builder = new StringBuilder();
+ toString(builder);
+ return builder.toString();
}
@@ -2817,15 +655,23 @@
* Appends a string representation of this DN to the provided
* buffer.
*
- * @param buffer The buffer to which the information should be
- * appended.
+ * @param buffer
+ * The buffer to which the information should be appended.
*/
- public void toString(StringBuilder buffer)
- {
+ public void toString(StringBuilder buffer) {
assert debugEnter(CLASS_NAME, "toString",
- "java.lang.StringBuilder");
+ "java.lang.StringBuilder");
- buffer.append(toString());
+ ensureNotNull(buffer);
+
+ if (numComponents != 0) {
+ getRDN(0).toString(buffer);
+
+ for (int i = 1; i < numComponents; i++) {
+ buffer.append(",");
+ getRDN(i).toString(buffer);
+ }
+ }
}
@@ -2833,33 +679,11 @@
/**
* Retrieves a normalized string representation of this DN.
*
- * @return A normalized string representation of this DN.
+ * @return A normalized string representation of this DN.
*/
- public String toNormalizedString()
- {
+ public String toNormalizedString() {
assert debugEnter(CLASS_NAME, "toNormalizedString");
- if (normalizedDN == null)
- {
- if (numComponents == 0)
- {
- normalizedDN = "";
- }
- else
- {
- StringBuilder buffer = new StringBuilder();
- rdnComponents[0].toNormalizedString(buffer);
-
- for (int i=1; i < numComponents; i++)
- {
- buffer.append(',');
- rdnComponents[i].toNormalizedString(buffer);
- }
-
- normalizedDN = buffer.toString();
- }
- }
-
return normalizedDN;
}
@@ -2869,15 +693,16 @@
* Appends a normalized string representation of this DN to the
* provided buffer.
*
- * @param buffer The buffer to which the information should be
- * appended.
+ * @param buffer
+ * The buffer to which the information should be appended.
*/
- public void toNormalizedString(StringBuilder buffer)
- {
+ public void toNormalizedString(StringBuilder buffer) {
assert debugEnter(CLASS_NAME, "toNormalizedString",
- "java.lang.StringBuilder");
+ "java.lang.StringBuilder");
- buffer.append(toNormalizedString());
+ ensureNotNull(buffer);
+
+ buffer.append(normalizedDN);
}
@@ -2887,54 +712,69 @@
* This order will be first hierarchical (ancestors will come before
* descendants) and then alphabetical by attribute name(s) and
* value(s).
+ * <p>
+ * NOTE: the implementation of this method does not perform a
+ * lexicographic comparison of the DN's normalized form. Instead,
+ * each individual RDN is compared using ordering matching rules
+ * where possible.
*
- * @param dn The DN against which to compare this DN.
- *
- * @return A negative integer if this DN should come before the
- * provided DN, a positive integer if this DN should come
- * after the provided DN, or zero if there is no difference
- * with regard to ordering.
+ * @param dn
+ * The DN against which to compare this DN.
+ * @return A negative integer if this DN should come before the
+ * provided DN, a positive integer if this DN should come
+ * after the provided DN, or zero if there is no difference
+ * with regard to ordering.
*/
- public int compareTo(DN dn)
- {
- assert debugEnter(CLASS_NAME, "compareTo", String.valueOf(dn));
+ public int compareTo(DN dn) {
+ assert debugEnter(CLASS_NAME, "compareTo", String.valueOf(this),
+ String.valueOf(dn));
- if (equals(dn))
- {
- return 0;
- }
- else if (isNullDN())
- {
- return -1;
- }
- else if (dn.isNullDN())
- {
- return 1;
- }
- else if (isAncestorOf(dn))
- {
- return -1;
- }
- else if (isDescendantOf(dn))
- {
- return 1;
- }
- else
- {
- int minComps = Math.min(numComponents, dn.numComponents);
- for (int i=0; i < minComps; i++)
- {
- RDN r1 = rdnComponents[rdnComponents.length-1-i];
- RDN r2 = dn.rdnComponents[dn.rdnComponents.length-1-i];
- int result = r1.compareTo(r2);
- if (result != 0)
- {
- return result;
+ ensureNotNull(dn);
+
+ int index1 = numComponents - 1;
+ int index2 = dn.numComponents - 1;
+
+ while (true) {
+ if (index1 >= 0) {
+ if (index2 >= 0) {
+ int value = getRDN(index1).compareTo(dn.getRDN(index2));
+ if (value != 0) {
+ return value;
+ }
+ } else {
+ return 1;
}
+ } else if (index2 >= 0) {
+ return -1;
+ } else {
+ return 0;
}
- return 0;
+ index1--;
+ index2--;
+ }
+ }
+
+
+
+ /**
+ * Construct the normalized form of this DN.
+ *
+ * @return Returns the normalized string representation of this DN.
+ */
+ private String normalize() {
+ if (numComponents == 0) {
+ return "";
+ } else {
+ StringBuilder buffer = new StringBuilder();
+ getRDN(0).toNormalizedString(buffer);
+
+ for (int i = 1; i < numComponents; i++) {
+ buffer.append(',');
+ getRDN(i).toNormalizedString(buffer);
+ }
+
+ return buffer.toString();
}
}
}
-
diff --git a/opends/src/server/org/opends/server/types/DNComparator.java b/opends/src/server/org/opends/server/types/DNComparator.java
deleted file mode 100644
index d7655fd..0000000
--- a/opends/src/server/org/opends/server/types/DNComparator.java
+++ /dev/null
@@ -1,128 +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
- *
- *
- * Portions Copyright 2006 Sun Microsystems, Inc.
- */
-package org.opends.server.types;
-
-
-
-import java.util.Comparator;
-
-import static org.opends.server.loggers.Debug.*;
-
-
-
-/**
- * This class defines a <CODE>Comparator</CODE> object that may be
- * used to compare DNs, particularly for inclusion in a sorted list.
- * The DNs will be compared first by hierarchy (so a child will always
- * be ordered after its parent) and then using RDN comparators for DN
- * components from suffix to leaf.
- */
-public class DNComparator
- implements Comparator<DN>
-{
- /**
- * The fully-qualified name of this class for debugging purposes.
- */
- private static final String CLASS_NAME =
- "org.opends.server.types.DNComparator";
-
-
-
- // The RDN comparator that will be used to compare RDN components.
- private RDNComparator rdnComparator;
-
-
-
- /**
- * Creates a new instance of this DN comparator.
- */
- public DNComparator()
- {
- assert debugConstructor(CLASS_NAME);
-
- rdnComparator = new RDNComparator();
- }
-
-
-
- /**
- * Compares the provided DNs and returns an integer value that
- * reflects the relative order between them.
- *
- * @param dn1 The first DN to compare.
- * @param dn2 The second DN to compare.
- *
- * @return A negative value if the first DN should come before the
- * second in an ordered list, a positive value if they
- * first DN should come after the second in an ordered
- * list, or zero if there is no difference between their
- * order (i.e., the DNs are equal).
- */
- public int compare(DN dn1, DN dn2)
- {
- assert debugEnter(CLASS_NAME, "compare", String.valueOf(dn1),
- String.valueOf(dn2));
-
- RDN[] rdns1 = dn1.getRDNComponents();
- RDN[] rdns2 = dn2.getRDNComponents();
-
- int index1 = rdns1.length - 1;
- int index2 = rdns2.length - 1;
-
- while (true)
- {
- if (index1 >= 0)
- {
- if (index2 >= 0)
- {
- int value = rdnComparator.compare(rdns1[index1],
- rdns2[index2]);
- if (value != 0)
- {
- return value;
- }
- }
- else
- {
- return 1;
- }
- }
- else if (index2 >= 0)
- {
- return -1;
- }
- else
- {
- return 0;
- }
-
- index1--;
- index2--;
- }
- }
-}
-
diff --git a/opends/src/server/org/opends/server/types/Entry.java b/opends/src/server/org/opends/server/types/Entry.java
index f2d9f54..6235eea 100644
--- a/opends/src/server/org/opends/server/types/Entry.java
+++ b/opends/src/server/org/opends/server/types/Entry.java
@@ -143,7 +143,7 @@
if (dn == null)
{
- this.dn = new DN(new ArrayList<RDN>(0));
+ this.dn = DN.nullDN();
}
else
{
@@ -207,7 +207,7 @@
if (dn == null)
{
- this.dn = new DN(new ArrayList<RDN>(0));
+ this.dn = DN.nullDN();
}
else
{
@@ -2352,8 +2352,10 @@
}
// Make sure that all attributes in the RDN are allowed.
- for (AttributeType t : rdn.getAttributeTypes())
+ int numAVAs = rdn.getNumValues();
+ for (int i = 0; i < numAVAs; i++)
{
+ AttributeType t = rdn.getAttributeType(i);
if (! nameForm.isRequiredOrOptional(t))
{
int msgID = MSGID_ENTRY_SCHEMA_RDN_DISALLOWED_ATTR;
@@ -2408,7 +2410,7 @@
else
{
// Get the DN of the parent entry if possible.
- DN parentDN = dn.getParent();
+ DN parentDN = dn.getParentDNInSuffix();
if (parentDN != null)
{
// Get the parent entry and check its structural
@@ -2768,8 +2770,6 @@
{
assert debugEnter(CLASS_NAME, "duplicate");
- DN dnCopy = dn.duplicate();
-
HashMap<ObjectClass,String> objectClassesCopy =
new HashMap<ObjectClass,String>(objectClasses);
@@ -2783,7 +2783,7 @@
operationalAttributes.size());
deepCopy(operationalAttributes, operationalAttrsCopy, false);
- return new Entry(dnCopy, objectClassesCopy, userAttrsCopy,
+ return new Entry(dn, objectClassesCopy, userAttrsCopy,
operationalAttrsCopy);
}
@@ -2806,8 +2806,6 @@
{
assert debugEnter(CLASS_NAME, "duplicate");
- DN dnCopy = dn.duplicate();
-
HashMap<ObjectClass,String> objectClassesCopy;
if (typesOnly)
{
@@ -2838,7 +2836,7 @@
HashMap<AttributeType,List<Attribute>> operationalAttrsCopy =
new HashMap<AttributeType,List<Attribute>>(0);
- return new Entry(dnCopy, objectClassesCopy, userAttrsCopy,
+ return new Entry(dn, objectClassesCopy, userAttrsCopy,
operationalAttrsCopy);
}
@@ -2890,8 +2888,6 @@
{
assert debugEnter(CLASS_NAME, "duplicate");
- DN dnCopy = dn.duplicate();
-
HashMap<ObjectClass,String> objectClassesCopy =
new HashMap<ObjectClass,String>(objectClasses.size());
@@ -2903,7 +2899,7 @@
new HashMap<AttributeType,List<Attribute>>(
operationalAttributes.size());
- return new Entry(dnCopy, objectClassesCopy, userAttrsCopy,
+ return new Entry(dn, objectClassesCopy, userAttrsCopy,
operationalAttrsCopy);
}
@@ -3216,7 +3212,7 @@
case SINGLE_LEVEL:
// The parent DN for this entry must equal the base DN.
- return baseDN.equals(dn.getParent());
+ return baseDN.equals(dn.getParentDNInSuffix());
case WHOLE_SUBTREE:
// The base DN must be an ancestor of the entry DN.
diff --git a/opends/src/server/org/opends/server/types/LDAPURL.java b/opends/src/server/org/opends/server/types/LDAPURL.java
index 38aa628..849330d 100644
--- a/opends/src/server/org/opends/server/types/LDAPURL.java
+++ b/opends/src/server/org/opends/server/types/LDAPURL.java
@@ -76,7 +76,7 @@
/**
* The default base DN that will be used if none is provided.
*/
- public static final DN DEFAULT_BASE_DN = new DN();
+ public static final DN DEFAULT_BASE_DN = DN.nullDN();
diff --git a/opends/src/server/org/opends/server/types/RDN.java b/opends/src/server/org/opends/server/types/RDN.java
index 9fc3a9b..548f0cf 100644
--- a/opends/src/server/org/opends/server/types/RDN.java
+++ b/opends/src/server/org/opends/server/types/RDN.java
@@ -28,18 +28,23 @@
+import static org.opends.server.config.ConfigConstants.*;
+import static org.opends.server.loggers.Debug.*;
+import static org.opends.server.messages.CoreMessages.*;
+import static org.opends.server.messages.MessageHandler.getMessage;
+import static org.opends.server.messages.SchemaMessages.*;
+import static org.opends.server.util.StaticUtils.*;
+import static org.opends.server.util.Validator.ensureNotNull;
+
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
-import java.util.TreeSet;
+import java.util.TreeMap;
+import org.opends.server.api.OrderingMatchingRule;
import org.opends.server.core.DirectoryServer;
import org.opends.server.protocols.asn1.ASN1OctetString;
-
-import static org.opends.server.loggers.Debug.*;
-import static org.opends.server.messages.CoreMessages.*;
-import static org.opends.server.messages.MessageHandler.*;
-import static org.opends.server.util.StaticUtils.*;
+import org.opends.server.util.StaticUtils;
@@ -47,57 +52,55 @@
* This class defines a data structure for storing and interacting
* with the relative distinguished names associated with entries in
* the Directory Server.
+ * <p>
+ * All the methods in this class will throw a
+ * <code>NullPointerException</code> when provided with
+ * <code>null</code> reference parameters unless otherwise stated.
*/
-public class RDN
- implements Comparable<RDN>
-{
+public final class RDN implements Comparable<RDN> {
+ // TODO: per-thread cache of common RDNs?
+
+ // TODO: implement pimpl idiom and provide a "singleton"
+ // implementation for common case where the RDN only has a single
+ // type and value. This would result in less memory being used.
+
/**
* The fully-qualified name of this class for debugging purposes.
*/
private static final String CLASS_NAME =
- "org.opends.server.types.RDN";
-
-
+ "org.opends.server.types.RDN";
// The set of attribute types for the elements in this RDN.
- private AttributeType[] attributeTypes;
-
- // The set of values for the elements in this RDN.
- private AttributeValue[] attributeValues;
-
- // The number of values for this RDN.
- private int numValues;
-
- // The string representation of the normalized form of this RDN.
- private String normalizedRDN;
-
- // The string representation of this RDN.
- private String rdnString;
+ private final AttributeType[] attributeTypes;
// The set of user-provided names for the attributes in this RDN.
- private String[] attributeNames;
+ private final String[] attributeNames;
+
+ // The set of values for the elements in this RDN.
+ private final AttributeValue[] attributeValues;
+
+ /**
+ * The cached normalized string representation of this RDN.
+ *
+ * This non-final field will default to null. The Java memory model
+ * guarantees that it will be initialized to null before being
+ * visible to other threads.
+ */
+ private String normalizedRDN;
/**
* Creates a new RDN with the provided information.
*
- * @param attributeType The attribute type for this RDN.
- * @param attributeValue The value for this RDN.
+ * @param type
+ * The attribute type for this RDN.
+ * @param value
+ * The value for this RDN.
+ * @return Returns the new RDN.
*/
- public RDN(AttributeType attributeType,
- AttributeValue attributeValue)
- {
- assert debugConstructor(CLASS_NAME, String.valueOf(attributeType),
- String.valueOf(attributeValue));
-
- attributeTypes = new AttributeType[] { attributeType };
- attributeNames = new String[] { attributeType.getPrimaryName() };
- attributeValues = new AttributeValue[] { attributeValue };
-
- numValues = 1;
- rdnString = null;
- normalizedRDN = null;
+ public static RDN create(AttributeType type, AttributeValue value) {
+ return create(type, type.getNameOrOID(), value);
}
@@ -105,85 +108,414 @@
/**
* Creates a new RDN with the provided information.
*
- * @param attributeType The attribute type for this RDN.
- * @param attributeName The user-provided name for this RDN.
- * @param attributeValue The value for this RDN.
+ * @param type
+ * The attribute type for this RDN.
+ * @param name
+ * The user-provided name for this RDN.
+ * @param value
+ * The value for this RDN.
+ * @return Returns the new RDN.
*/
- public RDN(AttributeType attributeType, String attributeName,
- AttributeValue attributeValue)
- {
- assert debugConstructor(CLASS_NAME, String.valueOf(attributeType),
- String.valueOf(attributeName),
- String.valueOf(attributeValue));
+ public static RDN create(AttributeType type, String name,
+ AttributeValue value) {
+ ensureNotNull(type, name, value);
- attributeTypes = new AttributeType[] { attributeType };
- attributeNames = new String[] { attributeName };
- attributeValues = new AttributeValue[] { attributeValue };
+ AttributeType[] types = new AttributeType[] { type };
+ String[] names = new String[] { name };
+ AttributeValue[] values = new AttributeValue[] { value };
- numValues = 1;
- rdnString = null;
- normalizedRDN = null;
+ return new RDN(types, names, values);
}
/**
- * Creates a new RDN with the provided information. The number of
- * type, name, and value elements must be nonzero and equal.
+ * Create a new RDN builder which can be used to incrementally build
+ * a new RDN.
*
- * @param attributeTypes The set of attribute types for this RDN.
- * @param attributeNames The set of user-provided names for this
- * RDN.
- * @param attributeValues The set of values for this RDN.
+ * @return Returns the new RDN builder.
*/
- public RDN(List<AttributeType> attributeTypes,
- List<String> attributeNames,
- List<AttributeValue> attributeValues)
- {
- assert debugConstructor(CLASS_NAME,
- String.valueOf(attributeTypes),
- String.valueOf(attributeNames),
- String.valueOf(attributeValues));
-
- this.attributeTypes = new AttributeType[attributeTypes.size()];
- this.attributeNames = new String[attributeNames.size()];
- this.attributeValues = new AttributeValue[attributeValues.size()];
-
- attributeTypes.toArray(this.attributeTypes);
- attributeNames.toArray(this.attributeNames);
- attributeValues.toArray(this.attributeValues);
-
- numValues = attributeTypes.size();
- rdnString = null;
- normalizedRDN = null;
+ public static Builder createBuilder() {
+ return new Builder();
}
/**
- * Creates a new RDN with the provided information. The number of
- * type, name, and value elements must be nonzero and equal.
- *
- * @param attributeTypes The set of attribute types for this RDN.
- * @param attributeNames The set of user-provided names for this
- * RDN.
- * @param attributeValues The set of values for this RDN.
+ * This class provides an interface for constructing RDNs
+ * incrementally.
+ * <p>
+ * Typically, an application will construct a new
+ * <code>Builder</code> and append attribute value assertions
+ * (AVAs) using the <code>append</code> method. When the RDN is
+ * fully constructed, it can be retrieved using the
+ * <code>getInstance</code> method.
*/
- public RDN(AttributeType[] attributeTypes, String[] attributeNames,
- AttributeValue[] attributeValues)
- {
- assert debugConstructor(CLASS_NAME,
- String.valueOf(attributeTypes),
- String.valueOf(attributeNames),
- String.valueOf(attributeValues));
+ public static final class Builder {
+ // The list of attribute types.
+ private List<AttributeType> attributeTypes;
- this.numValues = attributeTypes.length;
- this.attributeTypes = attributeTypes;
- this.attributeNames = attributeNames;
- this.attributeValues = attributeValues;
+ // The list of user-provided attribute names.
+ private List<String> attributeNames;
- rdnString = null;
- normalizedRDN = null;
+ // The list of attribute values.
+ private List<AttributeValue> attributeValues;
+
+
+
+ /**
+ * Create the new empty RDN builder.
+ */
+ private Builder() {
+ clear();
+ }
+
+
+
+ /**
+ * Appends the provided attribute value assertion to the RDN.
+ *
+ * @param type
+ * The attribute type.
+ * @param value
+ * The attribute value.
+ * @throws IllegalArgumentException
+ * If the RDN being constructed already contains an
+ * attribute value assertion for this attribute type.
+ */
+ public void append(AttributeType type, AttributeValue value)
+ throws IllegalArgumentException {
+ append(type, type.getNameOrOID(), value);
+ }
+
+
+
+ /**
+ * Appends the provided attribute value assertion to the RDN.
+ *
+ * @param type
+ * The attribute type.
+ * @param name
+ * The user-provided attribute name.
+ * @param value
+ * The attribute value.
+ * @throws IllegalArgumentException
+ * If the RDN being constructed already contains an
+ * attribute value assertion for this attribute type.
+ */
+ public void append(AttributeType type, String name,
+ AttributeValue value) throws IllegalArgumentException {
+ ensureNotNull(type, name, value);
+
+ if (attributeTypes.contains(type)) {
+ throw new IllegalArgumentException(
+ "Builder already contains the attribute type "
+ + type.getNameOrOID());
+ }
+
+ attributeTypes.add(type);
+ attributeNames.add(name);
+ attributeValues.add(value);
+ }
+
+
+
+ /**
+ * Parses an RDN from the provided string starting at the
+ * specified location, appending any AVAs to this RDN builder.
+ * <p>
+ * This method is package visible so that it can be used by
+ * the DN decoder. It is not intended for use elsewhere.
+ *
+ * @param s
+ * The string to be parsed.
+ * @param pos
+ * The position of the first character in the string to
+ * parse.
+ * @param allowEmpty
+ * Flag indicating whether or not the parsed RDN can be
+ * empty or not.
+ * @return Returns <code>-1</code> if decoding was successful
+ * and parsing consumed the remainder of the string
+ * (including trailing space), or the position of the next
+ * RDN separator character (i.e. a ',' or ';').
+ * @throws DirectoryException
+ * If it was not possible to parse a valid RDN from the
+ * provided string.
+ */
+ int parse(String s, int pos, boolean allowEmpty)
+ throws DirectoryException {
+ assert debugEnter(CLASS_NAME, "parse", String.valueOf(s),
+ String.valueOf(pos));
+
+ // There must be at least one AVA.
+ int count = attributeTypes.size();
+ pos = parseAVA(s, pos);
+
+ if (pos == -1 && !allowEmpty) {
+ if (count == attributeTypes.size()) {
+ // Nothing was parsed.
+ int msgID = MSGID_RDN_DECODE_NULL;
+ String message = getMessage(msgID);
+ throw new DirectoryException(ResultCode.INVALID_DN_SYNTAX,
+ message, msgID);
+ }
+ }
+
+ // Parse any remaining AVAs.
+ while (pos != -1 && s.charAt(pos) == '+') {
+ count = attributeTypes.size();
+ pos = parseAVA(s, pos + 1);
+
+ if (pos == -1 && count == attributeTypes.size()) {
+ // Nothing was parsed.
+ int msgID = MSGID_RDN_UNEXPECTED_COMMA;
+ String message = getMessage(msgID, s, pos);
+ throw new DirectoryException(ResultCode.INVALID_DN_SYNTAX,
+ message, msgID);
+ }
+ }
+
+ return pos;
+ }
+
+
+
+ /**
+ * Parse a single AVA.
+ *
+ * @param s
+ * The string to be parsed.
+ * @param pos
+ * The position of the first character in the string to
+ * parse.
+ * @return Returns <code>-1</code> if decoding was successful
+ * and parsing consumed the remainder of the possibly
+ * empty string (including trailing space), or the
+ * position of the next AVA separator character (i.e. a
+ * '+', ',' or ';').
+ * @throws DirectoryException
+ * If it was not possible to parse a valid AVA from the
+ * provided string.
+ */
+ private int parseAVA(String s, int pos)
+ throws DirectoryException {
+ int length = s.length();
+
+ // Skip over any spaces that may follow it
+ // before the next attribute name.
+ char c;
+ while ((pos < length) && ((c = s.charAt(pos)) == ' ')) {
+ pos++;
+ }
+
+ // Reached the end of the string - let the caller handle this.
+ if (pos >= length) {
+ return -1;
+ }
+
+ // Parse the attribute name.
+ StringBuilder attributeName = new StringBuilder();
+ pos = parseAttributeName(s, pos, attributeName);
+
+ // Make sure we're not at the end of the RDN.
+ if (pos >= length) {
+ int msgID = MSGID_ATTR_SYNTAX_DN_END_WITH_ATTR_NAME;
+ String message = getMessage(msgID, s, attributeName
+ .toString());
+ throw new DirectoryException(ResultCode.INVALID_DN_SYNTAX,
+ message, msgID);
+ }
+
+ // Skip over any spaces between the attribute name and the
+ // equal sign.
+ c = s.charAt(pos);
+ while (c == ' ') {
+ pos++;
+ if (pos >= length) {
+ // This means that we hit the end of the string before
+ // finding a '='. This is illegal because there is no
+ // attribute-value separator.
+ int msgID = MSGID_ATTR_SYNTAX_DN_END_WITH_ATTR_NAME;
+ String message = getMessage(msgID, s, attributeName
+ .toString());
+ throw new DirectoryException(ResultCode.INVALID_DN_SYNTAX,
+ message, msgID);
+ } else {
+ c = s.charAt(pos);
+ }
+ }
+
+ // The next character must be an equal sign.
+ if (c == '=') {
+ pos++;
+ } else {
+ int msgID = MSGID_ATTR_SYNTAX_DN_NO_EQUAL;
+ String message = getMessage(msgID, s, attributeName
+ .toString(), c, pos);
+ throw new DirectoryException(ResultCode.INVALID_DN_SYNTAX,
+ message, msgID);
+ }
+
+ // Skip over any spaces after the equal sign.
+ while ((pos < length) && ((c = s.charAt(pos)) == ' ')) {
+ pos++;
+ }
+
+ // If we are at the end of the RDN string, then that must mean
+ // that the attribute value was empty. This will probably
+ // never happen in a real-world environment, but technically
+ // isn't illegal. If it does happen, then go ahead and return
+ // the RDN.
+ if (pos >= length) {
+ String name = attributeName.toString();
+ String lowerName = toLowerCase(name);
+ AttributeType attrType = DirectoryServer
+ .getAttributeType(lowerName);
+
+ if (attrType == null) {
+ // This must be an attribute type that we don't know
+ // about.
+ // In that case, we'll create a new attribute using the
+ // default syntax. If this is a problem, it will be caught
+ // later either by not finding the target entry or by not
+ // allowing the entry to be added.
+ attrType = DirectoryServer.getDefaultAttributeType(name);
+ }
+
+ AttributeValue value = new AttributeValue(
+ new ASN1OctetString(), new ASN1OctetString());
+ append(attrType, name, value);
+ return -1;
+ }
+
+ // Parse the value for this RDN component.
+ ByteString parsedValue = new ASN1OctetString();
+ pos = parseAttributeValue(s, pos, parsedValue);
+
+ // Update the RDN to include the new attribute/value.
+ String name = attributeName.toString();
+ String lowerName = toLowerCase(name);
+ AttributeType attrType = DirectoryServer
+ .getAttributeType(lowerName);
+ if (attrType == null) {
+ // This must be an attribute type that we don't know about.
+ // In that case, we'll create a new attribute using the
+ // default syntax. If this is a problem, it will be caught
+ // later either by not finding the target entry or by not
+ // allowing the entry to be added.
+ attrType = DirectoryServer.getDefaultAttributeType(name);
+ }
+
+ AttributeValue value = new AttributeValue(attrType,
+ parsedValue);
+ append(attrType, name, value);
+
+ // Skip over any spaces that might be after the attribute
+ // value.
+ while ((pos < length) && ((c = s.charAt(pos)) == ' ')) {
+ pos++;
+ }
+
+ // If we're at the end of the string, then return the RDN.
+ if (pos >= length) {
+ return -1;
+ }
+
+ // If the next character is a comma or semicolon, then that is
+ // not allowed. It would be legal for a DN but not an RDN.
+ if ((c == ',') || (c == ';')) {
+ return pos;
+ }
+
+ // If the next character is anything but a plus sign, then it
+ // is illegal.
+ if (c != '+') {
+ int msgID = MSGID_ATTR_SYNTAX_DN_INVALID_CHAR;
+ String message = getMessage(msgID, s, c, pos);
+ throw new DirectoryException(ResultCode.INVALID_DN_SYNTAX,
+ message, msgID);
+ }
+
+ return pos;
+ }
+
+
+
+ /**
+ * Removes all the attribute value assertions from this RDN
+ * builder.
+ */
+ public void clear() {
+ attributeTypes = new ArrayList<AttributeType>(3);
+ attributeValues = new ArrayList<AttributeValue>(3);
+ attributeNames = new ArrayList<String>(3);
+ }
+
+
+
+ /**
+ * Returns <code>true</code> if this RDN builder is empty.
+ *
+ * @return Returns <code>true</code> if this RDN builder is
+ * empty.
+ */
+ public boolean isEmpty() {
+ return attributeTypes.isEmpty();
+ }
+
+
+
+ /**
+ * Creates a new RDN instance based on the current contents of
+ * this RDN builder. Subsequent changes to this RDN builder do not
+ * affect the contents of the returned <code>RDN</code>.
+ *
+ * @return Returns a new RDN instance based on the current
+ * contents of this RDN builder.
+ * @throws IllegalStateException
+ * If a new RDN could not be created because this RDN
+ * builder is emtpy.
+ */
+ public RDN getInstance() throws IllegalStateException {
+ int sz = attributeTypes.size();
+
+ if (sz == 0) {
+ throw new IllegalStateException("RDN builder is empty");
+ }
+
+ AttributeType[] types = new AttributeType[sz];
+ String[] names = new String[sz];
+ AttributeValue[] values = new AttributeValue[sz];
+
+ attributeTypes.toArray(types);
+ attributeNames.toArray(names);
+ attributeValues.toArray(values);
+
+ return new RDN(types, names, values);
+ }
+ }
+
+
+
+ /**
+ * Creates a new RDN with the provided information.
+ *
+ * @param types
+ * The attribute types for this RDN.
+ * @param names
+ * The user-provided names for this RDN.
+ * @param values
+ * The values for this RDN.
+ */
+ private RDN(AttributeType[] types, String[] names,
+ AttributeValue[] values) {
+ assert debugConstructor(CLASS_NAME, String.valueOf(types), String
+ .valueOf(names), String.valueOf(values));
+
+ this.attributeTypes = types;
+ this.attributeNames = names;
+ this.attributeValues = values;
}
@@ -192,29 +524,89 @@
* Retrieves the number of attribute-value pairs contained in this
* RDN.
*
- * @return The number of attribute-value pairs contained in this
- * RDN.
+ * @return The number of attribute-value pairs contained in this
+ * RDN.
*/
- public int getNumValues()
- {
+ public int getNumValues() {
assert debugEnter(CLASS_NAME, "getNumValues");
- return numValues;
+ return attributeTypes.length;
}
/**
- * Retrieves the set of attribute types for this RDN. The returned
- * array must not be modified by the caller.
+ * Retrieves the attribute type at the specified AVA in this RDN.
*
- * @return The set of attribute types for this RDN.
+ * @param index
+ * The index of the AVA in this RDN.
+ * @return Returns the attribute type at the specified AVA in this
+ * RDN.
+ * @throws IndexOutOfBoundsException
+ * If <code>index</code> is out of range
+ * <code>(index < 0 || index >= getNumValues()</code>.
*/
- public AttributeType[] getAttributeTypes()
- {
- assert debugEnter(CLASS_NAME, "getAttributeTypes");
+ public AttributeType getAttributeType(int index)
+ throws IndexOutOfBoundsException {
+ assert debugEnter(CLASS_NAME, "getAttributeType");
- return attributeTypes;
+ if (index < 0 || index >= attributeTypes.length) {
+ throw new IndexOutOfBoundsException("Index: " + index
+ + ", Size: " + attributeTypes.length);
+ }
+ return attributeTypes[index];
+ }
+
+
+
+ /**
+ * Retrieves the user-defined attribute name at the specified AVA in
+ * this RDN.
+ *
+ * @param index
+ * The index of the AVA in this RDN.
+ * @return Returns the user-defined attribute name at the specified
+ * AVA in this RDN.
+ * @throws IndexOutOfBoundsException
+ * If <code>index</code> is out of range
+ * <code>(index < 0 || index >= getNumValues()</code>.
+ */
+ public String getAttributeName(int index)
+ throws IndexOutOfBoundsException {
+ assert debugEnter(CLASS_NAME, "getAttributeName");
+
+ if (index < 0 || index >= attributeTypes.length) {
+ throw new IndexOutOfBoundsException("Index: " + index
+ + ", Size: " + attributeTypes.length);
+ }
+ return attributeNames[index];
+ }
+
+
+
+ /**
+ * Retrieves the attribute value at the specified AVA in this RDN.
+ * <p>
+ * Applications <b>must not</b> modify the contents of the returned
+ * attribute value.
+ *
+ * @param index
+ * The index of the AVA in this RDN.
+ * @return Returns the attribute value at the specified AVA in this
+ * RDN.
+ * @throws IndexOutOfBoundsException
+ * If <code>index</code> is out of range
+ * <code>(index < 0 || index >= getNumValues()</code>.
+ */
+ public AttributeValue getAttributeValue(int index)
+ throws IndexOutOfBoundsException {
+ assert debugEnter(CLASS_NAME, "getAttributeValue");
+
+ if (index < 0 || index >= attributeTypes.length) {
+ throw new IndexOutOfBoundsException("Index: " + index
+ + ", Size: " + attributeTypes.length);
+ }
+ return attributeValues[index];
}
@@ -222,21 +614,19 @@
/**
* Indicates whether this RDN includes the specified attribute type.
*
- * @param attributeType The attribute type for which to make the
- * determination.
- *
- * @return <CODE>true</CODE> if the RDN includes the specified
- * attribute type, or <CODE>false</CODE> if not.
+ * @param attributeType
+ * The attribute type for which to make the determination.
+ * @return <code>true</code> if the RDN includes the specified
+ * attribute type, or <code>false</code> if not.
*/
- public boolean hasAttributeType(AttributeType attributeType)
- {
- assert debugEnter(CLASS_NAME, "hasAttributeType",
- String.valueOf(attributeType));
+ public boolean hasAttributeType(AttributeType attributeType) {
+ assert debugEnter(CLASS_NAME, "hasAttributeType", String
+ .valueOf(attributeType));
- for (AttributeType t : attributeTypes)
- {
- if (t.equals(attributeType))
- {
+ ensureNotNull(attributeType);
+
+ for (AttributeType t : attributeTypes) {
+ if (t.equals(attributeType)) {
return true;
}
}
@@ -247,91 +637,28 @@
/**
- * Indicates whether this RDN includes the specified attribute type.
- *
- * @param lowerName The name or OID for the attribute type for
- * which to make the determination, formatted in
- * all lowercase characters.
- *
- * @return <CODE>true</CODE> if the RDN includes the specified
- * attribute type, or <CODE>false</CODE> if not.
- */
- public boolean hasAttributeType(String lowerName)
- {
- assert debugEnter(CLASS_NAME, "hasAttributeType",
- String.valueOf(lowerName));
-
- for (AttributeType t : attributeTypes)
- {
- if (t.hasNameOrOID(lowerName))
- {
- return true;
- }
- }
-
- for (String s : attributeNames)
- {
- if (s.equalsIgnoreCase(lowerName))
- {
- return true;
- }
- }
-
- return false;
- }
-
-
-
- /**
- * Retrieves the set of user-provided names for this RDN. The
- * returned array must not be modified by the caller.
- *
- * @return The set of user-provided names for this RDN.
- */
- public String[] getAttributeNames()
- {
- assert debugEnter(CLASS_NAME, "getAttributeNames");
-
- return attributeNames;
- }
-
-
-
- /**
- * Retrieves the set of attribute values for this RDN. The returned
- * list must not be modified by the caller.
- *
- * @return The set of attribute values for this RDN.
- */
- public AttributeValue[] getAttributeValues()
- {
- assert debugEnter(CLASS_NAME, "getAttributeValues");
-
- return attributeValues;
- }
-
-
-
- /**
* Retrieves the attribute value that is associated with the
* specified attribute type.
+ * <p>
+ * Applications <b>must not</b> modify the contents of the returned
+ * attribute value.
*
- * @param attributeType The attribute type for which to retrieve
- * the corresponding value.
- *
- * @return The value for the requested attribute type, or
- * <CODE>null</CODE> if the specified attribute type is not
- * present in the RDN.
+ * @param attributeType
+ * The attribute type for which to retrieve the
+ * corresponding value.
+ * @return The value for the requested attribute type, or
+ * <code>null</code> if the specified attribute type is
+ * not present in the RDN.
*/
- public AttributeValue getAttributeValue(AttributeType attributeType)
- {
- assert debugEnter(CLASS_NAME, "getAttributeValue",
- String.valueOf(attributeType));
+ public AttributeValue getAttributeValue(
+ AttributeType attributeType) {
+ assert debugEnter(CLASS_NAME, "getAttributeValue", String
+ .valueOf(attributeType));
- for (int i=0; i < numValues; i++)
- {
- if (attributeTypes[i].equals(attributeType))
- {
+ ensureNotNull(attributeType);
+
+ for (int i = 0; i < attributeTypes.length; i++) {
+ if (attributeTypes[i].equals(attributeType)) {
return attributeValues[i];
}
}
@@ -344,252 +671,57 @@
/**
* Indicates whether this RDN is multivalued.
*
- * @return <CODE>true</CODE> if this RDN is multivalued, or
- * <CODE>false</CODE> if not.
+ * @return <code>true</code> if this RDN is multivalued, or
+ * <code>false</code> if not.
*/
- public boolean isMultiValued()
- {
+ public boolean isMultiValued() {
assert debugEnter(CLASS_NAME, "isMultiValued");
- return (numValues > 1);
+ return (attributeTypes.length > 1);
}
/**
- * Indicates whether this RDN contains the specified type-value
- * pair.
+ * Returns an <code>RDN</code> object holding the value of the
+ * specified <code>String</code>. The argument is interpreted as
+ * representing the LDAP string representation of an RDN.
+ * <p>
+ * This method is identical to {@link #decode(String)}.
*
- * @param type The attribute type for which to make the
- * determination.
- * @param value The value for which to make the determination.
- *
- * @return <CODE>true</CODE> if this RDN contains the specified
- * attribute value, or <CODE>false</CODE> if not.
+ * @param s
+ * The string to be parsed.
+ * @return Returns a <code>RDN</code> holding the value
+ * represented by the <code>string</code> argument.
+ * @throws DirectoryException
+ * If a problem occurs while trying to decode the provided
+ * string as a RDN.
*/
- public boolean hasValue(AttributeType type, AttributeValue value)
- {
- assert debugEnter(CLASS_NAME, "hasValue", String.valueOf(type),
- String.valueOf(value));
-
- for (int i=0; i < numValues; i++)
- {
- if (attributeTypes[i].equals(type) &&
- attributeValues[i].equals(value))
- {
- return true;
- }
- }
-
- return false;
+ public static RDN valueOf(String s) throws DirectoryException {
+ return decode(s);
}
/**
- * Adds the provided type-value pair from this RDN.
+ * Decodes the provided ASN.1 octet string as a RDN.
*
- * @param type The attribute type of the pair to add.
- * @param name The user-provided name of the pair to add.
- * @param value The attribute value of the pair to add.
- *
- * @return <CODE>true</CODE> if the type-value pair was added to
- * this RDN, or <CODE>false</CODE> if it was not (e.g., it
- * was already present).
+ * @param rdnString
+ * The ASN.1 octet string to decode as a RDN.
+ * @return The decoded RDN.
+ * @throws DirectoryException
+ * If a problem occurs while trying to decode the provided
+ * ASN.1 octet string as a RDN.
*/
- public boolean addValue(AttributeType type, String name,
- AttributeValue value)
- {
- assert debugEnter(CLASS_NAME, "addValue", String.valueOf(type),
- String.valueOf(name), String.valueOf(value));
+ public static RDN decode(ByteString rdnString)
+ throws DirectoryException {
+ assert debugEnter(CLASS_NAME, "decode",
+ String.valueOf(rdnString));
- for (int i=0; i < numValues; i++)
- {
- if (attributeTypes[i].equals(type) &&
- attributeValues[i].equals(value))
- {
- return false;
- }
- }
+ ensureNotNull(rdnString);
- numValues++;
-
- AttributeType[] newTypes = new AttributeType[numValues];
- System.arraycopy(attributeTypes, 0, newTypes, 0,
- attributeTypes.length);
- newTypes[attributeTypes.length] = type;
- attributeTypes = newTypes;
-
- String[] newNames = new String[numValues];
- System.arraycopy(attributeNames, 0, newNames, 0,
- attributeNames.length);
- newNames[attributeNames.length] = name;
- attributeNames = newNames;
-
- AttributeValue[] newValues = new AttributeValue[numValues];
- System.arraycopy(attributeValues, 0, newValues, 0,
- attributeValues.length);
- newValues[attributeValues.length] = value;
- attributeValues = newValues;
-
- rdnString = null;
- normalizedRDN = null;
-
- return true;
- }
-
-
-
- /**
- * Removes the provided type-value pair from this RDN.
- *
- * @param type The attribute type of the pair to remove.
- * @param value The attribute value of the pair to remove.
- *
- * @return <CODE>true</CODE> if the type-value pair was found and
- * removed from this RDN, or <CODE>false</CODE> if it was
- * not.
- */
- public boolean removeValue(AttributeType type, AttributeValue value)
- {
- assert debugEnter(CLASS_NAME, "removeValue", String.valueOf(type),
- String.valueOf(value));
-
- for (int i=0; i < numValues; i++)
- {
- if (attributeTypes[i].equals(type) &&
- attributeValues[i].equals(value))
- {
- numValues--;
-
- if (numValues == 0)
- {
- attributeTypes = new AttributeType[0];
- attributeNames = new String[0];
- attributeValues = new AttributeValue[0];
- }
- else if (i == 0)
- {
- AttributeType[] newTypes = new AttributeType[numValues];
- System.arraycopy(attributeTypes, 1, newTypes, 0, numValues);
- attributeTypes = newTypes;
-
- String[] newNames = new String[numValues];
- System.arraycopy(attributeNames, 1, newNames, 0, numValues);
- attributeNames = newNames;
-
- AttributeValue[] newValues = new AttributeValue[numValues];
- System.arraycopy(attributeValues, 1, newValues, 0,
- numValues);
- attributeValues = newValues;
- }
- else if (i == numValues)
- {
- AttributeType[] newTypes = new AttributeType[numValues];
- System.arraycopy(attributeTypes, 0, newTypes, 0, numValues);
- attributeTypes = newTypes;
-
- String[] newNames = new String[numValues];
- System.arraycopy(attributeNames, 0, newNames, 0, numValues);
- attributeNames = newNames;
-
- AttributeValue[] newValues = new AttributeValue[numValues];
- System.arraycopy(attributeValues, 0, newValues, 0,
- numValues);
- attributeValues = newValues;
- }
- else
- {
- int remaining = numValues - i;
-
- AttributeType[] newTypes = new AttributeType[numValues];
- System.arraycopy(attributeTypes, 0, newTypes, 0, i);
- System.arraycopy(attributeTypes, i+1, newTypes, i,
- remaining);
- attributeTypes = newTypes;
-
- String[] newNames = new String[numValues];
- System.arraycopy(attributeNames, 0, newNames, 0, i);
- System.arraycopy(attributeNames, i+1, newNames, i,
- remaining);
- attributeNames = newNames;
-
- AttributeValue[] newValues = new AttributeValue[numValues];
- System.arraycopy(attributeValues, 0, newValues, 0, i);
- System.arraycopy(attributeValues, i+1, newValues, i,
- remaining);
- attributeValues = newValues;
- }
-
- rdnString = null;
- normalizedRDN = null;
-
- return true;
- }
- }
-
- return false;
- }
-
-
-
- /**
- * Replaces the set of values for this RDN with the provided
- * name-value pair.
- *
- * @param type The attribute type for this RDN.
- * @param name The user-provided name for this RDN.
- * @param value The attribute value for this RDN.
- */
- public void replaceValues(AttributeType type, String name,
- AttributeValue value)
- {
- assert debugEnter(CLASS_NAME, "replaceValues",
- String.valueOf(type), String.valueOf(name),
- String.valueOf(value));
-
- attributeTypes = new AttributeType[] { type };
- attributeNames = new String[] { name };
- attributeValues = new AttributeValue[] { value };
-
- numValues = 1;
- rdnString = null;
- normalizedRDN = null;
- }
-
-
-
- /**
- * Replaces the set of values for this RDN with the provided set of
- * name-value pairs. The number of elements in each list must be
- * equal and greater than one.
- *
- * @param attributeTypes The set of attribute types for this RDN.
- * @param attributeNames The set of user-provided names for this
- * RDN.
- * @param attributeValues The set of values for this RDN.
- */
- public void replaceValues(ArrayList<AttributeType> attributeTypes,
- ArrayList<String> attributeNames,
- ArrayList<AttributeValue> attributeValues)
- {
- assert debugEnter(CLASS_NAME, "replaceValues",
- String.valueOf(attributeTypes),
- String.valueOf(attributeNames),
- String.valueOf(attributeValues));
-
- this.attributeTypes = new AttributeType[attributeTypes.size()];
- attributeTypes.toArray(this.attributeTypes);
-
- this.attributeNames = new String[attributeNames.size()];
- attributeNames.toArray(this.attributeNames);
-
- this.attributeValues = new AttributeValue[attributeValues.size()];
- attributeValues.toArray(this.attributeValues);
-
- numValues = attributeTypes.size();
- rdnString = null;
- normalizedRDN = null;
+ // Use string-based decoder.
+ return decode(rdnString.stringValue());
}
@@ -597,477 +729,78 @@
/**
* Decodes the provided string as an RDN.
*
- * @param rdnString The string to decode as an RDN.
- *
- * @return The decoded RDN.
- *
- * @throws DirectoryException If a problem occurs while trying to
- * decode the provided string as a RDN.
+ * @param rdnString
+ * The string to decode as an RDN.
+ * @return The decoded RDN.
+ * @throws DirectoryException
+ * If a problem occurs while trying to decode the provided
+ * string as a RDN.
*/
public static RDN decode(String rdnString)
- throws DirectoryException
- {
+ throws DirectoryException {
assert debugEnter(CLASS_NAME, "decode",
- String.valueOf(rdnString));
+ String.valueOf(rdnString));
+ ensureNotNull(rdnString);
- // A null or empty RDN is not acceptable.
- if (rdnString == null)
- {
- int msgID = MSGID_RDN_DECODE_NULL;
- String message = getMessage(msgID);
- throw new DirectoryException(ResultCode.INVALID_DN_SYNTAX,
- message, msgID);
- }
+ // Use an RDN builder to parse the string.
+ Builder builder = createBuilder();
+ int pos = builder.parse(rdnString, 0, false);
- int length = rdnString.length();
- if (length == 0)
- {
- int msgID = MSGID_RDN_DECODE_NULL;
- String message = getMessage(msgID);
- throw new DirectoryException(ResultCode.INVALID_DN_SYNTAX,
- message, msgID);
- }
-
-
- // Iterate through the RDN string. The first thing to do is to
- // get rid of any leading spaces.
- int pos = 0;
- char c = rdnString.charAt(pos);
- while (c == ' ')
- {
- pos++;
- if (pos == length)
- {
- // This means that the RDN was completely comprised of spaces,
- // which is not valid.
- int msgID = MSGID_RDN_DECODE_NULL;
- String message = getMessage(msgID);
- throw new DirectoryException(ResultCode.INVALID_DN_SYNTAX,
- message, msgID);
- }
- else
- {
- c = rdnString.charAt(pos);
- }
- }
-
-
- // We know that it's not an empty RDN, so we can do the real
- // processing. First, parse the attribute name. We can borrow
- // the DN code for this.
- boolean allowExceptions =
- DirectoryServer.allowAttributeNameExceptions();
- StringBuilder attributeName = new StringBuilder();
- pos = DN.parseAttributeName(rdnString, pos, attributeName,
- allowExceptions);
-
-
- // Make sure that we're not at the end of the RDN string because
- // that would be invalid.
- if (pos >= length)
- {
- int msgID = MSGID_RDN_END_WITH_ATTR_NAME;
- String message = getMessage(msgID,
- rdnString, attributeName.toString());
- throw new DirectoryException(ResultCode.INVALID_DN_SYNTAX,
- message, msgID);
- }
-
-
- // Skip over any spaces between the attribute name and its value.
- c = rdnString.charAt(pos);
- while (c == ' ')
- {
- pos++;
- if (pos >= length)
- {
- // This means that we hit the end of the string before
- // finding a '='. This is illegal because there is no
- // attribute-value separator.
- int msgID = MSGID_RDN_END_WITH_ATTR_NAME;
- String message = getMessage(msgID,
- rdnString, attributeName.toString());
- throw new DirectoryException(ResultCode.INVALID_DN_SYNTAX,
- message, msgID);
- }
- else
- {
- c = rdnString.charAt(pos);
- }
- }
-
-
- // The next character must be an equal sign. If it is not, then
- // that's an error.
- if (c == '=')
- {
- pos++;
- }
- else
- {
- int msgID = MSGID_RDN_NO_EQUAL;
- String message = getMessage(msgID, rdnString,
- attributeName.toString(), c, pos);
- throw new DirectoryException(ResultCode.INVALID_DN_SYNTAX,
- message, msgID);
- }
-
-
- // Skip over any spaces between the equal sign and the value.
- while ((pos < length) && ((c = rdnString.charAt(pos)) == ' '))
- {
- pos++;
- }
-
-
- // If we are at the end of the RDN string, then that must mean
- // that the attribute value was empty. This will probably never
- // happen in a real-world environment, but technically isn't
- // illegal. If it does happen, then go ahead and return the RDN.
- if (pos >= length)
- {
- String name = attributeName.toString();
- String lowerName = toLowerCase(name);
- AttributeType attrType =
- DirectoryServer.getAttributeType(lowerName);
-
- if (attrType == null)
- {
- // This must be an attribute type that we don't know about.
- // In that case, we'll create a new attribute using the
- // default syntax. If this is a problem, it will be caught
- // later either by not finding the target entry or by not
- // allowing the entry to be added.
- attrType = DirectoryServer.getDefaultAttributeType(name);
- }
-
- AttributeValue value = new AttributeValue(new ASN1OctetString(),
- new ASN1OctetString());
- return new RDN(attrType, name, value);
- }
-
-
- // Parse the value for this RDN component. This can be done using
- // the DN code.
- ByteString parsedValue = new ASN1OctetString();
- pos = DN.parseAttributeValue(rdnString, pos, parsedValue);
-
-
- // Create the new RDN with the provided information. However,
- // don't return it yet because this could be a multi-valued RDN.
- String name = attributeName.toString();
- String lowerName = toLowerCase(name);
- AttributeType attrType =
- DirectoryServer.getAttributeType(lowerName);
- if (attrType == null)
- {
- // This must be an attribute type that we don't know about.
- // In that case, we'll create a new attribute using the default
- // syntax. If this is a problem, it will be caught later either
- // by not finding the target entry or by not allowing the entry
- // to be added.
- attrType = DirectoryServer.getDefaultAttributeType(name);
- }
-
- AttributeValue value = new AttributeValue(attrType, parsedValue);
- RDN rdn = new RDN(attrType, name, value);
-
-
- // Skip over any spaces that might be after the attribute value.
- while ((pos < length) && ((c = rdnString.charAt(pos)) == ' '))
- {
- pos++;
- }
-
-
- // Most likely, this is the end of the RDN. If so, then return
- // it.
- if (pos >= length)
- {
- return rdn;
- }
-
-
- // If the next character is a comma or semicolon, then that is not
- // allowed. It would be legal for a DN but not an RDN.
- if ((c == ',') || (c == ';'))
- {
- int msgID = MSGID_RDN_UNEXPECTED_COMMA;
+ // Make sure that the string did not contain any trailing RDNs.
+ if (pos != -1) {
+ int msgID = MSGID_RDN_UNEXPECTED_COMMA;
String message = getMessage(msgID, rdnString, pos);
throw new DirectoryException(ResultCode.INVALID_DN_SYNTAX,
- message, msgID);
+ message, msgID);
}
-
- // If the next character is anything but a plus sign, then it is
- // illegal.
- if (c != '+')
- {
- int msgID = MSGID_RDN_ILLEGAL_CHARACTER;
- String message = getMessage(msgID, rdnString, c, pos);
- throw new DirectoryException(ResultCode.INVALID_DN_SYNTAX,
- message, msgID);
- }
-
-
- // If we have gotten here, then it is a multi-valued RDN. Parse
- // the remaining attribute/value pairs and add them to the RDN
- // that we've already created.
- while (true)
- {
- // Skip over the plus sign and any spaces that may follow it
- // before the next attribute name.
- pos++;
- while ((pos < length) && ((c = rdnString.charAt(pos)) == ' '))
- {
- pos++;
- }
-
-
- // Parse the attribute name.
- attributeName = new StringBuilder();
- pos = DN.parseAttributeName(rdnString, pos, attributeName,
- allowExceptions);
-
-
- // Make sure we're not at the end of the RDN.
- if (pos >= length)
- {
- int msgID = MSGID_RDN_END_WITH_ATTR_NAME;
- String message = getMessage(msgID, rdnString,
- attributeName.toString());
- throw new DirectoryException(ResultCode.INVALID_DN_SYNTAX,
- message, msgID);
- }
-
-
- // Skip over any spaces between the attribute name and the equal
- // sign.
- c = rdnString.charAt(pos);
- while (c == ' ')
- {
- pos++;
- if (pos >= length)
- {
- // This means that we hit the end of the string before
- // finding a '='. This is illegal because there is no
- // attribute-value separator.
- int msgID = MSGID_RDN_END_WITH_ATTR_NAME;
- String message = getMessage(msgID, rdnString,
- attributeName.toString());
- throw new DirectoryException(ResultCode.INVALID_DN_SYNTAX,
- message, msgID);
- }
- else
- {
- c = rdnString.charAt(pos);
- }
- }
-
-
- // The next character must be an equal sign.
- if (c == '=')
- {
- pos++;
- }
- else
- {
- int msgID = MSGID_RDN_NO_EQUAL;
- String message = getMessage(msgID, rdnString,
- attributeName.toString(), c, pos);
- throw new DirectoryException(ResultCode.INVALID_DN_SYNTAX,
- message, msgID);
- }
-
-
- // Skip over any spaces after the equal sign.
- while ((pos < length) && ((c = rdnString.charAt(pos)) == ' '))
- {
- pos++;
- }
-
-
- // If we are at the end of the RDN string, then that must mean
- // that the attribute value was empty. This will probably never
- // happen in a real-world environment, but technically isn't
- // illegal. If it does happen, then go ahead and return the
- // RDN.
- if (pos >= length)
- {
- name = attributeName.toString();
- lowerName = toLowerCase(name);
- attrType = DirectoryServer.getAttributeType(lowerName);
-
- if (attrType == null)
- {
- // This must be an attribute type that we don't know about.
- // In that case, we'll create a new attribute using the
- // default syntax. If this is a problem, it will be caught
- // later either by not finding the target entry or by not
- // allowing the entry to be added.
- attrType = DirectoryServer.getDefaultAttributeType(name);
- }
-
- value = new AttributeValue(new ASN1OctetString(),
- new ASN1OctetString());
- rdn.addValue(attrType, name, value);
- return rdn;
- }
-
-
- // Parse the value for this RDN component.
- parsedValue = new ASN1OctetString();
- pos = DN.parseAttributeValue(rdnString, pos, parsedValue);
-
-
- // Update the RDN to include the new attribute/value.
- name = attributeName.toString();
- lowerName = toLowerCase(name);
- attrType = DirectoryServer.getAttributeType(lowerName);
- if (attrType == null)
- {
- // This must be an attribute type that we don't know about.
- // In that case, we'll create a new attribute using the
- // default syntax. If this is a problem, it will be caught
- // later either by not finding the target entry or by not
- // allowing the entry to be added.
- attrType = DirectoryServer.getDefaultAttributeType(name);
- }
-
- value = new AttributeValue(attrType, parsedValue);
- rdn.addValue(attrType, name, value);
-
-
- // Skip over any spaces that might be after the attribute value.
- while ((pos < length) && ((c = rdnString.charAt(pos)) == ' '))
- {
- pos++;
- }
-
-
- // If we're at the end of the string, then return the RDN.
- if (pos >= length)
- {
- return rdn;
- }
-
-
- // If the next character is a comma or semicolon, then that is
- // not allowed. It would be legal for a DN but not an RDN.
- if ((c == ',') || (c == ';'))
- {
- int msgID = MSGID_RDN_UNEXPECTED_COMMA;
- String message = getMessage(msgID, rdnString, pos);
- throw new DirectoryException(ResultCode.INVALID_DN_SYNTAX,
- message, msgID);
- }
-
-
- // If the next character is anything but a plus sign, then it is
- // illegal.
- if (c != '+')
- {
- int msgID = MSGID_RDN_ILLEGAL_CHARACTER;
- String message = getMessage(msgID, rdnString, c, pos);
- throw new DirectoryException(ResultCode.INVALID_DN_SYNTAX,
- message, msgID);
- }
- }
+ // Return the parsed RDN instance.
+ return builder.getInstance();
}
/**
- * Creates a duplicate of this RDN that can be modified without
- * impacting this RDN.
+ * Indicates whether the provided object is equal to this RDN. It
+ * will only be considered equal if it is an RDN object containing
+ * the same attribute value assertions as this RDN (the order does
+ * not matter).
*
- * @return A duplicate of this RDN that can be modified without
- * impacting this RDN.
+ * @param o
+ * The object for which to make the determination.
+ * @return <code>true</code> if it is determined that the provided
+ * object is equal to this RDN, or <code>false</code> if
+ * not.
*/
- public RDN duplicate()
- {
- assert debugEnter(CLASS_NAME, "duplicate");
-
- AttributeType[] newTypes = new AttributeType[numValues];
- System.arraycopy(attributeTypes, 0, newTypes, 0, numValues);
-
- String[] newNames = new String[numValues];
- System.arraycopy(attributeNames, 0, newNames, 0, numValues);
-
- AttributeValue[] newValues = new AttributeValue[numValues];
- System.arraycopy(attributeValues, 0, newValues, 0, numValues);
-
- return new RDN(newTypes, newNames, newValues);
- }
-
-
-
- /**
- * Indicates whether the provided object is equal to this RDN. It
- * will only be considered equal if it is an RDN object that
- * contains the same number of elements in the same order with the
- * same types and normalized values.
- *
- * @param o The object for which to make the determination.
- *
- * @return <CODE>true</CODE> if it is determined that the provided
- * object is equal to this RDN, or <CODE>false</CODE> if
- * not.
- */
- public boolean equals(Object o)
- {
+ public boolean equals(Object o) {
assert debugEnter(CLASS_NAME, "equals", String.valueOf(o));
- if (this == o)
- {
+ if (this == o) {
return true;
- }
+ } else if (o instanceof RDN) {
+ RDN other = (RDN) o;
- if ((o == null) || (! (o instanceof RDN)))
- {
+ String nvalue1 = toNormalizedString();
+ String nvalue2 = other.toNormalizedString();
+ return nvalue1.equals(nvalue2);
+ } else {
return false;
}
-
- RDN rdn = (RDN) o;
- if (numValues != rdn.numValues)
- {
- return false;
- }
-
- for (int i=0; i < numValues; i++)
- {
- if ((! attributeTypes[i].equals(rdn.attributeTypes[i])) ||
- (! attributeValues[i].equals(rdn.attributeValues[i])))
- {
- return false;
- }
- }
-
- return true;
}
/**
- * Retrieves the hash code for this RDN. It will be calculated as
- * the sum of the hash codes of the types and values.
+ * Retrieves the hash code for this RDN. It will be calculated as
+ * the hash code of the RDN's normalized string representation.
*
- * @return The hash code for this RDN.
+ * @return The hash code for this RDN.
*/
- public int hashCode()
- {
+ public int hashCode() {
assert debugEnter(CLASS_NAME, "hashCode");
- int hashCode = 0;
-
- for (int i=0; i < numValues; i++)
- {
- hashCode += attributeTypes[i].hashCode() +
- attributeValues[i].hashCode();
- }
-
- return hashCode;
+ return toNormalizedString().hashCode();
}
@@ -1075,30 +808,14 @@
/**
* Retrieves a string representation of this RDN.
*
- * @return A string representation of this RDN.
+ * @return A string representation of this RDN.
*/
- public String toString()
- {
- if (rdnString == null)
- {
- StringBuilder buffer = new StringBuilder();
+ public String toString() {
+ assert debugEnter(CLASS_NAME, "toString");
- buffer.append(attributeNames[0]);
- buffer.append("=");
- buffer.append(attributeValues[0].getDNStringValue());
-
- for (int i=1; i < numValues; i++)
- {
- buffer.append("+");
- buffer.append(attributeNames[i]);
- buffer.append("=");
- buffer.append(attributeValues[i].getDNStringValue());
- }
-
- rdnString = buffer.toString();
- }
-
- return rdnString;
+ StringBuilder buffer = new StringBuilder();
+ toString(buffer);
+ return buffer.toString();
}
@@ -1107,15 +824,29 @@
* Appends a string representation of this RDN to the provided
* buffer.
*
- * @param buffer The buffer to which the string representation
- * should be appended.
+ * @param buffer
+ * The buffer to which the string representation should be
+ * appended.
*/
- public void toString(StringBuilder buffer)
- {
+ public void toString(StringBuilder buffer) {
assert debugEnter(CLASS_NAME, "toString",
- "java.lang.StringBuilder");
+ "java.lang.StringBuilder");
- buffer.append(toString());
+ ensureNotNull(buffer);
+
+ buffer.append(attributeNames[0]);
+ buffer.append("=");
+ String value = attributeValues[0].getStringValue();
+ quoteAttributeValue(buffer, value);
+
+ for (int i = 1; i < attributeTypes.length; i++) {
+ buffer.append("+");
+ buffer.append(attributeNames[i]);
+ buffer.append("=");
+
+ value = attributeValues[i].getStringValue();
+ quoteAttributeValue(buffer, value);
+ }
}
@@ -1123,14 +854,38 @@
/**
* Retrieves a normalized string representation of this RDN.
*
- * @return A normalized string representation of this RDN.
+ * @return A normalized string representation of this RDN.
*/
- public String toNormalizedString()
- {
- if (normalizedRDN == null)
- {
- StringBuilder buffer = new StringBuilder();
- toNormalizedString(buffer);
+ public String toNormalizedString() {
+ if (normalizedRDN == null) {
+ StringBuilder builder = new StringBuilder();
+
+ if (attributeNames.length == 1) {
+ // Optimize for the common case of a single AVA.
+ appendNormalizedAVA(builder, attributeTypes[0],
+ attributeValues[0]);
+ } else {
+ // Multiple AVAs require sorting.
+ TreeMap<String, Integer> map;
+
+ map = new TreeMap<String, Integer>();
+ for (int i = 0; i < attributeTypes.length; i++) {
+ map.put(attributeTypes[i].getNameOrOID(), i);
+ }
+
+ boolean isFirst = true;
+ for (Integer i : map.values()) {
+ if (!isFirst) {
+ builder.append('+');
+ } else {
+ isFirst = false;
+ }
+ appendNormalizedAVA(builder, attributeTypes[i],
+ attributeValues[i]);
+ }
+ }
+
+ normalizedRDN = builder.toString();
}
return normalizedRDN;
@@ -1142,143 +897,899 @@
* Appends a normalized string representation of this RDN to the
* provided buffer.
*
- * @param buffer The buffer to which to append the information.
+ * @param buffer
+ * The buffer to which to append the information.
*/
- public void toNormalizedString(StringBuilder buffer)
- {
+ public void toNormalizedString(StringBuilder buffer) {
assert debugEnter(CLASS_NAME, "toNormalizedString",
- "java.lang.StringBuilder");
+ "java.lang.StringBuilder");
- if (normalizedRDN != null)
- {
- buffer.append(normalizedRDN);
- return;
+ ensureNotNull(buffer);
+
+ buffer.append(toNormalizedString());
+ }
+
+
+
+ /**
+ * Compares this RDN with the provided RDN.
+ * <p>
+ * The comparison will be done in order of the sorted RDN
+ * components. It will attempt to use an ordering matching rule for
+ * the associated attributes (if one is provided), but will fall
+ * back on a bytewise comparison of the normalized values if
+ * necessary.
+ *
+ * @param rdn
+ * The RDN against which to compare this RDN.
+ * @return A negative integer if this RDN should come before the
+ * provided RDN, a positive integer if this RDN should come
+ * after the provided RDN, or zero if there is no difference
+ * with regard to ordering.
+ */
+ public int compareTo(RDN rdn) {
+ assert debugEnter(CLASS_NAME, "compareTo", String.valueOf(rdn));
+
+ ensureNotNull(rdn);
+
+ // Handle the common case efficiently.
+ if (attributeTypes.length == 1
+ && rdn.attributeTypes.length == 1) {
+ AttributeType type1 = attributeTypes[0];
+ AttributeType type2 = rdn.attributeTypes[0];
+
+ AttributeValue value1 = attributeValues[0];
+ AttributeValue value2 = rdn.attributeValues[0];
+
+ return compareAVA(type1, value1, type2, value2);
}
- boolean bufferEmpty = (buffer.length() == 0);
+ // We have at least one multi-valued RDNs, so we need to sort.
+ TreeMap<String, Integer> map1;
+ TreeMap<String, Integer> map2;
- if (attributeNames.length == 1)
- {
- toLowerCase(attributeNames[0], buffer);
- buffer.append('=');
+ map1 = new TreeMap<String, Integer>();
+ map2 = new TreeMap<String, Integer>();
- try
- {
- buffer.append(
- attributeValues[0].getNormalizedDNStringValue());
- }
- catch (Exception e)
- {
- assert debugException(CLASS_NAME, "toNormalizedString", e);
-
- buffer.append(attributeValues[0].getStringValue());
- }
+ for (int i = 0; i < attributeTypes.length; i++) {
+ map1.put(attributeTypes[i].getNameOrOID(), i);
}
- else
- {
- TreeSet<String> rdnElementStrings = new TreeSet<String>();
- for (int i=0; i < attributeNames.length; i++)
- {
- StringBuilder b2 = new StringBuilder();
- toLowerCase(attributeNames[i], b2);
- b2.append('=');
+ for (int i = 0; i < rdn.attributeTypes.length; i++) {
+ map2.put(rdn.attributeTypes[i].getNameOrOID(), i);
+ }
- try
- {
- b2.append(attributeValues[i].getNormalizedStringValue());
- }
- catch (Exception e)
- {
- assert debugException(CLASS_NAME, "toNormalizedString", e);
+ // Now compare the sorted AVAs.
+ Iterator<Integer> i1= map1.values().iterator();
+ Iterator<Integer> i2 = map2.values().iterator();
- b2.append(attributeValues[i].getStringValue());
- }
+ while (i1.hasNext() && i2.hasNext()) {
+ int int1 = i1.next();
+ int int2 = i2.next();
- rdnElementStrings.add(b2.toString());
- }
+ AttributeType type1 = attributeTypes[int1];
+ AttributeType type2 = rdn.attributeTypes[int2];
- Iterator<String> iterator = rdnElementStrings.iterator();
- buffer.append(iterator.next());
+ AttributeValue value1 = attributeValues[int1];
+ AttributeValue value2 = rdn.attributeValues[int2];
- while (iterator.hasNext())
- {
- buffer.append('+');
- buffer.append(iterator.next());
+ int rc = compareAVA(type1, value1, type2, value2);
+ if (rc != 0) {
+ return rc;
}
}
- if (bufferEmpty)
- {
- normalizedRDN = buffer.toString();
+ // At least one of the iterators has finished.
+ if (i1.hasNext() == false && i2.hasNext() == false) {
+ return 0;
+ } else if (i1.hasNext() == false) {
+ return -1;
+ } else {
+ return 1;
}
}
/**
- * Compares this RDN with the provided RDN based on an alphabetic
- * comparison of the attribute names and values.
+ * Compare two AVAs for order.
*
- * @param rdn The RDN against which to compare this RDN.
- *
- * @return A negative integer if this RDN should come before the
- * provided RDN, a positive integer if this RDN should come
- * after the provided RDN, or zero if there is no
- * difference with regard to ordering.
+ * @param type1
+ * The attribute type of the first AVA.
+ * @param value1
+ * The attribute value of the first AVA.
+ * @param type2
+ * The attribute type of the second AVA.
+ * @param value2
+ * The attribute value of the second AVA.
+ * @return Returns a negative integer, zero, or a positive integer
+ * if the first AVA is less than, equal to, or greater than
+ * the second.
*/
- public int compareTo(RDN rdn)
- {
- assert debugEnter(CLASS_NAME, "compareTo", String.valueOf(rdn));
+ private int compareAVA(AttributeType type1, AttributeValue value1,
+ AttributeType type2, AttributeValue value2) {
+ if (type1.equals(type2)) {
+ OrderingMatchingRule rule = type1.getOrderingMatchingRule();
- if (equals(rdn))
- {
- return 0;
- }
+ try {
+ if (rule != null) {
+ byte[] b1 = value1.getNormalizedValueBytes();
+ byte[] b2 = value2.getNormalizedValueBytes();
- int minValues = Math.min(numValues, rdn.numValues);
- for (int i=0; i < minValues; i++)
- {
- String n1 = attributeNames[i].toLowerCase();
- String n2 = rdn.attributeNames[i].toLowerCase();
+ return rule.compare(b1, b2);
+ } else {
+ byte[] b1 = value1.getNormalizedValue().value();
+ byte[] b2 = value2.getNormalizedValue().value();
- int result = n1.compareTo(n2);
- if (result != 0)
- {
- return result;
- }
-
- try
- {
- String v1 = attributeValues[i].getNormalizedStringValue();
- String v2 = rdn.attributeValues[i].getNormalizedStringValue();
-
- result = v1.compareTo(v2);
- if (result != 0)
- {
- return result;
+ return StaticUtils.compare(b1, b2);
}
- }
- catch (Exception e)
- {
- assert debugException(CLASS_NAME, "compareTo", e);
+ } catch (Exception e) {
+ assert debugException(CLASS_NAME, "compareAVA", e);
- return 0;
- }
- }
+ // Just get the raw values and do a comparison between them.
+ byte[] b1 = value1.getValue().value();
+ byte[] b2 = value2.getValue().value();
- if (numValues > minValues)
- {
- return 1;
- }
- else if (rdn.numValues > minValues)
- {
- return -1;
- }
- else
- {
- return 0;
+ return StaticUtils.compare(b1, b2);
+ }
+ } else {
+ String name1 = toLowerCase(type1.getNameOrOID());
+ String name2 = toLowerCase(type2.getNameOrOID());
+
+ return name1.compareTo(name2);
}
}
-}
+
+
+ /**
+ * Normalize and append the provided attribute type and value to the
+ * provided buffer.
+ *
+ * @param buffer
+ * The string buffer.
+ * @param type
+ * The attribute type.
+ * @param value
+ * The attribute value.
+ */
+ private void appendNormalizedAVA(StringBuilder buffer,
+ AttributeType type, AttributeValue value) {
+ toLowerCase(type.getNameOrOID(), buffer);
+ buffer.append('=');
+
+ try {
+ quoteAttributeValue(buffer, value.getNormalizedStringValue());
+ } catch (Exception e) {
+ assert debugException(CLASS_NAME, "toNormalizedString", e);
+ quoteAttributeValue(buffer, value.getStringValue());
+ }
+ }
+
+
+
+ /**
+ * Encode an attribute value according to the DN string encoding
+ * rules, and append it to the provided buffer.
+ *
+ * @param buffer
+ * Append the attribtue value to this buffer.
+ * @param value
+ * The value to be represented in a DN-safe form.
+ */
+ private void quoteAttributeValue(StringBuilder buffer,
+ String value) {
+ assert debugEnter(CLASS_NAME, "quoteAttributeValue", String
+ .valueOf(value));
+
+ // Do nothing if the value is empty.
+ int length = value.length();
+ if (length == 0) {
+ return;
+ }
+
+ // Assume 1-byte UTF8 and that no quoting will be required.
+ buffer.ensureCapacity(buffer.length() + length);
+
+ // Quote leading space or #.
+ char c = value.charAt(0);
+ if (c == ' ' || c == '#') {
+ buffer.append('\\');
+ buffer.append(c);
+ } else {
+ quoteChar(buffer, c);
+ }
+
+ // Process the remainder of the string.
+ for (int i = 1; i < (length - 1); i++) {
+ quoteChar(buffer, value.charAt(i));
+ }
+
+ // Quote trailing space.
+ if (length > 1) {
+ c = value.charAt(length - 1);
+ if (c == ' ') {
+ buffer.append('\\');
+ buffer.append(c);
+ } else {
+ quoteChar(buffer, c);
+ }
+ }
+ }
+
+
+
+ /**
+ * Encode a single attribute value from an RDN according to the DN
+ * string encoding rules.
+ *
+ * @param buffer
+ * Append the character to this buffer.
+ * @param c
+ * The character to be encoded.
+ */
+ private void quoteChar(StringBuilder buffer, char c) {
+ if ((c < ' ') || (c > '~')) {
+ for (byte b : getBytes(String.valueOf(c))) {
+ buffer.append('\\');
+ buffer.append(byteToLowerHex(b));
+ }
+ } else {
+ switch (c) {
+ case ',':
+ case '+':
+ case '"':
+ case '\\':
+ case '<':
+ case '>':
+ case ';':
+ buffer.append('\\');
+ }
+
+ buffer.append(c);
+ }
+ }
+
+
+
+ /**
+ * Parses an attribute name from the provided DN string starting at
+ * the specified location.
+ *
+ * @param dnString
+ * The DN string to be parsed.
+ * @param pos
+ * The position at which to start parsing the attribute
+ * name.
+ * @param attributeName
+ * The buffer to which to append the parsed attribute name.
+ * @return The position of the first character that is not part of
+ * the attribute name.
+ * @throws DirectoryException
+ * If it was not possible to parse a valid attribute name
+ * from the provided DN string.
+ */
+ private static int parseAttributeName(String dnString, int pos,
+ StringBuilder attributeName) throws DirectoryException {
+ assert debugEnter(CLASS_NAME, "parseAttributeName", String
+ .valueOf(dnString), String.valueOf(pos),
+ "java.lang.StringBuilder");
+ boolean allowExceptions = DirectoryServer
+ .allowAttributeNameExceptions();
+
+ int length = dnString.length();
+
+ // Skip over any leading spaces.
+ if (pos < length) {
+ while (dnString.charAt(pos) == ' ') {
+ pos++;
+ if (pos == length) {
+ // This means that the remainder of the DN was completely
+ // comprised of spaces. If we have gotten here, then we
+ // know that there is at least one RDN component, and
+ // therefore the last non-space character of the DN must
+ // have been a comma. This is not acceptable.
+ int msgID = MSGID_ATTR_SYNTAX_DN_END_WITH_COMMA;
+ String message = getMessage(msgID, dnString);
+ throw new DirectoryException(ResultCode.INVALID_DN_SYNTAX,
+ message, msgID);
+ }
+ }
+ }
+
+ // Next, we should find the attribute name for this RDN component.
+ // It may either be a name (with only letters, digits, and dashes
+ // and starting with a letter) or an OID (with only digits and
+ // periods, optionally prefixed with "oid."), and there is also a
+ // special case in which we will allow underscores. Because of
+ // the complexity involved, read the entire name first with
+ // minimal validation and then do more thorough validation later.
+ boolean checkForOID = false;
+ boolean endOfName = false;
+ while (pos < length) {
+ // To make the switch more efficient, we'll include all ASCII
+ // characters in the range of allowed values and then reject the
+ // ones that aren't allowed.
+ char c = dnString.charAt(pos);
+ switch (c) {
+ case ' ':
+ // This should denote the end of the attribute name.
+ endOfName = true;
+ break;
+
+ case '!':
+ case '"':
+ case '#':
+ case '$':
+ case '%':
+ case '&':
+ case '\'':
+ case '(':
+ case ')':
+ case '*':
+ case '+':
+ case ',':
+ // None of these are allowed in an attribute name or any
+ // character immediately following it.
+ int msgID = MSGID_ATTR_SYNTAX_DN_ATTR_ILLEGAL_CHAR;
+ String message = getMessage(msgID, dnString, c, pos);
+ throw new DirectoryException(ResultCode.INVALID_DN_SYNTAX,
+ message, msgID);
+
+ case '-':
+ // This will be allowed as long as it isn't the first
+ // character in the attribute name.
+ if (attributeName.length() > 0) {
+ attributeName.append(c);
+ } else {
+ msgID = MSGID_ATTR_SYNTAX_DN_ATTR_ILLEGAL_INITIAL_DASH;
+ message = getMessage(msgID, dnString, c);
+ throw new DirectoryException(ResultCode.INVALID_DN_SYNTAX,
+ message, msgID);
+ }
+ break;
+
+ case '.':
+ // The period could be allowed if the attribute name is
+ // actually expressed as an OID. We'll accept it for now,
+ // but make sure to check it later.
+ attributeName.append(c);
+ checkForOID = true;
+ break;
+
+ case '/':
+ // This is not allowed in an attribute name or any character
+ // immediately following it.
+ msgID = MSGID_ATTR_SYNTAX_DN_ATTR_ILLEGAL_CHAR;
+ message = getMessage(msgID, dnString, c, pos);
+ throw new DirectoryException(ResultCode.INVALID_DN_SYNTAX,
+ message, msgID);
+
+ case '0':
+ case '1':
+ case '2':
+ case '3':
+ case '4':
+ case '5':
+ case '6':
+ case '7':
+ case '8':
+ case '9':
+ // Digits are always allowed if they are not the first
+ // character. However, they may be allowed if they are the
+ // first character if the valid is an OID or if the
+ // attribute name exceptions option is enabled. Therefore,
+ // we'll accept it now and check it later.
+ attributeName.append(c);
+ break;
+
+ case ':':
+ case ';': // NOTE: attribute options are not allowed in a DN.
+ case '<':
+ // None of these are allowed in an attribute name or any
+ // character immediately following it.
+ msgID = MSGID_ATTR_SYNTAX_DN_ATTR_ILLEGAL_CHAR;
+ message = getMessage(msgID, dnString, c, pos);
+ throw new DirectoryException(ResultCode.INVALID_DN_SYNTAX,
+ message, msgID);
+
+ case '=':
+ // This should denote the end of the attribute name.
+ endOfName = true;
+ break;
+
+ case '>':
+ case '?':
+ case '@':
+ // None of these are allowed in an attribute name or any
+ // character immediately following it.
+ msgID = MSGID_ATTR_SYNTAX_DN_ATTR_ILLEGAL_CHAR;
+ message = getMessage(msgID, dnString, c, pos);
+ throw new DirectoryException(ResultCode.INVALID_DN_SYNTAX,
+ message, msgID);
+
+ case 'A':
+ case 'B':
+ case 'C':
+ case 'D':
+ case 'E':
+ case 'F':
+ case 'G':
+ case 'H':
+ case 'I':
+ case 'J':
+ case 'K':
+ case 'L':
+ case 'M':
+ case 'N':
+ case 'O':
+ case 'P':
+ case 'Q':
+ case 'R':
+ case 'S':
+ case 'T':
+ case 'U':
+ case 'V':
+ case 'W':
+ case 'X':
+ case 'Y':
+ case 'Z':
+ // These will always be allowed.
+ attributeName.append(c);
+ break;
+
+ case '[':
+ case '\\':
+ case ']':
+ case '^':
+ // None of these are allowed in an attribute name or any
+ // character immediately following it.
+ msgID = MSGID_ATTR_SYNTAX_DN_ATTR_ILLEGAL_CHAR;
+ message = getMessage(msgID, dnString, c, pos);
+ throw new DirectoryException(ResultCode.INVALID_DN_SYNTAX,
+ message, msgID);
+
+ case '_':
+ // This will never be allowed as the first character. It
+ // may be allowed for subsequent characters if the attribute
+ // name exceptions option is enabled.
+ if (attributeName.length() == 0) {
+ msgID =
+ MSGID_ATTR_SYNTAX_DN_ATTR_ILLEGAL_INITIAL_UNDERSCORE;
+ message = getMessage(msgID, dnString,
+ ATTR_ALLOW_ATTRIBUTE_NAME_EXCEPTIONS);
+ throw new DirectoryException(ResultCode.INVALID_DN_SYNTAX,
+ message, msgID);
+ } else if (allowExceptions) {
+ attributeName.append(c);
+ } else {
+ msgID = MSGID_ATTR_SYNTAX_DN_ATTR_ILLEGAL_UNDERSCORE_CHAR;
+ message = getMessage(msgID, dnString,
+ ATTR_ALLOW_ATTRIBUTE_NAME_EXCEPTIONS);
+ throw new DirectoryException(ResultCode.INVALID_DN_SYNTAX,
+ message, msgID);
+ }
+ break;
+
+ case '`':
+ // This is not allowed in an attribute name or any character
+ // immediately following it.
+ msgID = MSGID_ATTR_SYNTAX_DN_ATTR_ILLEGAL_CHAR;
+ message = getMessage(msgID, dnString, c, pos);
+ throw new DirectoryException(ResultCode.INVALID_DN_SYNTAX,
+ message, msgID);
+
+ case 'a':
+ case 'b':
+ case 'c':
+ case 'd':
+ case 'e':
+ case 'f':
+ case 'g':
+ case 'h':
+ case 'i':
+ case 'j':
+ case 'k':
+ case 'l':
+ case 'm':
+ case 'n':
+ case 'o':
+ case 'p':
+ case 'q':
+ case 'r':
+ case 's':
+ case 't':
+ case 'u':
+ case 'v':
+ case 'w':
+ case 'x':
+ case 'y':
+ case 'z':
+ // These will always be allowed.
+ attributeName.append(c);
+ break;
+
+ default:
+ // This is not allowed in an attribute name or any character
+ // immediately following it.
+ msgID = MSGID_ATTR_SYNTAX_DN_ATTR_ILLEGAL_CHAR;
+ message = getMessage(msgID, dnString, c, pos);
+ throw new DirectoryException(ResultCode.INVALID_DN_SYNTAX,
+ message, msgID);
+ }
+
+ if (endOfName) {
+ break;
+ }
+
+ pos++;
+ }
+
+ // We should now have the full attribute name. However, we may
+ // still need to perform some validation, particularly if the
+ // name contains a period or starts with a digit. It must also
+ // have at least one character.
+ if (attributeName.length() == 0) {
+ int msgID = MSGID_ATTR_SYNTAX_DN_ATTR_NO_NAME;
+ String message = getMessage(msgID, dnString);
+ throw new DirectoryException(ResultCode.INVALID_DN_SYNTAX,
+ message, msgID);
+ } else if (checkForOID) {
+ boolean validOID = true;
+
+ int namePos = 0;
+ int nameLength = attributeName.length();
+ char ch = attributeName.charAt(0);
+ if ((ch == 'o') || (ch == 'O')) {
+ if (nameLength <= 4) {
+ validOID = false;
+ } else {
+ if ((((ch = attributeName.charAt(1)) == 'i') || (ch == 'I'))
+ && (((ch = attributeName.charAt(2)) == 'd')
+ || (ch == 'D'))
+ && (attributeName.charAt(3) == '.')) {
+ attributeName.delete(0, 4);
+ nameLength -= 4;
+ } else {
+ validOID = false;
+ }
+ }
+ }
+
+ while (validOID && (namePos < nameLength)) {
+ ch = attributeName.charAt(namePos++);
+ if (isDigit(ch)) {
+ while (validOID && (namePos < nameLength)
+ && isDigit(attributeName.charAt(namePos))) {
+ namePos++;
+ }
+
+ if ((namePos < nameLength)
+ && (attributeName.charAt(namePos) != '.')) {
+ validOID = false;
+ }
+ } else if (ch == '.') {
+ if ((namePos == 1)
+ || (attributeName.charAt(namePos - 2) == '.')) {
+ validOID = false;
+ }
+ } else {
+ validOID = false;
+ }
+ }
+
+ if (validOID && (attributeName.charAt(nameLength - 1) == '.')) {
+ validOID = false;
+ }
+
+ if (!validOID) {
+ int msgID = MSGID_ATTR_SYNTAX_DN_ATTR_ILLEGAL_PERIOD;
+ String message = getMessage(msgID, dnString, attributeName
+ .toString());
+ throw new DirectoryException(ResultCode.INVALID_DN_SYNTAX,
+ message, msgID);
+ }
+ } else if (isDigit(attributeName.charAt(0))
+ && (!allowExceptions)) {
+ int msgID = MSGID_ATTR_SYNTAX_DN_ATTR_ILLEGAL_INITIAL_DIGIT;
+ String message = getMessage(msgID, dnString, attributeName
+ .charAt(0), ATTR_ALLOW_ATTRIBUTE_NAME_EXCEPTIONS);
+ throw new DirectoryException(ResultCode.INVALID_DN_SYNTAX,
+ message, msgID);
+ }
+
+ return pos;
+ }
+
+
+
+ /**
+ * Parses the attribute value from the provided DN string starting
+ * at the specified location. When the value has been parsed, it
+ * will be assigned to the provided ASN.1 octet string.
+ *
+ * @param dnString
+ * The DN string to be parsed.
+ * @param pos
+ * The position of the first character in the attribute
+ * value to parse.
+ * @param attributeValue
+ * The ASN.1 octet string whose value should be set to the
+ * parsed attribute value when this method completes
+ * successfully.
+ * @return The position of the first character that is not part of
+ * the attribute value.
+ * @throws DirectoryException
+ * If it was not possible to parse a valid attribute value
+ * from the provided DN string.
+ */
+ private static int parseAttributeValue(String dnString, int pos,
+ ByteString attributeValue) throws DirectoryException {
+ assert debugEnter(CLASS_NAME, "parseAttributeValue", String
+ .valueOf(dnString), String.valueOf(pos),
+ "java.lang.StringBuilder");
+
+ // All leading spaces have already been stripped so we can start
+ // reading the value. However, it may be empty so check for that.
+ int length = dnString.length();
+ if (pos >= length) {
+ attributeValue.setValue("");
+ return pos;
+ }
+
+ // Look at the first character. If it is an octothorpe (#), then
+ // that means that the value should be a hex string.
+ char c = dnString.charAt(pos++);
+ if (c == '#') {
+ // The first two characters must be hex characters.
+ StringBuilder hexString = new StringBuilder();
+ if ((pos + 2) > length) {
+ int msgID = MSGID_ATTR_SYNTAX_DN_HEX_VALUE_TOO_SHORT;
+ String message = getMessage(msgID, dnString);
+ throw new DirectoryException(ResultCode.INVALID_DN_SYNTAX,
+ message, msgID);
+ }
+
+ for (int i = 0; i < 2; i++) {
+ c = dnString.charAt(pos++);
+ if (isHexDigit(c)) {
+ hexString.append(c);
+ } else {
+ int msgID = MSGID_ATTR_SYNTAX_DN_INVALID_HEX_DIGIT;
+ String message = getMessage(msgID, dnString, c);
+ throw new DirectoryException(ResultCode.INVALID_DN_SYNTAX,
+ message, msgID);
+ }
+ }
+
+ // The rest of the value must be a multiple of two hex
+ // characters. The end of the value may be designated by the
+ // end of the DN, a comma or semicolon, or a space.
+ while (pos < length) {
+ c = dnString.charAt(pos++);
+ if (isHexDigit(c)) {
+ hexString.append(c);
+
+ if (pos < length) {
+ c = dnString.charAt(pos++);
+ if (isHexDigit(c)) {
+ hexString.append(c);
+ } else {
+ int msgID = MSGID_ATTR_SYNTAX_DN_INVALID_HEX_DIGIT;
+ String message = getMessage(msgID, dnString, c);
+ throw new DirectoryException(
+ ResultCode.INVALID_DN_SYNTAX, message, msgID);
+ }
+ } else {
+ int msgID = MSGID_ATTR_SYNTAX_DN_HEX_VALUE_TOO_SHORT;
+ String message = getMessage(msgID, dnString);
+ throw new DirectoryException(
+ ResultCode.INVALID_DN_SYNTAX, message, msgID);
+ }
+ } else if ((c == ' ') || (c == ',') || (c == ';')
+ || (c == '+')) {
+ // This denotes the end of the value.
+ pos--;
+ break;
+ } else {
+ int msgID = MSGID_ATTR_SYNTAX_DN_INVALID_HEX_DIGIT;
+ String message = getMessage(msgID, dnString, c);
+ throw new DirectoryException(ResultCode.INVALID_DN_SYNTAX,
+ message, msgID);
+ }
+ }
+
+ // At this point, we should have a valid hex string. Convert it
+ // to a byte array and set that as the value of the provided
+ // octet string.
+ try {
+ attributeValue.setValue(hexStringToByteArray(hexString
+ .toString()));
+ return pos;
+ } catch (Exception e) {
+ assert debugException(CLASS_NAME, "parseAttributeValue", e);
+
+ int msgID = MSGID_ATTR_SYNTAX_DN_ATTR_VALUE_DECODE_FAILURE;
+ String message = getMessage(msgID, dnString, String
+ .valueOf(e));
+ throw new DirectoryException(ResultCode.INVALID_DN_SYNTAX,
+ message, msgID);
+ }
+ }
+
+ // If the first character is a quotation mark, then the value
+ // should continue until the corresponding closing quotation mark.
+ else if (c == '"') {
+ // Keep reading until we find an unescaped closing quotation
+ // mark.
+ boolean escaped = false;
+ StringBuilder valueString = new StringBuilder();
+ while (true) {
+ if (pos >= length) {
+ // We hit the end of the DN before the closing quote.
+ // That's an error.
+ int msgID = MSGID_ATTR_SYNTAX_DN_UNMATCHED_QUOTE;
+ String message = getMessage(msgID, dnString);
+ throw new DirectoryException(ResultCode.INVALID_DN_SYNTAX,
+ message, msgID);
+ }
+
+ c = dnString.charAt(pos++);
+ if (escaped) {
+ // The previous character was an escape, so we'll take this
+ // one no matter what.
+ valueString.append(c);
+ escaped = false;
+ } else if (c == '\\') {
+ // The next character is escaped. Set a flag to denote
+ // this, but don't include the backslash.
+ escaped = true;
+ } else if (c == '"') {
+ // This is the end of the value.
+ break;
+ } else {
+ // This is just a regular character that should be in the
+ // value.
+ valueString.append(c);
+ }
+ }
+
+ attributeValue.setValue(valueString.toString());
+ return pos;
+ }
+
+ // Otherwise, use general parsing to find the end of the value.
+ else {
+ boolean escaped;
+ StringBuilder valueString = new StringBuilder();
+ StringBuilder hexChars = new StringBuilder();
+
+ if (c == '\\') {
+ escaped = true;
+ } else {
+ escaped = false;
+ valueString.append(c);
+ }
+
+ // Keep reading until we find an unescaped comma or plus sign or
+ // the end of the DN.
+ while (true) {
+ if (pos >= length) {
+ // This is the end of the DN and therefore the end of the
+ // value. If there are any hex characters, then we need to
+ // deal with them accordingly.
+ appendHexChars(dnString, valueString, hexChars);
+ break;
+ }
+
+ c = dnString.charAt(pos++);
+ if (escaped) {
+ // The previous character was an escape, so we'll take this
+ // one. However, this could be a hex digit, and if that's
+ // the case then the escape would actually be in front of
+ // two hex digits that should be treated as a special
+ // character.
+ if (isHexDigit(c)) {
+ // It is a hexadecimal digit, so the next digit must be
+ // one too. However, this could be just one in a series
+ // of escaped hex pairs that is used in a string
+ // containing one or more multi-byte UTF-8 characters so
+ // we can't just treat this byte in isolation. Collect
+ // all the bytes together and make sure to take care of
+ // these hex bytes before appending anything else to the
+ // value.
+ if (pos >= length) {
+ int msgID =
+ MSGID_ATTR_SYNTAX_DN_ESCAPED_HEX_VALUE_INVALID;
+ String message = getMessage(msgID, dnString);
+ throw new DirectoryException(
+ ResultCode.INVALID_DN_SYNTAX, message, msgID);
+ } else {
+ char c2 = dnString.charAt(pos++);
+ if (isHexDigit(c2)) {
+ hexChars.append(c);
+ hexChars.append(c2);
+ } else {
+ int msgID =
+ MSGID_ATTR_SYNTAX_DN_ESCAPED_HEX_VALUE_INVALID;
+ String message = getMessage(msgID, dnString);
+ throw new DirectoryException(
+ ResultCode.INVALID_DN_SYNTAX, message, msgID);
+ }
+ }
+ } else {
+ appendHexChars(dnString, valueString, hexChars);
+ valueString.append(c);
+ }
+
+ escaped = false;
+ } else if (c == '\\') {
+ escaped = true;
+ } else if ((c == ',') || (c == ';') || (c == '+')) {
+ appendHexChars(dnString, valueString, hexChars);
+ pos--;
+ break;
+ } else {
+ appendHexChars(dnString, valueString, hexChars);
+ valueString.append(c);
+ }
+ }
+
+ // Strip off any unescaped spaces that may be at the end of the
+ // value.
+ if (pos > 2 && dnString.charAt(pos - 1) == ' '
+ && dnString.charAt(pos - 2) != '\\') {
+ int lastPos = valueString.length() - 1;
+ while (lastPos > 0) {
+ if (valueString.charAt(lastPos) == ' ') {
+ valueString.delete(lastPos, lastPos + 1);
+ lastPos--;
+ } else {
+ break;
+ }
+ }
+ }
+
+ attributeValue.setValue(valueString.toString());
+ return pos;
+ }
+ }
+
+
+
+ /**
+ * Decodes a hexadecimal string from the provided
+ * <code>hexChars</code> buffer, converts it to a byte array, and
+ * then converts that to a UTF-8 string. The resulting UTF-8 string
+ * will be appended to the provided <code>valueString</code>
+ * buffer, and the <code>hexChars</code> buffer will be cleared.
+ *
+ * @param dnString
+ * The DN string that is being decoded.
+ * @param valueString
+ * The buffer containing the value to which the decoded
+ * string should be appended.
+ * @param hexChars
+ * The buffer containing the hexadecimal characters to
+ * decode to a UTF-8 string.
+ * @throws DirectoryException
+ * If any problem occurs during the decoding process.
+ */
+ private static void appendHexChars(String dnString,
+ StringBuilder valueString, StringBuilder hexChars)
+ throws DirectoryException {
+ try {
+ byte[] hexBytes = hexStringToByteArray(hexChars.toString());
+ valueString.append(new String(hexBytes, "UTF-8"));
+ hexChars.delete(0, hexChars.length());
+ } catch (Exception e) {
+ assert debugException(CLASS_NAME, "appendHexChars", e);
+
+ int msgID = MSGID_ATTR_SYNTAX_DN_ATTR_VALUE_DECODE_FAILURE;
+ String message = getMessage(msgID, dnString, String.valueOf(e));
+ throw new DirectoryException(ResultCode.INVALID_DN_SYNTAX,
+ message, msgID);
+ }
+ }
+
+}
diff --git a/opends/src/server/org/opends/server/types/RDNComparator.java b/opends/src/server/org/opends/server/types/RDNComparator.java
deleted file mode 100644
index e95842f..0000000
--- a/opends/src/server/org/opends/server/types/RDNComparator.java
+++ /dev/null
@@ -1,132 +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
- *
- *
- * Portions Copyright 2006 Sun Microsystems, Inc.
- */
-package org.opends.server.types;
-
-
-
-import java.util.Comparator;
-
-import static org.opends.server.loggers.Debug.*;
-
-
-
-/**
- * This class defines a <CODE>Comparator</CODE> object that may be
- * used to compare RDNs, particularly for inclusion in a sorted list.
- * The comparison will be done in order of the RDN components. It
- * will attempt to use an ordering matching rule for the associated
- * attributes (if one is provided), but will fall back on a bytewise
- * comparison of the normalized values if necessary.
- */
-public class RDNComparator
- implements Comparator<RDN>
-{
- /**
- * The fully-qualified name of this class for debugging purposes.
- */
- private static final String CLASS_NAME =
- "org.opends.server.types.RDNComparator";
-
-
-
- /**
- * Creates a new instance of this RDN comparator.
- */
- public RDNComparator()
- {
- assert debugConstructor(CLASS_NAME);
- }
-
-
-
- /**
- * Compares the provided RDNs and returns an integer value that
- * reflects the relative order between them.
- *
- * @param rdn1 The first RDN to compare.
- * @param rdn2 The second RDN to compare.
- *
- * @return A negative value if the first RDN should come before the
- * second in an ordered list, a positive value if they
- * first RDN should come after the second in an ordered
- * list, or zero if there is no difference between their
- * order (i.e., the RDNs are equal).
- */
- public int compare(RDN rdn1, RDN rdn2)
- {
- assert debugEnter(CLASS_NAME, "compare", String.valueOf(rdn1),
- String.valueOf(rdn2));
-
- AttributeType[] types1 = rdn1.getAttributeTypes();
- AttributeType[] types2 = rdn2.getAttributeTypes();
- AttributeValue[] values1 = rdn1.getAttributeValues();
- AttributeValue[] values2 = rdn2.getAttributeValues();
-
- int index = 0;
-
- while (true)
- {
- if (index < types1.length)
- {
- if (index < types1.length)
- {
- if (types1[index].equals(types2[index]))
- {
- AttributeValueComparator valueComparator =
- new AttributeValueComparator(types1[index]);
- int value = valueComparator.compare(values1[index],
- values2[index]);
- if (value != 0)
- {
- return value;
- }
- }
- else
- {
- return types1[index].getNormalizedPrimaryName().compareTo(
- types2[index].getNormalizedPrimaryName());
- }
- }
- else
- {
- return 1;
- }
- }
- else if (index < types1.length)
- {
- return -1;
- }
- else
- {
- return 0;
- }
-
- index++;
- }
- }
-}
-
diff --git a/opends/src/server/org/opends/server/types/SearchFilter.java b/opends/src/server/org/opends/server/types/SearchFilter.java
index 7dbd3ca..1d91d29 100644
--- a/opends/src/server/org/opends/server/types/SearchFilter.java
+++ b/opends/src/server/org/opends/server/types/SearchFilter.java
@@ -3558,21 +3558,23 @@
// attributes, then do so.
if (dnAttributes)
{
- for (RDN rdn : entry.getDN().getRDNComponents())
+ DN entryDN = entry.getDN();
+ int count = entryDN.getNumComponents();
+ for (int rdnIndex = 0; rdnIndex < count; rdnIndex++)
{
- AttributeType[] types = rdn.getAttributeTypes();
- AttributeValue[] values = rdn.getAttributeValues();
-
- for (int i=0; i < types.length; i++)
+ RDN rdn = entryDN.getRDN(rdnIndex);
+ int numAVAs = rdn.getNumValues();
+ for (int i=0; i < numAVAs; i++)
{
try
{
if ((attributeType == null) ||
- attributeType.equals(types[i]))
+ attributeType.equals(rdn.getAttributeType(i)))
{
+ AttributeValue v = rdn.getAttributeValue(i);
ByteString nv =
- matchingRule.normalizeValue(values[i].getValue());
+ matchingRule.normalizeValue(v.getValue());
ConditionResult r =
matchingRule.valuesMatch(nv, normalizedValue);
switch (r)
diff --git a/opends/src/server/org/opends/server/util/LDIFReader.java b/opends/src/server/org/opends/server/util/LDIFReader.java
index 679bcaf..8b6c10b 100644
--- a/opends/src/server/org/opends/server/util/LDIFReader.java
+++ b/opends/src/server/org/opends/server/util/LDIFReader.java
@@ -580,7 +580,7 @@
int length = line.length();
if (colonPos == (length-1))
{
- return new DN(new ArrayList<RDN>(0));
+ return DN.nullDN();
}
if (line.charAt(colonPos+1) == ':')
diff --git a/opends/src/server/org/opends/server/util/StaticUtils.java b/opends/src/server/org/opends/server/util/StaticUtils.java
index b886c7e..d14109b 100644
--- a/opends/src/server/org/opends/server/util/StaticUtils.java
+++ b/opends/src/server/org/opends/server/util/StaticUtils.java
@@ -1273,15 +1273,59 @@
/**
- * Indicates whether the two array lists are equal. They will be considered
- * equal if they have the same number of elements, and the corresponding
- * elements between them are equal (in the same order).
+ * Compare two byte arrays for order. Returns a negative integer,
+ * zero, or a positive integer as the first argument is less than,
+ * equal to, or greater than the second.
*
- * @param list1 The first list for which to make the determination.
- * @param list2 The second list for which to make the determination.
+ * @param a
+ * The first byte array to be compared.
+ * @param a2
+ * The second byte array to be compared.
+ * @return Returns a negative integer, zero, or a positive integer
+ * if the first byte array is less than, equal to, or greater
+ * than the second.
+ */
+ public static int compare(byte[] a, byte[] a2) {
+ if (a == a2) {
+ return 0;
+ }
+
+ if (a == null) {
+ return -1;
+ }
+
+ if (a2 == null) {
+ return 1;
+ }
+
+ int minLength = Math.min(a.length, a2.length);
+ for (int i = 0; i < minLength; i++) {
+ if (a[i] != a2[i]) {
+ if (a[i] < a2[i]) {
+ return -1;
+ } else if (a[i] > a2[i]) {
+ return 1;
+ }
+ }
+ }
+
+ return (a.length - a2.length);
+ }
+
+
+
+ /**
+ * Indicates whether the two array lists are equal. They will be
+ * considered equal if they have the same number of elements, and
+ * the corresponding elements between them are equal (in the same
+ * order).
*
- * @return <CODE>true</CODE> if the two array lists are equal, or
- * <CODE>false</CODE> if they are not.
+ * @param list1
+ * The first list for which to make the determination.
+ * @param list2
+ * The second list for which to make the determination.
+ * @return <CODE>true</CODE> if the two array lists are equal, or
+ * <CODE>false</CODE> if they are not.
*/
public static boolean listsAreEqual(List list1, List list2)
{
@@ -3259,29 +3303,28 @@
// Get the information about the RDN attributes.
RDN rdn = dn.getRDN();
- AttributeType[] rdnTypes = rdn.getAttributeTypes();
- String[] rdnNames = rdn.getAttributeNames();
- AttributeValue[] rdnValues = rdn.getAttributeValues();
-
+ int numAVAs = rdn.getNumValues();
// If there is only one RDN attribute, then see which objectclass we should
// use.
ObjectClass structuralClass;
- if (rdnTypes.length == 1)
+ if (numAVAs == 1)
{
- if (rdnTypes[0].hasName(ATTR_C))
+ AttributeType attrType = rdn.getAttributeType(0);
+
+ if (attrType.hasName(ATTR_C))
{
structuralClass = DirectoryServer.getObjectClass(OC_COUNTRY, true);
}
- else if (rdnTypes[0].hasName(ATTR_DC))
+ else if (attrType.hasName(ATTR_DC))
{
structuralClass = DirectoryServer.getObjectClass(OC_DOMAIN, true);
}
- else if (rdnTypes[0].hasName(ATTR_O))
+ else if (attrType.hasName(ATTR_O))
{
structuralClass = DirectoryServer.getObjectClass(OC_ORGANIZATION, true);
}
- else if (rdnTypes[0].hasName(ATTR_OU))
+ else if (attrType.hasName(ATTR_OU))
{
structuralClass =
DirectoryServer.getObjectClass(OC_ORGANIZATIONAL_UNIT_LC, true);
@@ -3315,11 +3358,15 @@
new LinkedHashMap<AttributeType,List<Attribute>>();
boolean extensibleObjectAdded = false;
- for (int i=0; i < rdnTypes.length; i++)
+ for (int i=0; i < numAVAs; i++)
{
+ AttributeType attrType = rdn.getAttributeType(i);
+ AttributeValue attrValue = rdn.getAttributeValue(i);
+ String attrName = rdn.getAttributeName(i);
+
// First, see if this type is allowed by the untypedObject class. If not,
// then we'll need to include the extensibleObject class.
- if ((! structuralClass.isRequiredOrOptional(rdnTypes[i])) &&
+ if ((! structuralClass.isRequiredOrOptional(attrType)) &&
(! extensibleObjectAdded))
{
ObjectClass extensibleObjectOC =
@@ -3337,36 +3384,36 @@
// Create the attribute and add it to the appropriate map.
LinkedHashSet<AttributeValue> valueSet =
new LinkedHashSet<AttributeValue>(1);
- valueSet.add(rdnValues[i]);
+ valueSet.add(attrValue);
- if (rdnTypes[i].isOperational())
+ if (attrType.isOperational())
{
- List<Attribute> attrList = operationalAttributes.get(rdnTypes[i]);
+ List<Attribute> attrList = operationalAttributes.get(attrType);
if ((attrList == null) || attrList.isEmpty())
{
attrList = new ArrayList<Attribute>(1);
- attrList.add(new Attribute(rdnTypes[i], rdnNames[i], valueSet));
- operationalAttributes.put(rdnTypes[i], attrList);
+ attrList.add(new Attribute(attrType, attrName, valueSet));
+ operationalAttributes.put(attrType, attrList);
}
else
{
Attribute attr = attrList.get(0);
- attr.getValues().add(rdnValues[i]);
+ attr.getValues().add(attrValue);
}
}
else
{
- List<Attribute> attrList = userAttributes.get(rdnTypes[i]);
+ List<Attribute> attrList = userAttributes.get(attrType);
if ((attrList == null) || attrList.isEmpty())
{
attrList = new ArrayList<Attribute>(1);
- attrList.add(new Attribute(rdnTypes[i], rdnNames[i], valueSet));
- userAttributes.put(rdnTypes[i], attrList);
+ attrList.add(new Attribute(attrType, attrName, valueSet));
+ userAttributes.put(attrType, attrList);
}
else
{
Attribute attr = attrList.get(0);
- attr.getValues().add(rdnValues[i]);
+ attr.getValues().add(attrValue);
}
}
}
diff --git a/opends/tests/unit-tests-testng/src/server/org/opends/server/backends/jeb/JebTestCase.java b/opends/tests/unit-tests-testng/src/server/org/opends/server/backends/jeb/JebTestCase.java
index 7831bc0..97ca98d 100644
--- a/opends/tests/unit-tests-testng/src/server/org/opends/server/backends/jeb/JebTestCase.java
+++ b/opends/tests/unit-tests-testng/src/server/org/opends/server/backends/jeb/JebTestCase.java
@@ -39,7 +39,6 @@
import org.opends.server.tools.makeldif.MakeLDIFInputStream;
import org.opends.server.tools.makeldif.TemplateFile;
import org.opends.server.types.DN;
-import org.opends.server.types.DNComparator;
import org.opends.server.types.LDIFImportConfig;
import org.opends.server.types.ResultCode;
import org.opends.server.DirectoryServerTestCase;
@@ -53,8 +52,7 @@
*/
@Test(groups = { "precommit", "jeb" })
public abstract class JebTestCase extends DirectoryServerTestCase {
- private DNComparator comparator = new DNComparator();
- private TreeMap<DN,Entry> entryTreeMap = new TreeMap<DN,Entry>(comparator);
+ private TreeMap<DN,Entry> entryTreeMap = new TreeMap<DN,Entry>();
int numEntries;
/**
diff --git a/opends/tests/unit-tests-testng/src/server/org/opends/server/core/BindOperationTestCase.java b/opends/tests/unit-tests-testng/src/server/org/opends/server/core/BindOperationTestCase.java
index 6714e0b..a5761ac 100644
--- a/opends/tests/unit-tests-testng/src/server/org/opends/server/core/BindOperationTestCase.java
+++ b/opends/tests/unit-tests-testng/src/server/org/opends/server/core/BindOperationTestCase.java
@@ -116,17 +116,17 @@
noControls, new ASN1OctetString("cn=Directory Manager"),
new ASN1OctetString("password")),
new BindOperation(conn, conn.nextOperationID(), conn.nextMessageID(),
- null, new DN(), new ASN1OctetString()),
+ null, DN.nullDN(), new ASN1OctetString()),
new BindOperation(conn, conn.nextOperationID(), conn.nextMessageID(),
- noControls, new DN(), new ASN1OctetString()),
+ noControls, DN.nullDN(), new ASN1OctetString()),
new BindOperation(conn, conn.nextOperationID(), conn.nextMessageID(),
null, nullDN, new ASN1OctetString()),
new BindOperation(conn, conn.nextOperationID(), conn.nextMessageID(),
noControls, nullDN, new ASN1OctetString()),
new BindOperation(conn, conn.nextOperationID(), conn.nextMessageID(),
- null, new DN(), nullOS),
+ null, DN.nullDN(), nullOS),
new BindOperation(conn, conn.nextOperationID(), conn.nextMessageID(),
- noControls, new DN(), nullOS),
+ noControls, DN.nullDN(), nullOS),
new BindOperation(conn, conn.nextOperationID(), conn.nextMessageID(),
null, nullDN, nullOS),
new BindOperation(conn, conn.nextOperationID(), conn.nextMessageID(),
@@ -187,18 +187,18 @@
noControls, nullOS, "PLAIN",
new ASN1OctetString("\u0000u:test.user\u0000password")),
new BindOperation(conn, conn.nextOperationID(), conn.nextMessageID(),
- null, new DN(), "EXTERNAL", null),
+ null, DN.nullDN(), "EXTERNAL", null),
new BindOperation(conn, conn.nextOperationID(), conn.nextMessageID(),
- noControls, new DN(), "EXTERNAL", null),
+ noControls, DN.nullDN(), "EXTERNAL", null),
new BindOperation(conn, conn.nextOperationID(), conn.nextMessageID(),
null, nullDN, "EXTERNAL", null),
new BindOperation(conn, conn.nextOperationID(), conn.nextMessageID(),
noControls, nullDN, "EXTERNAL", null),
new BindOperation(conn, conn.nextOperationID(), conn.nextMessageID(),
- null, new DN(), "PLAIN",
+ null, DN.nullDN(), "PLAIN",
new ASN1OctetString("\u0000u:test.user\u0000password")),
new BindOperation(conn, conn.nextOperationID(), conn.nextMessageID(),
- noControls, new DN(), "PLAIN",
+ noControls, DN.nullDN(), "PLAIN",
new ASN1OctetString("\u0000u:test.user\u0000password")),
new BindOperation(conn, conn.nextOperationID(), conn.nextMessageID(),
null, nullDN, "PLAIN",
@@ -608,7 +608,7 @@
new ASN1OctetString("\u0000dn:cn=Directory Manager\u0000password");
BindOperation bindOperation =
- conn.processSASLBind(new DN(), "PLAIN", saslCreds);
+ conn.processSASLBind(DN.nullDN(), "PLAIN", saslCreds);
assertEquals(bindOperation.getResultCode(), ResultCode.SUCCESS);
assertNotNull(bindOperation.getSASLAuthUserEntry());
}
@@ -676,7 +676,7 @@
new ASN1OctetString("\u0000dn:cn=Directory Manager\u0000password");
BindOperation bindOperation =
- conn.processSASLBind(new DN(), "PLAIN", saslCreds);
+ conn.processSASLBind(DN.nullDN(), "PLAIN", saslCreds);
assertEquals(bindOperation.getResultCode(), ResultCode.SUCCESS);
assertNotNull(bindOperation.getUserEntryDN());
}
@@ -721,7 +721,7 @@
new ASN1OctetString("\u0000dn:cn=Directory Manager\u0000password");
BindOperation bindOperation =
- conn.processSASLBind(new DN(), "PLAIN", saslCreds);
+ conn.processSASLBind(DN.nullDN(), "PLAIN", saslCreds);
assertEquals(bindOperation.getResultCode(), ResultCode.SUCCESS);
assertTrue(bindOperation.getProcessingStartTime() > 0);
assertTrue(bindOperation.getProcessingStopTime() >=
@@ -793,7 +793,7 @@
new ASN1OctetString("\u0000dn:cn=Directory Manager\u0000password");
BindOperation bindOperation =
- conn.processSASLBind(new DN(), "PLAIN", saslCreds);
+ conn.processSASLBind(DN.nullDN(), "PLAIN", saslCreds);
assertEquals(bindOperation.getResultCode(), ResultCode.SUCCESS);
assertNotNull(bindOperation.getResponseLogElements());
assertTrue(bindOperation.getResponseLogElements().length > 0);
@@ -867,7 +867,7 @@
new ASN1OctetString("\u0000dn:cn=Directory Manager\u0000password");
BindOperation bindOperation =
- conn.processSASLBind(new DN(), "PLAIN", saslCreds);
+ conn.processSASLBind(DN.nullDN(), "PLAIN", saslCreds);
assertEquals(bindOperation.getResultCode(), ResultCode.SUCCESS);
assertTrue(InvocationCounterPlugin.getPreParseCount() > 0);
@@ -1636,7 +1636,7 @@
BindOperation bindOperation =
new BindOperation(conn, conn.nextOperationID(), conn.nextMessageID(),
- requestControls, new DN(), new ASN1OctetString());
+ requestControls, DN.nullDN(), new ASN1OctetString());
bindOperation.run();
assertEquals(bindOperation.getResultCode(),
ResultCode.UNAVAILABLE_CRITICAL_EXTENSION);
@@ -1662,7 +1662,7 @@
BindOperation bindOperation =
new BindOperation(conn, conn.nextOperationID(), conn.nextMessageID(),
- requestControls, new DN(), "PLAIN", saslCreds);
+ requestControls, DN.nullDN(), "PLAIN", saslCreds);
bindOperation.run();
assertEquals(bindOperation.getResultCode(),
ResultCode.UNAVAILABLE_CRITICAL_EXTENSION);
@@ -1685,7 +1685,7 @@
BindOperation bindOperation =
new BindOperation(conn, conn.nextOperationID(), conn.nextMessageID(),
- requestControls, new DN(), new ASN1OctetString());
+ requestControls, DN.nullDN(), new ASN1OctetString());
bindOperation.run();
assertEquals(bindOperation.getResultCode(), ResultCode.SUCCESS);
}
@@ -1710,7 +1710,7 @@
BindOperation bindOperation =
new BindOperation(conn, conn.nextOperationID(), conn.nextMessageID(),
- requestControls, new DN(), "PLAIN", saslCreds);
+ requestControls, DN.nullDN(), "PLAIN", saslCreds);
bindOperation.run();
assertEquals(bindOperation.getResultCode(), ResultCode.SUCCESS);
}
diff --git a/opends/tests/unit-tests-testng/src/server/org/opends/server/core/DeleteOperationTestCase.java b/opends/tests/unit-tests-testng/src/server/org/opends/server/core/DeleteOperationTestCase.java
index 343ed1a..6a01495 100644
--- a/opends/tests/unit-tests-testng/src/server/org/opends/server/core/DeleteOperationTestCase.java
+++ b/opends/tests/unit-tests-testng/src/server/org/opends/server/core/DeleteOperationTestCase.java
@@ -93,9 +93,9 @@
new DeleteOperation(conn, conn.nextOperationID(), conn.nextMessageID(),
null, new ASN1OctetString("o=test")),
new DeleteOperation(conn, conn.nextOperationID(), conn.nextMessageID(),
- new ArrayList<Control>(), new DN()),
+ new ArrayList<Control>(), DN.nullDN()),
new DeleteOperation(conn, conn.nextOperationID(), conn.nextMessageID(),
- null, new DN()),
+ null, DN.nullDN()),
new DeleteOperation(conn, conn.nextOperationID(), conn.nextMessageID(),
new ArrayList<Control>(), DN.decode("o=test")),
new DeleteOperation(conn, conn.nextOperationID(), conn.nextMessageID(),
diff --git a/opends/tests/unit-tests-testng/src/server/org/opends/server/core/ModifyOperationTestCase.java b/opends/tests/unit-tests-testng/src/server/org/opends/server/core/ModifyOperationTestCase.java
index f43db15..918a95b 100644
--- a/opends/tests/unit-tests-testng/src/server/org/opends/server/core/ModifyOperationTestCase.java
+++ b/opends/tests/unit-tests-testng/src/server/org/opends/server/core/ModifyOperationTestCase.java
@@ -196,9 +196,9 @@
new Attribute("description", "foo")));
opList.add(new ModifyOperation(conn, conn.nextOperationID(),
- conn.nextMessageID(), null, new DN(), mods));
+ conn.nextMessageID(), null, DN.nullDN(), mods));
opList.add(new ModifyOperation(conn, conn.nextOperationID(),
- conn.nextMessageID(), noControls, new DN(),
+ conn.nextMessageID(), noControls, DN.nullDN(),
mods));
opList.add(new ModifyOperation(conn, conn.nextOperationID(),
conn.nextMessageID(), null,
@@ -212,9 +212,9 @@
new Attribute("description", "foo")));
opList.add(new ModifyOperation(conn, conn.nextOperationID(),
- conn.nextMessageID(), null, new DN(), mods));
+ conn.nextMessageID(), null, DN.nullDN(), mods));
opList.add(new ModifyOperation(conn, conn.nextOperationID(),
- conn.nextMessageID(), noControls, new DN(),
+ conn.nextMessageID(), noControls, DN.nullDN(),
mods));
opList.add(new ModifyOperation(conn, conn.nextOperationID(),
conn.nextMessageID(), null,
@@ -228,9 +228,9 @@
new Attribute("description", "foo")));
opList.add(new ModifyOperation(conn, conn.nextOperationID(),
- conn.nextMessageID(), null, new DN(), mods));
+ conn.nextMessageID(), null, DN.nullDN(), mods));
opList.add(new ModifyOperation(conn, conn.nextOperationID(),
- conn.nextMessageID(), noControls, new DN(),
+ conn.nextMessageID(), noControls, DN.nullDN(),
mods));
opList.add(new ModifyOperation(conn, conn.nextOperationID(),
conn.nextMessageID(), null,
@@ -246,9 +246,9 @@
new Attribute("description", "bar")));
opList.add(new ModifyOperation(conn, conn.nextOperationID(),
- conn.nextMessageID(), null, new DN(), mods));
+ conn.nextMessageID(), null, DN.nullDN(), mods));
opList.add(new ModifyOperation(conn, conn.nextOperationID(),
- conn.nextMessageID(), noControls, new DN(),
+ conn.nextMessageID(), noControls, DN.nullDN(),
mods));
opList.add(new ModifyOperation(conn, conn.nextOperationID(),
conn.nextMessageID(), null,
@@ -264,9 +264,9 @@
new Attribute("cn", "bar")));
opList.add(new ModifyOperation(conn, conn.nextOperationID(),
- conn.nextMessageID(), null, new DN(), mods));
+ conn.nextMessageID(), null, DN.nullDN(), mods));
opList.add(new ModifyOperation(conn, conn.nextOperationID(),
- conn.nextMessageID(), noControls, new DN(),
+ conn.nextMessageID(), noControls, DN.nullDN(),
mods));
opList.add(new ModifyOperation(conn, conn.nextOperationID(),
conn.nextMessageID(), null,
@@ -375,7 +375,7 @@
new Attribute("description", "foo")));
ModifyOperation modifyOperation =
new ModifyOperation(conn, conn.nextOperationID(), conn.nextMessageID(),
- null, new DN(), mods);
+ null, DN.nullDN(), mods);
assertNotNull(modifyOperation.getEntryDN());
}
@@ -400,7 +400,7 @@
new Attribute("description", "foo")));
ModifyOperation modifyOperation =
new ModifyOperation(conn, conn.nextOperationID(), conn.nextMessageID(),
- null, new DN(), mods);
+ null, DN.nullDN(), mods);
assertNotNull(modifyOperation.getEntryDN());
modifyOperation.setRawEntryDN(new ASN1OctetString("ou=Users,o=test"));
diff --git a/opends/tests/unit-tests-testng/src/server/org/opends/server/core/TestModifyDNOperation.java b/opends/tests/unit-tests-testng/src/server/org/opends/server/core/TestModifyDNOperation.java
index ae01530..3f57605 100644
--- a/opends/tests/unit-tests-testng/src/server/org/opends/server/core/TestModifyDNOperation.java
+++ b/opends/tests/unit-tests-testng/src/server/org/opends/server/core/TestModifyDNOperation.java
@@ -241,8 +241,10 @@
Entry newEntry = DirectoryServer.getEntry(DN.decode(
"uid=user.test0,ou=People,dc=example,dc=com"));
assertNotNull(newEntry);
- for(AttributeType attribute : newEntry.getDN().getRDN().getAttributeTypes())
+ RDN rdn = newEntry.getDN().getRDN();
+ for (int i = 0; i < rdn.getNumValues(); i++)
{
+ AttributeType attribute = rdn.getAttributeType(i);
assertTrue(newEntry.hasValue(attribute, null, new AttributeValue(attribute, "user.0")));
assertTrue(newEntry.hasValue(attribute, null, new AttributeValue(attribute, "user.test0")));
}
@@ -264,8 +266,10 @@
newEntry = DirectoryServer.getEntry(DN.decode(
"uid=user.0,ou=People,dc=example,dc=com"));
assertNotNull(newEntry);
- for(AttributeType attribute : newEntry.getDN().getRDN().getAttributeTypes())
+ rdn = newEntry.getDN().getRDN();
+ for (int i = 0; i < rdn.getNumValues(); i++)
{
+ AttributeType attribute = rdn.getAttributeType(i);
assertTrue(newEntry.hasValue(attribute, null, new AttributeValue(attribute, "user.0")));
assertFalse(newEntry.hasValue(attribute, null, new AttributeValue(attribute, "user.test0")));
}
@@ -296,8 +300,10 @@
Entry newEntry = DirectoryServer.getEntry(DN.decode(
"uid=user.test0,ou=People,dc=example,dc=com"));
assertNotNull(newEntry);
- for(AttributeType attribute : newEntry.getDN().getRDN().getAttributeTypes())
+ RDN rdn = newEntry.getDN().getRDN();
+ for (int i = 0; i < rdn.getNumValues(); i++)
{
+ AttributeType attribute = rdn.getAttributeType(i);
assertTrue(newEntry.hasValue(attribute, null, new AttributeValue(attribute, "user.0")));
assertTrue(newEntry.hasValue(attribute, null, new AttributeValue(attribute, "user.test0")));
}
@@ -319,8 +325,10 @@
newEntry = DirectoryServer.getEntry(DN.decode(
"uid=user.0,ou=People,dc=example,dc=com"));
assertNotNull(newEntry);
- for(AttributeType attribute : newEntry.getDN().getRDN().getAttributeTypes())
+ rdn = newEntry.getDN().getRDN();
+ for (int i = 0; i < rdn.getNumValues(); i++)
{
+ AttributeType attribute = rdn.getAttributeType(i);
assertTrue(newEntry.hasValue(attribute, null, new AttributeValue(attribute, "user.0")));
assertFalse(newEntry.hasValue(attribute, null, new AttributeValue(attribute, "user.test0")));
}
@@ -351,8 +359,10 @@
Entry newEntry = DirectoryServer.getEntry(DN.decode(
"uid=user.test0,ou=People,dc=example,dc=com"));
assertNotNull(newEntry);
- for(AttributeType attribute : newEntry.getDN().getRDN().getAttributeTypes())
+ RDN rdn = newEntry.getDN().getRDN();
+ for (int i = 0; i < rdn.getNumValues(); i++)
{
+ AttributeType attribute = rdn.getAttributeType(i);
assertFalse(newEntry.hasValue(attribute, null, new AttributeValue(attribute, "user.0")));
assertTrue(newEntry.hasValue(attribute, null, new AttributeValue(attribute, "user.test0")));
}
@@ -374,8 +384,10 @@
newEntry = DirectoryServer.getEntry(DN.decode(
"uid=user.0,ou=People,dc=example,dc=com"));
assertNotNull(newEntry);
- for(AttributeType attribute : newEntry.getDN().getRDN().getAttributeTypes())
+ rdn = newEntry.getDN().getRDN();
+ for (int i = 0; i < rdn.getNumValues(); i++)
{
+ AttributeType attribute = rdn.getAttributeType(i);
assertTrue(newEntry.hasValue(attribute, null, new AttributeValue(attribute, "user.0")));
assertFalse(newEntry.hasValue(attribute, null, new AttributeValue(attribute, "user.test0")));
}
@@ -406,8 +418,10 @@
Entry newEntry = DirectoryServer.getEntry(DN.decode(
"uid=user.test0,ou=People,dc=example,dc=com"));
assertNotNull(newEntry);
- for(AttributeType attribute : newEntry.getDN().getRDN().getAttributeTypes())
+ RDN rdn = newEntry.getDN().getRDN();
+ for (int i = 0; i < rdn.getNumValues(); i++)
{
+ AttributeType attribute = rdn.getAttributeType(i);
assertFalse(newEntry.hasValue(attribute, null, new AttributeValue(attribute, "user.0")));
assertTrue(newEntry.hasValue(attribute, null, new AttributeValue(attribute, "user.test0")));
}
@@ -429,8 +443,10 @@
newEntry = DirectoryServer.getEntry(DN.decode(
"uid=user.0,ou=People,dc=example,dc=com"));
assertNotNull(newEntry);
- for(AttributeType attribute : newEntry.getDN().getRDN().getAttributeTypes())
+ rdn = newEntry.getDN().getRDN();
+ for (int i = 0; i < rdn.getNumValues(); i++)
{
+ AttributeType attribute = rdn.getAttributeType(i);
assertTrue(newEntry.hasValue(attribute, null, new AttributeValue(attribute, "user.0")));
assertFalse(newEntry.hasValue(attribute, null, new AttributeValue(attribute, "user.test0")));
}
@@ -461,8 +477,10 @@
Entry newEntry = DirectoryServer.getEntry(DN.decode(
"uid=user.test0,dc=example,dc=com"));
assertNotNull(newEntry);
- for(AttributeType attribute : newEntry.getDN().getRDN().getAttributeTypes())
+ RDN rdn = newEntry.getDN().getRDN();
+ for (int i = 0; i < rdn.getNumValues(); i++)
{
+ AttributeType attribute = rdn.getAttributeType(i);
assertFalse(newEntry.hasValue(attribute, null, new AttributeValue(attribute, "user.0")));
assertTrue(newEntry.hasValue(attribute, null, new AttributeValue(attribute, "user.test0")));
}
@@ -484,8 +502,10 @@
newEntry = DirectoryServer.getEntry(DN.decode(
"uid=user.0,ou=People,dc=example,dc=com"));
assertNotNull(newEntry);
- for(AttributeType attribute : newEntry.getDN().getRDN().getAttributeTypes())
+ rdn = newEntry.getDN().getRDN();
+ for (int i = 0; i < rdn.getNumValues(); i++)
{
+ AttributeType attribute = rdn.getAttributeType(i);
assertTrue(newEntry.hasValue(attribute, null, new AttributeValue(attribute, "user.0")));
assertFalse(newEntry.hasValue(attribute, null, new AttributeValue(attribute, "user.test0")));
}
@@ -516,8 +536,10 @@
Entry newEntry = DirectoryServer.getEntry(DN.decode(
"uid=user.test0,dc=example,dc=com"));
assertNotNull(newEntry);
- for(AttributeType attribute : newEntry.getDN().getRDN().getAttributeTypes())
+ RDN rdn = newEntry.getDN().getRDN();
+ for (int i = 0; i < rdn.getNumValues(); i++)
{
+ AttributeType attribute = rdn.getAttributeType(i);
assertFalse(newEntry.hasValue(attribute, null, new AttributeValue(attribute, "user.0")));
assertTrue(newEntry.hasValue(attribute, null, new AttributeValue(attribute, "user.test0")));
}
@@ -539,8 +561,10 @@
newEntry = DirectoryServer.getEntry(DN.decode(
"uid=user.0,ou=People,dc=example,dc=com"));
assertNotNull(newEntry);
- for(AttributeType attribute : newEntry.getDN().getRDN().getAttributeTypes())
+ rdn = newEntry.getDN().getRDN();
+ for (int i = 0; i < rdn.getNumValues(); i++)
{
+ AttributeType attribute = rdn.getAttributeType(i);
assertTrue(newEntry.hasValue(attribute, null, new AttributeValue(attribute, "user.0")));
assertFalse(newEntry.hasValue(attribute, null, new AttributeValue(attribute, "user.test0")));
}
@@ -798,8 +822,10 @@
Entry newEntry = DirectoryServer.getEntry(DN.decode(
"uid=user.test0,ou=People,dc=example,dc=com"));
assertNotNull(newEntry);
- for(AttributeType attribute : newEntry.getDN().getRDN().getAttributeTypes())
+ RDN rdn = newEntry.getDN().getRDN();
+ for (int i = 0; i < rdn.getNumValues(); i++)
{
+ AttributeType attribute = rdn.getAttributeType(i);
assertTrue(newEntry.hasValue(attribute, null, new AttributeValue(attribute, "user.0")));
assertTrue(newEntry.hasValue(attribute, null, new AttributeValue(attribute, "user.test0")));
}
@@ -821,8 +847,10 @@
newEntry = DirectoryServer.getEntry(DN.decode(
"uid=user.0,ou=People,dc=example,dc=com"));
assertNotNull(newEntry);
- for(AttributeType attribute : newEntry.getDN().getRDN().getAttributeTypes())
+ rdn = newEntry.getDN().getRDN();
+ for (int i = 0; i < rdn.getNumValues(); i++)
{
+ AttributeType attribute = rdn.getAttributeType(i);
assertTrue(newEntry.hasValue(attribute, null, new AttributeValue(attribute, "user.0")));
assertFalse(newEntry.hasValue(attribute, null, new AttributeValue(attribute, "user.test0")));
}
@@ -856,8 +884,10 @@
Entry newEntry = DirectoryServer.getEntry(DN.decode(
"uid=user.test0,ou=People,dc=example,dc=com"));
assertNotNull(newEntry);
- for(AttributeType attribute : newEntry.getDN().getRDN().getAttributeTypes())
+ RDN rdn = newEntry.getDN().getRDN();
+ for (int i = 0; i < rdn.getNumValues(); i++)
{
+ AttributeType attribute = rdn.getAttributeType(i);
assertTrue(newEntry.hasValue(attribute, null, new AttributeValue(attribute, "user.0")));
assertTrue(newEntry.hasValue(attribute, null, new AttributeValue(attribute, "user.test0")));
}
@@ -879,8 +909,10 @@
newEntry = DirectoryServer.getEntry(DN.decode(
"uid=user.0,ou=People,dc=example,dc=com"));
assertNotNull(newEntry);
- for(AttributeType attribute : newEntry.getDN().getRDN().getAttributeTypes())
+ rdn = newEntry.getDN().getRDN();
+ for (int i = 0; i < rdn.getNumValues(); i++)
{
+ AttributeType attribute = rdn.getAttributeType(i);
assertTrue(newEntry.hasValue(attribute, null, new AttributeValue(attribute, "user.0")));
assertFalse(newEntry.hasValue(attribute, null, new AttributeValue(attribute, "user.test0")));
}
@@ -941,8 +973,10 @@
Entry newEntry = DirectoryServer.getEntry(DN.decode(
"uid=user.test0,ou=People,dc=example,dc=com"));
assertNotNull(newEntry);
- for(AttributeType attribute : newEntry.getDN().getRDN().getAttributeTypes())
+ RDN rdn = newEntry.getDN().getRDN();
+ for (int i = 0; i < rdn.getNumValues(); i++)
{
+ AttributeType attribute = rdn.getAttributeType(i);
assertTrue(newEntry.hasValue(attribute, null, new AttributeValue(attribute, "user.0")));
assertTrue(newEntry.hasValue(attribute, null, new AttributeValue(attribute, "user.test0")));
}
@@ -964,8 +998,10 @@
newEntry = DirectoryServer.getEntry(DN.decode(
"uid=user.0,ou=People,dc=example,dc=com"));
assertNotNull(newEntry);
- for(AttributeType attribute : newEntry.getDN().getRDN().getAttributeTypes())
+ rdn = newEntry.getDN().getRDN();
+ for (int i = 0; i < rdn.getNumValues(); i++)
{
+ AttributeType attribute = rdn.getAttributeType(i);
assertTrue(newEntry.hasValue(attribute, null, new AttributeValue(attribute, "user.0")));
assertFalse(newEntry.hasValue(attribute, null, new AttributeValue(attribute, "user.test0")));
}
diff --git a/opends/tests/unit-tests-testng/src/server/org/opends/server/core/TestRFC3672SubtreeSpecification.java b/opends/tests/unit-tests-testng/src/server/org/opends/server/core/TestRFC3672SubtreeSpecification.java
index 17b93d3..3ac81cb 100644
--- a/opends/tests/unit-tests-testng/src/server/org/opends/server/core/TestRFC3672SubtreeSpecification.java
+++ b/opends/tests/unit-tests-testng/src/server/org/opends/server/core/TestRFC3672SubtreeSpecification.java
@@ -40,7 +40,7 @@
SubtreeSpecificationTestCase {
// Cached root DN.
- private DN rootDN = new DN();
+ private DN rootDN = DN.nullDN();
/**
* Tests the {@link RFC3672SubtreeSpecification#valueOf(DN, String)}
diff --git a/opends/tests/unit-tests-testng/src/server/org/opends/server/core/TestRelativeSubtreeSpecification.java b/opends/tests/unit-tests-testng/src/server/org/opends/server/core/TestRelativeSubtreeSpecification.java
index 748126f..a6290b3 100644
--- a/opends/tests/unit-tests-testng/src/server/org/opends/server/core/TestRelativeSubtreeSpecification.java
+++ b/opends/tests/unit-tests-testng/src/server/org/opends/server/core/TestRelativeSubtreeSpecification.java
@@ -44,7 +44,7 @@
SubtreeSpecificationTestCase {
// Cached root DN.
- private DN rootDN = new DN();
+ private DN rootDN = DN.nullDN();
/**
* Tests the {@link RelativeSubtreeSpecification#valueOf(DN, String)}
diff --git a/opends/tests/unit-tests-testng/src/server/org/opends/server/extensions/AnonymousSASLMechanismHandlerTestCase.java b/opends/tests/unit-tests-testng/src/server/org/opends/server/extensions/AnonymousSASLMechanismHandlerTestCase.java
index b01df89..6181470 100644
--- a/opends/tests/unit-tests-testng/src/server/org/opends/server/extensions/AnonymousSASLMechanismHandlerTestCase.java
+++ b/opends/tests/unit-tests-testng/src/server/org/opends/server/extensions/AnonymousSASLMechanismHandlerTestCase.java
@@ -139,7 +139,7 @@
InternalClientConnection.getRootConnection();
BindOperation bindOperation =
new BindOperation(conn, conn.nextOperationID(), conn.nextMessageID(),
- new ArrayList<Control>(), new DN(),
+ new ArrayList<Control>(), DN.nullDN(),
SASL_MECHANISM_ANONYMOUS, null);
handler.processSASLBind(bindOperation);
assertEquals(bindOperation.getResultCode(), ResultCode.SUCCESS);
@@ -166,7 +166,7 @@
InternalClientConnection.getRootConnection();
BindOperation bindOperation =
new BindOperation(conn, conn.nextOperationID(), conn.nextMessageID(),
- new ArrayList<Control>(), new DN(),
+ new ArrayList<Control>(), DN.nullDN(),
SASL_MECHANISM_ANONYMOUS, new ASN1OctetString());
handler.processSASLBind(bindOperation);
assertEquals(bindOperation.getResultCode(), ResultCode.SUCCESS);
@@ -192,7 +192,7 @@
InternalClientConnection.getRootConnection();
BindOperation bindOperation =
new BindOperation(conn, conn.nextOperationID(), conn.nextMessageID(),
- new ArrayList<Control>(), new DN(),
+ new ArrayList<Control>(), DN.nullDN(),
SASL_MECHANISM_ANONYMOUS,
new ASN1OctetString("Internal Trace String"));
handler.processSASLBind(bindOperation);
diff --git a/opends/tests/unit-tests-testng/src/server/org/opends/server/extensions/CRAMMD5SASLMechanismHandlerTestCase.java b/opends/tests/unit-tests-testng/src/server/org/opends/server/extensions/CRAMMD5SASLMechanismHandlerTestCase.java
index 64054b0..c46c4d0 100644
--- a/opends/tests/unit-tests-testng/src/server/org/opends/server/extensions/CRAMMD5SASLMechanismHandlerTestCase.java
+++ b/opends/tests/unit-tests-testng/src/server/org/opends/server/extensions/CRAMMD5SASLMechanismHandlerTestCase.java
@@ -688,7 +688,7 @@
InternalClientConnection conn =
new InternalClientConnection(new AuthenticationInfo());
BindOperation bindOperation =
- conn.processSASLBind(new DN(), SASL_MECHANISM_CRAM_MD5,
+ conn.processSASLBind(DN.nullDN(), SASL_MECHANISM_CRAM_MD5,
new ASN1OctetString("invalid"));
assertFalse(bindOperation.getResultCode() == ResultCode.SUCCESS);
}
@@ -708,12 +708,12 @@
InternalClientConnection conn =
new InternalClientConnection(new AuthenticationInfo());
BindOperation bindOperation =
- conn.processSASLBind(new DN(), SASL_MECHANISM_CRAM_MD5, null);
+ conn.processSASLBind(DN.nullDN(), SASL_MECHANISM_CRAM_MD5, null);
assertEquals(bindOperation.getResultCode(),
ResultCode.SASL_BIND_IN_PROGRESS);
bindOperation =
- conn.processSASLBind(new DN(), SASL_MECHANISM_CRAM_MD5,
+ conn.processSASLBind(DN.nullDN(), SASL_MECHANISM_CRAM_MD5,
new ASN1OctetString("malformed"));
assertFalse(bindOperation.getResultCode() == ResultCode.SUCCESS);
}
@@ -733,14 +733,14 @@
InternalClientConnection conn =
new InternalClientConnection(new AuthenticationInfo());
BindOperation bindOperation =
- conn.processSASLBind(new DN(), SASL_MECHANISM_CRAM_MD5, null);
+ conn.processSASLBind(DN.nullDN(), SASL_MECHANISM_CRAM_MD5, null);
assertEquals(bindOperation.getResultCode(),
ResultCode.SASL_BIND_IN_PROGRESS);
ASN1OctetString creds =
new ASN1OctetString("dn:cn=Directory Manager malformeddigest");
bindOperation =
- conn.processSASLBind(new DN(), SASL_MECHANISM_CRAM_MD5, creds);
+ conn.processSASLBind(DN.nullDN(), SASL_MECHANISM_CRAM_MD5, creds);
assertFalse(bindOperation.getResultCode() == ResultCode.SUCCESS);
}
@@ -760,7 +760,7 @@
InternalClientConnection conn =
new InternalClientConnection(new AuthenticationInfo());
BindOperation bindOperation =
- conn.processSASLBind(new DN(), SASL_MECHANISM_CRAM_MD5, null);
+ conn.processSASLBind(DN.nullDN(), SASL_MECHANISM_CRAM_MD5, null);
assertEquals(bindOperation.getResultCode(),
ResultCode.SASL_BIND_IN_PROGRESS);
@@ -768,7 +768,7 @@
new ASN1OctetString("dn:cn=Directory Manager " +
"malformedcredswiththerightlength");
bindOperation =
- conn.processSASLBind(new DN(), SASL_MECHANISM_CRAM_MD5, creds);
+ conn.processSASLBind(DN.nullDN(), SASL_MECHANISM_CRAM_MD5, creds);
assertFalse(bindOperation.getResultCode() == ResultCode.SUCCESS);
}
}
diff --git a/opends/tests/unit-tests-testng/src/server/org/opends/server/extensions/DigestMD5SASLMechanismHandlerTestCase.java b/opends/tests/unit-tests-testng/src/server/org/opends/server/extensions/DigestMD5SASLMechanismHandlerTestCase.java
index 436375b..3b5429d 100644
--- a/opends/tests/unit-tests-testng/src/server/org/opends/server/extensions/DigestMD5SASLMechanismHandlerTestCase.java
+++ b/opends/tests/unit-tests-testng/src/server/org/opends/server/extensions/DigestMD5SASLMechanismHandlerTestCase.java
@@ -823,7 +823,7 @@
InternalClientConnection conn =
new InternalClientConnection(new AuthenticationInfo());
BindOperation bindOperation =
- conn.processSASLBind(new DN(), SASL_MECHANISM_DIGEST_MD5,
+ conn.processSASLBind(DN.nullDN(), SASL_MECHANISM_DIGEST_MD5,
new ASN1OctetString("invalid"));
assertFalse(bindOperation.getResultCode() == ResultCode.SUCCESS);
}
@@ -843,12 +843,12 @@
InternalClientConnection conn =
new InternalClientConnection(new AuthenticationInfo());
BindOperation bindOperation =
- conn.processSASLBind(new DN(), SASL_MECHANISM_DIGEST_MD5, null);
+ conn.processSASLBind(DN.nullDN(), SASL_MECHANISM_DIGEST_MD5, null);
assertEquals(bindOperation.getResultCode(),
ResultCode.SASL_BIND_IN_PROGRESS);
bindOperation =
- conn.processSASLBind(new DN(), SASL_MECHANISM_DIGEST_MD5,
+ conn.processSASLBind(DN.nullDN(), SASL_MECHANISM_DIGEST_MD5,
new ASN1OctetString("malformed"));
assertFalse(bindOperation.getResultCode() == ResultCode.SUCCESS);
}
diff --git a/opends/tests/unit-tests-testng/src/server/org/opends/server/monitors/InternalSearchMonitorTestCase.java b/opends/tests/unit-tests-testng/src/server/org/opends/server/monitors/InternalSearchMonitorTestCase.java
index 81daa25..e4f0458 100644
--- a/opends/tests/unit-tests-testng/src/server/org/opends/server/monitors/InternalSearchMonitorTestCase.java
+++ b/opends/tests/unit-tests-testng/src/server/org/opends/server/monitors/InternalSearchMonitorTestCase.java
@@ -140,10 +140,10 @@
throws Exception
{
AttributeType cnType = DirectoryServer.getAttributeType(ATTR_COMMON_NAME);
- RDN[] components = new RDN[2];
- components[0] = new RDN(cnType, new AttributeValue(cnType, monitorName));
- components[1] = new RDN(cnType, new AttributeValue(cnType, "monitor"));
- DN monitorDN = new DN(components);
+
+ RDN rdn0 = RDN.create(cnType, new AttributeValue(cnType, monitorName));
+ RDN rdn1 = RDN.create(cnType, new AttributeValue(cnType, "monitor"));
+ DN monitorDN = DN.create(rdn0, rdn1);
InternalClientConnection conn =
InternalClientConnection.getRootConnection();
diff --git a/opends/tests/unit-tests-testng/src/server/org/opends/server/protocols/internal/InternalClientConnectionTestCase.java b/opends/tests/unit-tests-testng/src/server/org/opends/server/protocols/internal/InternalClientConnectionTestCase.java
index ed229f7..3bb47c9 100644
--- a/opends/tests/unit-tests-testng/src/server/org/opends/server/protocols/internal/InternalClientConnectionTestCase.java
+++ b/opends/tests/unit-tests-testng/src/server/org/opends/server/protocols/internal/InternalClientConnectionTestCase.java
@@ -449,7 +449,7 @@
InternalClientConnection conn =
InternalClientConnection.getRootConnection();
BindOperation bindOperation =
- conn.processSASLBind(new DN(), "PLAIN", creds);
+ conn.processSASLBind(DN.nullDN(), "PLAIN", creds);
assertEquals(bindOperation.getResultCode(), ResultCode.SUCCESS);
}
@@ -902,7 +902,7 @@
InternalClientConnection conn =
InternalClientConnection.getRootConnection();
InternalSearchOperation searchOperation =
- conn.processSearch(new DN(), SearchScope.BASE_OBJECT,
+ conn.processSearch(DN.nullDN(), SearchScope.BASE_OBJECT,
SearchFilter.createFilterFromString("(objectClass=*)"));
assertEquals(searchOperation.getResultCode(), ResultCode.SUCCESS);
assertFalse(searchOperation.getSearchEntries().isEmpty());
@@ -924,7 +924,7 @@
InternalClientConnection conn =
InternalClientConnection.getRootConnection();
InternalSearchOperation searchOperation =
- conn.processSearch(new DN(), SearchScope.BASE_OBJECT,
+ conn.processSearch(DN.nullDN(), SearchScope.BASE_OBJECT,
DereferencePolicy.NEVER_DEREF_ALIASES, 0, 0, false,
SearchFilter.createFilterFromString("(objectClass=*)"),
new LinkedHashSet<String>());
@@ -952,7 +952,7 @@
InternalClientConnection conn =
InternalClientConnection.getRootConnection();
InternalSearchOperation searchOperation =
- conn.processSearch(new DN(), SearchScope.BASE_OBJECT,
+ conn.processSearch(DN.nullDN(), SearchScope.BASE_OBJECT,
DereferencePolicy.NEVER_DEREF_ALIASES, 0, 0, false,
SearchFilter.createFilterFromString("(objectClass=*)"),
new LinkedHashSet<String>(), searchListener);
diff --git a/opends/tests/unit-tests-testng/src/server/org/opends/server/protocols/internal/InternalSearchOperationTestCase.java b/opends/tests/unit-tests-testng/src/server/org/opends/server/protocols/internal/InternalSearchOperationTestCase.java
index 17144b7..8464003 100644
--- a/opends/tests/unit-tests-testng/src/server/org/opends/server/protocols/internal/InternalSearchOperationTestCase.java
+++ b/opends/tests/unit-tests-testng/src/server/org/opends/server/protocols/internal/InternalSearchOperationTestCase.java
@@ -133,7 +133,7 @@
InternalClientConnection.getRootConnection();
new InternalSearchOperation(conn, conn.nextOperationID(),
conn.nextMessageID(), new ArrayList<Control>(),
- new DN(), SearchScope.BASE_OBJECT,
+ DN.nullDN(), SearchScope.BASE_OBJECT,
DereferencePolicy.NEVER_DEREF_ALIASES, 0, 0,
false, searchFilter,
new LinkedHashSet<String>(), null);
@@ -158,7 +158,7 @@
InternalClientConnection.getRootConnection();
new InternalSearchOperation(conn, conn.nextOperationID(),
conn.nextMessageID(), new ArrayList<Control>(),
- new DN(), SearchScope.BASE_OBJECT,
+ DN.nullDN(), SearchScope.BASE_OBJECT,
DereferencePolicy.NEVER_DEREF_ALIASES, 0, 0,
false, searchFilter,
new LinkedHashSet<String>(),
diff --git a/opends/tests/unit-tests-testng/src/server/org/opends/server/protocols/ldap/TestAddResponseProtocolOp.java b/opends/tests/unit-tests-testng/src/server/org/opends/server/protocols/ldap/TestAddResponseProtocolOp.java
index 7021b77..e66a856 100644
--- a/opends/tests/unit-tests-testng/src/server/org/opends/server/protocols/ldap/TestAddResponseProtocolOp.java
+++ b/opends/tests/unit-tests-testng/src/server/org/opends/server/protocols/ldap/TestAddResponseProtocolOp.java
@@ -82,11 +82,9 @@
AttributeValue attributeValue = new AttributeValue(attribute, "testValue");
- RDN rdn = new RDN(attribute, attributeValue);
-
- RDN[] rdns = {rdn};
-
- dn = new DN(rdns);
+ RDN rdn = RDN.create(attribute, attributeValue);
+
+ dn = DN.create(rdn);
}
/**
@@ -295,7 +293,7 @@
//Test case for a full encode decode operation with an empty DN params.
- addEncoded = new AddResponseProtocolOp(resultCode, resultMsg, new DN(),
+ addEncoded = new AddResponseProtocolOp(resultCode, resultMsg, DN.nullDN(),
referralURLs);
element = addEncoded.encode();
addDecoded = (AddResponseProtocolOp)AddResponseProtocolOp.decode(element);
diff --git a/opends/tests/unit-tests-testng/src/server/org/opends/server/protocols/ldap/TestCompareResponseProtocolOp.java b/opends/tests/unit-tests-testng/src/server/org/opends/server/protocols/ldap/TestCompareResponseProtocolOp.java
index c34b36f..79a1d3e 100644
--- a/opends/tests/unit-tests-testng/src/server/org/opends/server/protocols/ldap/TestCompareResponseProtocolOp.java
+++ b/opends/tests/unit-tests-testng/src/server/org/opends/server/protocols/ldap/TestCompareResponseProtocolOp.java
@@ -84,11 +84,8 @@
AttributeValue attributeValue = new AttributeValue(attribute, "testValue");
- RDN rdn = new RDN(attribute, attributeValue);
-
- RDN[] rdns = {rdn};
-
- dn = new DN(rdns);
+ RDN rdn = RDN.create(attribute, attributeValue);
+ dn = DN.create(rdn);
}
/**
@@ -303,7 +300,7 @@
//Test case for a full encode decode operation with an empty DN params.
- deleteEncoded = new CompareResponseProtocolOp(resultCode, resultMsg, new DN(),
+ deleteEncoded = new CompareResponseProtocolOp(resultCode, resultMsg, DN.nullDN(),
referralURLs);
element = deleteEncoded.encode();
deleteDecoded = (CompareResponseProtocolOp)CompareResponseProtocolOp.decode(
diff --git a/opends/tests/unit-tests-testng/src/server/org/opends/server/protocols/ldap/TestDeleteResponseProtocolOp.java b/opends/tests/unit-tests-testng/src/server/org/opends/server/protocols/ldap/TestDeleteResponseProtocolOp.java
index bb5f2af..7988f13 100644
--- a/opends/tests/unit-tests-testng/src/server/org/opends/server/protocols/ldap/TestDeleteResponseProtocolOp.java
+++ b/opends/tests/unit-tests-testng/src/server/org/opends/server/protocols/ldap/TestDeleteResponseProtocolOp.java
@@ -82,11 +82,8 @@
AttributeValue attributeValue = new AttributeValue(attribute, "testValue");
- RDN rdn = new RDN(attribute, attributeValue);
-
- RDN[] rdns = {rdn};
-
- dn = new DN(rdns);
+ RDN rdn = RDN.create(attribute, attributeValue);
+ dn = DN.create(rdn);
}
/**
@@ -301,7 +298,7 @@
//Test case for a full encode decode operation with an empty DN params.
- deleteEncoded = new DeleteResponseProtocolOp(resultCode, resultMsg, new DN(),
+ deleteEncoded = new DeleteResponseProtocolOp(resultCode, resultMsg, DN.nullDN(),
referralURLs);
element = deleteEncoded.encode();
deleteDecoded = (DeleteResponseProtocolOp)DeleteResponseProtocolOp.decode(
diff --git a/opends/tests/unit-tests-testng/src/server/org/opends/server/protocols/ldap/TestModifyDNResponseProtocolOp.java b/opends/tests/unit-tests-testng/src/server/org/opends/server/protocols/ldap/TestModifyDNResponseProtocolOp.java
index 0001437..dfed6c8 100644
--- a/opends/tests/unit-tests-testng/src/server/org/opends/server/protocols/ldap/TestModifyDNResponseProtocolOp.java
+++ b/opends/tests/unit-tests-testng/src/server/org/opends/server/protocols/ldap/TestModifyDNResponseProtocolOp.java
@@ -84,11 +84,8 @@
AttributeValue attributeValue = new AttributeValue(attribute, "testValue");
- RDN rdn = new RDN(attribute, attributeValue);
-
- RDN[] rdns = {rdn};
-
- dn = new DN(rdns);
+ RDN rdn = RDN.create(attribute, attributeValue);
+ dn = DN.create(rdn);
}
/**
@@ -303,7 +300,7 @@
//Test case for a full encode decode operation with an empty DN params.
- deleteEncoded = new ModifyDNResponseProtocolOp(resultCode, resultMsg, new DN(),
+ deleteEncoded = new ModifyDNResponseProtocolOp(resultCode, resultMsg, DN.nullDN(),
referralURLs);
element = deleteEncoded.encode();
deleteDecoded = (ModifyDNResponseProtocolOp)ModifyDNResponseProtocolOp.decode(
diff --git a/opends/tests/unit-tests-testng/src/server/org/opends/server/protocols/ldap/TestModifyResponseProtocolOp.java b/opends/tests/unit-tests-testng/src/server/org/opends/server/protocols/ldap/TestModifyResponseProtocolOp.java
index d4c3380..e5e67cf 100644
--- a/opends/tests/unit-tests-testng/src/server/org/opends/server/protocols/ldap/TestModifyResponseProtocolOp.java
+++ b/opends/tests/unit-tests-testng/src/server/org/opends/server/protocols/ldap/TestModifyResponseProtocolOp.java
@@ -84,11 +84,8 @@
AttributeValue attributeValue = new AttributeValue(attribute, "testValue");
- RDN rdn = new RDN(attribute, attributeValue);
-
- RDN[] rdns = {rdn};
-
- dn = new DN(rdns);
+ RDN rdn = RDN.create(attribute, attributeValue);
+ dn = DN.create(rdn);
}
/**
@@ -303,7 +300,7 @@
//Test case for a full encode decode operation with an empty DN params.
- modifyEncoded = new ModifyResponseProtocolOp(resultCode, resultMsg, new DN(),
+ modifyEncoded = new ModifyResponseProtocolOp(resultCode, resultMsg, DN.nullDN(),
referralURLs);
element = modifyEncoded.encode();
modifyDecoded = (ModifyResponseProtocolOp)ModifyResponseProtocolOp.decode(
diff --git a/opends/tests/unit-tests-testng/src/server/org/opends/server/types/TestDN.java b/opends/tests/unit-tests-testng/src/server/org/opends/server/types/TestDN.java
index 6490cd2..34bca38 100644
--- a/opends/tests/unit-tests-testng/src/server/org/opends/server/types/TestDN.java
+++ b/opends/tests/unit-tests-testng/src/server/org/opends/server/types/TestDN.java
@@ -26,16 +26,18 @@
*/
package org.opends.server.types;
+
+
import static org.testng.Assert.*;
import org.opends.server.TestCaseUtils;
+import org.opends.server.core.DirectoryServer;
import org.opends.server.protocols.asn1.ASN1OctetString;
import org.testng.annotations.DataProvider;
import org.testng.annotations.Test;
import org.testng.annotations.BeforeClass;
-import org.testng.annotations.AfterClass;
-import java.util.Arrays;
+
/**
* This class defines a set of tests for the org.opends.server.core.DN
@@ -50,45 +52,73 @@
@DataProvider(name = "testDNs")
public Object[][] createData() {
return new Object[][] {
- { "", "" },
- { " ", "" },
- { "dc=com", "dc=com" },
- { "DC=COM", "dc=com" },
- { "dc = com", "dc=com" },
- { " dc = com ", "dc=com" },
- { "dc=example,dc=com", "dc=example,dc=com" },
- { "dc=example, dc=com", "dc=example,dc=com" },
- { "dc=example ,dc=com", "dc=example,dc=com" },
- { "dc =example , dc = com", "dc=example,dc=com" },
+ { "", "", "" },
+ { " ", "", "" },
+ { "dc=com", "dc=com", "dc=com" },
+ { "DC=COM", "dc=com", "DC=COM" },
+ { "dc = com", "dc=com", "dc=com" },
+ { " dc = com ", "dc=com", "dc=com" },
+ { "dc=example,dc=com", "dc=example,dc=com",
+ "dc=example,dc=com" },
+ { "dc=example, dc=com", "dc=example,dc=com",
+ "dc=example,dc=com" },
+ { "dc=example ,dc=com", "dc=example,dc=com",
+ "dc=example,dc=com" },
+ { "dc =example , dc = com", "dc=example,dc=com",
+ "dc=example,dc=com" },
{ "givenName=John+cn=Doe,ou=People,dc=example,dc=com",
- "cn=doe+givenname=john,ou=people,dc=example,dc=com" },
+ "cn=doe+givenname=john,ou=people,dc=example,dc=com",
+ "givenName=John+cn=Doe,ou=People,dc=example,dc=com" },
{ "givenName=John\\+cn=Doe,ou=People,dc=example,dc=com",
- "givenname=john\\+cn=doe,ou=people,dc=example,dc=com" },
+ "givenname=john\\+cn=doe,ou=people,dc=example,dc=com",
+ "givenName=John\\+cn=Doe,ou=People,dc=example,dc=com" },
{ "cn=Doe\\, John,ou=People,dc=example,dc=com",
- "cn=doe\\, john,ou=people,dc=example,dc=com" },
- { "UID=jsmith,DC=example,DC=net", "uid=jsmith,dc=example,dc=net" },
+ "cn=doe\\, john,ou=people,dc=example,dc=com",
+ "cn=Doe\\, John,ou=People,dc=example,dc=com" },
+ { "UID=jsmith,DC=example,DC=net",
+ "uid=jsmith,dc=example,dc=net",
+ "UID=jsmith,DC=example,DC=net" },
{ "OU=Sales+CN=J. Smith,DC=example,DC=net",
- "cn=j. smith+ou=sales,dc=example,dc=net" },
+ "cn=j. smith+ou=sales,dc=example,dc=net",
+ "OU=Sales+CN=J. Smith,DC=example,DC=net" },
{ "CN=James \\\"Jim\\\" Smith\\, III,DC=example,DC=net",
- "cn=james \\\"jim\\\" smith\\, iii,dc=example,dc=net" },
+ "cn=james \\\"jim\\\" smith\\, iii,dc=example,dc=net",
+ "CN=James \\\"Jim\\\" Smith\\, III,DC=example,DC=net" },
+ { "CN=John Smith\\2C III,DC=example,DC=net",
+ "cn=john smith\\, iii,dc=example,dc=net",
+ "CN=John Smith\\, III,DC=example,DC=net" },
+ { "CN=\\23John Smith\\20,DC=example,DC=net",
+ "cn=\\#john smith,dc=example,dc=net",
+ "CN=\\#John Smith\\ ,DC=example,DC=net" },
{ "CN=Before\\0dAfter,DC=example,DC=net",
- "cn=before\\0dafter,dc=example,dc=net" },
- { "1.3.6.1.4.1.1466.0=#04024869", "1.3.6.1.4.1.1466.0=\\04\\02hi" },
- { "CN=Lu\\C4\\8Di\\C4\\87", "cn=lu\\c4\\8di\\c4\\87" },
+ "cn=before\\0dafter,dc=example,dc=net",
+ "CN=Before\\0dAfter,DC=example,DC=net" },
+ { "1.3.6.1.4.1.1466.0=#04024869",
+ "1.3.6.1.4.1.1466.0=\\04\\02hi",
+ "1.3.6.1.4.1.1466.0=\\04\\02Hi" },
+ { "1.1.1=", "1.1.1=", "1.1.1=" },
+ { "CN=Lu\\C4\\8Di\\C4\\87", "cn=lu\\c4\\8di\\c4\\87",
+ "CN=Lu\\c4\\8di\\c4\\87" },
{ "ou=\\e5\\96\\b6\\e6\\a5\\ad\\e9\\83\\a8,o=Airius",
- "ou=\\e5\\96\\b6\\e6\\a5\\ad\\e9\\83\\a8,o=airius" },
- { "photo=\\ john \\ ,dc=com", "photo=\\ john \\ ,dc=com" },
- { "AB-global=", "ab-global=" },
+ "ou=\\e5\\96\\b6\\e6\\a5\\ad\\e9\\83\\a8,o=airius",
+ "ou=\\e5\\96\\b6\\e6\\a5\\ad\\e9\\83\\a8,o=Airius" },
+ { "photo=\\ john \\ ,dc=com", "photo=\\ john \\ ,dc=com",
+ "photo=\\ john \\ ,dc=com" },
+ { "AB-global=", "ab-global=", "AB-global=" },
{ "OU= Sales + CN = J. Smith ,DC=example,DC=net",
- "cn=j. smith+ou=sales,dc=example,dc=net" },
- { "cn=John+a=", "a=+cn=john" },
- { "OID.1.3.6.1.4.1.1466.0=#04024869",
- "1.3.6.1.4.1.1466.0=\\04\\02hi" },
- { "O=\"Sue, Grabbit and Runn\",C=US",
- "o=sue\\, grabbit and runn,c=us" },
- };
+ "cn=j. smith+ou=sales,dc=example,dc=net",
+ "OU=Sales+CN=J. Smith,DC=example,DC=net" },
+ { "cn=John+a=", "a=+cn=john", "cn=John+a=" },
+ { "OID.1.3.6.1.4.1.1466.0=#04024869",
+ "1.3.6.1.4.1.1466.0=\\04\\02hi",
+ "1.3.6.1.4.1.1466.0=\\04\\02Hi" },
+ { "O=\"Sue, Grabbit and Runn\",C=US",
+ "o=sue\\, grabbit and runn,c=us",
+ "O=Sue\\, Grabbit and Runn,C=US" }, };
}
+
+
/**
* Illegal DN test data provider.
*
@@ -96,66 +126,15 @@
*/
@DataProvider(name = "illegalDNs")
public Object[][] createIllegalData() {
- return new Object[][] {
- { "manager" },
- { "manager " },
- { "cn+Jim" },
- { "cn=Jim+" },
- { "cn=Jim," },
- { "cn=Jim, " },
- { "cn+uid=Jim" },
- { "-cn=Jim" },
- { "/tmp=a" },
- { "\\tmp=a" },
- { "cn;lang-en=Jim" },
- { "@cn=Jim" },
- { "_name_=Jim" },
- { "\u03c0=pi" },
- { "v1.0=buggy" },
- { "1.3.6.1.4.1.1466..0=#04024869" },
- };
+ return new Object[][] { { "manager" }, { "manager " },
+ { "cn+Jim" }, { "cn=Jim+" }, { "cn=Jim," }, { "cn=Jim, " },
+ { "cn+uid=Jim" }, { "-cn=Jim" }, { "/tmp=a" }, { "\\tmp=a" },
+ { "cn;lang-en=Jim" }, { "@cn=Jim" }, { "_name_=Jim" },
+ { "\u03c0=pi" }, { "v1.0=buggy" },
+ { "1.3.6.1.4.1.1466..0=#04024869" }, };
}
- /**
- * DN compare test data provider.
- *
- * @return The unsorted and sorted DN strings .
- */
- @DataProvider(name = "compareDNs")
- public Object[][] createSortData() {
- return new Object[][] {
- {
- // Not sorted.
- new String[]
- {
- "UID=jsmith,DC=example,DC=net",
- "dc=com",
- "",
- "dc=example,dc=net",
- "uid=jsmith,dc=example,dc=com",
- "dc=example,dc=com",
- "cn=jsmith,dc=example,dc=com",
- "",
- "dc =example , dc = com",
- "uid=asmith,dc=example,dc=net",
- },
- // Sorted.
- new String[]
- {
- "",
- "",
- "dc=com",
- "dc =example , dc = com",
- "dc=example,dc=com",
- "cn=jsmith,dc=example,dc=com",
- "uid=jsmith,dc=example,dc=com",
- "dc=example,dc=net",
- "uid=asmith,dc=example,dc=net",
- "UID=jsmith,DC=example,DC=net",
- },
- }
- };
- }
+
/**
* Set up the environment for performing the tests in this suite.
@@ -165,138 +144,799 @@
*/
@BeforeClass
public void setUp() throws Exception {
- // This test suite depends on having the schema available, so we'll start
- // the server.
+ // This test suite depends on having the schema available, so
+ // we'll start the server.
TestCaseUtils.startServer();
+
+ AttributeType dummy = DirectoryServer.getDefaultAttributeType(
+ "x-test-integer-type", DirectoryServer
+ .getDefaultIntegerSyntax());
+ DirectoryServer.getSchema().registerAttributeType(dummy, true);
}
+
+
+ /**
+ * Tests the create method.
+ *
+ * @throws Exception
+ * If the test failed unexpectedly.
+ */
+ @Test(expectedExceptions = { NullPointerException.class,
+ AssertionError.class })
+ public void testCreateNPE() throws Exception {
+ DN.create((RDN[]) null);
+ }
+
+
+
+ /**
+ * Tests the create method.
+ *
+ * @throws Exception
+ * If the test failed unexpectedly.
+ */
+ @Test
+ public void testCreateNullDN1() throws Exception {
+ DN dn = DN.create(new RDN[0]);
+
+ assertEquals(dn, DN.nullDN());
+ }
+
+
+
+ /**
+ * Tests the create method.
+ *
+ * @throws Exception
+ * If the test failed unexpectedly.
+ */
+ @Test
+ public void testCreateNullDN2() throws Exception {
+ DN dn = DN.create();
+
+ assertEquals(dn, DN.nullDN());
+ }
+
+
+
+ /**
+ * Tests the create method.
+ *
+ * @throws Exception
+ * If the test failed unexpectedly.
+ */
+ @Test
+ public void testCreateWithSingleRDN1() throws Exception {
+ DN dn = DN.create(new RDN[] { RDN.decode("dc=com") });
+
+ assertEquals(dn, DN.decode("dc=com"));
+ }
+
+
+
+ /**
+ * Tests the create method.
+ *
+ * @throws Exception
+ * If the test failed unexpectedly.
+ */
+ @Test
+ public void testCreateWithSingleRDN2() throws Exception {
+ DN dn = DN.create(RDN.decode("dc=com"));
+
+ assertEquals(dn, DN.decode("dc=com"));
+ }
+
+
+
+ /**
+ * Tests the create method.
+ *
+ * @throws Exception
+ * If the test failed unexpectedly.
+ */
+ @Test
+ public void testCreateWithMultipleRDNs1() throws Exception {
+ DN dn = DN.create(new RDN[] { RDN.decode("dc=foo"),
+ RDN.decode("dc=opends"), RDN.decode("dc=org") });
+
+ assertEquals(dn, DN.decode("dc=foo,dc=opends,dc=org"));
+ }
+
+
+
+ /**
+ * Tests the create method.
+ *
+ * @throws Exception
+ * If the test failed unexpectedly.
+ */
+ @Test
+ public void testCreateWithMultipleRDNs2() throws Exception {
+ DN dn = DN.create(RDN.decode("dc=foo"), RDN.decode("dc=opends"),
+ RDN.decode("dc=org"));
+
+ assertEquals(dn, DN.decode("dc=foo,dc=opends,dc=org"));
+ }
+
+
+
/**
* Tests the <CODE>decode</CODE> method which takes a String
* argument.
*
* @param rawDN
- * The raw undecoded DN string.
+ * Raw DN string representation.
* @param normDN
- * The expected normalized value.
+ * Normalized DN string representation.
+ * @param stringDN
+ * String representation.
* @throws Exception
* If the test failed unexpectedly.
*/
@Test(dataProvider = "testDNs")
- public void testDecodeString(String rawDN, String normDN)
- throws Exception {
+ public void testDecodeString(String rawDN, String normDN,
+ String stringDN) throws Exception {
DN dn = DN.decode(rawDN);
- assertEquals(normDN, dn.toNormalizedString());
+ assertEquals(dn.toNormalizedString(), normDN);
}
+
+
/**
* Tests the <CODE>decode</CODE> method which takes a String
* argument.
*
* @param rawDN
- * The raw undecoded DN string.
+ * Raw DN string representation.
* @param normDN
- * The expected normalized value.
+ * Normalized DN string representation.
+ * @param stringDN
+ * String representation.
* @throws Exception
* If the test failed unexpectedly.
*/
@Test(dataProvider = "testDNs")
- public void testDecodeOctetString(String rawDN, String normDN)
- throws Exception {
+ public void testDecodeOctetString(String rawDN, String normDN,
+ String stringDN) throws Exception {
ASN1OctetString octetString = new ASN1OctetString(rawDN);
DN dn = DN.decode(octetString);
- assertEquals(normDN, dn.toNormalizedString());
+ assertEquals(dn.toNormalizedString(), normDN);
+ }
+
+
+
+ /**
+ * Tests the <CODE>valueOf</CODE> method which takes a String
+ * argument.
+ *
+ * @param rawDN
+ * Raw DN string representation.
+ * @param normDN
+ * Normalized DN string representation.
+ * @param stringDN
+ * String representation.
+ * @throws Exception
+ * If the test failed unexpectedly.
+ */
+ @Test(dataProvider = "testDNs")
+ public void testValueOf(String rawDN, String normDN, String stringDN)
+ throws Exception {
+ DN dn = DN.valueOf(rawDN);
+ assertEquals(dn.toNormalizedString(), normDN);
}
/**
* Test that decoding an illegal DN as a String throws an exception.
- * @param dn The illegal DN to be tested.
+ *
+ * @param dn
+ * The illegal DN to be tested.
* @throws Exception
* If the test failed unexpectedly.
*/
- @Test(dataProvider = "illegalDNs",
- expectedExceptions = DirectoryException.class )
- public void testIllegalStringDNs(String dn)
- throws Exception
- {
- try
- {
+ @Test(dataProvider = "illegalDNs", expectedExceptions = DirectoryException.class)
+ public void testIllegalStringDNs(String dn) throws Exception {
+ try {
DN.decode(dn);
- }
- catch (DirectoryException e)
- {
+ } catch (DirectoryException e) {
throw e;
- }
- catch (Exception e)
- {
- System.out.println(
- "Illegal DN <" + dn + "> threw the wrong type of exception");
+ } catch (Exception e) {
+ System.out.println("Illegal DN <" + dn
+ + "> threw the wrong type of exception");
throw e;
}
- throw new RuntimeException(
- "Illegal DN <" + dn + "> did not throw an exception");
+ throw new RuntimeException("Illegal DN <" + dn
+ + "> did not throw an exception");
}
+
+
/**
- * Test that decoding an illegal DN as an octet string throws an exception.
- * @param dn The illegal DN to be tested.
+ * Test that decoding an illegal DN as an octet string throws an
+ * exception.
+ *
+ * @param dn
+ * The illegal DN to be tested.
* @throws Exception
* If the test failed unexpectedly.
*/
- @Test(dataProvider = "illegalDNs",
- expectedExceptions = DirectoryException.class )
- public void testIllegalOctetStringDNs(String dn)
- throws Exception
- {
+ @Test(dataProvider = "illegalDNs", expectedExceptions = DirectoryException.class)
+ public void testIllegalOctetStringDNs(String dn) throws Exception {
ASN1OctetString octetString = new ASN1OctetString(dn);
- try
- {
+ try {
DN.decode(octetString);
- }
- catch (DirectoryException e)
- {
+ } catch (DirectoryException e) {
throw e;
- }
- catch (Exception e)
- {
- System.out.println(
- "Illegal DN <" + dn + "> threw the wrong type of exception");
+ } catch (Exception e) {
+ System.out.println("Illegal DN <" + dn
+ + "> threw the wrong type of exception");
throw e;
}
- throw new RuntimeException(
- "Illegal DN <" + dn + "> did not throw an exception");
+ throw new RuntimeException("Illegal DN <" + dn
+ + "> did not throw an exception");
}
+
+
/**
- * Test the <CODE>compareTo</CODE> method.
- * @param unsorted An array of string DNs in no particular order.
- * @param sorted An array of the same DNs in sort order.
+ * Test that decoding an illegal DN as a String throws an exception.
+ *
+ * @param dn
+ * The illegal DN to be tested.
* @throws Exception
* If the test failed unexpectedly.
*/
- @Test(dataProvider = "compareDNs")
- public void testCompareTo(String[] unsorted, String[] sorted)
- throws Exception
- {
- DN[] expected = new DN[sorted.length];
- for (int i = 0; i < sorted.length; i++)
- {
- expected[i] = DN.decode(sorted[i]);
+ @Test(dataProvider = "illegalDNs", expectedExceptions = DirectoryException.class)
+ public void testIllegalValueOf(String dn) throws Exception {
+ try {
+ DN.valueOf(dn);
+ } catch (DirectoryException e) {
+ throw e;
+ } catch (Exception e) {
+ System.out.println("Illegal DN <" + dn
+ + "> threw the wrong type of exception");
+ throw e;
}
+ throw new RuntimeException("Illegal DN <" + dn
+ + "> did not throw an exception");
+ }
- DN[] actual = new DN[unsorted.length];
- for (int i = 0; i < unsorted.length; i++)
- {
- actual[i] = DN.decode(unsorted[i]);
+
+
+ /**
+ * Test the nullDN method.
+ *
+ * @throws Exception
+ * If the test failed unexpectedly.
+ */
+ @Test
+ public void testNullDN() throws Exception {
+ DN nullDN = DN.nullDN();
+
+ assertTrue(nullDN.getNumComponents() == 0);
+ assertEquals(nullDN.toNormalizedString(), "");
+ }
+
+
+
+ /**
+ * Test the isNullDN method.
+ *
+ * @throws Exception
+ * If the test failed unexpectedly.
+ */
+ @Test
+ public void testIsNullDNWithNullDN() throws Exception {
+ DN nullDN = DN.nullDN();
+ assertTrue(nullDN.isNullDN());
+ }
+
+
+
+ /**
+ * Test the isNullDN method.
+ *
+ * @throws Exception
+ * If the test failed unexpectedly.
+ */
+ @Test
+ public void testIsNullDNWithNonNullDN() throws Exception {
+ DN dn = DN.decode("dc=com");
+ assertFalse(dn.isNullDN());
+ }
+
+
+
+ /**
+ * DN test data provider.
+ *
+ * @return The array of test DN strings.
+ */
+ @DataProvider(name = "createNumComponentsTestData")
+ public Object[][] createNumComponentsTestData() {
+ return new Object[][] { { "", 0 }, { "dc=com", 1 },
+ { "dc=opends,dc=com", 2 },
+ { "dc=world,dc=opends,dc=com", 3 },
+ { "dc=hello,dc=world,dc=opends,dc=com", 4 }, };
+ }
+
+
+
+ /**
+ * Test the getNumComponents method.
+ *
+ * @param s
+ * The test DN string.
+ * @param sz
+ * The expected number of RDNs.
+ * @throws Exception
+ * If the test failed unexpectedly.
+ */
+ @Test(dataProvider = "createNumComponentsTestData")
+ public void testNumComponents(String s, int sz) throws Exception {
+ DN dn = DN.decode(s);
+ assertEquals(dn.getNumComponents(), sz);
+ }
+
+
+
+ /**
+ * DN test data provider.
+ *
+ * @return The array of test DN strings.
+ */
+ @DataProvider(name = "createParentAndRDNTestData")
+ public Object[][] createParentAndRDNTestData() {
+ return new Object[][] {
+ { "", null, null },
+ { "dc=com", null, "dc=com" },
+ { "dc=opends,dc=com", "dc=com", "dc=opends" },
+ { "dc=world,dc=opends,dc=com", "dc=opends,dc=com", "dc=world" },
+ { "dc=hello,dc=world,dc=opends,dc=com",
+ "dc=world,dc=opends,dc=com", "dc=hello" }, };
+ }
+
+
+
+ /**
+ * Test the getParent method.
+ *
+ * @param s
+ * The test DN string.
+ * @param p
+ * The expected parent.
+ * @param r
+ * The expected rdn.
+ * @throws Exception
+ * If the test failed unexpectedly.
+ */
+ @Test(dataProvider = "createParentAndRDNTestData")
+ public void testGetParent(String s, String p, String r)
+ throws Exception {
+ DN dn = DN.decode(s);
+ DN parent = (p != null ? DN.decode(p) : null);
+
+ assertEquals(dn.getParent(), parent, "For DN " + s);
+ }
+
+
+
+ /**
+ * Test the getParent method's interaction with other methods.
+ *
+ * @throws Exception
+ * If the test failed unexpectedly.
+ */
+ @Test
+ public void testGetParentInteraction() throws Exception {
+ DN c = DN.decode("dc=foo,dc=bar,dc=opends,dc=org");
+ DN e = DN.decode("dc=bar,dc=opends,dc=org");
+ DN p = c.getParent();
+
+ assertFalse(p.isNullDN());
+
+ assertEquals(p.getNumComponents(), 3);
+
+ assertEquals(p.compareTo(c), -1);
+ assertEquals(c.compareTo(p), 1);
+
+ assertTrue(p.isAncestorOf(c));
+ assertFalse(c.isAncestorOf(p));
+
+ assertTrue(c.isDescendantOf(p));
+ assertFalse(p.isDescendantOf(c));
+
+ assertEquals(p, e);
+ assertEquals(p.hashCode(), e.hashCode());
+
+ assertEquals(p.toNormalizedString(), e.toNormalizedString());
+ assertEquals(p.toString(), e.toString());
+
+ assertEquals(p.getRDN(), RDN.decode("dc=bar"));
+
+ assertEquals(p.getRDN(0), RDN.decode("dc=bar"));
+ assertEquals(p.getRDN(1), RDN.decode("dc=opends"));
+ assertEquals(p.getRDN(2), RDN.decode("dc=org"));
+
+ assertEquals(p.getParent(), DN.decode("dc=opends,dc=org"));
+ assertEquals(p.getParent(), e.getParent());
+
+ assertEquals(p.concat(RDN.decode("dc=foo")), DN
+ .decode("dc=foo,dc=bar,dc=opends,dc=org"));
+ assertEquals(p.concat(RDN.decode("dc=foo")), c);
+ assertEquals(p.concat(DN.decode("dc=xxx,dc=foo")), DN
+ .decode("dc=xxx,dc=foo,dc=bar,dc=opends,dc=org"));
+
+ assertEquals(p.getLocalName(1), DN.decode("dc=bar,dc=opends"));
+ assertEquals(p.getLocalName(0, 2), DN.decode("dc=opends,dc=org"));
+ }
+
+
+
+ /**
+ * Test the getRDN method.
+ *
+ * @param s
+ * The test DN string.
+ * @param p
+ * The expected parent.
+ * @param r
+ * The expected rdn.
+ * @throws Exception
+ * If the test failed unexpectedly.
+ */
+ @Test(dataProvider = "createParentAndRDNTestData")
+ public void testGetRDN(String s, String p, String r)
+ throws Exception {
+ DN dn = DN.decode(s);
+ RDN rdn = (r != null ? RDN.decode(r) : null);
+
+ assertEquals(dn.getRDN(), rdn, "For DN " + s);
+ }
+
+
+
+ /**
+ * DN test data provider.
+ *
+ * @return The array of test DN strings.
+ */
+ @DataProvider(name = "createRDNTestData")
+ public Object[][] createRDNTestData() {
+ return new Object[][] { { "dc=com", 0, "dc=com" },
+ { "dc=opends,dc=com", 0, "dc=opends" },
+ { "dc=opends,dc=com", 1, "dc=com" },
+ { "dc=hello,dc=world,dc=opends,dc=com", 0, "dc=hello" },
+ { "dc=hello,dc=world,dc=opends,dc=com", 1, "dc=world" },
+ { "dc=hello,dc=world,dc=opends,dc=com", 2, "dc=opends" },
+ { "dc=hello,dc=world,dc=opends,dc=com", 3, "dc=com" }, };
+ }
+
+
+
+ /**
+ * Test the getRDN indexed method.
+ *
+ * @param s
+ * The test DN string.
+ * @param i
+ * The RDN index.
+ * @param r
+ * The expected rdn.
+ * @throws Exception
+ * If the test failed unexpectedly.
+ */
+ @Test(dataProvider = "createRDNTestData")
+ public void testGetRDNIndexed(String s, int i, String r)
+ throws Exception {
+ DN dn = DN.decode(s);
+ RDN rdn = RDN.decode(r);
+
+ assertEquals(dn.getRDN(i), rdn, "For DN " + s);
+ }
+
+
+
+ /**
+ * DN test data provider.
+ *
+ * @return The array of test DN strings.
+ */
+ @DataProvider(name = "createRDNIllegalTestData")
+ public Object[][] createRDNIllegalTestData() {
+ return new Object[][] { { "", 0 }, { "", -1 }, { "", 1 },
+ { "dc=com", -1 }, { "dc=com", 1 },
+ { "dc=opends,dc=com", -1 }, { "dc=opends,dc=com", 2 },
+ { "dc=hello,dc=world,dc=opends,dc=com", -1 },
+ { "dc=hello,dc=world,dc=opends,dc=com", 4 }, };
+ }
+
+
+
+ /**
+ * Test the getRDN indexed method with illegal indexes.
+ *
+ * @param s
+ * The test DN string.
+ * @param i
+ * The illegal RDN index.
+ * @throws Exception
+ * If the test failed unexpectedly.
+ */
+ @Test(dataProvider = "createRDNIllegalTestData", expectedExceptions = IndexOutOfBoundsException.class)
+ public void testGetRDNIndexedException(String s, int i)
+ throws Exception {
+ DN dn = DN.decode(s);
+
+ // Shoudld throw.
+ dn.getRDN(i);
+
+ fail("Excepted exception for RDN index " + i + " in DN " + s);
+ }
+
+
+
+ /**
+ * Concat DN test data provider.
+ *
+ * @return The array of test data.
+ */
+ @DataProvider(name = "createConcatDNTestData")
+ public Object[][] createConcatDNTestData() {
+ return new Object[][] {
+ { "", "", "" },
+ { "", "dc=org", "dc=org" },
+ { "", "dc=opends,dc=org", "dc=opends,dc=org" },
+ { "dc=org", "", "dc=org" },
+ { "dc=org", "dc=opends", "dc=opends,dc=org" },
+ { "dc=org", "dc=foo,dc=opends", "dc=foo,dc=opends,dc=org" },
+ { "dc=opends,dc=org", "", "dc=opends,dc=org" },
+ { "dc=opends,dc=org", "dc=foo", "dc=foo,dc=opends,dc=org" },
+ { "dc=opends,dc=org", "dc=bar,dc=foo",
+ "dc=bar,dc=foo,dc=opends,dc=org" }, };
+ }
+
+
+
+ /**
+ * Test the concat(DN) method.
+ *
+ * @param s
+ * The test DN string.
+ * @param l
+ * The local name to be appended.
+ * @param e
+ * The expected DN.
+ * @throws Exception
+ * If the test failed unexpectedly.
+ */
+ @Test(dataProvider = "createConcatDNTestData")
+ public void testConcatDN(String s, String l, String e)
+ throws Exception {
+ DN dn = DN.decode(s);
+ DN localName = DN.decode(l);
+ DN expected = DN.decode(e);
+
+ assertEquals(dn.concat(localName), expected);
+ }
+
+
+
+ /**
+ * Test the concat(DN) method.
+ *
+ * @throws Exception
+ * If the test failed unexpectedly.
+ */
+ @Test(expectedExceptions = { NullPointerException.class,
+ AssertionError.class })
+ public void testConcatDNException() throws Exception {
+ DN dn = DN.decode("dc=org");
+ dn.concat((DN) null);
+ }
+
+
+
+ /**
+ * Test the concat(DN) method's interaction with other methods.
+ *
+ * @throws Exception
+ * If the test failed unexpectedly.
+ */
+ @Test
+ public void testConcatDNInteraction() throws Exception {
+ DN p = DN.decode("dc=opends,dc=org");
+ DN l = DN.decode("dc=foo,dc=bar");
+ DN e = DN.decode("dc=foo,dc=bar,dc=opends,dc=org");
+ DN c = p.concat(l);
+
+ assertFalse(c.isNullDN());
+
+ assertEquals(c.getNumComponents(), 4);
+
+ assertEquals(c.compareTo(p), 1);
+ assertEquals(p.compareTo(c), -1);
+
+ assertTrue(p.isAncestorOf(c));
+ assertFalse(c.isAncestorOf(p));
+
+ assertTrue(c.isDescendantOf(p));
+ assertFalse(p.isDescendantOf(c));
+
+ assertEquals(c, e);
+ assertEquals(c.hashCode(), e.hashCode());
+
+ assertEquals(c.toNormalizedString(), e.toNormalizedString());
+ assertEquals(c.toString(), e.toString());
+
+ assertEquals(c.getRDN(), RDN.decode("dc=foo"));
+
+ assertEquals(c.getRDN(0), RDN.decode("dc=foo"));
+ assertEquals(c.getRDN(1), RDN.decode("dc=bar"));
+ assertEquals(c.getRDN(2), RDN.decode("dc=opends"));
+ assertEquals(c.getRDN(3), RDN.decode("dc=org"));
+
+ assertEquals(c.getParent(), DN.decode("dc=bar,dc=opends,dc=org"));
+ assertEquals(c.getParent(), e.getParent());
+
+ assertEquals(c.concat(RDN.decode("dc=xxx")), DN
+ .decode("dc=xxx,dc=foo,dc=bar,dc=opends,dc=org"));
+ assertEquals(c.concat(DN.decode("dc=xxx,dc=yyy")), DN
+ .decode("dc=xxx,dc=yyy,dc=foo,dc=bar,dc=opends,dc=org"));
+
+ assertEquals(c.getLocalName(1), DN
+ .decode("dc=foo,dc=bar,dc=opends"));
+ assertEquals(c.getLocalName(1, 3), DN.decode("dc=bar,dc=opends"));
+ }
+
+
+
+ /**
+ * Concat RDN test data provider.
+ *
+ * @return The array of test data.
+ */
+ @DataProvider(name = "createConcatRDNTestData")
+ public Object[][] createConcatRDNTestData() {
+ return new Object[][] { { "", "dc=org", "dc=org" },
+ { "dc=org", "dc=opends", "dc=opends,dc=org" },
+ { "dc=opends,dc=org", "dc=foo", "dc=foo,dc=opends,dc=org" }, };
+ }
+
+
+
+ /**
+ * Test the concat(RDN...) method.
+ *
+ * @param s
+ * The test DN string.
+ * @param r
+ * The RDN to be appended.
+ * @param e
+ * The expected DN.
+ * @throws Exception
+ * If the test failed unexpectedly.
+ */
+ @Test(dataProvider = "createConcatRDNTestData")
+ public void testConcatSingleRDN(String s, String r, String e)
+ throws Exception {
+ DN dn = DN.decode(s);
+ RDN rdn = RDN.decode(r);
+ DN expected = DN.decode(e);
+
+ assertEquals(dn.concat(rdn), expected);
+ }
+
+
+
+ /**
+ * Test the concat(RDN...) method.
+ *
+ * @throws Exception
+ * If the test failed unexpectedly.
+ */
+ @Test
+ public void testConcatRDNNoOp() throws Exception {
+ DN dn = DN.decode("dc=opends,dc=org");
+
+ assertEquals(dn.concat(), dn);
+ }
+
+
+
+ /**
+ * Test the concat(RDN...) method.
+ *
+ * @throws Exception
+ * If the test failed unexpectedly.
+ */
+ @Test(expectedExceptions = { NullPointerException.class,
+ AssertionError.class })
+ public void testConcatRDNException() throws Exception {
+ DN dn = DN.decode("dc=org");
+ dn.concat((RDN[]) null);
+ }
+
+
+
+ /**
+ * Test the concat(RDN[]...) method.
+ *
+ * @param s
+ * The test DN string.
+ * @param l
+ * The local name to be appended.
+ * @param e
+ * The expected DN.
+ * @throws Exception
+ * If the test failed unexpectedly.
+ */
+ @Test(dataProvider = "createConcatDNTestData")
+ public void testConcatRDNSequence1(String s, String l, String e)
+ throws Exception {
+ DN dn = DN.decode(s);
+ DN localName = DN.decode(l);
+ DN expected = DN.decode(e);
+
+ // Construct sequence.
+ RDN[] rdns = new RDN[localName.getNumComponents()];
+ for (int i = 0; i < localName.getNumComponents(); i++) {
+ rdns[i] = localName.getRDN(i);
}
- Arrays.sort(actual);
+ assertEquals(dn.concat(rdns), expected);
+ }
+
+
+
+ /**
+ * Test the concat(RDN[]...) method.
+ *
+ * @param s
+ * The test DN string.
+ * @param l
+ * The local name to be appended.
+ * @param e
+ * The expected DN.
+ * @throws Exception
+ * If the test failed unexpectedly.
+ */
+ @Test(dataProvider = "createConcatDNTestData")
+ public void testConcatRDNSequence2(String s, String l, String e)
+ throws Exception {
+ DN dn = DN.decode(s);
+ DN localName = DN.decode(l);
+ DN expected = DN.decode(e);
+
+ // Construct sequence.
+ DN actual = null;
+ switch (localName.getNumComponents()) {
+ case 0:
+ actual = dn.concat();
+ break;
+ case 1:
+ actual = dn.concat(localName.getRDN(0));
+ break;
+ case 2:
+ actual = dn.concat(localName.getRDN(0), localName.getRDN(1));
+ break;
+ case 3:
+ actual = dn.concat(localName.getRDN(0), localName.getRDN(1),
+ localName.getRDN(2));
+ break;
+ case 4:
+ actual = dn.concat(localName.getRDN(0), localName.getRDN(1),
+ localName.getRDN(3), localName.getRDN(3));
+ break;
+ }
assertEquals(actual, expected);
}
@@ -304,38 +944,427 @@
/**
- * Test the <CODE>duplicate</CODE> method.
+ * Get local name test data provider.
+ *
+ * @return The array of test data.
+ */
+ @DataProvider(name = "createGetLocalNameTestData")
+ public Object[][] createGetLocalNameTestData() {
+ return new Object[][] {
+ { "", 0, -1, "" },
+ { "", 0, 0, "" },
+ { "dc=org", 0, -1, "dc=org" },
+ { "dc=org", 1, -1, "" },
+ { "dc=org", 0, 0, "" },
+ { "dc=org", 0, 1, "dc=org" },
+ { "dc=org", 1, 1, "" },
+ { "dc=opends,dc=org", 0, -1, "dc=opends,dc=org" },
+ { "dc=opends,dc=org", 1, -1, "dc=opends" },
+ { "dc=opends,dc=org", 2, -1, "" },
+ { "dc=opends,dc=org", 0, 0, "" },
+ { "dc=opends,dc=org", 0, 1, "dc=org" },
+ { "dc=opends,dc=org", 0, 2, "dc=opends,dc=org" },
+ { "dc=opends,dc=org", 1, 1, "" },
+ { "dc=opends,dc=org", 1, 2, "dc=opends" },
+ { "dc=opends,dc=org", 2, 2, "" },
+ { "dc=foo,dc=opends,dc=org", 0, -1, "dc=foo,dc=opends,dc=org" },
+ { "dc=foo,dc=opends,dc=org", 1, -1, "dc=foo,dc=opends" },
+ { "dc=foo,dc=opends,dc=org", 2, -1, "dc=foo" },
+ { "dc=foo,dc=opends,dc=org", 3, -1, "" },
+ { "dc=foo,dc=opends,dc=org", 0, 0, "" },
+ { "dc=foo,dc=opends,dc=org", 0, 1, "dc=org" },
+ { "dc=foo,dc=opends,dc=org", 0, 2, "dc=opends,dc=org" },
+ { "dc=foo,dc=opends,dc=org", 0, 3, "dc=foo,dc=opends,dc=org" },
+ { "dc=foo,dc=opends,dc=org", 1, 1, "" },
+ { "dc=foo,dc=opends,dc=org", 1, 2, "dc=opends" },
+ { "dc=foo,dc=opends,dc=org", 1, 3, "dc=foo,dc=opends" },
+ { "dc=foo,dc=opends,dc=org", 2, 2, "" },
+ { "dc=foo,dc=opends,dc=org", 2, 3, "dc=foo" },
+ { "dc=foo,dc=opends,dc=org", 3, 3, "" }, };
+ }
+
+
+
+ /**
+ * Test the getLocalName methods.
+ *
+ * @param s
+ * The test DN string.
+ * @param beginIndex
+ * The index of the uppermost RDN.
+ * @param endIndex
+ * The index of the lowest RDN or -1 if there is no end
+ * index.
+ * @param e
+ * The expected result.
+ * @throws Exception
+ * If the test failed unexpectedly.
+ */
+ @Test(dataProvider = "createGetLocalNameTestData")
+ public void testGetLocalName(String s, int beginIndex,
+ int endIndex, String e) throws Exception {
+ DN dn = DN.decode(s);
+ DN expected = DN.decode(e);
+
+ if (endIndex < 0) {
+ assertEquals(dn.getLocalName(beginIndex), expected);
+ } else {
+ assertEquals(dn.getLocalName(beginIndex, endIndex), expected);
+ }
+ }
+
+
+
+ /**
+ * Test the getLocalName method's interaction with other methods.
+ *
* @throws Exception
* If the test failed unexpectedly.
*/
@Test
- public void testDuplicate() throws Exception
- {
- String s = "dc=example,dc=com";
- DN orig = DN.decode(s);
- DN dup = orig.duplicate();
+ public void testGetLocalNameInteraction() throws Exception {
+ DN p = DN.decode("dc=foo,dc=bar,dc=opends,dc=org");
+ DN e = DN.decode("dc=bar,dc=opends");
+ DN l = p.getLocalName(1, 3);
- // The duplicate and the original should compare equal.
- assertEquals(dup, orig);
+ assertFalse(l.isNullDN());
- // Alter the duplicate.
- RDN[] origRDNs = dup.getRDNComponents();
- RDN[] dupRDNs = new RDN[origRDNs.length];
- System.arraycopy(origRDNs, 0, dupRDNs, 0, origRDNs.length);
+ assertEquals(l.getNumComponents(), 2);
- AttributeValue[] values = new AttributeValue[1];
- values[0] = origRDNs[0].getAttributeValues()[0];
- values[0] = new AttributeValue(origRDNs[0].getAttributeTypes()[0],
- new ASN1OctetString("modified"));
- dupRDNs[0] = new RDN(origRDNs[0].getAttributeTypes(),
- origRDNs[0].getAttributeNames(),
- values);
+ assertEquals(l.compareTo(e), 0);
+ assertEquals(e.compareTo(l), 0);
- dup.setRDNComponents(dupRDNs);
+ assertTrue(l.isAncestorOf(DN.decode("dc=foo,dc=bar,dc=opends")));
+ assertFalse(DN.decode("dc=foo,dc=bar,dc=opends").isAncestorOf(l));
- // Check that the duplicate and the original are different.
- String msg = String.format("<%s> and <%s>", dup, orig);
- assertTrue(!dup.equals(orig), msg);
+ assertTrue(l.isDescendantOf(DN.decode("dc=opends")));
+ assertFalse(DN.decode("dc=opends").isDescendantOf(l));
+
+ assertEquals(l, e);
+ assertEquals(l.hashCode(), e.hashCode());
+
+ assertEquals(l.toNormalizedString(), e.toNormalizedString());
+ assertEquals(l.toString(), e.toString());
+
+ assertEquals(l.getRDN(), RDN.decode("dc=bar"));
+
+ assertEquals(l.getRDN(0), RDN.decode("dc=bar"));
+ assertEquals(l.getRDN(1), RDN.decode("dc=opends"));
+
+ assertEquals(l.getParent(), DN.decode("dc=opends"));
+ assertEquals(l.getParent(), e.getParent());
+
+ assertEquals(l.concat(RDN.decode("dc=xxx")), DN
+ .decode("dc=xxx,dc=bar,dc=opends"));
+ assertEquals(l.concat(DN.decode("dc=xxx,dc=yyy")), DN
+ .decode("dc=xxx,dc=yyy,dc=bar,dc=opends"));
+
+ assertEquals(l.getLocalName(1), DN.decode("dc=bar"));
+ assertEquals(l.getLocalName(0, 1), DN.decode("dc=opends"));
+ }
+
+
+
+ /**
+ * Is ancestor of test data provider.
+ *
+ * @return The array of test data.
+ */
+ @DataProvider(name = "createIsAncestorOfTestData")
+ public Object[][] createIsAncestorOfTestData() {
+ return new Object[][] {
+ { "", "", true },
+ { "", "dc=org", true },
+ { "", "dc=opends,dc=org", true },
+ { "", "dc=foo,dc=opends,dc=org", true },
+ { "dc=org", "", false },
+ { "dc=org", "dc=org", true },
+ { "dc=org", "dc=opends,dc=org", true },
+ { "dc=org", "dc=foo,dc=opends,dc=org", true },
+ { "dc=opends,dc=org", "", false },
+ { "dc=opends,dc=org", "dc=org", false },
+ { "dc=opends,dc=org", "dc=opends,dc=org", true },
+ { "dc=opends,dc=org", "dc=foo,dc=opends,dc=org", true },
+ { "dc=foo,dc=opends,dc=org", "", false },
+ { "dc=foo,dc=opends,dc=org", "dc=org", false },
+ { "dc=foo,dc=opends,dc=org", "dc=opends,dc=org", false },
+ { "dc=foo,dc=opends,dc=org", "dc=foo,dc=opends,dc=org", true },
+ { "dc=org", "dc=com", false },
+ { "dc=opends,dc=org", "dc=foo,dc=org", false },
+ { "dc=opends,dc=org", "dc=opends,dc=com", false }, };
+ }
+
+
+
+ /**
+ * Test the isAncestoryOf method.
+ *
+ * @param s
+ * The test DN string.
+ * @param d
+ * The dn parameter.
+ * @param e
+ * The expected result.
+ * @throws Exception
+ * If the test failed unexpectedly.
+ */
+ @Test(dataProvider = "createIsAncestorOfTestData")
+ public void testIsAncestorOf(String s, String d, boolean e)
+ throws Exception {
+ DN dn = DN.decode(s);
+ DN other = DN.decode(d);
+
+ assertEquals(dn.isAncestorOf(other), e, s + " isAncestoryOf " + d);
+ }
+
+
+
+ /**
+ * Test the isAncestorOf method.
+ *
+ * @throws Exception
+ * If the test failed unexpectedly.
+ */
+ @Test(expectedExceptions = { NullPointerException.class,
+ AssertionError.class })
+ public void testIsAncestorOfException() throws Exception {
+ DN dn = DN.decode("dc=com");
+ dn.isAncestorOf(null);
+ }
+
+
+
+ /**
+ * Is descendant of test data provider.
+ *
+ * @return The array of test data.
+ */
+ @DataProvider(name = "createIsDescendantOfTestData")
+ public Object[][] createIsDescendantOfTestData() {
+ return new Object[][] {
+ { "", "", true },
+ { "", "dc=org", false },
+ { "", "dc=opends,dc=org", false },
+ { "", "dc=foo,dc=opends,dc=org", false },
+ { "dc=org", "", true },
+ { "dc=org", "dc=org", true },
+ { "dc=org", "dc=opends,dc=org", false },
+ { "dc=org", "dc=foo,dc=opends,dc=org", false },
+ { "dc=opends,dc=org", "", true },
+ { "dc=opends,dc=org", "dc=org", true },
+ { "dc=opends,dc=org", "dc=opends,dc=org", true },
+ { "dc=opends,dc=org", "dc=foo,dc=opends,dc=org", false },
+ { "dc=foo,dc=opends,dc=org", "", true },
+ { "dc=foo,dc=opends,dc=org", "dc=org", true },
+ { "dc=foo,dc=opends,dc=org", "dc=opends,dc=org", true },
+ { "dc=foo,dc=opends,dc=org", "dc=foo,dc=opends,dc=org", true },
+ { "dc=org", "dc=com", false },
+ { "dc=opends,dc=org", "dc=foo,dc=org", false },
+ { "dc=opends,dc=org", "dc=opends,dc=com", false }, };
+ }
+
+
+
+ /**
+ * Test the isDescendantOf method.
+ *
+ * @param s
+ * The test DN string.
+ * @param d
+ * The dn parameter.
+ * @param e
+ * The expected result.
+ * @throws Exception
+ * If the test failed unexpectedly.
+ */
+ @Test(dataProvider = "createIsDescendantOfTestData")
+ public void testIsDescendantOf(String s, String d, boolean e)
+ throws Exception {
+ DN dn = DN.decode(s);
+ DN other = DN.decode(d);
+
+ assertEquals(dn.isDescendantOf(other), e, s + " isDescendantOf "
+ + d);
+ }
+
+
+
+ /**
+ * Test the isDescendantOf method.
+ *
+ * @throws Exception
+ * If the test failed unexpectedly.
+ */
+ @Test(expectedExceptions = { NullPointerException.class,
+ AssertionError.class })
+ public void testIsDescendantOfException() throws Exception {
+ DN dn = DN.decode("dc=com");
+ dn.isDescendantOf(null);
+ }
+
+
+
+ /**
+ * DN equality test data provider.
+ *
+ * @return The array of test DN strings.
+ */
+ @DataProvider(name = "createDNEqualityData")
+ public Object[][] createDNEqualityData() {
+ return new Object[][] {
+ { "cn=hello world,dc=com", "cn=hello world,dc=com", 0 },
+ { "cn=hello world,dc=com", "CN=hello world,dc=com", 0 },
+ { "cn=hello world,dc=com", "cn=hello world,dc=com", 0 },
+ { " cn = hello world ,dc=com", "cn=hello world,dc=com", 0 },
+ { "cn=hello world\\ ,dc=com", "cn=hello world,dc=com", 0 },
+ { "cn=HELLO WORLD,dc=com", "cn=hello world,dc=com", 0 },
+ { "cn=HELLO+sn=WORLD,dc=com", "sn=world+cn=hello,dc=com", 0 },
+ { "x-test-integer-type=10,dc=com",
+ "x-test-integer-type=9,dc=com", 1 },
+ { "x-test-integer-type=999,dc=com",
+ "x-test-integer-type=1000,dc=com", -1 },
+ { "x-test-integer-type=-1,dc=com",
+ "x-test-integer-type=0,dc=com", -1 },
+ { "x-test-integer-type=0,dc=com",
+ "x-test-integer-type=-1,dc=com", 1 },
+ { "cn=aaa,dc=com", "cn=aaaa,dc=com", -1 },
+ { "cn=AAA,dc=com", "cn=aaaa,dc=com", -1 },
+ { "cn=aaa,dc=com", "cn=AAAA,dc=com", -1 },
+ { "cn=aaaa,dc=com", "cn=aaa,dc=com", 1 },
+ { "cn=AAAA,dc=com", "cn=aaa,dc=com", 1 },
+ { "cn=aaaa,dc=com", "cn=AAA,dc=com", 1 },
+ { "cn=aaab,dc=com", "cn=aaaa,dc=com", 1 },
+ { "cn=aaaa,dc=com", "cn=aaab,dc=com", -1 },
+ { "dc=aaa,dc=aaa", "dc=bbb", -1 },
+ { "dc=bbb,dc=aaa", "dc=bbb", -1 },
+ { "dc=ccc,dc=aaa", "dc=bbb", -1 },
+ { "dc=aaa,dc=bbb", "dc=bbb", 1 },
+ { "dc=bbb,dc=bbb", "dc=bbb", 1 },
+ { "dc=ccc,dc=bbb", "dc=bbb", 1 },
+ { "dc=aaa,dc=ccc", "dc=bbb", 1 },
+ { "dc=bbb,dc=ccc", "dc=bbb", 1 },
+ { "dc=ccc,dc=ccc", "dc=bbb", 1 },
+
+ };
+ }
+
+
+
+ /**
+ * Test DN equality
+ *
+ * @param first
+ * First DN to compare.
+ * @param second
+ * Second DN to compare.
+ * @param result
+ * Expected comparison result.
+ * @throws Exception
+ * If the test failed unexpectedly.
+ */
+ @Test(dataProvider = "createDNEqualityData")
+ public void testEquality(String first, String second, int result)
+ throws Exception {
+ DN dn1 = DN.decode(first);
+ DN dn2 = DN.decode(second);
+
+ if (result == 0) {
+ assertTrue(dn1.equals(dn2), "DN equality for <" + first
+ + "> and <" + second + ">");
+ } else {
+ assertFalse(dn1.equals(dn2), "DN equality for <" + first
+ + "> and <" + second + ">");
+ }
+ }
+
+
+
+ /**
+ * Test DN hashCode
+ *
+ * @param first
+ * First DN to compare.
+ * @param second
+ * Second DN to compare.
+ * @param result
+ * Expected comparison result.
+ * @throws Exception
+ * If the test failed unexpectedly.
+ */
+ @Test(dataProvider = "createDNEqualityData")
+ public void testHashCode(String first, String second, int result)
+ throws Exception {
+ DN dn1 = DN.decode(first);
+ DN dn2 = DN.decode(second);
+
+ int h1 = dn1.hashCode();
+ int h2 = dn2.hashCode();
+
+ if (result == 0) {
+ if (h1 != h2) {
+ fail("Hash codes for <" + first + "> and <" + second
+ + "> should be the same.");
+ }
+ } else {
+ if (h1 == h2) {
+ fail("Hash codes for <" + first + "> and <" + second
+ + "> should be the same.");
+ }
+ }
+ }
+
+
+
+ /**
+ * Test DN compareTo
+ *
+ * @param first
+ * First DN to compare.
+ * @param second
+ * Second DN to compare.
+ * @param result
+ * Expected comparison result.
+ * @throws Exception
+ * If the test failed unexpectedly.
+ */
+ @Test(dataProvider = "createDNEqualityData")
+ public void testCompareTo(String first, String second, int result)
+ throws Exception {
+ DN dn1 = DN.decode(first);
+ DN dn2 = DN.decode(second);
+
+ int rc = dn1.compareTo(dn2);
+
+ // Normalize the result.
+ if (rc < 0) {
+ rc = -1;
+ } else if (rc > 0) {
+ rc = 1;
+ }
+
+ assertEquals(rc, result, "Comparison for <" + first + "> and <"
+ + second + ">.");
+ }
+
+
+
+ /**
+ * Test DN string decoder.
+ *
+ * @param rawDN
+ * Raw DN string representation.
+ * @param normDN
+ * Normalized DN string representation.
+ * @param stringDN
+ * String representation.
+ * @throws Exception
+ * If the test failed unexpectedly.
+ */
+ @Test(dataProvider = "testDNs")
+ public void testToString(String rawDN, String normDN,
+ String stringDN) throws Exception {
+ DN dn = DN.decode(rawDN);
+ assertEquals(dn.toString(), stringDN);
}
}
diff --git a/opends/tests/unit-tests-testng/src/server/org/opends/server/types/TestEntry.java b/opends/tests/unit-tests-testng/src/server/org/opends/server/types/TestEntry.java
index cca595a..e030d25 100644
--- a/opends/tests/unit-tests-testng/src/server/org/opends/server/types/TestEntry.java
+++ b/opends/tests/unit-tests-testng/src/server/org/opends/server/types/TestEntry.java
@@ -284,7 +284,7 @@
"{ base \"dc=example, dc=com\", maximum 2 }" };
// Relative to the root DN.
- DN rootDN = new DN();
+ DN rootDN = DN.nullDN();
SubtreeSpecificationSet expected = new SubtreeSpecificationSet();
for (String value : values) {
diff --git a/opends/tests/unit-tests-testng/src/server/org/opends/server/types/TestRDN.java b/opends/tests/unit-tests-testng/src/server/org/opends/server/types/TestRDN.java
new file mode 100644
index 0000000..eca7aa1
--- /dev/null
+++ b/opends/tests/unit-tests-testng/src/server/org/opends/server/types/TestRDN.java
@@ -0,0 +1,869 @@
+/*
+ * 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
+ *
+ *
+ * Portions Copyright 2006 Sun Microsystems, Inc.
+ */
+package org.opends.server.types;
+
+
+
+import static org.testng.Assert.assertEquals;
+import static org.testng.Assert.assertFalse;
+import static org.testng.Assert.assertTrue;
+import static org.testng.Assert.assertNull;
+import static org.testng.Assert.fail;
+
+import org.opends.server.TestCaseUtils;
+import org.opends.server.core.DirectoryServer;
+import org.opends.server.protocols.asn1.ASN1OctetString;
+import org.testng.annotations.BeforeClass;
+import org.testng.annotations.DataProvider;
+import org.testng.annotations.Test;
+
+
+
+/**
+ * This class defines a set of tests for the
+ * {@link org.opends.server.types.RDN} class.
+ */
+public final class TestRDN extends TypesTestCase {
+
+ // Domain component attribute type.
+ private AttributeType AT_DC;
+
+ // Common name attribute type.
+ private AttributeType AT_CN;
+
+ // Test attribute value.
+ private AttributeValue AV_DC_ORG;
+
+ // Test attribute value.
+ private AttributeValue AV_DC_OPENDS;
+
+ // Test attribute value.
+ private AttributeValue AV_CN;
+
+
+
+ /**
+ * Set up the environment for performing the tests in this suite.
+ *
+ * @throws Exception
+ * If the environment could not be set up.
+ */
+ @BeforeClass
+ public void setUp() throws Exception {
+ // This test suite depends on having the schema available, so
+ // we'll start the server.
+ TestCaseUtils.startServer();
+
+ AT_DC = DirectoryServer.getAttributeType("dc");
+ AT_CN = DirectoryServer.getAttributeType("cn");
+
+ AttributeType dummy = DirectoryServer.getDefaultAttributeType(
+ "x-test-integer-type", DirectoryServer
+ .getDefaultIntegerSyntax());
+ DirectoryServer.getSchema().registerAttributeType(dummy, true);
+
+ AV_DC_ORG = new AttributeValue(AT_DC, "org");
+ AV_DC_OPENDS = new AttributeValue(AT_DC, "opends");
+ AV_CN = new AttributeValue(AT_DC, "hello world");
+ }
+
+
+
+ // First test the constructors.
+
+ /**
+ * Check the constructor throws a NPE when parameters are not
+ * provided.
+ *
+ * @throws Exception
+ * If the test failed unexpectedly.
+ */
+ @Test(expectedExceptions = { NullPointerException.class,
+ AssertionError.class })
+ public void testConstructorNPE1() throws Exception {
+ RDN.create(AT_DC, null);
+ }
+
+
+
+ /**
+ * Check the constructor throws a NPE when parameters are not
+ * provided.
+ *
+ * @throws Exception
+ * If the test failed unexpectedly.
+ */
+ @Test(expectedExceptions = { NullPointerException.class,
+ AssertionError.class })
+ public void testConstructorNPE2() throws Exception {
+ RDN.create(null, AV_DC_ORG);
+ }
+
+
+
+ /**
+ * Check the constructor throws a NPE when parameters are not
+ * provided.
+ *
+ * @throws Exception
+ * If the test failed unexpectedly.
+ */
+ @Test(expectedExceptions = { NullPointerException.class,
+ AssertionError.class })
+ public void testConstructorNPE3() throws Exception {
+ RDN.create(AT_DC, "dc", null);
+ }
+
+
+
+ /**
+ * Check the constructor throws a NPE when parameters are not
+ * provided.
+ *
+ * @throws Exception
+ * If the test failed unexpectedly.
+ */
+ @Test(expectedExceptions = { NullPointerException.class,
+ AssertionError.class })
+ public void testConstructorNPE4() throws Exception {
+ RDN.create(AT_DC, null, AV_DC_ORG);
+ }
+
+
+
+ /**
+ * Check the constructor throws a NPE when parameters are not
+ * provided.
+ *
+ * @throws Exception
+ * If the test failed unexpectedly.
+ */
+ @Test(expectedExceptions = { NullPointerException.class,
+ AssertionError.class })
+ public void testConstructorNPE5() throws Exception {
+ RDN.create(null, "dc", AV_DC_ORG);
+ }
+
+
+
+ /**
+ * Check the decode method throws a NPE when parameters are not
+ * provided.
+ *
+ * @throws Exception
+ * If the test failed unexpectedly.
+ */
+ @Test(expectedExceptions = { NullPointerException.class,
+ AssertionError.class })
+ public void testDecodeNPE() throws Exception {
+ RDN.decode((String) null);
+ }
+
+
+
+ /**
+ * Check the valueOf method throws a NPE when parameters are not
+ * provided.
+ *
+ * @throws Exception
+ * If the test failed unexpectedly.
+ */
+ @Test(expectedExceptions = { NullPointerException.class,
+ AssertionError.class })
+ public void testValueOfNPE() throws Exception {
+ RDN.valueOf(null);
+ }
+
+
+
+ /**
+ * Test RDN construction with single AVA.
+ *
+ * @throws Exception
+ * If the test failed unexpectedly.
+ */
+ @Test
+ public void testConstructor() throws Exception {
+ RDN rdn = RDN.create(AT_DC, AV_DC_ORG);
+
+ assertEquals(rdn.getNumValues(), 1);
+ assertEquals(rdn.getAttributeType(0), AT_DC);
+ assertEquals(rdn.getAttributeName(0), AT_DC.getNameOrOID());
+ assertEquals(rdn.getAttributeValue(0), AV_DC_ORG);
+ }
+
+
+
+ /**
+ * Test RDN construction with single AVA and a user-defined name.
+ *
+ * @throws Exception
+ * If the test failed unexpectedly.
+ */
+ @Test
+ public void testConstructorWithName() throws Exception {
+ RDN rdn = RDN.create(AT_DC, "domainComponent", AV_DC_ORG);
+
+ assertEquals(rdn.getNumValues(), 1);
+ assertEquals(rdn.getAttributeType(0), AT_DC);
+ assertEquals(rdn.getAttributeName(0), "domainComponent");
+ assertEquals(rdn.getAttributeValue(0), AV_DC_ORG);
+ }
+
+
+
+ /**
+ * Test RDN builder.
+ *
+ * @throws Exception
+ * If the test failed unexpectedly.
+ */
+ @Test
+ public void testBuilder() throws Exception {
+ RDN.Builder builder = RDN.createBuilder();
+
+ builder.append(AT_DC, AV_DC_ORG);
+ RDN rdn = builder.getInstance();
+
+ assertEquals(rdn.getNumValues(), 1);
+ assertEquals(rdn.getAttributeType(0), AT_DC);
+ assertEquals(rdn.getAttributeName(0), AT_DC.getNameOrOID());
+ assertEquals(rdn.getAttributeValue(0), AV_DC_ORG);
+ }
+
+
+
+ /**
+ * Test RDN builder.
+ *
+ * @throws Exception
+ * If the test failed unexpectedly.
+ */
+ @Test
+ public void testBuilderWithName() throws Exception {
+ RDN.Builder builder = RDN.createBuilder();
+
+ builder.append(AT_DC, "domainComponent", AV_DC_ORG);
+ RDN rdn = builder.getInstance();
+
+ assertEquals(rdn.getNumValues(), 1);
+ assertEquals(rdn.getAttributeType(0), AT_DC);
+ assertEquals(rdn.getAttributeName(0), "domainComponent");
+ assertEquals(rdn.getAttributeValue(0), AV_DC_ORG);
+ }
+
+
+
+ /**
+ * Test RDN builder.
+ *
+ * @throws Exception
+ * If the test failed unexpectedly.
+ */
+ @Test
+ public void testBuilderIsEmpty() throws Exception {
+ RDN.Builder builder = RDN.createBuilder();
+
+ assertTrue(builder.isEmpty());
+
+ builder.append(AT_DC, AV_DC_ORG);
+
+ assertFalse(builder.isEmpty());
+
+ builder.getInstance();
+
+ assertFalse(builder.isEmpty());
+
+ builder.clear();
+
+ assertTrue(builder.isEmpty());
+ }
+
+
+
+ /**
+ * Test RDN builder.
+ *
+ * @throws Exception
+ * If the test failed unexpectedly.
+ */
+ @Test(expectedExceptions = IllegalArgumentException.class)
+ public void testBuilderDupesNotAllowed() throws Exception {
+ RDN.Builder builder = RDN.createBuilder();
+
+ builder.append(AT_DC, AV_DC_ORG);
+ builder.append(AT_DC, AV_DC_OPENDS);
+ }
+
+
+
+ /**
+ * Test RDN builder.
+ *
+ * @throws Exception
+ * If the test failed unexpectedly.
+ */
+ @Test
+ public void testBuilderMultiAVA() throws Exception {
+ RDN.Builder builder = RDN.createBuilder();
+
+ builder.append(AT_DC, AV_DC_ORG);
+ builder.append(AT_CN, AV_CN);
+ RDN rdn = builder.getInstance();
+
+ assertEquals(rdn.getNumValues(), 2);
+
+ assertEquals(rdn.getAttributeType(0), AT_DC);
+ assertEquals(rdn.getAttributeName(0), AT_DC.getNameOrOID());
+ assertEquals(rdn.getAttributeValue(0), AV_DC_ORG);
+
+ assertEquals(rdn.getAttributeType(1), AT_CN);
+ assertEquals(rdn.getAttributeName(1), AT_CN.getNameOrOID());
+ assertEquals(rdn.getAttributeValue(1), AV_CN);
+ }
+
+
+
+ /**
+ * RDN test data provider.
+ *
+ * @return The array of test RDN strings.
+ */
+ @DataProvider(name = "testRDNs")
+ public Object[][] createData() {
+ return new Object[][] {
+ { "dc=hello world", "dc=hello world", "dc=hello world" },
+ { "DC=HELLO WORLD", "dc=hello world", "DC=HELLO WORLD" },
+ { "dc = hello world", "dc=hello world",
+ "dc=hello world" },
+ { " dc = hello world ", "dc=hello world",
+ "dc=hello world" },
+ { "givenName=John+cn=Doe", "cn=doe+givenname=john",
+ "givenName=John+cn=Doe" },
+ { "givenName=John\\+cn=Doe", "givenname=john\\+cn=doe",
+ "givenName=John\\+cn=Doe" },
+ { "cn=Doe\\, John", "cn=doe\\, john", "cn=Doe\\, John" },
+ { "OU=Sales+CN=J. Smith", "cn=j. smith+ou=sales",
+ "OU=Sales+CN=J. Smith" },
+ { "CN=James \\\"Jim\\\" Smith\\, III",
+ "cn=james \\\"jim\\\" smith\\, iii",
+ "CN=James \\\"Jim\\\" Smith\\, III" },
+ { "CN=Before\\0dAfter", "cn=before\\0dafter",
+ "CN=Before\\0dAfter" },
+ { "1.3.6.1.4.1.1466.0=#04024869",
+ "1.3.6.1.4.1.1466.0=\\04\\02hi",
+ "1.3.6.1.4.1.1466.0=\\04\\02Hi" },
+ { "CN=Lu\\C4\\8Di\\C4\\87", "cn=lu\\c4\\8di\\c4\\87",
+ "CN=Lu\\c4\\8di\\c4\\87" },
+ { "ou=\\e5\\96\\b6\\e6\\a5\\ad\\e9\\83\\a8",
+ "ou=\\e5\\96\\b6\\e6\\a5\\ad\\e9\\83\\a8",
+ "ou=\\e5\\96\\b6\\e6\\a5\\ad\\e9\\83\\a8" },
+ { "photo=\\ john \\ ", "photo=\\ john \\ ",
+ "photo=\\ john \\ " },
+ { "AB-global=", "ab-global=", "AB-global=" },
+ { "cn=John+a=", "a=+cn=john", "cn=John+a=" },
+ { "OID.1.3.6.1.4.1.1466.0=#04024869",
+ "1.3.6.1.4.1.1466.0=\\04\\02hi",
+ "1.3.6.1.4.1.1466.0=\\04\\02Hi" },
+ { "O=\"Sue, Grabbit and Runn\"", "o=sue\\, grabbit and runn",
+ "O=Sue\\, Grabbit and Runn" }, };
+ }
+
+
+
+ /**
+ * Test RDN string decoder.
+ *
+ * @param rawRDN
+ * Raw RDN string representation.
+ * @param normRDN
+ * Normalized RDN string representation.
+ * @param stringRDN
+ * String representation.
+ * @throws Exception
+ * If the test failed unexpectedly.
+ */
+ @Test(dataProvider = "testRDNs")
+ public void testDecodeString(String rawRDN, String normRDN,
+ String stringRDN) throws Exception {
+ RDN rdn = RDN.decode(rawRDN);
+ assertEquals(rdn.toNormalizedString(), normRDN);
+ }
+
+
+
+ /**
+ * Test RDN byte string decoder.
+ *
+ * @param rawRDN
+ * Raw RDN string representation.
+ * @param normRDN
+ * Normalized RDN string representation.
+ * @param stringRDN
+ * String representation.
+ * @throws Exception
+ * If the test failed unexpectedly.
+ */
+ @Test(dataProvider = "testRDNs")
+ public void testDecodeByteString(String rawRDN, String normRDN,
+ String stringRDN) throws Exception {
+ ASN1OctetString octetString = new ASN1OctetString(rawRDN);
+ RDN rdn = RDN.decode(octetString);
+ assertEquals(rdn.toNormalizedString(), normRDN);
+ }
+
+
+
+ /**
+ * Test valueOf.
+ *
+ * @param rawRDN
+ * Raw RDN string representation.
+ * @param normRDN
+ * Normalized RDN string representation.
+ * @param stringRDN
+ * String representation.
+ * @throws Exception
+ * If the test failed unexpectedly.
+ */
+ @Test(dataProvider = "testRDNs")
+ public void testValueOf(String rawRDN, String normRDN,
+ String stringRDN) throws Exception {
+ RDN rdn = RDN.valueOf(rawRDN);
+ assertEquals(rdn.toNormalizedString(), normRDN);
+ }
+
+
+
+ /**
+ * Illegal RDN test data provider.
+ *
+ * @return The array of illegal test RDN strings.
+ */
+ @DataProvider(name = "illegalRDNs")
+ public Object[][] createIllegalData() {
+ return new Object[][] { { "" }, { "=" }, { "manager" },
+ { "manager " }, { "cn+Jim" }, { "cn=Jim+" }, { "cn=Jim+sn" },
+ { "cn=Jim," }, { "cn=Jim, " }, { "cn=Jim, sn=Jam " },
+ { "cn+uid=Jim" }, { "-cn=Jim" }, { "/tmp=a" }, { "\\tmp=a" },
+ { "cn;lang-en=Jim" }, { "@cn=Jim" }, { "_name_=Jim" },
+ { "\u03c0=pi" }, { "v1.0=buggy" },
+ { "1.3.6.1.4.1.1466..0=#04024869" }, };
+ }
+
+
+
+ /**
+ * Test RDN string decoder against illegal strings.
+ *
+ * @param rawRDN
+ * Illegal RDN string representation.
+ * @throws Exception
+ * If the test failed unexpectedly.
+ */
+ @Test(dataProvider = "illegalRDNs", expectedExceptions = DirectoryException.class)
+ public void testDecodeString(String rawRDN) throws Exception {
+ RDN.decode(rawRDN);
+
+ fail("Expected exception for value \"" + rawRDN + "\"");
+ }
+
+
+
+ /**
+ * Test RDN byte string decoder against illegal strings.
+ *
+ * @param rawRDN
+ * Illegal RDN string representation.
+ * @throws Exception
+ * If the test failed unexpectedly.
+ */
+ @Test(dataProvider = "illegalRDNs", expectedExceptions = DirectoryException.class)
+ public void testDecodeByteString(String rawRDN) throws Exception {
+ ASN1OctetString octetString = new ASN1OctetString(rawRDN);
+ RDN.decode(octetString);
+
+ fail("Expected exception for value \"" + rawRDN + "\"");
+ }
+
+
+
+ /**
+ * Test valueOf against illegal strings.
+ *
+ * @param rawRDN
+ * Illegal RDN string representation.
+ * @throws Exception
+ * If the test failed unexpectedly.
+ */
+ @Test(dataProvider = "illegalRDNs", expectedExceptions = DirectoryException.class)
+ public void testValueOf(String rawRDN) throws Exception {
+ RDN.valueOf(rawRDN);
+
+ fail("Expected exception for value \"" + rawRDN + "\"");
+ }
+
+
+
+ /**
+ * Test getAttributeName.
+ *
+ * @throws Exception
+ * If the test failed unexpectedly.
+ */
+ @Test
+ public void testGetAttributeName() throws Exception {
+ RDN.Builder builder = RDN.createBuilder();
+
+ builder.append(AT_DC, AV_DC_ORG);
+ builder.append(AT_CN, AV_CN);
+ RDN rdn = builder.getInstance();
+
+ assertEquals(rdn.getAttributeName(0), AT_DC.getNameOrOID());
+ assertEquals(rdn.getAttributeName(1), AT_CN.getNameOrOID());
+ }
+
+
+
+ /**
+ * Test getAttributeName IndexOutOfBoundsException.
+ *
+ * @throws Exception
+ * If the test failed unexpectedly.
+ */
+ @Test(expectedExceptions = IndexOutOfBoundsException.class)
+ public void testGetAttributeNameException() throws Exception {
+ RDN.Builder builder = RDN.createBuilder();
+
+ builder.append(AT_DC, AV_DC_ORG);
+ RDN rdn = builder.getInstance();
+
+ rdn.getAttributeName(1);
+ }
+
+
+
+ /**
+ * Test getAttributeType.
+ *
+ * @throws Exception
+ * If the test failed unexpectedly.
+ */
+ @Test
+ public void testGetAttributeType() throws Exception {
+ RDN.Builder builder = RDN.createBuilder();
+
+ builder.append(AT_DC, AV_DC_ORG);
+ builder.append(AT_CN, AV_CN);
+ RDN rdn = builder.getInstance();
+
+ assertEquals(rdn.getAttributeType(0), AT_DC);
+ assertEquals(rdn.getAttributeType(1), AT_CN);
+ }
+
+
+
+ /**
+ * Test getAttributeType IndexOutOfBoundsException.
+ *
+ * @throws Exception
+ * If the test failed unexpectedly.
+ */
+ @Test(expectedExceptions = IndexOutOfBoundsException.class)
+ public void testGetAttributeTypeException() throws Exception {
+ RDN.Builder builder = RDN.createBuilder();
+
+ builder.append(AT_DC, AV_DC_ORG);
+ RDN rdn = builder.getInstance();
+
+ rdn.getAttributeType(1);
+ }
+
+
+
+ /**
+ * Test getAttributeValue.
+ *
+ * @throws Exception
+ * If the test failed unexpectedly.
+ */
+ @Test
+ public void testGetAttributeValue() throws Exception {
+ RDN.Builder builder = RDN.createBuilder();
+
+ builder.append(AT_DC, AV_DC_ORG);
+ builder.append(AT_CN, AV_CN);
+ RDN rdn = builder.getInstance();
+
+ assertEquals(rdn.getAttributeValue(0), AV_DC_ORG);
+ assertEquals(rdn.getAttributeValue(1), AV_CN);
+ }
+
+
+
+ /**
+ * Test getAttributeValue IndexOutOfBoundsException.
+ *
+ * @throws Exception
+ * If the test failed unexpectedly.
+ */
+ @Test(expectedExceptions = IndexOutOfBoundsException.class)
+ public void testGetAttributeValueException() throws Exception {
+ RDN.Builder builder = RDN.createBuilder();
+
+ builder.append(AT_DC, AV_DC_ORG);
+ RDN rdn = builder.getInstance();
+
+ rdn.getAttributeValue(1);
+ }
+
+
+
+ /**
+ * Test getAttributeValue.
+ *
+ * @throws Exception
+ * If the test failed unexpectedly.
+ */
+ @Test
+ public void testGetAttributeValueByType() throws Exception {
+ RDN.Builder builder = RDN.createBuilder();
+
+ builder.append(AT_DC, AV_DC_ORG);
+ RDN rdn = builder.getInstance();
+
+ assertEquals(rdn.getAttributeValue(AT_DC), AV_DC_ORG);
+ assertNull(rdn.getAttributeValue(AT_CN));
+ }
+
+
+
+ /**
+ * Test getNumValues.
+ *
+ * @throws Exception
+ * If the test failed unexpectedly.
+ */
+ @Test
+ public void testGetNumValues() throws Exception {
+ RDN.Builder builder = RDN.createBuilder();
+
+ builder.append(AT_DC, AV_DC_ORG);
+ RDN rdn = builder.getInstance();
+ assertEquals(rdn.getNumValues(), 1);
+
+ builder.append(AT_CN, AV_CN);
+ rdn = builder.getInstance();
+ assertEquals(rdn.getNumValues(), 2);
+ }
+
+
+
+ /**
+ * Test hasAttributeType.
+ *
+ * @throws Exception
+ * If the test failed unexpectedly.
+ */
+ @Test
+ public void testHasAttributeType() throws Exception {
+ RDN.Builder builder = RDN.createBuilder();
+ builder.append(AT_DC, AV_DC_ORG);
+ RDN rdn = builder.getInstance();
+
+ assertTrue(rdn.hasAttributeType(AT_DC));
+ assertFalse(rdn.hasAttributeType(AT_CN));
+ }
+
+
+
+ /**
+ * Test isMultiValued.
+ *
+ * @throws Exception
+ * If the test failed unexpectedly.
+ */
+ @Test
+ public void testIsMultiValued() throws Exception {
+ RDN.Builder builder = RDN.createBuilder();
+
+ builder.append(AT_DC, AV_DC_ORG);
+ RDN rdn = builder.getInstance();
+ assertFalse(rdn.isMultiValued());
+
+ builder.append(AT_CN, AV_CN);
+ rdn = builder.getInstance();
+ assertTrue(rdn.isMultiValued());
+ }
+
+
+
+ /**
+ * Test RDN string decoder.
+ *
+ * @param rawRDN
+ * Raw RDN string representation.
+ * @param normRDN
+ * Normalized RDN string representation.
+ * @param stringRDN
+ * String representation.
+ * @throws Exception
+ * If the test failed unexpectedly.
+ */
+ @Test(dataProvider = "testRDNs")
+ public void testToString(String rawRDN, String normRDN,
+ String stringRDN) throws Exception {
+ RDN rdn = RDN.decode(rawRDN);
+ assertEquals(rdn.toString(), stringRDN);
+ }
+
+
+
+ /**
+ * RDN equality test data provider.
+ *
+ * @return The array of test RDN strings.
+ */
+ @DataProvider(name = "createRDNEqualityData")
+ public Object[][] createRDNEqualityData() {
+ return new Object[][] {
+ { "cn=hello world", "cn=hello world", 0 },
+ { "cn=hello world", "CN=hello world", 0 },
+ { "cn=hello world", "cn=hello world", 0 },
+ { " cn = hello world ", "cn=hello world", 0 },
+ { "cn=hello world\\ ", "cn=hello world", 0 },
+ { "cn=HELLO WORLD", "cn=hello world", 0 },
+ { "cn=HELLO+sn=WORLD", "sn=world+cn=hello", 0 },
+ { "x-test-integer-type=10", "x-test-integer-type=9", 1 },
+ { "x-test-integer-type=999", "x-test-integer-type=1000", -1 },
+ { "x-test-integer-type=-1", "x-test-integer-type=0", -1 },
+ { "x-test-integer-type=0", "x-test-integer-type=-1", 1 },
+ { "cn=aaa", "cn=aaaa", -1 }, { "cn=AAA", "cn=aaaa", -1 },
+ { "cn=aaa", "cn=AAAA", -1 }, { "cn=aaaa", "cn=aaa", 1 },
+ { "cn=AAAA", "cn=aaa", 1 }, { "cn=aaaa", "cn=AAA", 1 },
+ { "cn=aaab", "cn=aaaa", 1 }, { "cn=aaaa", "cn=aaab", -1 } };
+ }
+
+
+
+ /**
+ * Test RDN equality
+ *
+ * @param first
+ * First RDN to compare.
+ * @param second
+ * Second RDN to compare.
+ * @param result
+ * Expected comparison result.
+ * @throws Exception
+ * If the test failed unexpectedly.
+ */
+ @Test(dataProvider = "createRDNEqualityData")
+ public void testEquality(String first, String second, int result)
+ throws Exception {
+ RDN rdn1 = RDN.decode(first);
+ RDN rdn2 = RDN.decode(second);
+
+ if (result == 0) {
+ assertTrue(rdn1.equals(rdn2), "RDN equality for <" + first
+ + "> and <" + second + ">");
+ } else {
+ assertFalse(rdn1.equals(rdn2), "RDN equality for <" + first
+ + "> and <" + second + ">");
+ }
+ }
+
+
+
+ /**
+ * Test RDN hashCode
+ *
+ * @param first
+ * First RDN to compare.
+ * @param second
+ * Second RDN to compare.
+ * @param result
+ * Expected comparison result.
+ * @throws Exception
+ * If the test failed unexpectedly.
+ */
+ @Test(dataProvider = "createRDNEqualityData")
+ public void testHashCode(String first, String second, int result)
+ throws Exception {
+ RDN rdn1 = RDN.decode(first);
+ RDN rdn2 = RDN.decode(second);
+
+ int h1 = rdn1.hashCode();
+ int h2 = rdn2.hashCode();
+
+ if (result == 0) {
+ if (h1 != h2) {
+ fail("Hash codes for <" + first + "> and <" + second
+ + "> should be the same.");
+ }
+ } else {
+ if (h1 == h2) {
+ fail("Hash codes for <" + first + "> and <" + second
+ + "> should be the same.");
+ }
+ }
+ }
+
+
+
+ /**
+ * Test RDN compareTo
+ *
+ * @param first
+ * First RDN to compare.
+ * @param second
+ * Second RDN to compare.
+ * @param result
+ * Expected comparison result.
+ * @throws Exception
+ * If the test failed unexpectedly.
+ */
+ @Test(dataProvider = "createRDNEqualityData")
+ public void testCompareTo(String first, String second, int result)
+ throws Exception {
+ RDN rdn1 = RDN.decode(first);
+ RDN rdn2 = RDN.decode(second);
+
+ int rc = rdn1.compareTo(rdn2);
+
+ // Normalize the result.
+ if (rc < 0) {
+ rc = -1;
+ } else if (rc > 0) {
+ rc = 1;
+ }
+
+ assertEquals(rc, result, "Comparison for <" + first + "> and <"
+ + second + ">.");
+ }
+
+}
diff --git a/opends/tests/unit-tests-testng/src/server/org/opends/server/util/TestAddChangeRecordEntry.java b/opends/tests/unit-tests-testng/src/server/org/opends/server/util/TestAddChangeRecordEntry.java
index a174139..01882ec 100644
--- a/opends/tests/unit-tests-testng/src/server/org/opends/server/util/TestAddChangeRecordEntry.java
+++ b/opends/tests/unit-tests-testng/src/server/org/opends/server/util/TestAddChangeRecordEntry.java
@@ -83,7 +83,7 @@
@Test(expectedExceptions = { NullPointerException.class,
AssertionError.class })
public void testConstructorNullDN() throws Exception {
- AddChangeRecordEntry entry = new AddChangeRecordEntry(null, attributes);
+ new AddChangeRecordEntry(null, attributes);
}
/**
@@ -94,10 +94,10 @@
*/
@Test
public void testConstructorEmptyDN() throws Exception {
- AddChangeRecordEntry entry = new AddChangeRecordEntry(new DN(),
+ AddChangeRecordEntry entry = new AddChangeRecordEntry(DN.nullDN(),
attributes);
- Assert.assertEquals(entry.getDN(), new DN());
+ Assert.assertEquals(entry.getDN(), DN.nullDN());
}
/**
@@ -125,7 +125,7 @@
*/
@Test
public void testChangeOperationType() throws Exception {
- AddChangeRecordEntry entry = new AddChangeRecordEntry(new DN(), attributes);
+ AddChangeRecordEntry entry = new AddChangeRecordEntry(DN.nullDN(), attributes);
Assert.assertEquals(entry.getChangeOperationType(),
ChangeOperationType.ADD);
@@ -140,7 +140,7 @@
@Test
public void testGetAttributesEmpty() throws Exception {
Map<AttributeType, List<Attribute>> empty = Collections.emptyMap();
- AddChangeRecordEntry entry = new AddChangeRecordEntry(new DN(), empty);
+ AddChangeRecordEntry entry = new AddChangeRecordEntry(DN.nullDN(), empty);
List<Attribute> attrs = entry.getAttributes();
Assert.assertEquals(attrs.size(), 0);
@@ -154,7 +154,7 @@
*/
@Test
public void testGetAttributesNonEmpty() throws Exception {
- AddChangeRecordEntry entry = new AddChangeRecordEntry(new DN(), attributes);
+ AddChangeRecordEntry entry = new AddChangeRecordEntry(DN.nullDN(), attributes);
List<Attribute> attrs = entry.getAttributes();
Assert.assertEquals(attrs.size(), 1);
diff --git a/opends/tests/unit-tests-testng/src/server/org/opends/server/util/TestChangeRecordEntry.java b/opends/tests/unit-tests-testng/src/server/org/opends/server/util/TestChangeRecordEntry.java
index d7eca57..2940f7c 100644
--- a/opends/tests/unit-tests-testng/src/server/org/opends/server/util/TestChangeRecordEntry.java
+++ b/opends/tests/unit-tests-testng/src/server/org/opends/server/util/TestChangeRecordEntry.java
@@ -87,10 +87,9 @@
@Test(expectedExceptions = { NullPointerException.class,
AssertionError.class })
public void testConstructorNullDN() throws Exception {
- MyChangeRecordEntry entry = new MyChangeRecordEntry(null);
+ new MyChangeRecordEntry(null);
}
-
/**
* Tests the constructor with empty DN.
*
@@ -99,9 +98,9 @@
*/
@Test
public void testConstructorEmptyDN() throws Exception {
- MyChangeRecordEntry entry = new MyChangeRecordEntry(new DN());
+ MyChangeRecordEntry entry = new MyChangeRecordEntry(DN.nullDN());
- Assert.assertEquals(entry.getDN(), new DN());
+ Assert.assertEquals(entry.getDN(), DN.nullDN());
}
/**
diff --git a/opends/tests/unit-tests-testng/src/server/org/opends/server/util/TestDeleteChangeRecordEntry.java b/opends/tests/unit-tests-testng/src/server/org/opends/server/util/TestDeleteChangeRecordEntry.java
index 3edf953..2ecb885 100644
--- a/opends/tests/unit-tests-testng/src/server/org/opends/server/util/TestDeleteChangeRecordEntry.java
+++ b/opends/tests/unit-tests-testng/src/server/org/opends/server/util/TestDeleteChangeRecordEntry.java
@@ -63,7 +63,7 @@
@Test(expectedExceptions = { NullPointerException.class,
AssertionError.class })
public void testConstructorNullDN() throws Exception {
- DeleteChangeRecordEntry entry = new DeleteChangeRecordEntry(null);
+ new DeleteChangeRecordEntry(null);
}
/**
@@ -74,9 +74,9 @@
*/
@Test
public void testConstructorEmptyDN() throws Exception {
- DeleteChangeRecordEntry entry = new DeleteChangeRecordEntry(new DN());
+ DeleteChangeRecordEntry entry = new DeleteChangeRecordEntry(DN.nullDN());
- Assert.assertEquals(entry.getDN(), new DN());
+ Assert.assertEquals(entry.getDN(), DN.nullDN());
}
/**
@@ -103,7 +103,7 @@
*/
@Test
public void testChangeOperationType() throws Exception {
- DeleteChangeRecordEntry entry = new DeleteChangeRecordEntry(new DN());
+ DeleteChangeRecordEntry entry = new DeleteChangeRecordEntry(DN.nullDN());
Assert.assertEquals(entry.getChangeOperationType(),
ChangeOperationType.DELETE);
diff --git a/opends/tests/unit-tests-testng/src/server/org/opends/server/util/TestModifyChangeRecordEntry.java b/opends/tests/unit-tests-testng/src/server/org/opends/server/util/TestModifyChangeRecordEntry.java
index db2ab0d..c7c4a0f 100644
--- a/opends/tests/unit-tests-testng/src/server/org/opends/server/util/TestModifyChangeRecordEntry.java
+++ b/opends/tests/unit-tests-testng/src/server/org/opends/server/util/TestModifyChangeRecordEntry.java
@@ -85,8 +85,7 @@
@Test(expectedExceptions = { NullPointerException.class,
AssertionError.class })
public void testConstructorNullDN() throws Exception {
- ModifyChangeRecordEntry entry = new ModifyChangeRecordEntry(null,
- modifications);
+ new ModifyChangeRecordEntry(null, modifications);
}
/**
@@ -97,10 +96,10 @@
*/
@Test
public void testConstructorEmptyDN() throws Exception {
- ModifyChangeRecordEntry entry = new ModifyChangeRecordEntry(new DN(),
+ ModifyChangeRecordEntry entry = new ModifyChangeRecordEntry(DN.nullDN(),
modifications);
- Assert.assertEquals(entry.getDN(), new DN());
+ Assert.assertEquals(entry.getDN(), DN.nullDN());
}
/**
@@ -128,7 +127,7 @@
*/
@Test
public void testChangeOperationType() throws Exception {
- ModifyChangeRecordEntry entry = new ModifyChangeRecordEntry(new DN(),
+ ModifyChangeRecordEntry entry = new ModifyChangeRecordEntry(DN.nullDN(),
modifications);
Assert.assertEquals(entry.getChangeOperationType(),
@@ -144,7 +143,7 @@
@Test
public void testGetModificationsEmpty() throws Exception {
List<LDAPModification> empty = Collections.emptyList();
- ModifyChangeRecordEntry entry = new ModifyChangeRecordEntry(new DN(),
+ ModifyChangeRecordEntry entry = new ModifyChangeRecordEntry(DN.nullDN(),
empty);
List<LDAPModification> mods = entry.getModifications();
@@ -159,7 +158,7 @@
*/
@Test
public void testGetModificationsNonEmpty() throws Exception {
- ModifyChangeRecordEntry entry = new ModifyChangeRecordEntry(new DN(),
+ ModifyChangeRecordEntry entry = new ModifyChangeRecordEntry(DN.nullDN(),
modifications);
List<LDAPModification> mods = entry.getModifications();
diff --git a/opends/tests/unit-tests-testng/src/server/org/opends/server/util/TestModifyDNChangeRecordEntry.java b/opends/tests/unit-tests-testng/src/server/org/opends/server/util/TestModifyDNChangeRecordEntry.java
index 804535b..3428a07 100644
--- a/opends/tests/unit-tests-testng/src/server/org/opends/server/util/TestModifyDNChangeRecordEntry.java
+++ b/opends/tests/unit-tests-testng/src/server/org/opends/server/util/TestModifyDNChangeRecordEntry.java
@@ -71,8 +71,7 @@
@Test(expectedExceptions = { NullPointerException.class,
AssertionError.class })
public void testConstructorNullDN() throws Exception {
- ModifyDNChangeRecordEntry entry =
- new ModifyDNChangeRecordEntry(null, newRDN, false, newSuperiorDN);
+ new ModifyDNChangeRecordEntry(null, newRDN, false, newSuperiorDN);
}
/**
@@ -84,9 +83,9 @@
@Test
public void testConstructorEmptyDN() throws Exception {
ModifyDNChangeRecordEntry entry = new ModifyDNChangeRecordEntry(
- new DN(), newRDN, false, newSuperiorDN);
+ DN.nullDN(), newRDN, false, newSuperiorDN);
- Assert.assertEquals(entry.getDN(), new DN());
+ Assert.assertEquals(entry.getDN(), DN.nullDN());
}
/**
@@ -115,7 +114,7 @@
@Test
public void testChangeOperationType() throws Exception {
ModifyDNChangeRecordEntry entry =
- new ModifyDNChangeRecordEntry(new DN(), newRDN, false, newSuperiorDN);
+ new ModifyDNChangeRecordEntry(DN.nullDN(), newRDN, false, newSuperiorDN);
Assert.assertEquals(entry.getChangeOperationType(),
ChangeOperationType.MODIFY_DN);
@@ -130,9 +129,9 @@
@Test
public void testGetNewRDN() throws Exception {
ModifyDNChangeRecordEntry entry =
- new ModifyDNChangeRecordEntry(new DN(), newRDN, false, newSuperiorDN);
+ new ModifyDNChangeRecordEntry(DN.nullDN(), newRDN, false, newSuperiorDN);
- Assert.assertEquals(entry.getNewRDN(), newRDN.duplicate());
+ Assert.assertEquals(entry.getNewRDN(), newRDN);
}
/**
@@ -144,10 +143,10 @@
@Test
public void testGetNewSuperiorDN() throws Exception {
ModifyDNChangeRecordEntry entry =
- new ModifyDNChangeRecordEntry(new DN(), newRDN, false, newSuperiorDN);
+ new ModifyDNChangeRecordEntry(DN.nullDN(), newRDN, false, newSuperiorDN);
Assert
- .assertEquals(entry.getNewSuperiorDN(), newSuperiorDN.duplicate());
+ .assertEquals(entry.getNewSuperiorDN(), newSuperiorDN);
}
/**
@@ -159,7 +158,7 @@
@Test
public void testDeleteOldRDNFalse() throws Exception {
ModifyDNChangeRecordEntry entry =
- new ModifyDNChangeRecordEntry(new DN(), newRDN, false, newSuperiorDN);
+ new ModifyDNChangeRecordEntry(DN.nullDN(), newRDN, false, newSuperiorDN);
Assert.assertEquals(entry.deleteOldRDN(), false);
}
@@ -173,7 +172,7 @@
@Test
public void testDeleteOldRDNTrue() throws Exception {
ModifyDNChangeRecordEntry entry =
- new ModifyDNChangeRecordEntry(new DN(), newRDN, true, newSuperiorDN);
+ new ModifyDNChangeRecordEntry(DN.nullDN(), newRDN, true, newSuperiorDN);
Assert.assertEquals(entry.deleteOldRDN(), true);
}
diff --git a/opends/tests/unit-tests-testng/src/server/org/opends/server/util/TestStaticUtils.java b/opends/tests/unit-tests-testng/src/server/org/opends/server/util/TestStaticUtils.java
index 059c3d5..a6ee8a4 100644
--- a/opends/tests/unit-tests-testng/src/server/org/opends/server/util/TestStaticUtils.java
+++ b/opends/tests/unit-tests-testng/src/server/org/opends/server/util/TestStaticUtils.java
@@ -293,6 +293,65 @@
}
/**
+ * Create test data for {@link StaticUtils#compare(byte[], byte[])}.
+ *
+ * @return Returns an array of test data.
+ */
+ @DataProvider(name = "compareBytesTestData")
+ public Object[][] createCompareBytesTestData() {
+ return new Object[][] {
+ { null, null, 0 },
+ { null, new byte[0], -1 },
+ { new byte[0], null, 1 },
+ { new byte[0], new byte[0], 0 },
+ { new byte[] { 0x00 }, new byte[] { 0x00 }, 0 },
+ { new byte[] { 0x01 }, new byte[] { 0x00 }, 1 },
+ { new byte[] { 0x7f }, new byte[] { 0x00 }, 1 },
+ { new byte[] { (byte) 0x80 }, new byte[] { 0x00 }, -1 },
+ { new byte[] { (byte) 0xff }, new byte[] { 0x00 }, -1 },
+ { new byte[] { 0x00 }, new byte[] { 0x01 }, -1 },
+ { new byte[] { 0x00 }, new byte[] { 0x7f }, -1 },
+ { new byte[] { 0x00 }, new byte[] { (byte) 0x80 }, 1 },
+ { new byte[] { 0x00 }, new byte[] { (byte) 0xff }, 1 },
+ { new byte[] { 0x00, 0x01, 0x02 },
+ new byte[] { 0x00, 0x01, 0x02 }, 0 },
+ { new byte[] { 0x00, 0x01 }, new byte[] { 0x00, 0x01, 0x02 },
+ -1 },
+ { new byte[] { 0x00, 0x01, 0x02 }, new byte[] { 0x00, 0x01 },
+ 1 }, };
+ }
+
+ /**
+ * Tests the {@link StaticUtils#compare(byte[], byte[])} method.
+ *
+ * @param a
+ * The first byte array.
+ * @param a2
+ * The second byte array.
+ * @param expected
+ * The expected result.
+ * @throws Exception
+ * If the test failed unexpectedly.
+ */
+ @Test(dataProvider = "compareBytesTestData")
+ public void testCompareBytes(byte[] a, byte[] a2, int expected)
+ throws Exception {
+ int rc = StaticUtils.compare(a, a2);
+
+ if (expected < 0 && rc >= 0) {
+ Assert.fail("Expected negative result but got " + rc);
+ }
+
+ if (expected > 0 && rc <= 0) {
+ Assert.fail("Expected positive result but got " + rc);
+ }
+
+ if (expected == 0 && rc != 0) {
+ Assert.fail("Expected zero result but got " + rc);
+ }
+ }
+
+ /**
* Create test strings for the {@link StaticUtils#isDigit(char)}.
*
* @return Returns an array of test data.
--
Gitblit v1.10.0