From 4b31a35ca148d08a0c89ebbcbb51edeb3ba411b9 Mon Sep 17 00:00:00 2001
From: neil_a_wilson <neil_a_wilson@localhost>
Date: Thu, 25 Jan 2007 01:59:52 +0000
Subject: [PATCH] Make a number of updates to schema processing, all of which fall under the umbrella of issue #1163.  The individual issues addressed include:

---
 opendj-sdk/opends/src/server/org/opends/server/schema/DITContentRuleSyntax.java |  358 ++++++++++++++++++++++++++++++++---------------------------
 1 files changed, 194 insertions(+), 164 deletions(-)

diff --git a/opendj-sdk/opends/src/server/org/opends/server/schema/DITContentRuleSyntax.java b/opendj-sdk/opends/src/server/org/opends/server/schema/DITContentRuleSyntax.java
index a8dc05e..d9f00ed 100644
--- a/opendj-sdk/opends/src/server/org/opends/server/schema/DITContentRuleSyntax.java
+++ b/opendj-sdk/opends/src/server/org/opends/server/schema/DITContentRuleSyntax.java
@@ -45,15 +45,13 @@
 import org.opends.server.types.ByteString;
 import org.opends.server.types.DirectoryException;
 import org.opends.server.types.DITContentRule;
-import org.opends.server.types.ErrorLogCategory;
-import org.opends.server.types.ErrorLogSeverity;
+import org.opends.server.types.InitializationException;
 import org.opends.server.types.ObjectClass;
 import org.opends.server.types.ObjectClassType;
 import org.opends.server.types.ResultCode;
 import org.opends.server.types.Schema;
 
 import static org.opends.server.loggers.Debug.*;
-import static org.opends.server.loggers.Error.*;
 import static org.opends.server.messages.MessageHandler.*;
 import static org.opends.server.messages.SchemaMessages.*;
 import static org.opends.server.schema.SchemaConstants.*;
@@ -104,17 +102,10 @@
 
 
   /**
-   * Initializes this attribute syntax based on the information in the provided
-   * configuration entry.
-   *
-   * @param  configEntry  The configuration entry that contains the information
-   *                      to use to initialize this attribute syntax.
-   *
-   * @throws  ConfigException  If an unrecoverable problem arises in the
-   *                           process of performing the initialization.
+   * {@inheritDoc}
    */
   public void initializeSyntax(ConfigEntry configEntry)
-         throws ConfigException
+         throws ConfigException, InitializationException
   {
     assert debugEnter(CLASS_NAME, "initializeSyntax",
                       String.valueOf(configEntry));
@@ -123,36 +114,37 @@
          DirectoryServer.getEqualityMatchingRule(EMR_CASE_IGNORE_OID);
     if (defaultEqualityMatchingRule == null)
     {
-      logError(ErrorLogCategory.SCHEMA, ErrorLogSeverity.SEVERE_ERROR,
-               MSGID_ATTR_SYNTAX_UNKNOWN_EQUALITY_MATCHING_RULE,
-               EMR_CASE_IGNORE_OID, SYNTAX_DIT_CONTENT_RULE_NAME);
+      int    msgID   = MSGID_ATTR_SYNTAX_UNKNOWN_EQUALITY_MATCHING_RULE;
+      String message = getMessage(msgID, EMR_CASE_IGNORE_OID,
+                                  SYNTAX_DIT_CONTENT_RULE_NAME);
+      throw new InitializationException(msgID, message);
     }
 
     defaultOrderingMatchingRule =
          DirectoryServer.getOrderingMatchingRule(OMR_CASE_IGNORE_OID);
     if (defaultOrderingMatchingRule == null)
     {
-      logError(ErrorLogCategory.SCHEMA, ErrorLogSeverity.SEVERE_ERROR,
-               MSGID_ATTR_SYNTAX_UNKNOWN_ORDERING_MATCHING_RULE,
-               OMR_CASE_IGNORE_OID, SYNTAX_DIT_CONTENT_RULE_NAME);
+      int    msgID   = MSGID_ATTR_SYNTAX_UNKNOWN_ORDERING_MATCHING_RULE;
+      String message = getMessage(msgID, OMR_CASE_IGNORE_OID,
+                                  SYNTAX_DIT_CONTENT_RULE_NAME);
+      throw new InitializationException(msgID, message);
     }
 
     defaultSubstringMatchingRule =
          DirectoryServer.getSubstringMatchingRule(SMR_CASE_IGNORE_OID);
     if (defaultSubstringMatchingRule == null)
     {
-      logError(ErrorLogCategory.SCHEMA, ErrorLogSeverity.SEVERE_ERROR,
-               MSGID_ATTR_SYNTAX_UNKNOWN_SUBSTRING_MATCHING_RULE,
-               SMR_CASE_IGNORE_OID, SYNTAX_DIT_CONTENT_RULE_NAME);
+      int    msgID   = MSGID_ATTR_SYNTAX_UNKNOWN_SUBSTRING_MATCHING_RULE;
+      String message = getMessage(msgID, SMR_CASE_IGNORE_OID,
+                                  SYNTAX_DIT_CONTENT_RULE_NAME);
+      throw new InitializationException(msgID, message);
     }
   }
 
 
 
   /**
-   * Retrieves the common name for this attribute syntax.
-   *
-   * @return  The common name for this attribute syntax.
+   * {@inheritDoc}
    */
   public String getSyntaxName()
   {
@@ -164,9 +156,7 @@
 
 
   /**
-   * Retrieves the OID for this attribute syntax.
-   *
-   * @return  The OID for this attribute syntax.
+   * {@inheritDoc}
    */
   public String getOID()
   {
@@ -178,9 +168,7 @@
 
 
   /**
-   * Retrieves a description for this attribute syntax.
-   *
-   * @return  A description for this attribute syntax.
+   * {@inheritDoc}
    */
   public String getDescription()
   {
@@ -192,12 +180,7 @@
 
 
   /**
-   * Retrieves the default equality matching rule that will be used for
-   * attributes with this syntax.
-   *
-   * @return  The default equality matching rule that will be used for
-   *          attributes with this syntax, or <CODE>null</CODE> if equality
-   *          matches will not be allowed for this type by default.
+   * {@inheritDoc}
    */
   public EqualityMatchingRule getEqualityMatchingRule()
   {
@@ -209,12 +192,7 @@
 
 
   /**
-   * Retrieves the default ordering matching rule that will be used for
-   * attributes with this syntax.
-   *
-   * @return  The default ordering matching rule that will be used for
-   *          attributes with this syntax, or <CODE>null</CODE> if ordering
-   *          matches will not be allowed for this type by default.
+   * {@inheritDoc}
    */
   public OrderingMatchingRule getOrderingMatchingRule()
   {
@@ -226,12 +204,7 @@
 
 
   /**
-   * Retrieves the default substring matching rule that will be used for
-   * attributes with this syntax.
-   *
-   * @return  The default substring matching rule that will be used for
-   *          attributes with this syntax, or <CODE>null</CODE> if substring
-   *          matches will not be allowed for this type by default.
+   * {@inheritDoc}
    */
   public SubstringMatchingRule getSubstringMatchingRule()
   {
@@ -243,12 +216,7 @@
 
 
   /**
-   * Retrieves the default approximate matching rule that will be used for
-   * attributes with this syntax.
-   *
-   * @return  The default approximate matching rule that will be used for
-   *          attributes with this syntax, or <CODE>null</CODE> if approximate
-   *          matches will not be allowed for this type by default.
+   * {@inheritDoc}
    */
   public ApproximateMatchingRule getApproximateMatchingRule()
   {
@@ -261,16 +229,7 @@
 
 
   /**
-   * Indicates whether the provided value is acceptable for use in an attribute
-   * with this syntax.  If it is not, then the reason may be appended to the
-   * provided buffer.
-   *
-   * @param  value          The value for which to make the determination.
-   * @param  invalidReason  The buffer to which the invalid reason should be
-   *                        appended.
-   *
-   * @return  <CODE>true</CODE> if the provided value is acceptable for use with
-   *          this syntax, or <CODE>false</CODE> if not.
+   * {@inheritDoc}
    */
   public boolean valueIsAcceptable(ByteString value,
                                    StringBuilder invalidReason)
@@ -283,7 +242,7 @@
     // acceptable.
     try
     {
-      decodeDITContentRule(value, DirectoryServer.getSchema());
+      decodeDITContentRule(value, DirectoryServer.getSchema(), true);
       return true;
     }
     catch (DirectoryException de)
@@ -304,10 +263,16 @@
    * should not be in order to allow the desired capitalization to be
    * preserved).
    *
-   * @param  value   The ASN.1 octet string containing the value to decode (it
-   *                 does not need to be normalized).
-   * @param  schema  The schema to use to resolve references to other schema
-   *                 elements.
+   * @param  value                 The ASN.1 octet string containing the value
+   *                               to decode (it does not need to be
+   *                               normalized).
+   * @param  schema                The schema to use to resolve references to
+   *                               other schema elements.
+   * @param  allowUnknownElements  Indicates whether to allow values that
+   *                               reference a name form and/or superior rules
+   *                               which are not defined in the server schema.
+   *                               This should only be true when called by
+   *                               {@code valueIsAcceptable}.
    *
    * @return  The decoded DIT content rule definition.
    *
@@ -315,7 +280,7 @@
    *                              DIT content rule definition.
    */
   public static DITContentRule decodeDITContentRule(ByteString value,
-                                                    Schema schema)
+                                    Schema schema, boolean allowUnknownElements)
          throws DirectoryException
   {
     assert debugEnter(CLASS_NAME, "decodeDITContentRule",
@@ -457,16 +422,21 @@
 
 
     // Get the objectclass with the specified OID.  If it does not exist or is
-    // not structural, then log a warning but continue on.
+    // not structural, then fail.
     ObjectClass structuralClass = schema.getObjectClass(oid);
     if (structuralClass == null)
     {
-      int    msgID   = MSGID_ATTR_SYNTAX_DCR_UNKNOWN_STRUCTURAL_CLASS;
-      String message = getMessage(msgID, valueStr, oid);
-      logError(ErrorLogCategory.SCHEMA, ErrorLogSeverity.SEVERE_WARNING,
-               message, msgID);
-
-      structuralClass = DirectoryServer.getDefaultObjectClass(oid);
+      if (allowUnknownElements)
+      {
+        structuralClass = DirectoryServer.getDefaultObjectClass(oid);
+      }
+      else
+      {
+        int    msgID   = MSGID_ATTR_SYNTAX_DCR_UNKNOWN_STRUCTURAL_CLASS;
+        String message = getMessage(msgID, valueStr, oid);
+        throw new DirectoryException(ResultCode.CONSTRAINT_VIOLATION, message,
+                                     msgID);
+      }
     }
     else if (structuralClass.getObjectClassType() != ObjectClassType.STRUCTURAL)
     {
@@ -474,8 +444,8 @@
       String message =
            getMessage(msgID, valueStr, oid, structuralClass.getNameOrOID(),
                       String.valueOf(structuralClass.getObjectClassType()));
-      logError(ErrorLogCategory.SCHEMA, ErrorLogSeverity.SEVERE_WARNING,
-               message, msgID);
+      throw new DirectoryException(ResultCode.CONSTRAINT_VIOLATION, message,
+                                   msgID);
     }
 
 
@@ -627,25 +597,30 @@
             ObjectClass oc = schema.getObjectClass(woidBuffer.toString());
             if (oc == null)
             {
-              // This isn't good because it is an unknown auxiliary class.  Log
-              // a message and construct a default.
-              int    msgID   = MSGID_ATTR_SYNTAX_DCR_UNKNOWN_AUXILIARY_CLASS;
-              String message = getMessage(msgID, valueStr,
+              // This isn't good because it is an unknown auxiliary class.
+              if (allowUnknownElements)
+              {
+                oc = DirectoryServer.getDefaultAuxiliaryObjectClass(
                                           woidBuffer.toString());
-              logError(ErrorLogCategory.SCHEMA, ErrorLogSeverity.SEVERE_WARNING,
-                       message, msgID);
-
-              oc = DirectoryServer.getDefaultObjectClass(woidBuffer.toString());
+              }
+              else
+              {
+                int    msgID   = MSGID_ATTR_SYNTAX_DCR_UNKNOWN_AUXILIARY_CLASS;
+                String message = getMessage(msgID, valueStr,
+                                            woidBuffer.toString());
+                throw new DirectoryException(ResultCode.CONSTRAINT_VIOLATION,
+                                             message, msgID);
+              }
             }
             else if (oc.getObjectClassType() != ObjectClassType.AUXILIARY)
             {
-              // This isn't good because it isn't an auxiliary class.  Log a
-              // message but continue on.
+              // This isn't good because it isn't an auxiliary class.
               int msgID = MSGID_ATTR_SYNTAX_DCR_AUXILIARY_CLASS_NOT_AUXILIARY;
               String message = getMessage(msgID, valueStr,
-                                          woidBuffer.toString());
-              logError(ErrorLogCategory.SCHEMA, ErrorLogSeverity.SEVERE_WARNING,
-                       message, msgID);
+                                          woidBuffer.toString(),
+                                          oc.getObjectClassType().toString());
+              throw new DirectoryException(ResultCode.CONSTRAINT_VIOLATION,
+                                           message, msgID);
             }
 
             ocs.add(oc);
@@ -676,23 +651,29 @@
           ObjectClass oc = schema.getObjectClass(woidBuffer.toString());
           if (oc == null)
           {
-            // This isn't good because it is an unknown auxiliary class.  Log
-            // a message and construct a default.
-            int    msgID   = MSGID_ATTR_SYNTAX_DCR_UNKNOWN_AUXILIARY_CLASS;
-            String message = getMessage(msgID, valueStr, woidBuffer.toString());
-            logError(ErrorLogCategory.SCHEMA, ErrorLogSeverity.SEVERE_WARNING,
-                     message, msgID);
-
-            oc = DirectoryServer.getDefaultObjectClass(woidBuffer.toString());
+            // This isn't good because it is an unknown auxiliary class.
+            if (allowUnknownElements)
+            {
+              oc = DirectoryServer.getDefaultAuxiliaryObjectClass(
+                                        woidBuffer.toString());
+            }
+            else
+            {
+              int    msgID   = MSGID_ATTR_SYNTAX_DCR_UNKNOWN_AUXILIARY_CLASS;
+              String message = getMessage(msgID, valueStr,
+                                          woidBuffer.toString());
+              throw new DirectoryException(ResultCode.CONSTRAINT_VIOLATION,
+                                           message, msgID);
+            }
           }
           else if (oc.getObjectClassType() != ObjectClassType.AUXILIARY)
           {
-            // This isn't good because it isn't an auxiliary class.  Log a
-            // message but continue on.
+            // This isn't good because it isn't an auxiliary class.
             int msgID = MSGID_ATTR_SYNTAX_DCR_AUXILIARY_CLASS_NOT_AUXILIARY;
-            String message = getMessage(msgID, valueStr, woidBuffer.toString());
-            logError(ErrorLogCategory.SCHEMA, ErrorLogSeverity.SEVERE_WARNING,
-                     message, msgID);
+            String message = getMessage(msgID, valueStr, woidBuffer.toString(),
+                                        oc.getObjectClassType().toString());
+            throw new DirectoryException(ResultCode.CONSTRAINT_VIOLATION,
+                                         message, msgID);
           }
 
           ocs.add(oc);
@@ -721,16 +702,19 @@
             {
               // This isn't good because it means that the DIT content rule
               // requires an attribute type that we don't know anything about.
-              // in this case all we can do is log a message and construct a
-              // default type.
-              int    msgID   = MSGID_ATTR_SYNTAX_DCR_UNKNOWN_REQUIRED_ATTR;
-              String message = getMessage(msgID, valueStr,
-                                          woidBuffer.toString());
-              logError(ErrorLogCategory.SCHEMA, ErrorLogSeverity.SEVERE_WARNING,
-                       message, msgID);
-
-              attr = DirectoryServer.getDefaultAttributeType(
-                                          woidBuffer.toString());
+              if (allowUnknownElements)
+              {
+                attr = DirectoryServer.getDefaultAttributeType(
+                                            woidBuffer.toString());
+              }
+              else
+              {
+                int    msgID   = MSGID_ATTR_SYNTAX_DCR_UNKNOWN_REQUIRED_ATTR;
+                String message = getMessage(msgID, valueStr,
+                                            woidBuffer.toString());
+                throw new DirectoryException(ResultCode.CONSTRAINT_VIOLATION,
+                                             message, msgID);
+              }
             }
 
             attrs.add(attr);
@@ -762,16 +746,20 @@
           if (attr == null)
           {
             // This isn't good because it means that the DIT content rule
-            // requires an attribute type that we don't know anything about.  In
-            // this case all we can do is log a message and construct a default
-            // type.
-            int    msgID   = MSGID_ATTR_SYNTAX_DCR_UNKNOWN_REQUIRED_ATTR;
-            String message = getMessage(msgID, valueStr, woidBuffer.toString());
-            logError(ErrorLogCategory.SCHEMA, ErrorLogSeverity.SEVERE_WARNING,
-                     message, msgID);
-
-            attr = DirectoryServer.getDefaultAttributeType(
-                                        woidBuffer.toString());
+            // requires an attribute type that we don't know anything about.
+            if (allowUnknownElements)
+            {
+              attr = DirectoryServer.getDefaultAttributeType(
+                                          woidBuffer.toString());
+            }
+            else
+            {
+              int    msgID   = MSGID_ATTR_SYNTAX_DCR_UNKNOWN_REQUIRED_ATTR;
+              String message = getMessage(msgID, valueStr,
+                                          woidBuffer.toString());
+              throw new DirectoryException(ResultCode.CONSTRAINT_VIOLATION,
+                                           message, msgID);
+            }
           }
 
           attrs.add(attr);
@@ -799,17 +787,20 @@
             if (attr == null)
             {
               // This isn't good because it means that the DIT content rule
-              // allows an attribute type that we don't know anything about.  In
-              // this case all we can do is log a message and construct a
-              // default type.
-              int    msgID   = MSGID_ATTR_SYNTAX_DCR_UNKNOWN_OPTIONAL_ATTR;
-              String message = getMessage(msgID, valueStr,
-                                          woidBuffer.toString());
-              logError(ErrorLogCategory.SCHEMA, ErrorLogSeverity.SEVERE_WARNING,
-                       message, msgID);
-
-              attr = DirectoryServer.getDefaultAttributeType(
-                                          woidBuffer.toString());
+              // allows an attribute type that we don't know anything about.
+              if (allowUnknownElements)
+              {
+                attr = DirectoryServer.getDefaultAttributeType(
+                                            woidBuffer.toString());
+              }
+              else
+              {
+                int    msgID   = MSGID_ATTR_SYNTAX_DCR_UNKNOWN_OPTIONAL_ATTR;
+                String message = getMessage(msgID, valueStr,
+                                            woidBuffer.toString());
+                throw new DirectoryException(ResultCode.CONSTRAINT_VIOLATION,
+                                             message, msgID);
+              }
             }
 
             attrs.add(attr);
@@ -841,15 +832,20 @@
           if (attr == null)
           {
             // This isn't good because it means that the DIT content rule allows
-            // an attribute type that we don't know anything about.  In this
-            // case all we can do is log a message and construct a default type.
-            int    msgID   = MSGID_ATTR_SYNTAX_DCR_UNKNOWN_OPTIONAL_ATTR;
-            String message = getMessage(msgID, valueStr, woidBuffer.toString());
-            logError(ErrorLogCategory.SCHEMA, ErrorLogSeverity.SEVERE_WARNING,
-                     message, msgID);
-
-            attr = DirectoryServer.getDefaultAttributeType(
-                                        woidBuffer.toString());
+            // an attribute type that we don't know anything about.
+            if (allowUnknownElements)
+            {
+              attr = DirectoryServer.getDefaultAttributeType(
+                                          woidBuffer.toString());
+            }
+            else
+            {
+              int    msgID   = MSGID_ATTR_SYNTAX_DCR_UNKNOWN_OPTIONAL_ATTR;
+              String message = getMessage(msgID, valueStr,
+                                          woidBuffer.toString());
+              throw new DirectoryException(ResultCode.CONSTRAINT_VIOLATION,
+                                           message, msgID);
+            }
           }
 
           attrs.add(attr);
@@ -878,16 +874,19 @@
             {
               // This isn't good because it means that the DIT content rule
               // prohibits an attribute type that we don't know anything about.
-              // In this case all we can do is log a message and construct a
-              // default type.
-              int    msgID   = MSGID_ATTR_SYNTAX_DCR_UNKNOWN_PROHIBITED_ATTR;
-              String message = getMessage(msgID, valueStr,
-                                          woidBuffer.toString());
-              logError(ErrorLogCategory.SCHEMA, ErrorLogSeverity.SEVERE_WARNING,
-                       message, msgID);
-
-              attr = DirectoryServer.getDefaultAttributeType(
-                                          woidBuffer.toString());
+              if (allowUnknownElements)
+              {
+                attr = DirectoryServer.getDefaultAttributeType(
+                                            woidBuffer.toString());
+              }
+              else
+              {
+                int    msgID   = MSGID_ATTR_SYNTAX_DCR_UNKNOWN_PROHIBITED_ATTR;
+                String message = getMessage(msgID, valueStr,
+                                            woidBuffer.toString());
+                throw new DirectoryException(ResultCode.CONSTRAINT_VIOLATION,
+                                             message, msgID);
+              }
             }
 
             attrs.add(attr);
@@ -920,15 +919,19 @@
           {
             // This isn't good because it means that the DIT content rule
             // prohibits an attribute type that we don't know anything about.
-            // In this case all we can do is log a message and construct a
-            // default type.
-            int    msgID   = MSGID_ATTR_SYNTAX_DCR_UNKNOWN_PROHIBITED_ATTR;
-            String message = getMessage(msgID, valueStr, woidBuffer.toString());
-            logError(ErrorLogCategory.SCHEMA, ErrorLogSeverity.SEVERE_WARNING,
-                     message, msgID);
-
-            attr = DirectoryServer.getDefaultAttributeType(
-                                        woidBuffer.toString());
+            if (allowUnknownElements)
+            {
+              attr = DirectoryServer.getDefaultAttributeType(
+                                          woidBuffer.toString());
+            }
+            else
+            {
+              int    msgID   = MSGID_ATTR_SYNTAX_DCR_UNKNOWN_PROHIBITED_ATTR;
+              String message = getMessage(msgID, valueStr,
+                                          woidBuffer.toString());
+              throw new DirectoryException(ResultCode.CONSTRAINT_VIOLATION,
+                                           message, msgID);
+            }
           }
 
           attrs.add(attr);
@@ -949,6 +952,33 @@
     }
 
 
+    // Make sure that none of the prohibited attributes is required by the
+    // structural or any of the auxiliary classes.
+    for (AttributeType t : prohibitedAttributes)
+    {
+      if (structuralClass.isRequired(t))
+      {
+        int msgID = MSGID_ATTR_SYNTAX_DCR_PROHIBITED_REQUIRED_BY_STRUCTURAL;
+        String message = getMessage(msgID, valueStr, t.getNameOrOID(),
+                                    structuralClass.getNameOrOID());
+        throw new DirectoryException(ResultCode.CONSTRAINT_VIOLATION, message,
+                                     msgID);
+      }
+
+      for (ObjectClass oc : auxiliaryClasses)
+      {
+        if (oc.isRequired(t))
+        {
+          int msgID = MSGID_ATTR_SYNTAX_DCR_PROHIBITED_REQUIRED_BY_AUXILIARY;
+          String message = getMessage(msgID, valueStr, t.getNameOrOID(),
+                                      oc.getNameOrOID());
+          throw new DirectoryException(ResultCode.CONSTRAINT_VIOLATION, message,
+                                       msgID);
+        }
+      }
+    }
+
+
     return new DITContentRule(value.stringValue(), structuralClass, names,
                               description, auxiliaryClasses, requiredAttributes,
                               optionalAttributes, prohibitedAttributes,

--
Gitblit v1.10.0