opendj-core/src/main/java/org/forgerock/opendj/ldap/AVA.java
@@ -799,7 +799,7 @@ * @param builder * The builder to use to construct the normalized byte string. * @return The normalized byte string representation. * @see DN#toIrreversibleNormalizedByteString() * @see DN#toNormalizedByteString() */ ByteStringBuilder toNormalizedByteString(final ByteStringBuilder builder) { builder.append(toLowerCase(attributeType.getNameOrOID())); @@ -819,9 +819,9 @@ * @param builder * The builder to use to construct the normalized string. * @return The normalized readable string representation. * @see DN#toIrreversibleReadableString() * @see DN#toNormalizedUrlSafeString() */ StringBuilder toNormalizedReadableString(final StringBuilder builder) { StringBuilder toNormalizedUrlSafe(final StringBuilder builder) { builder.append(toLowerCase(attributeType.getNameOrOID())); builder.append('='); final ByteString value = getEqualityNormalizedValue(); opendj-core/src/main/java/org/forgerock/opendj/ldap/DN.java
@@ -258,7 +258,8 @@ /** * Compares the provided DN values to determine their relative order in a * sorted list. * sorted list. The order is the natural order as defined by the * {@code toNormalizedByteString()} method. * * @param dn1 * The first DN to be compared. It must not be {@code null}. @@ -270,42 +271,7 @@ * values can be considered equal. */ private static int compareTo(final DN dn1, final DN dn2) { // Quickly check if we are comparing against root dse. if (dn1.isRootDN()) { if (dn2.isRootDN()) { // both are equal. return 0; } // dn1 comes before dn2. return -1; } if (dn2.isRootDN()) { // dn1 comes after dn2. return 1; } int dn1Size = dn1.size - 1; int dn2Size = dn2.size - 1; while (dn1Size >= 0 && dn2Size >= 0) { final DN dn1Parent = dn1.parent(dn1Size--); final DN dn2Parent = dn2.parent(dn2Size--); final int result = dn1Parent.rdn.compareTo(dn2Parent.rdn); if (result > 0) { return 1; } else if (result < 0) { return -1; } } // What do we have here? if (dn1Size > dn2Size) { return 1; } else if (dn1Size < dn2Size) { return -1; } return 0; return dn1.toNormalizedByteString().compareTo(dn2.toNormalizedByteString()); } /** Decodes a DN using the provided reader and schema. */ @@ -370,6 +336,12 @@ private final int size; /** * The normalized byte string representation of this DN, which is not * a valid DN and is not reversible to a valid DN. */ private ByteString normalizedDN; /** * We need to store the original string value if provided in order to * preserve the original whitespace. */ @@ -497,29 +469,18 @@ public boolean equals(final Object obj) { if (this == obj) { return true; } else if (obj instanceof DN) { DN other = (DN) obj; if (size == other.size()) { if (size == 0) { return true; } if (rdn.equals(other.rdn)) { return parent.equals(other.parent); } } } if (obj instanceof DN) { DN otherDN = (DN) obj; return toNormalizedByteString().equals(otherDN.toNormalizedByteString()); } return false; } /** {@inheritDoc} */ @Override public int hashCode() { if (size == 0) { return 0; } return 31 * parent.hashCode() + rdn.hashCode(); return toNormalizedByteString().hashCode(); } /** @@ -920,62 +881,60 @@ } /** * Returns the irreversible normalized byte string representation of a DN, * suitable for equality and comparisons, and providing a natural hierarchical * ordering, but not usable as a valid DN nor reversible to a valid DN. * Retrieves a normalized byte string representation of this DN. * <p> * This representation should be used only when a byte string representation * is needed and when no reversibility to a valid DN is needed. Always consider * using a {@code CompactDn} as an alternative. * This representation is suitable for equality and comparisons, and * for providing a natural hierarchical ordering. * However, it is not a valid DN and can't be reverted to a valid DN. * You should consider using a {@code CompactDn} as an alternative. * * @return The normalized byte string representation of the provided DN, not * usable as a valid DN * @return The normalized string representation of this DN. */ public ByteString toIrreversibleNormalizedByteString() { if (rdn() == null) { return ByteString.empty(); } final ByteStringBuilder builder = new ByteStringBuilder(); int i = size() - 1; parent(i).rdn().toNormalizedByteString(builder); for (i--; i >= 0; i--) { final RDN rdn = parent(i).rdn(); // Only add a separator if the RDN is not RDN.maxValue(). if (rdn.size() != 0) { builder.append(DN.NORMALIZED_RDN_SEPARATOR); public ByteString toNormalizedByteString() { if (normalizedDN == null) { if (rdn() == null) { normalizedDN = ByteString.empty(); } else { final ByteStringBuilder builder = new ByteStringBuilder(); int i = size() - 1; parent(i).rdn().toNormalizedByteString(builder); for (i--; i >= 0; i--) { final RDN rdn = parent(i).rdn(); // Only add a separator if the RDN is not RDN.maxValue(). if (rdn.size() != 0) { builder.append(DN.NORMALIZED_RDN_SEPARATOR); } rdn.toNormalizedByteString(builder); } normalizedDN = builder.toByteString(); } rdn.toNormalizedByteString(builder); } return builder.toByteString(); return normalizedDN; } /** * Returns the irreversible readable string representation of a DN, suitable * for equality and usage as a name in file system or URL, but not usable as * a valid DN nor reversible to a valid DN. * Retrieves a normalized string representation of this DN. * <p> * This representation should be used only when a string representation is * needed and when no reversibility to a valid DN is needed. * This representation is safe to use in an URL or in a file name. * However, it is not a valid DN and can't be reverted to a valid DN. * * @return The readable string representation of the provided DN, * not usable as a valid DN * @return The normalized string representation of this DN. */ public String toIrreversibleReadableString() { public String toNormalizedUrlSafeString() { if (rdn() == null) { return ""; } final StringBuilder builder = new StringBuilder(); int i = size() - 1; parent(i).rdn().toNormalizedReadableString(builder); parent(i).rdn().toNormalizedUrlSafeString(builder); for (i--; i >= 0; i--) { final RDN rdn = parent(i).rdn(); // Only add a separator if the RDN is not RDN.maxValue(). if (rdn.size() != 0) { builder.append(','); } rdn.toNormalizedReadableString(builder); rdn.toNormalizedUrlSafeString(builder); } return builder.toString(); } @@ -1058,7 +1017,7 @@ private byte[] getNormalizedValue() { if (normalizedValue == null) { normalizedValue = toDn().toIrreversibleNormalizedByteString().toByteArray(); normalizedValue = toDn().toNormalizedByteString().toByteArray(); } return normalizedValue; } opendj-core/src/main/java/org/forgerock/opendj/ldap/RDN.java
@@ -257,6 +257,7 @@ } /** {@inheritDoc} */ @Override public int compareTo(final RDN rdn) { // Identity. if (this == rdn) { @@ -373,6 +374,7 @@ * * @return An iterator of the AVAs contained in this RDN. */ @Override public Iterator<AVA> iterator() { return Iterators.arrayIterator(avas); } @@ -421,7 +423,7 @@ * @param builder * The builder to use to construct the normalized byte string. * @return The normalized byte string representation. * @see DN#toIrreversibleNormalizedByteString() * @see DN#toNormalizedByteString() */ ByteStringBuilder toNormalizedByteString(final ByteStringBuilder builder) { switch (size()) { @@ -445,30 +447,29 @@ } /** * Returns the normalized readable string representation of this RDN. * Retrieves a normalized string representation of this RDN. * <p> * The representation is not a valid RDN. * This representation is safe to use in an URL or in a file name. * However, it is not a valid RDN and can't be reverted to a valid RDN. * * @param builder * The builder to use to construct the normalized string. * @return The normalized readable string representation. * @see DN#toIrreversibleReadableString() * @return The normalized string representation of this RDN. * @see DN#toNormalizedUrlSafeString() */ StringBuilder toNormalizedReadableString(final StringBuilder builder) { StringBuilder toNormalizedUrlSafeString(final StringBuilder builder) { switch (size()) { case 0: // Handle RDN.maxValue(). builder.append(RDN.AVA_CHAR_SEPARATOR); break; case 1: getFirstAVA().toNormalizedReadableString(builder); getFirstAVA().toNormalizedUrlSafe(builder); break; default: Iterator<AVA> it = getSortedAvas(); it.next().toNormalizedReadableString(builder); it.next().toNormalizedUrlSafe(builder); while (it.hasNext()) { builder.append(RDN.AVA_CHAR_SEPARATOR); it.next().toNormalizedReadableString(builder); it.next().toNormalizedUrlSafe(builder); } break; } opendj-core/src/main/java/org/forgerock/opendj/ldap/schema/CertificateExactMatchingRuleImpl.java
@@ -187,7 +187,7 @@ private ByteString normalizeDN(final Schema schema, final String dnstring) throws DecodeException { try { DN dn = DN.valueOf(dnstring, schema.asNonStrictSchema()); return dn.toIrreversibleNormalizedByteString(); return dn.toNormalizedByteString(); } catch (Exception e) { logger.traceException(e); opendj-core/src/main/java/org/forgerock/opendj/ldap/schema/DistinguishedNameEqualityMatchingRuleImpl.java
@@ -43,7 +43,7 @@ throws DecodeException { try { DN dn = DN.valueOf(value.toString(), schema.asNonStrictSchema()); return dn.toIrreversibleNormalizedByteString(); return dn.toNormalizedByteString(); } catch (final LocalizedIllegalArgumentException e) { throw DecodeException.error(e.getMessageObject()); } opendj-core/src/main/java/org/forgerock/opendj/ldap/schema/UniqueMemberEqualityMatchingRuleImpl.java
@@ -57,7 +57,7 @@ try { DN dn = DN.valueOf(stringValue.substring(0, dnEndPosition), schema.asNonStrictSchema()); return new ByteStringBuilder() .append(dn.toIrreversibleNormalizedByteString()) .append(dn.toNormalizedByteString()) .append(optionalUid).toByteString(); } catch (final LocalizedIllegalArgumentException e) { throw DecodeException.error(e.getMessageObject()); opendj-core/src/main/java/org/forgerock/opendj/ldif/LDIF.java
@@ -830,7 +830,7 @@ } private static byte[] toNormalizedByteArray(DN dn) { return dn.toIrreversibleNormalizedByteString().toByteArray(); return dn.toNormalizedByteString().toByteArray(); } private static byte[][] encodeEntry(final Entry entry) { opendj-core/src/test/java/org/forgerock/opendj/ldap/DNTestCase.java
@@ -26,6 +26,8 @@ */ package org.forgerock.opendj.ldap; import static java.lang.Integer.*; import static org.fest.assertions.Assertions.*; import static org.testng.Assert.*; @@ -389,8 +391,8 @@ assertEquals(c.size(), 3); assertEquals(c.compareTo(p), 1); assertEquals(p.compareTo(c), -1); assertEquals(signum(c.compareTo(p)), 1); assertEquals(signum(p.compareTo(c)), -1); assertTrue(p.isParentOf(c)); assertFalse(c.isParentOf(p)); @@ -666,8 +668,8 @@ assertEquals(p.size(), 3); assertEquals(p.compareTo(c), -1); assertEquals(c.compareTo(p), 1); assertEquals(signum(p.compareTo(c)), -1); assertEquals(signum(c.compareTo(p)), 1); assertTrue(p.isParentOf(c)); assertFalse(c.isParentOf(p)); @@ -1005,12 +1007,12 @@ assertEquals(actual, "\\#cn\\=foo\\+sn\\=bar"); } /** Tests the {@link DN#toIrreversibleNormalizedByteString()} method. */ @Test public void testToIrreversibleNormalizedByteStringWithRootDN() { ByteString actual = DN.rootDN().toIrreversibleNormalizedByteString(); assertEquals(actual, ByteString.empty()); } /** Tests the {@link DN#toNormalizedByteString()} method. */ @Test public void testToNormalizedByteStringWithRootDN() { ByteString actual = DN.rootDN().toNormalizedByteString(); assertEquals(actual, ByteString.empty()); } /** Tests the {@link DN#iterator()} method. */ @Test @@ -1080,24 +1082,24 @@ } @Test(dataProvider = "toIrreversibleNormalizedByteStringDataProvider") public void testToIrreversibleNormalizedByteString(String first, String second, int expectedCompareResult) { DN actual = DN.valueOf(first); DN expected = DN.valueOf(second); int cmp = actual.toIrreversibleNormalizedByteString().compareTo(expected.toIrreversibleNormalizedByteString()); assertThat(Integer.signum(cmp)).isEqualTo(expectedCompareResult); } public void testToNormalizedByteString(String first, String second, int expectedCompareResult) { DN actual = DN.valueOf(first); DN expected = DN.valueOf(second); int cmp = actual.toNormalizedByteString().compareTo(expected.toNormalizedByteString()); assertThat(signum(cmp)).isEqualTo(expectedCompareResult); } /** Additional tests with testDNs data provider. */ @Test(dataProvider = "testDNs") public void testToIrreversibleNormalizedByteString2(String one, String two, String three) { DN dn1 = DN.valueOf(one); DN dn2 = DN.valueOf(two); DN dn3 = DN.valueOf(three); int cmp = dn1.toIrreversibleNormalizedByteString().compareTo(dn2.toIrreversibleNormalizedByteString()); assertThat(cmp).isEqualTo(0); int cmp2 = dn1.toIrreversibleNormalizedByteString().compareTo(dn3.toIrreversibleNormalizedByteString()); assertThat(cmp2).isEqualTo(0); } @Test(dataProvider = "testDNs") public void testToNormalizedByteString2(String one, String two, String three) { DN dn1 = DN.valueOf(one); DN dn2 = DN.valueOf(two); DN dn3 = DN.valueOf(three); int cmp = dn1.toNormalizedByteString().compareTo(dn2.toNormalizedByteString()); assertThat(cmp).isEqualTo(0); int cmp2 = dn1.toNormalizedByteString().compareTo(dn3.toNormalizedByteString()); assertThat(cmp2).isEqualTo(0); } @DataProvider public Object[][] toIrreversibleReadableStringDataProvider() { @@ -1134,19 +1136,19 @@ } @Test(dataProvider = "toIrreversibleReadableStringDataProvider") public void testToIrreversibleReadableString(String dnAsString, String expectedReadableString) { DN actual = DN.valueOf(dnAsString); assertEquals(actual.toIrreversibleReadableString(), expectedReadableString); } public void testToNormalizedUrlSafeString(String dnAsString, String expectedReadableString) { DN actual = DN.valueOf(dnAsString); assertEquals(actual.toNormalizedUrlSafeString(), expectedReadableString); } /** Additional tests with testDNs data provider. */ @Test(dataProvider = "testDNs") public void testToIrreversibleReadableString2(String one, String two, String three) { DN dn1 = DN.valueOf(one); DN dn2 = DN.valueOf(two); DN dn3 = DN.valueOf(three); String irreversibleReadableString = dn1.toIrreversibleReadableString(); assertEquals(irreversibleReadableString, dn2.toIrreversibleReadableString()); assertEquals(irreversibleReadableString, dn3.toIrreversibleReadableString()); } @Test(dataProvider = "testDNs") public void testToNormalizedUrlSafeString2(String one, String two, String three) { DN dn1 = DN.valueOf(one); DN dn2 = DN.valueOf(two); DN dn3 = DN.valueOf(three); String irreversibleReadableString = dn1.toNormalizedUrlSafeString(); assertEquals(irreversibleReadableString, dn2.toNormalizedUrlSafeString()); assertEquals(irreversibleReadableString, dn3.toNormalizedUrlSafeString()); } }