From 345b41d38fd85b8c88ba1e5fb5ef64f260e49b63 Mon Sep 17 00:00:00 2001
From: Matthew Swift <matthew.swift@forgerock.com>
Date: Fri, 13 Dec 2013 22:37:07 +0000
Subject: [PATCH] Fix OPENDJ-1252: ReadSchema example throws NPE

---
 opendj-core/src/test/java/org/forgerock/opendj/ldap/schema/SchemaBuilderTestCase.java |   34 +++++++++++++++++++++++++++++++++-
 opendj-core/src/main/java/org/forgerock/opendj/ldap/schema/MatchingRule.java          |   13 +++++++++----
 opendj-core/src/main/java/org/forgerock/opendj/ldap/schema/Syntax.java                |    7 ++++++-
 3 files changed, 48 insertions(+), 6 deletions(-)

diff --git a/opendj-core/src/main/java/org/forgerock/opendj/ldap/schema/MatchingRule.java b/opendj-core/src/main/java/org/forgerock/opendj/ldap/schema/MatchingRule.java
index 6f376b7..85f07b4 100644
--- a/opendj-core/src/main/java/org/forgerock/opendj/ldap/schema/MatchingRule.java
+++ b/opendj-core/src/main/java/org/forgerock/opendj/ldap/schema/MatchingRule.java
@@ -517,10 +517,15 @@
         }
 
         if (impl == null) {
-            impl = schema.getDefaultMatchingRule().impl;
-            final LocalizableMessage message = WARN_MATCHING_RULE_NOT_IMPLEMENTED1
-                    .get(getNameOrOID(), schema.getDefaultMatchingRule()
-                            .getOID());
+            final MatchingRule defaultMatchingRule = schema.getDefaultMatchingRule();
+            if (defaultMatchingRule.impl == null) {
+                // The default matching rule was never validated.
+                defaultMatchingRule.validate(schema, warnings);
+            }
+            impl = defaultMatchingRule.impl;
+            final LocalizableMessage message =
+                    WARN_MATCHING_RULE_NOT_IMPLEMENTED1.get(getNameOrOID(), schema
+                            .getDefaultMatchingRule().getOID());
             warnings.add(message);
         }
 
diff --git a/opendj-core/src/main/java/org/forgerock/opendj/ldap/schema/Syntax.java b/opendj-core/src/main/java/org/forgerock/opendj/ldap/schema/Syntax.java
index faa6eb9..02f41a2 100644
--- a/opendj-core/src/main/java/org/forgerock/opendj/ldap/schema/Syntax.java
+++ b/opendj-core/src/main/java/org/forgerock/opendj/ldap/schema/Syntax.java
@@ -294,7 +294,12 @@
             }
 
             if (impl == null) {
-                impl = schema.getDefaultSyntax().impl;
+                final Syntax defaultSyntax = schema.getDefaultSyntax();
+                if (defaultSyntax.impl == null) {
+                    // The default syntax was never validated.
+                    defaultSyntax.validate(schema, warnings);
+                }
+                impl = defaultSyntax.impl;
                 final LocalizableMessage message = WARN_ATTR_SYNTAX_NOT_IMPLEMENTED1
                         .get(getDescription(), oid, schema.getDefaultSyntax()
                                 .getOID());
diff --git a/opendj-core/src/test/java/org/forgerock/opendj/ldap/schema/SchemaBuilderTestCase.java b/opendj-core/src/test/java/org/forgerock/opendj/ldap/schema/SchemaBuilderTestCase.java
index add66e4..b50e04c 100644
--- a/opendj-core/src/test/java/org/forgerock/opendj/ldap/schema/SchemaBuilderTestCase.java
+++ b/opendj-core/src/test/java/org/forgerock/opendj/ldap/schema/SchemaBuilderTestCase.java
@@ -35,7 +35,9 @@
 import java.util.Set;
 
 import org.forgerock.i18n.LocalizedIllegalArgumentException;
+import org.forgerock.opendj.ldap.ByteString;
 import org.forgerock.opendj.ldap.DN;
+import org.forgerock.opendj.ldap.DecodeException;
 import org.forgerock.opendj.ldap.Entry;
 import org.forgerock.opendj.ldap.EntryNotFoundException;
 import org.forgerock.opendj.ldap.LinkedHashMapEntry;
@@ -43,6 +45,7 @@
 import static org.mockito.Matchers.any;
 import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.when;
+
 import org.testng.annotations.Test;
 import org.forgerock.opendj.ldap.Connection;
 import org.forgerock.opendj.ldap.requests.SearchRequest;
@@ -2000,9 +2003,38 @@
         final Schema schema =
                 new SchemaBuilder(Schema.getCoreSchema()).defaultMatchingRule(
                         CoreSchema.getCaseIgnoreMatchingRule()).toSchema().asNonStrictSchema();
-        assertThat(schema.getDefaultMatchingRule()).isEqualTo(CoreSchema.getCaseIgnoreMatchingRule());
+        assertThat(schema.getDefaultMatchingRule()).isEqualTo(
+                CoreSchema.getCaseIgnoreMatchingRule());
         assertThat(schema.getAttributeType("dummy").getEqualityMatchingRule()).isEqualTo(
                 CoreSchema.getCaseIgnoreMatchingRule());
     }
 
+    @Test
+    public void testDefaultSyntaxDefinedInSchema() {
+        // The next line was triggering a NPE with OPENDJ-1252.
+        final Schema schema =
+                new SchemaBuilder().addSyntax("( 9.9.9 DESC 'Test Syntax' )", false).addSyntax(
+                        CoreSchema.getOctetStringSyntax().toString(), false).toSchema();
+
+        // Ensure that the substituted syntax is usable.
+        assertThat(schema.getSyntax("9.9.9").valueIsAcceptable(ByteString.valueOf("test"), null))
+                .isTrue();
+    }
+
+    @Test
+    public void testDefaultMatchingRuleDefinedInSchema() throws DecodeException {
+        final Schema schema =
+                new SchemaBuilder().addSyntax(CoreSchema.getOctetStringSyntax().toString(), false)
+                        .addMatchingRule(
+                                "( 9.9.9 NAME 'testRule' SYNTAX 1.3.6.1.4.1.1466.115.121.1.40 )",
+                                false).addMatchingRule(
+                                CoreSchema.getOctetStringMatchingRule().toString(), false)
+                        .toSchema();
+
+        // Ensure that the substituted rule is usable: was triggering a NPE with OPENDJ-1252.
+        assertThat(
+                schema.getMatchingRule("9.9.9").normalizeAttributeValue(ByteString.valueOf("test")))
+                .isEqualTo(ByteString.valueOf("test"));
+    }
+
 }

--
Gitblit v1.10.0