From bfc65fc02eed6d98c1025a924561d89a1af97a4e Mon Sep 17 00:00:00 2001
From: Matthew Swift <matthew.swift@forgerock.com>
Date: Mon, 07 May 2012 10:20:21 +0000
Subject: [PATCH] Fix OPENDJ-484: Implement equals and hashCode for SDK schema elements

---
 opendj-sdk/opendj3/opendj-ldap-sdk/src/main/java/org/forgerock/opendj/ldap/schema/SchemaElement.java                             |   15 +
 opendj-sdk/opendj3/opendj-ldap-sdk/src/main/java/org/forgerock/opendj/ldap/schema/DistinguishedNameEqualityMatchingRuleImpl.java |  136 ++++++------
 opendj-sdk/opendj3/opendj-ldap-sdk/src/main/java/org/forgerock/opendj/ldap/schema/Schema.java                                    |  102 ++++----
 opendj-sdk/opendj3/opendj-ldap-sdk/src/main/java/org/forgerock/opendj/ldap/schema/DefaultSchema.java                             |    4 
 opendj-sdk/opendj3/opendj-ldap-sdk/src/main/java/org/forgerock/opendj/ldap/schema/SchemaBuilder.java                             |  186 ++++++++--------
 opendj-sdk/opendj3/opendj-ldap-sdk/src/main/java/org/forgerock/opendj/ldap/schema/DITStructureRule.java                          |   27 ++
 opendj-sdk/opendj3/opendj-ldap-sdk/src/main/java/org/forgerock/opendj/ldap/schema/MatchingRule.java                              |   26 +-
 opendj-sdk/opendj3/opendj-ldap-sdk/src/main/java/org/forgerock/opendj/ldap/schema/Syntax.java                                    |   27 ++
 opendj-sdk/opendj3/opendj-ldap-sdk/src/main/java/org/forgerock/opendj/ldap/schema/ObjectClass.java                               |   23 +
 opendj-sdk/opendj3/opendj-ldap-sdk/src/main/java/org/forgerock/opendj/ldap/schema/DITContentRule.java                            |   27 ++
 opendj-sdk/opendj3/opendj-ldap-sdk/src/main/java/org/forgerock/opendj/ldap/schema/NameForm.java                                  |   27 ++
 opendj-sdk/opendj3/opendj-ldap-sdk/src/main/java/org/forgerock/opendj/ldap/schema/MatchingRuleUse.java                           |   27 ++
 opendj-sdk/opendj3/opendj-ldap-sdk/src/main/java/org/forgerock/opendj/ldap/schema/AttributeType.java                             |   23 +
 13 files changed, 412 insertions(+), 238 deletions(-)

diff --git a/opendj-sdk/opendj3/opendj-ldap-sdk/src/main/java/org/forgerock/opendj/ldap/schema/AttributeType.java b/opendj-sdk/opendj3/opendj-ldap-sdk/src/main/java/org/forgerock/opendj/ldap/schema/AttributeType.java
index 39a9aea..589d1db 100644
--- a/opendj-sdk/opendj3/opendj-ldap-sdk/src/main/java/org/forgerock/opendj/ldap/schema/AttributeType.java
+++ b/opendj-sdk/opendj3/opendj-ldap-sdk/src/main/java/org/forgerock/opendj/ldap/schema/AttributeType.java
@@ -228,18 +228,25 @@
         }
     }
 
+    /**
+     * Returns {@code true} if the provided object is an attribute type having
+     * the same numeric OID as this attribute type.
+     *
+     * @param o
+     *            The object to be compared.
+     * @return {@code true} if the provided object is an attribute type having
+     *         the same numeric OID as this attribute type.
+     */
     @Override
     public boolean equals(final Object o) {
         if (this == o) {
             return true;
-        }
-
-        if (o instanceof AttributeType) {
+        } else if (o instanceof AttributeType) {
             final AttributeType other = (AttributeType) o;
             return oid.equals(other.oid);
+        } else {
+            return false;
         }
-
-        return false;
     }
 
     /**
@@ -349,6 +356,12 @@
         return attributeUsage;
     }
 
+    /**
+     * Returns the hash code for this attribute type. It will be calculated as
+     * the hash code of the numeric OID.
+     *
+     * @return The hash code for this attribute type.
+     */
     @Override
     public int hashCode() {
         return oid.hashCode();
diff --git a/opendj-sdk/opendj3/opendj-ldap-sdk/src/main/java/org/forgerock/opendj/ldap/schema/DITContentRule.java b/opendj-sdk/opendj3/opendj-ldap-sdk/src/main/java/org/forgerock/opendj/ldap/schema/DITContentRule.java
index 4daa04c..06fff35 100644
--- a/opendj-sdk/opendj3/opendj-ldap-sdk/src/main/java/org/forgerock/opendj/ldap/schema/DITContentRule.java
+++ b/opendj-sdk/opendj3/opendj-ldap-sdk/src/main/java/org/forgerock/opendj/ldap/schema/DITContentRule.java
@@ -105,6 +105,27 @@
     }
 
     /**
+     * Returns {@code true} if the provided object is a DIT content rule having
+     * the same structural object class OID as this DIT content rule.
+     *
+     * @param o
+     *            The object to be compared.
+     * @return {@code true} if the provided object is a DIT content rule having
+     *         the same numeric OID as this DIT content rule.
+     */
+    @Override
+    public boolean equals(final Object o) {
+        if (this == o) {
+            return true;
+        } else if (o instanceof DITContentRule) {
+            final DITContentRule other = (DITContentRule) o;
+            return structuralClassOID.equals(other.structuralClassOID);
+        } else {
+            return false;
+        }
+    }
+
+    /**
      * Returns an unmodifiable set containing the auxiliary objectclasses that
      * may be used for entries associated with this DIT content rule.
      *
@@ -191,6 +212,12 @@
         return structuralClassOID;
     }
 
+    /**
+     * Returns the hash code for this DIT content rule. It will be calculated as
+     * the hash code of the structural object class OID.
+     *
+     * @return The hash code for this DIT content rule.
+     */
     @Override
     public int hashCode() {
         return structuralClassOID.hashCode();
diff --git a/opendj-sdk/opendj3/opendj-ldap-sdk/src/main/java/org/forgerock/opendj/ldap/schema/DITStructureRule.java b/opendj-sdk/opendj3/opendj-ldap-sdk/src/main/java/org/forgerock/opendj/ldap/schema/DITStructureRule.java
index 8c3101c..8b5f2cf 100644
--- a/opendj-sdk/opendj3/opendj-ldap-sdk/src/main/java/org/forgerock/opendj/ldap/schema/DITStructureRule.java
+++ b/opendj-sdk/opendj3/opendj-ldap-sdk/src/main/java/org/forgerock/opendj/ldap/schema/DITStructureRule.java
@@ -93,6 +93,27 @@
     }
 
     /**
+     * Returns {@code true} if the provided object is a DIT structure rule
+     * having the same rule ID as this DIT structure rule.
+     *
+     * @param o
+     *            The object to be compared.
+     * @return {@code true} if the provided object is a DIT structure rule
+     *         having the same rule ID as this DIT structure rule.
+     */
+    @Override
+    public boolean equals(final Object o) {
+        if (this == o) {
+            return true;
+        } else if (o instanceof DITStructureRule) {
+            final DITStructureRule other = (DITStructureRule) o;
+            return ruleID.equals(other.ruleID);
+        } else {
+            return false;
+        }
+    }
+
+    /**
      * Retrieves the name form for this DIT structure rule.
      *
      * @return The name form for this DIT structure rule.
@@ -146,6 +167,12 @@
         return superiorRules;
     }
 
+    /**
+     * Returns the hash code for this DIT structure rule. It will be calculated
+     * as the hash code of the rule ID.
+     *
+     * @return The hash code for this DIT structure rule.
+     */
     @Override
     public int hashCode() {
         return ruleID.hashCode();
diff --git a/opendj-sdk/opendj3/opendj-ldap-sdk/src/main/java/org/forgerock/opendj/ldap/schema/DefaultSchema.java b/opendj-sdk/opendj3/opendj-ldap-sdk/src/main/java/org/forgerock/opendj/ldap/schema/DefaultSchema.java
index aa5de46..9414ceb 100644
--- a/opendj-sdk/opendj3/opendj-ldap-sdk/src/main/java/org/forgerock/opendj/ldap/schema/DefaultSchema.java
+++ b/opendj-sdk/opendj3/opendj-ldap-sdk/src/main/java/org/forgerock/opendj/ldap/schema/DefaultSchema.java
@@ -32,9 +32,9 @@
  * can cause initialization errors because the CoreSchema depends on Schema.
  */
 final class DefaultSchema {
+    static volatile Schema schema = Schema.getCoreSchema();
+
     private DefaultSchema() {
         // Prevent instantiation.
     }
-
-    static volatile Schema schema = Schema.getCoreSchema();
 }
diff --git a/opendj-sdk/opendj3/opendj-ldap-sdk/src/main/java/org/forgerock/opendj/ldap/schema/DistinguishedNameEqualityMatchingRuleImpl.java b/opendj-sdk/opendj3/opendj-ldap-sdk/src/main/java/org/forgerock/opendj/ldap/schema/DistinguishedNameEqualityMatchingRuleImpl.java
index 227a618..b005f62 100644
--- a/opendj-sdk/opendj3/opendj-ldap-sdk/src/main/java/org/forgerock/opendj/ldap/schema/DistinguishedNameEqualityMatchingRuleImpl.java
+++ b/opendj-sdk/opendj3/opendj-ldap-sdk/src/main/java/org/forgerock/opendj/ldap/schema/DistinguishedNameEqualityMatchingRuleImpl.java
@@ -46,74 +46,6 @@
  */
 final class DistinguishedNameEqualityMatchingRuleImpl extends AbstractMatchingRuleImpl {
     /**
-     * {@inheritDoc}
-     */
-    public ByteString normalizeAttributeValue(final Schema schema, final ByteSequence value)
-            throws DecodeException {
-        try {
-            DN dn = DN.valueOf(value.toString(), schema.asNonStrictSchema());
-            StringBuilder builder = new StringBuilder(value.length());
-            return ByteString.valueOf(normalizeDN(builder, dn));
-        } catch (final LocalizedIllegalArgumentException e) {
-            throw DecodeException.error(e.getMessageObject());
-        }
-    }
-
-    /**
-     * Returns the normalized string representation of a DN.
-     *
-     * @param builder
-     *            The StringBuilder to use to construct the normalized string.
-     * @param dn
-     *            The DN.
-     * @return The normalized string representation of the provided DN.
-     */
-    private static StringBuilder normalizeDN(final StringBuilder builder, final DN dn) {
-        if (dn.rdn() == null) {
-            return builder;
-        }
-
-        int i = dn.size() - 1;
-        normalizeRDN(builder, dn.parent(i).rdn());
-        for (i--; i >= 0; i--) {
-            builder.append('\u0000');
-            normalizeRDN(builder, dn.parent(i).rdn());
-        }
-        return builder;
-    }
-
-    /**
-     * Returns the normalized string representation of a RDN.
-     *
-     * @param builder
-     *            The StringBuilder to use to construct the normalized string.
-     * @param rdn
-     *            The RDN.
-     * @return The normalized string representation of the provided RDN.
-     */
-    private static StringBuilder normalizeRDN(final StringBuilder builder, final RDN rdn) {
-        final int sz = rdn.size();
-        if (sz == 1) {
-            return normalizeAVA(builder, rdn.getFirstAVA());
-        } else {
-            // Need to sort the AVAs before comparing.
-            TreeSet<AVA> a = new TreeSet<AVA>();
-            for (AVA ava : rdn) {
-                a.add(ava);
-            }
-            Iterator<AVA> i = a.iterator();
-            // Normalize the first AVA.
-            normalizeAVA(builder, i.next());
-            while (i.hasNext()) {
-                builder.append('\u0001');
-                normalizeAVA(builder, i.next());
-            }
-
-            return builder;
-        }
-    }
-
-    /**
      * Returns the normalized string representation of an AVA.
      *
      * @param builder
@@ -181,4 +113,72 @@
         }
         return builder;
     }
+
+    /**
+     * Returns the normalized string representation of a DN.
+     *
+     * @param builder
+     *            The StringBuilder to use to construct the normalized string.
+     * @param dn
+     *            The DN.
+     * @return The normalized string representation of the provided DN.
+     */
+    private static StringBuilder normalizeDN(final StringBuilder builder, final DN dn) {
+        if (dn.rdn() == null) {
+            return builder;
+        }
+
+        int i = dn.size() - 1;
+        normalizeRDN(builder, dn.parent(i).rdn());
+        for (i--; i >= 0; i--) {
+            builder.append('\u0000');
+            normalizeRDN(builder, dn.parent(i).rdn());
+        }
+        return builder;
+    }
+
+    /**
+     * Returns the normalized string representation of a RDN.
+     *
+     * @param builder
+     *            The StringBuilder to use to construct the normalized string.
+     * @param rdn
+     *            The RDN.
+     * @return The normalized string representation of the provided RDN.
+     */
+    private static StringBuilder normalizeRDN(final StringBuilder builder, final RDN rdn) {
+        final int sz = rdn.size();
+        if (sz == 1) {
+            return normalizeAVA(builder, rdn.getFirstAVA());
+        } else {
+            // Need to sort the AVAs before comparing.
+            TreeSet<AVA> a = new TreeSet<AVA>();
+            for (AVA ava : rdn) {
+                a.add(ava);
+            }
+            Iterator<AVA> i = a.iterator();
+            // Normalize the first AVA.
+            normalizeAVA(builder, i.next());
+            while (i.hasNext()) {
+                builder.append('\u0001');
+                normalizeAVA(builder, i.next());
+            }
+
+            return builder;
+        }
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public ByteString normalizeAttributeValue(final Schema schema, final ByteSequence value)
+            throws DecodeException {
+        try {
+            DN dn = DN.valueOf(value.toString(), schema.asNonStrictSchema());
+            StringBuilder builder = new StringBuilder(value.length());
+            return ByteString.valueOf(normalizeDN(builder, dn));
+        } catch (final LocalizedIllegalArgumentException e) {
+            throw DecodeException.error(e.getMessageObject());
+        }
+    }
 }
diff --git a/opendj-sdk/opendj3/opendj-ldap-sdk/src/main/java/org/forgerock/opendj/ldap/schema/MatchingRule.java b/opendj-sdk/opendj3/opendj-ldap-sdk/src/main/java/org/forgerock/opendj/ldap/schema/MatchingRule.java
index 1e1dd74..8511741 100644
--- a/opendj-sdk/opendj3/opendj-ldap-sdk/src/main/java/org/forgerock/opendj/ldap/schema/MatchingRule.java
+++ b/opendj-sdk/opendj3/opendj-ldap-sdk/src/main/java/org/forgerock/opendj/ldap/schema/MatchingRule.java
@@ -100,23 +100,24 @@
     }
 
     /**
-     * {@inheritDoc}
+     * Returns {@code true} if the provided object is a matching rule having the
+     * same numeric OID as this matching rule.
+     *
+     * @param o
+     *            The object to be compared.
+     * @return {@code true} if the provided object is a matching rule having the
+     *         same numeric OID as this matching rule.
      */
     @Override
     public boolean equals(final Object o) {
-        if (o == null) {
-            return false;
-        }
-
         if (this == o) {
             return true;
-        }
-
-        if (!(o instanceof MatchingRule)) {
+        } else if (o instanceof MatchingRule) {
+            final MatchingRule other = (MatchingRule) o;
+            return oid.equals(other.oid);
+        } else {
             return false;
         }
-
-        return getOID().equals(((MatchingRule) o).getOID());
     }
 
     /**
@@ -238,7 +239,10 @@
     }
 
     /**
-     * {@inheritDoc}
+     * Returns the hash code for this matching rule. It will be calculated as
+     * the hash code of the numeric OID.
+     *
+     * @return The hash code for this matching rule.
      */
     @Override
     public int hashCode() {
diff --git a/opendj-sdk/opendj3/opendj-ldap-sdk/src/main/java/org/forgerock/opendj/ldap/schema/MatchingRuleUse.java b/opendj-sdk/opendj3/opendj-ldap-sdk/src/main/java/org/forgerock/opendj/ldap/schema/MatchingRuleUse.java
index b582c50..8f986c3 100644
--- a/opendj-sdk/opendj3/opendj-ldap-sdk/src/main/java/org/forgerock/opendj/ldap/schema/MatchingRuleUse.java
+++ b/opendj-sdk/opendj3/opendj-ldap-sdk/src/main/java/org/forgerock/opendj/ldap/schema/MatchingRuleUse.java
@@ -85,6 +85,27 @@
     }
 
     /**
+     * Returns {@code true} if the provided object is a matching rule use having
+     * the same numeric OID as this matching rule use.
+     *
+     * @param o
+     *            The object to be compared.
+     * @return {@code true} if the provided object is a matching rule use having
+     *         the same numeric OID as this matching rule use.
+     */
+    @Override
+    public boolean equals(final Object o) {
+        if (this == o) {
+            return true;
+        } else if (o instanceof MatchingRuleUse) {
+            final MatchingRuleUse other = (MatchingRuleUse) o;
+            return oid.equals(other.oid);
+        } else {
+            return false;
+        }
+    }
+
+    /**
      * Returns an unmodifiable set containing the attributes associated with
      * this matching rule use.
      *
@@ -151,6 +172,12 @@
         return attributes.contains(attributeType);
     }
 
+    /**
+     * Returns the hash code for this matching rule use. It will be calculated
+     * as the hash code of the numeric OID.
+     *
+     * @return The hash code for this matching rule use.
+     */
     @Override
     public int hashCode() {
         return oid.hashCode();
diff --git a/opendj-sdk/opendj3/opendj-ldap-sdk/src/main/java/org/forgerock/opendj/ldap/schema/NameForm.java b/opendj-sdk/opendj3/opendj-ldap-sdk/src/main/java/org/forgerock/opendj/ldap/schema/NameForm.java
index 7a0273e..4cd1270 100644
--- a/opendj-sdk/opendj3/opendj-ldap-sdk/src/main/java/org/forgerock/opendj/ldap/schema/NameForm.java
+++ b/opendj-sdk/opendj3/opendj-ldap-sdk/src/main/java/org/forgerock/opendj/ldap/schema/NameForm.java
@@ -98,6 +98,27 @@
     }
 
     /**
+     * Returns {@code true} if the provided object is a name form having the
+     * same numeric OID as this name form.
+     *
+     * @param o
+     *            The object to be compared.
+     * @return {@code true} if the provided object is a name form having the
+     *         same numeric OID as this name form.
+     */
+    @Override
+    public boolean equals(final Object o) {
+        if (this == o) {
+            return true;
+        } else if (o instanceof NameForm) {
+            final NameForm other = (NameForm) o;
+            return oid.equals(other.oid);
+        } else {
+            return false;
+        }
+    }
+
+    /**
      * Returns the name or OID for this schema definition. If it has one or more
      * names, then the primary name will be returned. If it does not have any
      * names, then the OID will be returned.
@@ -163,6 +184,12 @@
         return structuralClass;
     }
 
+    /**
+     * Returns the hash code for this name form. It will be calculated as the
+     * hash code of the numeric OID.
+     *
+     * @return The hash code for this name form.
+     */
     @Override
     public int hashCode() {
         return oid.hashCode();
diff --git a/opendj-sdk/opendj3/opendj-ldap-sdk/src/main/java/org/forgerock/opendj/ldap/schema/ObjectClass.java b/opendj-sdk/opendj3/opendj-ldap-sdk/src/main/java/org/forgerock/opendj/ldap/schema/ObjectClass.java
index 7bf6a1b..ae4f1d4 100644
--- a/opendj-sdk/opendj3/opendj-ldap-sdk/src/main/java/org/forgerock/opendj/ldap/schema/ObjectClass.java
+++ b/opendj-sdk/opendj3/opendj-ldap-sdk/src/main/java/org/forgerock/opendj/ldap/schema/ObjectClass.java
@@ -136,18 +136,25 @@
         this.definition = buildDefinition();
     }
 
+    /**
+     * Returns {@code true} if the provided object is an object class having the
+     * same numeric OID as this object class.
+     *
+     * @param o
+     *            The object to be compared.
+     * @return {@code true} if the provided object is a object class having the
+     *         same numeric OID as this object class.
+     */
     @Override
     public boolean equals(final Object o) {
         if (this == o) {
             return true;
-        }
-
-        if (o instanceof ObjectClass) {
+        } else if (o instanceof ObjectClass) {
             final ObjectClass other = (ObjectClass) o;
             return oid.equals(other.oid);
+        } else {
+            return false;
         }
-
-        return false;
     }
 
     /**
@@ -252,6 +259,12 @@
         return superiorClasses;
     }
 
+    /**
+     * Returns the hash code for this object class. It will be calculated as the
+     * hash code of the numeric OID.
+     *
+     * @return The hash code for this object class.
+     */
     @Override
     public int hashCode() {
         return oid.hashCode();
diff --git a/opendj-sdk/opendj3/opendj-ldap-sdk/src/main/java/org/forgerock/opendj/ldap/schema/Schema.java b/opendj-sdk/opendj3/opendj-ldap-sdk/src/main/java/org/forgerock/opendj/ldap/schema/Schema.java
index 14e967e..2c460c8 100644
--- a/opendj-sdk/opendj3/opendj-ldap-sdk/src/main/java/org/forgerock/opendj/ldap/schema/Schema.java
+++ b/opendj-sdk/opendj3/opendj-ldap-sdk/src/main/java/org/forgerock/opendj/ldap/schema/Schema.java
@@ -299,6 +299,12 @@
     }
 
     private static interface Impl {
+        boolean allowMalformedNamesAndOptions();
+
+        boolean allowNonStandardTelephoneNumbers();
+
+        boolean allowZeroLengthDirectoryStrings();
+
         AttributeType getAttributeType(String name);
 
         Collection<AttributeType> getAttributeTypes();
@@ -374,12 +380,6 @@
         boolean hasSyntax(String numericOID);
 
         boolean isStrict();
-
-        boolean allowMalformedNamesAndOptions();
-
-        boolean allowNonStandardTelephoneNumbers();
-
-        boolean allowZeroLengthDirectoryStrings();
     }
 
     private static final class NonStrictImpl implements Impl {
@@ -1124,6 +1124,35 @@
     }
 
     /**
+     * Reads the schema contained in the named subschema sub-entry.
+     * <p>
+     * If the requested schema is not returned by the Directory Server then the
+     * request will fail with an {@link EntryNotFoundException}. More
+     * specifically, this method will never return {@code null}.
+     *
+     * @param connection
+     *            A connection to the Directory Server whose schema is to be
+     *            read.
+     * @param name
+     *            The distinguished name of the subschema sub-entry.
+     * @return The schema from the Directory Server.
+     * @throws ErrorResultException
+     *             If the result code indicates that the request failed for some
+     *             reason.
+     * @throws UnsupportedOperationException
+     *             If the connection does not support search operations.
+     * @throws IllegalStateException
+     *             If the connection has already been closed, i.e. if
+     *             {@code connection.isClosed() == true}.
+     * @throws NullPointerException
+     *             If the {@code connection} or {@code name} was {@code null}.
+     */
+    public static Schema readSchema(final Connection connection, final DN name)
+            throws ErrorResultException {
+        return new SchemaBuilder().addSchema(connection, name, true).toSchema();
+    }
+
+    /**
      * Asynchronously reads the schema contained in the named subschema
      * sub-entry.
      * <p>
@@ -1169,18 +1198,26 @@
     }
 
     /**
-     * Reads the schema contained in the named subschema sub-entry.
+     * Reads the schema contained in the subschema sub-entry which applies to
+     * the named entry.
      * <p>
-     * If the requested schema is not returned by the Directory Server then the
-     * request will fail with an {@link EntryNotFoundException}. More
-     * specifically, this method will never return {@code null}.
+     * If the requested entry or its associated schema are not returned by the
+     * Directory Server then the request will fail with an
+     * {@link EntryNotFoundException}. More specifically, this method will never
+     * return {@code null}.
+     * <p>
+     * This implementation first reads the {@code subschemaSubentry} attribute
+     * of the entry in order to identify the schema and then invokes
+     * {@link #readSchema(Connection, DN)} to read the schema.
      *
      * @param connection
      *            A connection to the Directory Server whose schema is to be
      *            read.
      * @param name
-     *            The distinguished name of the subschema sub-entry.
-     * @return The schema from the Directory Server.
+     *            The distinguished name of the entry whose schema is to be
+     *            located.
+     * @return The schema from the Directory Server which applies to the named
+     *         entry.
      * @throws ErrorResultException
      *             If the result code indicates that the request failed for some
      *             reason.
@@ -1192,9 +1229,9 @@
      * @throws NullPointerException
      *             If the {@code connection} or {@code name} was {@code null}.
      */
-    public static Schema readSchema(final Connection connection, final DN name)
+    public static Schema readSchemaForEntry(final Connection connection, final DN name)
             throws ErrorResultException {
-        return new SchemaBuilder().addSchema(connection, name, true).toSchema();
+        return new SchemaBuilder().addSchemaForEntry(connection, name, true).toSchema();
     }
 
     /**
@@ -1251,43 +1288,6 @@
     }
 
     /**
-     * Reads the schema contained in the subschema sub-entry which applies to
-     * the named entry.
-     * <p>
-     * If the requested entry or its associated schema are not returned by the
-     * Directory Server then the request will fail with an
-     * {@link EntryNotFoundException}. More specifically, this method will never
-     * return {@code null}.
-     * <p>
-     * This implementation first reads the {@code subschemaSubentry} attribute
-     * of the entry in order to identify the schema and then invokes
-     * {@link #readSchema(Connection, DN)} to read the schema.
-     *
-     * @param connection
-     *            A connection to the Directory Server whose schema is to be
-     *            read.
-     * @param name
-     *            The distinguished name of the entry whose schema is to be
-     *            located.
-     * @return The schema from the Directory Server which applies to the named
-     *         entry.
-     * @throws ErrorResultException
-     *             If the result code indicates that the request failed for some
-     *             reason.
-     * @throws UnsupportedOperationException
-     *             If the connection does not support search operations.
-     * @throws IllegalStateException
-     *             If the connection has already been closed, i.e. if
-     *             {@code connection.isClosed() == true}.
-     * @throws NullPointerException
-     *             If the {@code connection} or {@code name} was {@code null}.
-     */
-    public static Schema readSchemaForEntry(final Connection connection, final DN name)
-            throws ErrorResultException {
-        return new SchemaBuilder().addSchemaForEntry(connection, name, true).toSchema();
-    }
-
-    /**
      * Sets the default schema which should be used by this application. The
      * default schema is initially set to the core schema.
      *
diff --git a/opendj-sdk/opendj3/opendj-ldap-sdk/src/main/java/org/forgerock/opendj/ldap/schema/SchemaBuilder.java b/opendj-sdk/opendj3/opendj-ldap-sdk/src/main/java/org/forgerock/opendj/ldap/schema/SchemaBuilder.java
index 24e6a26..4308e87 100644
--- a/opendj-sdk/opendj3/opendj-ldap-sdk/src/main/java/org/forgerock/opendj/ldap/schema/SchemaBuilder.java
+++ b/opendj-sdk/opendj3/opendj-ldap-sdk/src/main/java/org/forgerock/opendj/ldap/schema/SchemaBuilder.java
@@ -96,7 +96,7 @@
     // attribute from the named entry.
     private static SearchRequest getReadSchemaForEntrySearchRequest(final DN dn) {
         return Requests.newSearchRequest(dn, SearchScope.BASE_OBJECT, Filter
-                .getObjectClassPresentFilter(), SUBSCHEMA_SUBENTRY_ATTRS);
+                .objectClassPresent(), SUBSCHEMA_SUBENTRY_ATTRS);
     }
 
     // Constructs a search request for retrieving the named subschema
@@ -1711,56 +1711,6 @@
     }
 
     /**
-     * Asynchronously reads the schema elements contained in the named subschema
-     * sub-entry and adds them to this schema builder.
-     * <p>
-     * If the requested schema is not returned by the Directory Server then the
-     * request will fail with an {@link EntryNotFoundException}.
-     *
-     * @param connection
-     *            A connection to the Directory Server whose schema is to be
-     *            read.
-     * @param name
-     *            The distinguished name of the subschema sub-entry.
-     * @param handler
-     *            A result handler which can be used to asynchronously process
-     *            the operation result when it is received, may be {@code null}.
-     * @param overwrite
-     *            {@code true} if existing schema elements with the same
-     *            conflicting OIDs should be overwritten.
-     * @return A future representing the updated schema builder.
-     * @throws UnsupportedOperationException
-     *             If the connection does not support search operations.
-     * @throws IllegalStateException
-     *             If the connection has already been closed, i.e. if
-     *             {@code connection.isClosed() == true}.
-     * @throws NullPointerException
-     *             If the {@code connection} or {@code name} was {@code null}.
-     */
-    public FutureResult<SchemaBuilder> addSchemaAsync(final Connection connection, final DN name,
-            final ResultHandler<? super SchemaBuilder> handler, final boolean overwrite) {
-        // The call to addSchema will perform copyOnWrite.
-        final SearchRequest request = getReadSchemaSearchRequest(name);
-
-        final FutureResultTransformer<SearchResultEntry, SchemaBuilder> future =
-                new FutureResultTransformer<SearchResultEntry, SchemaBuilder>(handler) {
-
-                    @Override
-                    protected SchemaBuilder transformResult(final SearchResultEntry result)
-                            throws ErrorResultException {
-                        addSchema(result, overwrite);
-                        return SchemaBuilder.this;
-                    }
-
-                };
-
-        final FutureResult<SearchResultEntry> innerFuture =
-                connection.searchSingleEntryAsync(request, future);
-        future.setFutureResult(innerFuture);
-        return future;
-    }
-
-    /**
      * Reads the schema elements contained in the named subschema sub-entry and
      * adds them to this schema builder.
      * <p>
@@ -1932,6 +1882,98 @@
     }
 
     /**
+     * Asynchronously reads the schema elements contained in the named subschema
+     * sub-entry and adds them to this schema builder.
+     * <p>
+     * If the requested schema is not returned by the Directory Server then the
+     * request will fail with an {@link EntryNotFoundException}.
+     *
+     * @param connection
+     *            A connection to the Directory Server whose schema is to be
+     *            read.
+     * @param name
+     *            The distinguished name of the subschema sub-entry.
+     * @param handler
+     *            A result handler which can be used to asynchronously process
+     *            the operation result when it is received, may be {@code null}.
+     * @param overwrite
+     *            {@code true} if existing schema elements with the same
+     *            conflicting OIDs should be overwritten.
+     * @return A future representing the updated schema builder.
+     * @throws UnsupportedOperationException
+     *             If the connection does not support search operations.
+     * @throws IllegalStateException
+     *             If the connection has already been closed, i.e. if
+     *             {@code connection.isClosed() == true}.
+     * @throws NullPointerException
+     *             If the {@code connection} or {@code name} was {@code null}.
+     */
+    public FutureResult<SchemaBuilder> addSchemaAsync(final Connection connection, final DN name,
+            final ResultHandler<? super SchemaBuilder> handler, final boolean overwrite) {
+        // The call to addSchema will perform copyOnWrite.
+        final SearchRequest request = getReadSchemaSearchRequest(name);
+
+        final FutureResultTransformer<SearchResultEntry, SchemaBuilder> future =
+                new FutureResultTransformer<SearchResultEntry, SchemaBuilder>(handler) {
+
+                    @Override
+                    protected SchemaBuilder transformResult(final SearchResultEntry result)
+                            throws ErrorResultException {
+                        addSchema(result, overwrite);
+                        return SchemaBuilder.this;
+                    }
+
+                };
+
+        final FutureResult<SearchResultEntry> innerFuture =
+                connection.searchSingleEntryAsync(request, future);
+        future.setFutureResult(innerFuture);
+        return future;
+    }
+
+    /**
+     * Reads the schema elements contained in the subschema sub-entry which
+     * applies to the named entry and adds them to this schema builder.
+     * <p>
+     * If the requested entry or its associated schema are not returned by the
+     * Directory Server then the request will fail with an
+     * {@link EntryNotFoundException}.
+     * <p>
+     * This implementation first reads the {@code subschemaSubentry} attribute
+     * of the entry in order to identify the schema and then invokes
+     * {@link #addSchemaForEntry(Connection, DN, boolean)} to read the schema.
+     *
+     * @param connection
+     *            A connection to the Directory Server whose schema is to be
+     *            read.
+     * @param name
+     *            The distinguished name of the entry whose schema is to be
+     *            located.
+     * @param overwrite
+     *            {@code true} if existing schema elements with the same
+     *            conflicting OIDs should be overwritten.
+     * @return A reference to this schema builder.
+     * @throws ErrorResultException
+     *             If the result code indicates that the request failed for some
+     *             reason.
+     * @throws UnsupportedOperationException
+     *             If the connection does not support search operations.
+     * @throws IllegalStateException
+     *             If the connection has already been closed, i.e. if
+     *             {@code connection.isClosed() == true}.
+     * @throws NullPointerException
+     *             If the {@code connection} or {@code name} was {@code null}.
+     */
+    public SchemaBuilder addSchemaForEntry(final Connection connection, final DN name,
+            final boolean overwrite) throws ErrorResultException {
+        // The call to addSchema will perform copyOnWrite.
+        final SearchRequest request = getReadSchemaForEntrySearchRequest(name);
+        final Entry entry = connection.searchSingleEntry(request);
+        final DN subschemaDN = getSubschemaSubentryDN(name, entry);
+        return addSchema(connection, subschemaDN, overwrite);
+    }
+
+    /**
      * Asynchronously reads the schema elements contained in the subschema
      * sub-entry which applies to the named entry and adds them to this schema
      * builder.
@@ -1992,48 +2034,6 @@
     }
 
     /**
-     * Reads the schema elements contained in the subschema sub-entry which
-     * applies to the named entry and adds them to this schema builder.
-     * <p>
-     * If the requested entry or its associated schema are not returned by the
-     * Directory Server then the request will fail with an
-     * {@link EntryNotFoundException}.
-     * <p>
-     * This implementation first reads the {@code subschemaSubentry} attribute
-     * of the entry in order to identify the schema and then invokes
-     * {@link #addSchemaForEntry(Connection, DN, boolean)} to read the schema.
-     *
-     * @param connection
-     *            A connection to the Directory Server whose schema is to be
-     *            read.
-     * @param name
-     *            The distinguished name of the entry whose schema is to be
-     *            located.
-     * @param overwrite
-     *            {@code true} if existing schema elements with the same
-     *            conflicting OIDs should be overwritten.
-     * @return A reference to this schema builder.
-     * @throws ErrorResultException
-     *             If the result code indicates that the request failed for some
-     *             reason.
-     * @throws UnsupportedOperationException
-     *             If the connection does not support search operations.
-     * @throws IllegalStateException
-     *             If the connection has already been closed, i.e. if
-     *             {@code connection.isClosed() == true}.
-     * @throws NullPointerException
-     *             If the {@code connection} or {@code name} was {@code null}.
-     */
-    public SchemaBuilder addSchemaForEntry(final Connection connection, final DN name,
-            final boolean overwrite) throws ErrorResultException {
-        // The call to addSchema will perform copyOnWrite.
-        final SearchRequest request = getReadSchemaForEntrySearchRequest(name);
-        final Entry entry = connection.searchSingleEntry(request);
-        final DN subschemaDN = getSubschemaSubentryDN(name, entry);
-        return addSchema(connection, subschemaDN, overwrite);
-    }
-
-    /**
      * Adds the provided substitution syntax definition to this schema builder.
      *
      * @param oid
diff --git a/opendj-sdk/opendj3/opendj-ldap-sdk/src/main/java/org/forgerock/opendj/ldap/schema/SchemaElement.java b/opendj-sdk/opendj3/opendj-ldap-sdk/src/main/java/org/forgerock/opendj/ldap/schema/SchemaElement.java
index ca496d6..dd53688 100644
--- a/opendj-sdk/opendj3/opendj-ldap-sdk/src/main/java/org/forgerock/opendj/ldap/schema/SchemaElement.java
+++ b/opendj-sdk/opendj3/opendj-ldap-sdk/src/main/java/org/forgerock/opendj/ldap/schema/SchemaElement.java
@@ -58,6 +58,11 @@
     }
 
     /**
+     * {@inheritDoc}
+     */
+    public abstract boolean equals(Object obj);
+
+    /**
      * Returns the description of this schema definition.
      *
      * @return The description of this schema definition.
@@ -97,6 +102,16 @@
     }
 
     /**
+     * {@inheritDoc}
+     */
+    public abstract int hashCode();
+
+    /**
+     * {@inheritDoc}
+     */
+    public abstract String toString();
+
+    /**
      * Builds a string representation of this schema definition in the form
      * specified in RFC 2252.
      *
diff --git a/opendj-sdk/opendj3/opendj-ldap-sdk/src/main/java/org/forgerock/opendj/ldap/schema/Syntax.java b/opendj-sdk/opendj3/opendj-ldap-sdk/src/main/java/org/forgerock/opendj/ldap/schema/Syntax.java
index 103e013..9e3eee1 100644
--- a/opendj-sdk/opendj3/opendj-ldap-sdk/src/main/java/org/forgerock/opendj/ldap/schema/Syntax.java
+++ b/opendj-sdk/opendj3/opendj-ldap-sdk/src/main/java/org/forgerock/opendj/ldap/schema/Syntax.java
@@ -90,6 +90,27 @@
     }
 
     /**
+     * Returns {@code true} if the provided object is an attribute syntax having
+     * the same numeric OID as this attribute syntax.
+     *
+     * @param o
+     *            The object to be compared.
+     * @return {@code true} if the provided object is an attribute syntax having
+     *         the same numeric OID as this attribute syntax.
+     */
+    @Override
+    public boolean equals(final Object o) {
+        if (this == o) {
+            return true;
+        } else if (o instanceof Syntax) {
+            final Syntax other = (Syntax) o;
+            return oid.equals(other.oid);
+        } else {
+            return false;
+        }
+    }
+
+    /**
      * Retrieves the default approximate matching rule that will be used for
      * attributes with this syntax.
      *
@@ -147,14 +168,14 @@
     }
 
     /**
-     * Retrieves the hash code for this schema element. It will be calculated as
-     * the sum of the characters in the OID.
+     * Returns the hash code for this attribute syntax. It will be calculated as
+     * the hash code of the numeric OID.
      *
      * @return The hash code for this attribute syntax.
      */
     @Override
     public int hashCode() {
-        return getOID().hashCode();
+        return oid.hashCode();
     }
 
     /**

--
Gitblit v1.10.0