mirror of https://github.com/OpenIdentityPlatform/OpenDJ.git

neil_a_wilson
25.59.2007 4b31a35ca148d08a0c89ebbcbb51edeb3ba411b9
Make a number of updates to schema processing, all of which fall under the
umbrella of issue #1163. The individual issues addressed include:

* 1139 -- Properly handle OBSOLETE flag in schema elements. The OBSOLETE flag
is now recognized when processing matching rules, attribute types, object
classes, name forms, DIT content rules, DIT structure rules, and matching rule
uses. It essentially provides a way to "deprecate" a schema element so that
existing data that makes use of them will still be treated properly, but the
server will not allow newly-created elements to reference them.

* 1145 -- Consider updating X-ORIGIN to reference newer RFCs. When the schema
configuration files were originally written, there were a number of references
to RFC 2252 and RFC 2256 that were updated in RFC 4512 and RFC 4519, among
others. The X-ORIGIN extension for each element in the 00-core.ldif schema
configuration file should now reference the latest specification that contains
that element.

* 1146 -- Consider enforcing object class inheritance restrictions. The server
will now ensure that abstract classes can only inherit from other abstract
classes, that auxiliary classes can only inherit from abstract classes and
other auxiliary classes, and that structural classes can only inherit from
abstract classes and other structural classes. Further, all structural object
classes must include the "top" abstract class as the root of their inheritance
chain.

* 1147 -- Consider enforcing attribute type inheritance restrictions. The
server will now ensure that a subordinate attribute type will have the same
usage as its superior type. Further, the server will enforce that a
subordinate attribute type may be collective if and only if its superior type
is collective. Due to the subjective nature of the "refinement" clause for
syntax inheritance, no check will be made regarding the syntax relationship
between a superior and subordinate attribute type.

* 1151 -- DIT content rule validation isn't handled correctly. The server will
now allow attribute types to appear in an entry if they are included in the
required or optional attribute type lists for a DIT content rule even if those
attributes are not allowed by any of the entry's associated object classes.
Further, the DIT content rule validation process will now ensure that none of
the prohibited attribute types are required by the structural object class or
any of the allowed auxiliary object classes.

* 1158 -- Attribute syntaxes describing schema elements aren't strict enough.
Previously, in most cases that one schema element referenced another element
that was not defined (e.g., an object class allows an attribute type that is
not defined in the server schema), the server would ignore the unresolved
dependency. The server will now fail to validate schema elements that depend
on other schema elements which are not defined in the server schema.
Similarly, there were cases in which the server did not properly validate that
an object class was of the appropriate type (e.g., for a DIT content rule,
there was no check to ensure that the structural object class was actually
declared structural, or that all of the allowed auxiliary objectclasses were
actually declared auxiliary). The server will also fail to validate schema
elements with these kinds of problems.

* 1159 -- Incomplete attribute type usage constraints. The server did not
properly ensure that COLLECTIVE attribute types had a usage of
userApplications, and that NO-USER-MODIFICATION attribute types had an
operational usage.

* 1164 -- Need more complete DIT structure rule validation. The server did not
properly ensure that if an entry's parent was associated with a DIT structure
rule, that entry would only be valid if it was covered by a DIT structure rule
which listed the parent's DIT structure rule as a superior rule.

* 1165 -- Consider reduced name form and DIT structure rule checking. The
server would often perform more schema validation than necessary for most types
of operations. In particular, name form and DIT structure rule validation
should not be required for modify operations, and DIT structure rule validation
should also not be required for LDIF import operations since we cannot
guarantee that the parent will be accessible.
1 files added
32 files modified
6377 ■■■■ changed files
opendj-sdk/opends/resource/schema/00-core.ldif 192 ●●●● patch | view | raw | blame | history
opendj-sdk/opends/resource/schema/02-config.ldif 3 ●●●● patch | view | raw | blame | history
opendj-sdk/opends/src/server/org/opends/server/backends/SchemaBackend.java 224 ●●●●● patch | view | raw | blame | history
opendj-sdk/opends/src/server/org/opends/server/core/AddOperation.java 45 ●●●●● patch | view | raw | blame | history
opendj-sdk/opends/src/server/org/opends/server/core/DirectoryServer.java 36 ●●●●● patch | view | raw | blame | history
opendj-sdk/opends/src/server/org/opends/server/core/ModifyDNOperation.java 19 ●●●● patch | view | raw | blame | history
opendj-sdk/opends/src/server/org/opends/server/core/ModifyOperation.java 23 ●●●●● patch | view | raw | blame | history
opendj-sdk/opends/src/server/org/opends/server/core/SchemaConfigManager.java 11 ●●●● patch | view | raw | blame | history
opendj-sdk/opends/src/server/org/opends/server/messages/BackendMessages.java 279 ●●●●● patch | view | raw | blame | history
opendj-sdk/opends/src/server/org/opends/server/messages/CoreMessages.java 137 ●●●● patch | view | raw | blame | history
opendj-sdk/opends/src/server/org/opends/server/messages/SchemaMessages.java 199 ●●●● patch | view | raw | blame | history
opendj-sdk/opends/src/server/org/opends/server/schema/AttributeTypeSyntax.java 210 ●●●● patch | view | raw | blame | history
opendj-sdk/opends/src/server/org/opends/server/schema/DITContentRuleSyntax.java 304 ●●●● patch | view | raw | blame | history
opendj-sdk/opends/src/server/org/opends/server/schema/DITStructureRuleSyntax.java 87 ●●●● patch | view | raw | blame | history
opendj-sdk/opends/src/server/org/opends/server/schema/MatchingRuleUseSyntax.java 140 ●●●●● patch | view | raw | blame | history
opendj-sdk/opends/src/server/org/opends/server/schema/NameFormSyntax.java 202 ●●●● patch | view | raw | blame | history
opendj-sdk/opends/src/server/org/opends/server/schema/ObjectClassSyntax.java 300 ●●●●● patch | view | raw | blame | history
opendj-sdk/opends/src/server/org/opends/server/types/AttributeType.java 3 ●●●● patch | view | raw | blame | history
opendj-sdk/opends/src/server/org/opends/server/types/DITContentRule.java 3 ●●●● patch | view | raw | blame | history
opendj-sdk/opends/src/server/org/opends/server/types/Entry.java 537 ●●●●● patch | view | raw | blame | history
opendj-sdk/opends/src/server/org/opends/server/types/MatchingRuleUse.java 3 ●●●● patch | view | raw | blame | history
opendj-sdk/opends/src/server/org/opends/server/types/NameForm.java 2 ●●● patch | view | raw | blame | history
opendj-sdk/opends/src/server/org/opends/server/types/ObjectClass.java 2 ●●● patch | view | raw | blame | history
opendj-sdk/opends/src/server/org/opends/server/util/LDIFReader.java 2 ●●● patch | view | raw | blame | history
opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/backends/SchemaBackendTestCase.java 1529 ●●●●● patch | view | raw | blame | history
opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/backends/SchemaTestMatchingRule.java 39 ●●●●● patch | view | raw | blame | history
opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/core/AddOperationTestCase.java 176 ●●●●● patch | view | raw | blame | history
opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/core/ModifyOperationTestCase.java 118 ●●●●● patch | view | raw | blame | history
opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/core/TestModifyDNOperation.java 66 ●●●●● patch | view | raw | blame | history
opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/schema/AttributeTypeSyntaxTest.java 43 ●●●● patch | view | raw | blame | history
opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/schema/DITContentRuleSyntaxTest.java 8 ●●●● patch | view | raw | blame | history
opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/types/EntrySchemaCheckingTestCase.java 1433 ●●●●● patch | view | raw | blame | history
opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/types/TestEntry.java 2 ●●● patch | view | raw | blame | history
opendj-sdk/opends/resource/schema/00-core.ldif
@@ -34,72 +34,72 @@
objectClass: subschema
attributeTypes: ( 2.5.4.41 NAME 'name' EQUALITY caseIgnoreMatch
  SUBSTR caseIgnoreSubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{32768}
  X-ORIGIN 'RFC 2256' )
  X-ORIGIN 'RFC 4519' )
attributeTypes: ( 2.5.4.49 NAME 'distinguishedName'
  EQUALITY distinguishedNameMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.12
  X-ORIGIN 'RFC 2256' )
  X-ORIGIN 'RFC 4519' )
attributeTypes: ( 2.5.4.0 NAME 'objectClass' EQUALITY objectIdentifierMatch
  SYNTAX 1.3.6.1.4.1.1466.115.121.1.38 X-ORIGIN 'RFC 2256' )
  SYNTAX 1.3.6.1.4.1.1466.115.121.1.38 X-ORIGIN 'RFC 4512' )
attributeTypes: ( 2.5.4.1 NAME 'aliasedObjectName'
  EQUALITY distinguishedNameMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.12
  SINGLE-VALUE X-ORIGIN 'RFC 2256' )
  SINGLE-VALUE X-ORIGIN 'RFC 4512' )
attributeTypes: ( 2.5.4.2 NAME 'knowledgeInformation' EQUALITY caseIgnoreMatch
  SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{32768} X-ORIGIN 'RFC 2256' )
attributeTypes: ( 2.5.4.3 NAME 'cn' SUP name X-ORIGIN 'RFC 2256' )
attributeTypes: ( 2.5.4.4 NAME 'sn' SUP name X-ORIGIN 'RFC 2256' )
attributeTypes: ( 2.5.4.3 NAME 'cn' SUP name X-ORIGIN 'RFC 4519' )
attributeTypes: ( 2.5.4.4 NAME 'sn' SUP name X-ORIGIN 'RFC 4519' )
attributeTypes: ( 2.5.4.5 NAME 'serialNumber' EQUALITY caseIgnoreMatch
  SUBSTR caseIgnoreSubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.44{64}
  X-ORIGIN 'RFC 2256' )
attributeTypes: ( 2.5.4.6 NAME 'c' SUP name SINGLE-VALUE X-ORIGIN 'RFC 2256' )
attributeTypes: ( 2.5.4.7 NAME 'l' SUP name X-ORIGIN 'RFC 2256' )
attributeTypes: ( 2.5.4.8 NAME 'st' SUP name X-ORIGIN 'RFC 2256' )
  X-ORIGIN 'RFC 4519' )
attributeTypes: ( 2.5.4.6 NAME 'c' SUP name SINGLE-VALUE X-ORIGIN 'RFC 4519' )
attributeTypes: ( 2.5.4.7 NAME 'l' SUP name X-ORIGIN 'RFC 4519' )
attributeTypes: ( 2.5.4.8 NAME 'st' SUP name X-ORIGIN 'RFC 4519' )
attributeTypes: ( 2.5.4.9 NAME 'street' EQUALITY caseIgnoreMatch
  SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{128} X-ORIGIN 'RFC 2256' )
attributeTypes: ( 2.5.4.10 NAME 'o' SUP name X-ORIGIN 'RFC 2256' )
attributeTypes: ( 2.5.4.11 NAME 'ou' SUP name X-ORIGIN 'RFC 2256' )
attributeTypes: ( 2.5.4.12 NAME 'title' SUP name X-ORIGIN 'RFC 2256' )
  SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{128} X-ORIGIN 'RFC 4519' )
attributeTypes: ( 2.5.4.10 NAME 'o' SUP name X-ORIGIN 'RFC 4519' )
attributeTypes: ( 2.5.4.11 NAME 'ou' SUP name X-ORIGIN 'RFC 4519' )
attributeTypes: ( 2.5.4.12 NAME 'title' SUP name X-ORIGIN 'RFC 4519' )
attributeTypes: ( 2.5.4.13 NAME 'description' EQUALITY caseIgnoreMatch
  SUBSTR caseIgnoreSubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{1024}
  X-ORIGIN 'RFC 2256' )
  X-ORIGIN 'RFC 4519' )
attributeTypes: ( 2.5.4.14 NAME 'searchGuide'
  SYNTAX 1.3.6.1.4.1.1466.115.121.1.25 X-ORIGIN 'RFC 2256' )
  SYNTAX 1.3.6.1.4.1.1466.115.121.1.25 X-ORIGIN 'RFC 4519' )
attributeTypes: ( 2.5.4.15 NAME 'businessCategory' EQUALITY caseIgnoreMatch
  SUBSTR caseIgnoreSubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{128}
  X-ORIGIN 'RFC 2256' )
  X-ORIGIN 'RFC 4519' )
attributeTypes: ( 2.5.4.16 NAME 'postalAddress' EQUALITY caseIgnoreListMatch
  SUBSTR caseIgnoreListSubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.41
  X-ORIGIN 'RFC 2256' )
  X-ORIGIN 'RFC 4519' )
attributeTypes: ( 2.5.4.17 NAME 'postalCode' EQUALITY caseIgnoreMatch
  SUBSTR caseIgnoreSubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{40}
  X-ORIGIN 'RFC 2256' )
  X-ORIGIN 'RFC 4519' )
attributeTypes: ( 2.5.4.18 NAME 'postOfficeBox' EQUALITY caseIgnoreMatch
  SUBSTR caseIgnoreSubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{40}
  X-ORIGIN 'RFC 2256' )
  X-ORIGIN 'RFC 4519' )
attributeTypes: ( 2.5.4.19 NAME 'physicalDeliveryOfficeName'
  EQUALITY caseIgnoreMatch SUBSTR caseIgnoreSubstringsMatch
  SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{128} X-ORIGIN 'RFC 2256' )
  SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{128} X-ORIGIN 'RFC 4519' )
attributeTypes: ( 2.5.4.20 NAME 'telephoneNumber' EQUALITY telephoneNumberMatch
  SUBSTR telephoneNumberSubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.50{32}
  X-ORIGIN 'RFC 2256' )
  X-ORIGIN 'RFC 4519' )
attributeTypes: ( 2.5.4.21 NAME 'telexNumber'
  SYNTAX 1.3.6.1.4.1.1466.115.121.1.52 X-ORIGIN 'RFC 2256' )
  SYNTAX 1.3.6.1.4.1.1466.115.121.1.52 X-ORIGIN 'RFC 4519' )
attributeTypes: ( 2.5.4.22 NAME 'teletexTerminalIdentifier'
  SYNTAX 1.3.6.1.4.1.1466.115.121.1.51 X-ORIGIN 'RFC 2256' )
  SYNTAX 1.3.6.1.4.1.1466.115.121.1.51 X-ORIGIN 'RFC 4519' )
attributeTypes: ( 2.5.4.23 NAME 'facsimileTelephoneNumber'
  SYNTAX 1.3.6.1.4.1.1466.115.121.1.22 X-ORIGIN 'RFC 2256' )
  SYNTAX 1.3.6.1.4.1.1466.115.121.1.22 X-ORIGIN 'RFC 4519' )
attributeTypes: ( 2.5.4.24 NAME 'x121Address' EQUALITY numericStringMatch
  SUBSTR numericStringSubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.36{15}
  X-ORIGIN 'RFC 2256' )
  X-ORIGIN 'RFC 4519' )
attributeTypes: ( 2.5.4.25 NAME 'internationaliSDNNumber'
  EQUALITY numericStringMatch SUBSTR numericStringSubstringsMatch
  SYNTAX 1.3.6.1.4.1.1466.115.121.1.36{16} X-ORIGIN 'RFC 2256' )
  SYNTAX 1.3.6.1.4.1.1466.115.121.1.36{16} X-ORIGIN 'RFC 4519' )
attributeTypes: ( 2.5.4.26 NAME 'registeredAddress' SUP postalAddress
  SYNTAX 1.3.6.1.4.1.1466.115.121.1.41 X-ORIGIN 'RFC 2256' )
  SYNTAX 1.3.6.1.4.1.1466.115.121.1.41 X-ORIGIN 'RFC 4519' )
attributeTypes: ( 2.5.4.27 NAME 'destinationIndicator' EQUALITY caseIgnoreMatch
  SUBSTR caseIgnoreSubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.44{128}
  X-ORIGIN 'RFC 2256' )
  X-ORIGIN 'RFC 4519' )
attributeTypes: ( 2.5.4.28 NAME 'preferredDeliveryMethod'
  SYNTAX 1.3.6.1.4.1.1466.115.121.1.14 SINGLE-VALUE X-ORIGIN 'RFC 2256' )
  SYNTAX 1.3.6.1.4.1.1466.115.121.1.14 SINGLE-VALUE X-ORIGIN 'RFC 4519' )
attributeTypes: ( 2.5.4.29 NAME 'presentationAddress'
  EQUALITY presentationAddressMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.43
  SINGLE-VALUE X-ORIGIN 'RFC 2256' )
@@ -107,36 +107,36 @@
  EQUALITY objectIdentifierMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.38
  X-ORIGIN 'RFC 2256' )
attributeTypes: ( 2.5.4.31 NAME 'member' SUP distinguishedName
  X-ORIGIN 'RFC 2256' )
  X-ORIGIN 'RFC 4519' )
attributeTypes: ( 2.5.4.32 NAME 'owner' SUP distinguishedName
  X-ORIGIN 'RFC 2256' )
  X-ORIGIN 'RFC 4519' )
attributeTypes: ( 2.5.4.33 NAME 'roleOccupant' SUP distinguishedName
  X-ORIGIN 'RFC 2256' )
  X-ORIGIN 'RFC 4519' )
attributeTypes: ( 2.5.4.34 NAME 'seeAlso' SUP distinguishedName
  X-ORIGIN 'RFC 2256' )
  X-ORIGIN 'RFC 4519' )
attributeTypes: ( 2.5.4.35 NAME 'userPassword'
  SYNTAX 1.3.6.1.4.1.26027.1.3.1 X-ORIGIN 'RFC 2256' )
  SYNTAX 1.3.6.1.4.1.26027.1.3.1 X-ORIGIN 'RFC 4519' )
attributeTypes: ( 2.5.4.36 NAME 'userCertificate'
  SYNTAX 1.3.6.1.4.1.1466.115.121.1.8 X-ORIGIN 'RFC 2256' )
  SYNTAX 1.3.6.1.4.1.1466.115.121.1.8 X-ORIGIN 'RFC 4523' )
attributeTypes: ( 2.5.4.37 NAME 'cACertificate'
  SYNTAX 1.3.6.1.4.1.1466.115.121.1.8 X-ORIGIN 'RFC 2256' )
  SYNTAX 1.3.6.1.4.1.1466.115.121.1.8 X-ORIGIN 'RFC 4523' )
attributeTypes: ( 2.5.4.38 NAME 'authorityRevocationList'
  SYNTAX 1.3.6.1.4.1.1466.115.121.1.9 X-ORIGIN 'RFC 2256' )
  SYNTAX 1.3.6.1.4.1.1466.115.121.1.9 X-ORIGIN 'RFC 4523' )
attributeTypes: ( 2.5.4.39 NAME 'certificateRevocationList'
  SYNTAX 1.3.6.1.4.1.1466.115.121.1.9 X-ORIGIN 'RFC 2256' )
  SYNTAX 1.3.6.1.4.1.1466.115.121.1.9 X-ORIGIN 'RFC 4523' )
attributeTypes: ( 2.5.4.40 NAME 'crossCertificatePair'
  SYNTAX 1.3.6.1.4.1.1466.115.121.1.10 X-ORIGIN 'RFC 2256' )
attributeTypes: ( 2.5.4.42 NAME 'givenName' SUP name X-ORIGIN 'RFC 2256' )
attributeTypes: ( 2.5.4.43 NAME 'initials' SUP name X-ORIGIN 'RFC 2256' )
  SYNTAX 1.3.6.1.4.1.1466.115.121.1.10 X-ORIGIN 'RFC 4523' )
attributeTypes: ( 2.5.4.42 NAME 'givenName' SUP name X-ORIGIN 'RFC 4519' )
attributeTypes: ( 2.5.4.43 NAME 'initials' SUP name X-ORIGIN 'RFC 4519' )
attributeTypes: ( 2.5.4.44 NAME 'generationQualifier' SUP name
  X-ORIGIN 'RFC 2256' )
  X-ORIGIN 'RFC 4519' )
attributeTypes: ( 2.5.4.45 NAME 'x500UniqueIdentifier' EQUALITY bitStringMatch
  SYNTAX 1.3.6.1.4.1.1466.115.121.1.6 X-ORIGIN 'RFC 2256' )
  SYNTAX 1.3.6.1.4.1.1466.115.121.1.6 X-ORIGIN 'RFC 4519' )
attributeTypes: ( 2.5.4.46 NAME 'dnQualifier' EQUALITY caseIgnoreMatch
  ORDERING caseIgnoreOrderingMatch SUBSTR caseIgnoreSubstringsMatch
  SYNTAX 1.3.6.1.4.1.1466.115.121.1.44 X-ORIGIN 'RFC 2256' )
  SYNTAX 1.3.6.1.4.1.1466.115.121.1.44 X-ORIGIN 'RFC 4519' )
attributeTypes: ( 2.5.4.47 NAME 'enhancedSearchGuide'
  SYNTAX 1.3.6.1.4.1.1466.115.121.1.21 X-ORIGIN 'RFC 2256' )
  SYNTAX 1.3.6.1.4.1.1466.115.121.1.21 X-ORIGIN 'RFC 4519' )
attributeTypes: ( 1.3.6.1.1.16.4 NAME 'entryUUID'
  DESC 'UUID of the entry' EQUALITY uuidMatch ORDERING uuidOrderingMatch
  SYNTAX 1.3.6.1.1.16.1 SINGLE-VALUE NO-USER-MODIFICATION
@@ -145,75 +145,75 @@
  EQUALITY protocolInformationMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.42
  X-ORIGIN 'RFC 2256' )
attributeTypes: ( 2.5.4.50 NAME 'uniqueMember' EQUALITY uniqueMemberMatch
  SYNTAX 1.3.6.1.4.1.1466.115.121.1.34 X-ORIGIN 'RFC 2256' )
  SYNTAX 1.3.6.1.4.1.1466.115.121.1.34 X-ORIGIN 'RFC 4519' )
attributeTypes: ( 2.5.4.51 NAME 'houseIdentifier' EQUALITY caseIgnoreMatch
  SUBSTR caseIgnoreSubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{32768}
  X-ORIGIN 'RFC 2256' )
  X-ORIGIN 'RFC 4519' )
attributeTypes: ( 2.5.4.52 NAME 'supportedAlgorithms'
  SYNTAX 1.3.6.1.4.1.1466.115.121.1.49 X-ORIGIN 'RFC 2256' )
  SYNTAX 1.3.6.1.4.1.1466.115.121.1.49 X-ORIGIN 'RFC 4523' )
attributeTypes: ( 2.5.4.53 NAME 'deltaRevocationList'
  SYNTAX 1.3.6.1.4.1.1466.115.121.1.9 X-ORIGIN 'RFC 2256' )
  SYNTAX 1.3.6.1.4.1.1466.115.121.1.9 X-ORIGIN 'RFC 4523' )
attributeTypes: ( 2.5.4.54 NAME 'dmdName' SUP name X-ORIGIN 'RFC 2256' )
attributeTypes: ( 2.5.18.1 NAME 'createTimestamp' EQUALITY generalizedTimeMatch
  ORDERING generalizedTimeOrderingMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.24
  SINGLE-VALUE NO-USER-MODIFICATION USAGE directoryOperation
  X-ORIGIN 'RFC 2252' )
  X-ORIGIN 'RFC 4512' )
attributeTypes: ( 2.5.18.2 NAME 'modifyTimestamp' EQUALITY generalizedTimeMatch
  ORDERING generalizedTimeOrderingMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.24
  SINGLE-VALUE NO-USER-MODIFICATION USAGE directoryOperation
  X-ORIGIN 'RFC 2252' )
  X-ORIGIN 'RFC 4512' )
attributeTypes: ( 2.5.18.3 NAME 'creatorsName' EQUALITY distinguishedNameMatch
  SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 SINGLE-VALUE NO-USER-MODIFICATION
  USAGE directoryOperation X-ORIGIN 'RFC 2252' )
  USAGE directoryOperation X-ORIGIN 'RFC 4512' )
attributeTypes: ( 2.5.18.4 NAME 'modifiersName' EQUALITY distinguishedNameMatch
  SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 SINGLE-VALUE NO-USER-MODIFICATION
  USAGE directoryOperation X-ORIGIN 'RFC 2252' )
  USAGE directoryOperation X-ORIGIN 'RFC 4512' )
attributeTypes: ( 2.5.18.10 NAME 'subschemaSubentry'
  EQUALITY distinguishedNameMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.12
  SINGLE-VALUE NO-USER-MODIFICATION USAGE directoryOperation
  X-ORIGIN 'RFC 2252' )
  X-ORIGIN 'RFC 4512' )
attributeTypes: ( 2.5.21.5 NAME 'attributeTypes' EQUALITY caseIgnoreMatch
  SYNTAX 1.3.6.1.4.1.1466.115.121.1.3 USAGE directoryOperation
  X-ORIGIN 'RFC 2252' )
  X-ORIGIN 'RFC 4512' )
attributeTypes: ( 2.5.21.6 NAME 'objectClasses' EQUALITY caseIgnoreMatch
  SYNTAX 1.3.6.1.4.1.1466.115.121.1.37 USAGE directoryOperation
  X-ORIGIN 'RFC 2252' )
  X-ORIGIN 'RFC 4512' )
attributeTypes: ( 2.5.21.4 NAME 'matchingRules' EQUALITY caseIgnoreMatch
  SYNTAX 1.3.6.1.4.1.1466.115.121.1.30 USAGE directoryOperation
  X-ORIGIN 'RFC 2252' )
  X-ORIGIN 'RFC 4512' )
attributeTypes: ( 2.5.21.8 NAME 'matchingRuleUse' EQUALITY caseIgnoreMatch
  SYNTAX 1.3.6.1.4.1.1466.115.121.1.31 USAGE directoryOperation
  X-ORIGIN 'RFC 2252' )
  X-ORIGIN 'RFC 4512' )
attributeTypes: ( 1.3.6.1.4.1.1466.101.120.5 NAME 'namingContexts'
  SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 USAGE dSAOperation X-ORIGIN 'RFC 2252' )
  SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 USAGE dSAOperation X-ORIGIN 'RFC 4512' )
attributeTypes: ( 1.3.6.1.4.1.1466.101.120.6 NAME 'altServer'
  SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 USAGE dSAOperation X-ORIGIN 'RFC 2252' )
  SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 USAGE dSAOperation X-ORIGIN 'RFC 4512' )
attributeTypes: ( 1.3.6.1.4.1.1466.101.120.7 NAME 'supportedExtension'
  SYNTAX 1.3.6.1.4.1.1466.115.121.1.38 USAGE dSAOperation X-ORIGIN 'RFC 2252' )
  SYNTAX 1.3.6.1.4.1.1466.115.121.1.38 USAGE dSAOperation X-ORIGIN 'RFC 4512' )
attributeTypes: ( 1.3.6.1.4.1.1466.101.120.13 NAME 'supportedControl'
  SYNTAX 1.3.6.1.4.1.1466.115.121.1.38 USAGE dSAOperation X-ORIGIN 'RFC 2252' )
  SYNTAX 1.3.6.1.4.1.1466.115.121.1.38 USAGE dSAOperation X-ORIGIN 'RFC 4512' )
attributeTypes: ( 1.3.6.1.4.1.1466.101.120.14 NAME 'supportedSASLMechanisms'
  SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 USAGE dSAOperation X-ORIGIN 'RFC 2252' )
  SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 USAGE dSAOperation X-ORIGIN 'RFC 4512' )
attributeTypes: ( 1.3.6.1.4.1.1466.101.120.15 NAME 'supportedLDAPVersion'
  SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 USAGE dSAOperation X-ORIGIN 'RFC 2252' )
  SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 USAGE dSAOperation X-ORIGIN 'RFC 4512' )
attributeTypes: ( 1.3.6.1.4.1.4203.1.3.5 NAME 'supportedFeatures'
  EQUALITY objectIdentifierMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.38
  USAGE dSAOperation X-ORIGIN 'RFC 4512' )
attributeTypes: ( 1.3.6.1.4.1.1466.101.120.16 NAME 'ldapSyntaxes'
  SYNTAX 1.3.6.1.4.1.1466.115.121.1.54 USAGE directoryOperation
  X-ORIGIN 'RFC 2252' )
  X-ORIGIN 'RFC 4512' )
attributeTypes: ( 2.5.21.1 NAME 'dITStructureRules' EQUALITY caseIgnoreMatch
  SYNTAX 1.3.6.1.4.1.1466.115.121.1.17 USAGE directoryOperation
  X-ORIGIN 'RFC 2252' )
  X-ORIGIN 'RFC 4512' )
attributeTypes: ( 2.5.21.7 NAME 'nameForms' EQUALITY caseIgnoreMatch
  SYNTAX 1.3.6.1.4.1.1466.115.121.1.35 USAGE directoryOperation
  X-ORIGIN 'RFC 2252' )
  X-ORIGIN 'RFC 4512' )
attributeTypes: ( 2.5.21.2 NAME 'dITContentRules' EQUALITY caseIgnoreMatch
  SYNTAX 1.3.6.1.4.1.1466.115.121.1.16 USAGE directoryOperation
  X-ORIGIN 'RFC 2252' )
  X-ORIGIN 'RFC 4512' )
attributeTypes: ( 0.9.2342.19200300.100.1.25 NAME 'dc'
  EQUALITY caseIgnoreIA5Match SUBSTR caseIgnoreIA5SubstringsMatch
  SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE X-ORIGIN 'RFC 2247' )
  SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE X-ORIGIN 'RFC 4519' )
attributeTypes: ( 2.16.840.1.113730.3.1.1 NAME 'carLicense'
  DESC 'vehicle license or registration plate' EQUALITY caseIgnoreMatch
  SUBSTR caseIgnoreSubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15
@@ -332,13 +332,13 @@
  SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'RFC 2079' )
attributeTypes: ( 0.9.2342.19200300.100.1.55 NAME 'audio'
  EQUALITY octetStringMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.40{250000}
  X-ORIGIN 'RFC 1274' )
  X-ORIGIN 'RFC 2798' )
attributeTypes: ( 0.9.2342.19200300.100.1.7 NAME 'photo'
  EQUALITY octetStringMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.40
  X-ORIGIN 'RFC 1274' )
  X-ORIGIN 'RFC 2798' )
attributeTypes: ( 0.9.2342.19200300.100.1.1 NAME 'uid'
  EQUALITY caseIgnoreMatch SUBSTR caseIgnoreSubstringsMatch
  SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{256} X-ORIGIN 'RFC 1274' )
  SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{256} X-ORIGIN 'RFC 4519' )
attributeTypes: ( 1.3.6.1.1.4 NAME 'vendorName'
  EQUALITY 1.3.6.1.4.1.1466.109.114.1 SYNTAX 1.3.6.1.4.1.1466.115.121.1.15
  SINGLE-VALUE NO-USER-MODIFICATION USAGE dSAOperation X-ORIGIN 'RFC 3045' )
@@ -374,55 +374,55 @@
  NO-USER-MODIFICATION USAGE directoryOperation
  X-ORIGIN 'Sun Java System Directory Server' )
objectClasses: ( 2.5.6.0 NAME 'top' ABSTRACT MUST objectClass
  X-ORIGIN 'RFC 2256' )
  X-ORIGIN 'RFC 4512' )
objectClasses: ( 2.5.6.1 NAME 'alias' SUP top STRUCTURAL MUST aliasedObjectName
  X-ORIGIN 'RFC 2256' )
  X-ORIGIN 'RFC 4512' )
objectClasses: ( 2.5.6.2 NAME 'country' SUP top STRUCTURAL MUST c
  MAY ( searchGuide $ description ) X-ORIGIN 'RFC 2256' )
  MAY ( searchGuide $ description ) X-ORIGIN 'RFC 4519' )
objectClasses: ( 2.5.6.3 NAME 'locality' SUP top STRUCTURAL
  MAY ( street $ seeAlso $ searchGuide $ st $ l $ description )
  X-ORIGIN 'RFC 2256' )
  X-ORIGIN 'RFC 4519' )
objectClasses: ( 2.5.6.4 NAME 'organization' SUP top STRUCTURAL MUST o
  MAY ( userPassword $ searchGuide $ seeAlso $ businessCategory $ x121Address $
  registeredAddress $ destinationIndicator $ preferredDeliveryMethod $
  telexNumber $ teletexTerminalIdentifier $ telephoneNumber $
  internationaliSDNNumber $ facsimileTelephoneNumber $ street $ postOfficeBox $
  postalCode $ postalAddress $ physicalDeliveryOfficeName $ st $ l $
  description ) X-ORIGIN 'RFC 2256' )
  description ) X-ORIGIN 'RFC 4519' )
objectClasses: ( 2.5.6.5 NAME 'organizationalUnit' SUP top STRUCTURAL MUST ou
  MAY ( userPassword $ searchGuide $ seeAlso $ businessCategory $ x121Address $
  registeredAddress $ destinationIndicator $ preferredDeliveryMethod $
  telexNumber $ teletexTerminalIdentifier $ telephoneNumber $
  internationaliSDNNumber $ facsimileTelephoneNumber $ street $ postOfficeBox $
  postalCode $ postalAddress $ physicalDeliveryOfficeName $ st $ l $
  description ) X-ORIGIN 'RFC 2256' )
  description ) X-ORIGIN 'RFC 4519' )
objectClasses: ( 2.5.6.6 NAME 'person' SUP top STRUCTURAL MUST ( sn $ cn )
  MAY ( userPassword $ telephoneNumber $ seeAlso $ description )
  X-ORIGIN 'RFC 2256' )
  X-ORIGIN 'RFC 4519' )
objectClasses: ( 2.5.6.7 NAME 'organizationalPerson' SUP person STRUCTURAL
  MAY ( title $ x121Address $ registeredAddress $ destinationIndicator $
  preferredDeliveryMethod $ telexNumber $ teletexTerminalIdentifier $
  telephoneNumber $ internationaliSDNNumber $ facsimileTelephoneNumber $
  street $ postOfficeBox $ postalCode $ postalAddress $
  physicalDeliveryOfficeName $ ou $ st $ l ) X-ORIGIN 'RFC 2256' )
  physicalDeliveryOfficeName $ ou $ st $ l ) X-ORIGIN 'RFC 4519' )
objectClasses: ( 2.5.6.8 NAME 'organizationalRole' SUP top STRUCTURAL MUST cn
  MAY ( x121Address $ registeredAddress $ destinationIndicator $
  preferredDeliveryMethod $ telexNumber $ teletexTerminalIdentifier $
  telephoneNumber $ internationaliSDNNumber $ facsimileTelephoneNumber $
  seeAlso $ roleOccupant $ preferredDeliveryMethod $ street $ postOfficeBox $
  postalCode $ postalAddress $ physicalDeliveryOfficeName $ ou $ st $ l $
  description ) X-ORIGIN 'RFC 2256' )
  description ) X-ORIGIN 'RFC 4519' )
objectClasses: ( 2.5.6.9 NAME 'groupOfNames' SUP top STRUCTURAL
  MUST cn MAY ( member $ businessCategory $ seeAlso $ owner $ ou $ o $
  description ) X-ORIGIN 'RFC 2256' )
  description ) X-ORIGIN 'RFC 4519' )
objectClasses: ( 2.5.6.10 NAME 'residentialPerson' SUP person STRUCTURAL MUST l
  MAY ( businessCategory $ x121Address $ registeredAddress $
  destinationIndicator $ preferredDeliveryMethod $ telexNumber $
  teletexTerminalIdentifier $ telephoneNumber $ internationaliSDNNumber $
  facsimileTelephoneNumber $ street $ postOfficeBox $ postalCode $
  postalAddress $ physicalDeliveryOfficeName $ st $ l ) X-ORIGIN 'RFC 2256' )
  postalAddress $ physicalDeliveryOfficeName $ st $ l ) X-ORIGIN 'RFC 4519' )
objectClasses: ( 2.5.6.11 NAME 'applicationProcess' SUP top STRUCTURAL MUST cn
  MAY ( seeAlso $ ou $ l $ description ) X-ORIGIN 'RFC 2256' )
  MAY ( seeAlso $ ou $ l $ description ) X-ORIGIN 'RFC 4519' )
objectClasses: ( 2.5.6.12 NAME 'applicationEntity' SUP top STRUCTURAL
  MUST ( presentationAddress $ cn ) MAY ( supportedApplicationContext $
  seeAlso $ ou $ o $ l $ description ) X-ORIGIN 'RFC 2256' )
@@ -430,23 +430,23 @@
  MAY knowledgeInformation X-ORIGIN 'RFC 2256' )
objectClasses: ( 2.5.6.14 NAME 'device' SUP top STRUCTURAL MUST cn
  MAY ( serialNumber $ seeAlso $ owner $ ou $ o $ l $ description )
  X-ORIGIN 'RFC 2256' )
  X-ORIGIN 'RFC 4519' )
objectClasses: ( 2.5.6.15 NAME 'strongAuthenticationUser' SUP top AUXILIARY
  MUST userCertificate X-ORIGIN 'RFC 2256' )
  MUST userCertificate X-ORIGIN 'RFC 4523' )
objectClasses: ( 2.5.6.16 NAME 'certificationAuthority' SUP top AUXILIARY
  MUST ( authorityRevocationList $ certificateRevocationList $ caCertificate )
  MAY crossCertificatePair X-ORIGIN 'RFC 2256' )
  MAY crossCertificatePair X-ORIGIN 'RFC 4523' )
objectClasses: ( 2.5.6.16.2 NAME 'certificationAuthority-V2'
  SUP certificationAuthority AUXILIARY MAY deltaRevocationList
  X-ORIGIN 'RFC 2256' )
  X-ORIGIN 'RFC 4523' )
objectClasses: ( 2.5.6.17 NAME 'groupOfUniqueNames' SUP top STRUCTURAL
  MUST cn MAY ( uniqueMember $ businessCategory $ seeAlso $ owner $ ou $ o $
  description ) X-ORIGIN 'RFC 2256' )
  description ) X-ORIGIN 'RFC 4519' )
objectClasses: ( 2.5.6.18 NAME 'userSecurityInformation' SUP top AUXILIARY
  MAY ( supportedAlgorithms ) X-ORIGIN 'RFC 2256' )
  MAY ( supportedAlgorithms ) X-ORIGIN 'RFC 4523' )
objectClasses: ( 2.5.6.19 NAME 'cRLDistributionPoint' SUP top STRUCTURAL
  MUST cn MAY ( certificateRevocationList $ authorityRevocationList $
  deltaRevocationList ) X-ORIGIN 'RFC 2256' )
  deltaRevocationList ) X-ORIGIN 'RFC 4523' )
objectClasses: ( 2.5.6.20 NAME 'dmd' SUP top STRUCTURAL MUST dmdName
  MAY ( userPassword $ searchGuide $ seeAlso $ businessCategory $ x121Address $
  registeredAddress $ destinationIndicator $ preferredDeliveryMethod $
@@ -455,10 +455,10 @@
  postalCode $ postalAddress $ physicalDeliveryOfficeName $ st $ l $
  description ) X-ORIGIN 'RFC 2256' )
objectClasses: ( 1.3.6.1.4.1.1466.101.120.111 NAME 'extensibleObject' SUP top
  AUXILIARY X-ORIGIN 'RFC 2252' )
  AUXILIARY X-ORIGIN 'RFC 4512' )
objectClasses: ( 2.5.20.1 NAME 'subschema' AUXILIARY MAY ( dITStructureRules $
  nameForms $ ditContentRules $ objectClasses $ attributeTypes $ matchingRules $
  matchingRuleUse ) X-ORIGIN 'RFC 2252' )
  matchingRuleUse ) X-ORIGIN 'RFC 4512' )
objectClasses: ( 0.9.2342.19200300.100.4.5 NAME 'account' SUP top STRUCTURAL
  MUST uid MAY ( description $ seeAlso $ l $ o $ ou $ host )
  X-ORIGIN 'RFC 4524' )
@@ -494,7 +494,7 @@
objectClasses: ( 0.9.2342.19200300.100.4.19 NAME 'simpleSecurityObject' SUP top
  AUXILIARY MUST userPassword X-ORIGIN 'RFC 4524' )
objectClasses: ( 1.3.6.1.4.1.1466.344 NAME 'dcObject' SUP top AUXILIARY MUST dc
  X-ORIGIN 'RFC 2247' )
  X-ORIGIN 'RFC 4519' )
objectClasses: ( 2.16.840.1.113730.3.2.2 NAME 'inetOrgPerson'
  SUP organizationalPerson STRUCTURAL MAY ( audio $ businessCategory $
  carLicense $ departmentNumber $ displayName $ employeeNumber $ employeeType $
@@ -512,7 +512,7 @@
  o $ ou $ st $ street $ uid $ description $ owner $ seeAlso )
  X-ORIGIN 'draft-furuseth-ldap-untypedobject' )
objectClasses: ( 1.3.6.1.1.3.1 NAME 'uidObject' SUP top AUXILIARY MUST uid
  X-ORIGIN 'RFC 2377' )
  X-ORIGIN 'RFC 4519' )
objectClasses: ( 2.16.840.1.113730.3.2.6 NAME 'referral'
  DESC 'named subordinate reference object' STRUCTURAL MUST ref
  X-ORIGIN 'RFC 3296' )
opendj-sdk/opends/resource/schema/02-config.ldif
@@ -292,7 +292,8 @@
  SINGLE-VALUE X-ORIGIN 'OpenDS Directory Server' )
attributeTypes: ( 1.3.6.1.4.1.26027.1.1.84
  NAME 'ds-cfg-profiler-state' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15
  SINGLE-VALUE NO-USER-MODIFICATION X-ORIGIN 'OpenDS Directory Server' )
  SINGLE-VALUE NO-USER-MODIFICATION USAGE directoryOperation
  X-ORIGIN 'OpenDS Directory Server' )
attributeTypes: ( 1.3.6.1.4.1.26027.1.1.85
  NAME 'ds-cfg-profile-sample-interval' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15
  SINGLE-VALUE X-ORIGIN 'OpenDS Directory Server' )
opendj-sdk/opends/src/server/org/opends/server/backends/SchemaBackend.java
@@ -992,7 +992,7 @@
              try
              {
                type = AttributeTypeSyntax.decodeAttributeType(v.getValue(),
                                                               newSchema);
                                                newSchema, false);
              }
              catch (DirectoryException de)
              {
@@ -1017,7 +1017,7 @@
              try
              {
                oc = ObjectClassSyntax.decodeObjectClass(v.getValue(),
                                                         newSchema);
                                                         newSchema, false);
              }
              catch (DirectoryException de)
              {
@@ -1041,7 +1041,8 @@
              NameForm nf;
              try
              {
                nf = NameFormSyntax.decodeNameForm(v.getValue(), newSchema);
                nf = NameFormSyntax.decodeNameForm(v.getValue(), newSchema,
                                                   false);
              }
              catch (DirectoryException de)
              {
@@ -1066,7 +1067,7 @@
              try
              {
                dcr = DITContentRuleSyntax.decodeDITContentRule(v.getValue(),
                                                                newSchema);
                                                newSchema, false);
              }
              catch (DirectoryException de)
              {
@@ -1116,7 +1117,7 @@
              try
              {
                mru = MatchingRuleUseSyntax.decodeMatchingRuleUse(v.getValue(),
                                                                  newSchema);
                                                 newSchema, false);
              }
              catch (DirectoryException de)
              {
@@ -1162,7 +1163,7 @@
              try
              {
                type = AttributeTypeSyntax.decodeAttributeType(v.getValue(),
                                                               newSchema);
                                                newSchema, false);
              }
              catch (DirectoryException de)
              {
@@ -1188,7 +1189,7 @@
              try
              {
                oc = ObjectClassSyntax.decodeObjectClass(v.getValue(),
                                                         newSchema);
                                                         newSchema, false);
              }
              catch (DirectoryException de)
              {
@@ -1212,7 +1213,8 @@
              NameForm nf;
              try
              {
                nf = NameFormSyntax.decodeNameForm(v.getValue(), newSchema);
                nf = NameFormSyntax.decodeNameForm(v.getValue(), newSchema,
                                                   false);
              }
              catch (DirectoryException de)
              {
@@ -1237,7 +1239,7 @@
              try
              {
                dcr = DITContentRuleSyntax.decodeDITContentRule(v.getValue(),
                                                                newSchema);
                                                newSchema, false);
              }
              catch (DirectoryException de)
              {
@@ -1289,7 +1291,7 @@
              try
              {
                mru = MatchingRuleUseSyntax.decodeMatchingRuleUse(v.getValue(),
                                                                  newSchema);
                                                 newSchema, false);
              }
              catch (DirectoryException de)
              {
@@ -1435,7 +1437,7 @@
    // Make sure that the new attribute type doesn't reference an undefined
    // superior attribute type.
    // or OBSOLETE superior attribute type.
    AttributeType superiorType = attributeType.getSuperiorType();
    if (superiorType != null)
    {
@@ -1447,6 +1449,56 @@
        throw new DirectoryException(ResultCode.UNWILLING_TO_PERFORM, message,
                                     msgID);
      }
      else if (superiorType.isObsolete())
      {
        int    msgID   = MSGID_SCHEMA_MODIFY_OBSOLETE_SUPERIOR_ATTRIBUTE_TYPE;
        String message = getMessage(msgID, attributeType.getNameOrOID(),
                                    superiorType.getNameOrOID());
        throw new DirectoryException(ResultCode.CONSTRAINT_VIOLATION, message,
                                     msgID);
      }
    }
    // Make sure that none of the associated matching rules are marked OBSOLETE.
    MatchingRule mr = attributeType.getEqualityMatchingRule();
    if ((mr != null) && mr.isObsolete())
    {
      int    msgID   = MSGID_SCHEMA_MODIFY_ATTRTYPE_OBSOLETE_MR;
      String message = getMessage(msgID, attributeType.getNameOrOID(),
                                  mr.getNameOrOID());
      throw new DirectoryException(ResultCode.CONSTRAINT_VIOLATION, message,
                                   msgID);
    }
    mr = attributeType.getOrderingMatchingRule();
    if ((mr != null) && mr.isObsolete())
    {
      int    msgID   = MSGID_SCHEMA_MODIFY_ATTRTYPE_OBSOLETE_MR;
      String message = getMessage(msgID, attributeType.getNameOrOID(),
                                  mr.getNameOrOID());
      throw new DirectoryException(ResultCode.CONSTRAINT_VIOLATION, message,
                                   msgID);
    }
    mr = attributeType.getSubstringMatchingRule();
    if ((mr != null) && mr.isObsolete())
    {
      int    msgID   = MSGID_SCHEMA_MODIFY_ATTRTYPE_OBSOLETE_MR;
      String message = getMessage(msgID, attributeType.getNameOrOID(),
                                  mr.getNameOrOID());
      throw new DirectoryException(ResultCode.CONSTRAINT_VIOLATION, message,
                                   msgID);
    }
    mr = attributeType.getApproximateMatchingRule();
    if ((mr != null) && mr.isObsolete())
    {
      int    msgID   = MSGID_SCHEMA_MODIFY_ATTRTYPE_OBSOLETE_MR;
      String message = getMessage(msgID, attributeType.getNameOrOID(),
                                  mr.getNameOrOID());
      throw new DirectoryException(ResultCode.CONSTRAINT_VIOLATION, message,
                                   msgID);
    }
@@ -1572,7 +1624,8 @@
        AttributeType at;
        try
        {
          at = AttributeTypeSyntax.decodeAttributeType(v.getValue(), schema);
          at = AttributeTypeSyntax.decodeAttributeType(v.getValue(), schema,
                                                       false);
        }
        catch (DirectoryException de)
        {
@@ -1746,7 +1799,8 @@
    // Make sure that the new objectclass doesn't reference an undefined
    // superior class, or an undefined required or optional attribute type.
    // superior class, or an undefined required or optional attribute type,
    // and that none of them are OBSOLETE.
    ObjectClass superiorClass = objectClass.getSuperiorClass();
    if (superiorClass != null)
    {
@@ -1758,6 +1812,14 @@
        throw new DirectoryException(ResultCode.UNWILLING_TO_PERFORM, message,
                                     msgID);
      }
      else if (superiorClass.isObsolete())
      {
        int    msgID   = MSGID_SCHEMA_MODIFY_OBSOLETE_SUPERIOR_OBJECTCLASS;
        String message = getMessage(msgID, objectClass.getNameOrOID(),
                                    superiorClass.getNameOrOID());
        throw new DirectoryException(ResultCode.CONSTRAINT_VIOLATION, message,
                                     msgID);
      }
    }
    for (AttributeType at : objectClass.getRequiredAttributes())
@@ -1770,6 +1832,14 @@
        throw new DirectoryException(ResultCode.UNWILLING_TO_PERFORM, message,
                                     msgID);
      }
      else if (at.isObsolete())
      {
        int    msgID   = MSGID_SCHEMA_MODIFY_OC_OBSOLETE_REQUIRED_ATTR;
        String message = getMessage(msgID, objectClass.getNameOrOID(),
                                    at.getNameOrOID());
        throw new DirectoryException(ResultCode.CONSTRAINT_VIOLATION, message,
                                     msgID);
      }
    }
    for (AttributeType at : objectClass.getOptionalAttributes())
@@ -1782,6 +1852,14 @@
        throw new DirectoryException(ResultCode.UNWILLING_TO_PERFORM, message,
                                     msgID);
      }
      else if (at.isObsolete())
      {
        int    msgID   = MSGID_SCHEMA_MODIFY_OC_OBSOLETE_OPTIONAL_ATTR;
        String message = getMessage(msgID, objectClass.getNameOrOID(),
                                    at.getNameOrOID());
        throw new DirectoryException(ResultCode.CONSTRAINT_VIOLATION, message,
                                     msgID);
      }
    }
@@ -1906,7 +1984,7 @@
        ObjectClass oc;
        try
        {
          oc = ObjectClassSyntax.decodeObjectClass(v.getValue(), schema);
          oc = ObjectClassSyntax.decodeObjectClass(v.getValue(), schema, false);
        }
        catch (DirectoryException de)
        {
@@ -2045,7 +2123,8 @@
    // Make sure that the new name form doesn't reference an undefined
    // structural class, or an undefined required or optional attribute type.
    // structural class, or an undefined required or optional attribute type, or
    // that any of them are marked OBSOLETE.
    ObjectClass structuralClass = nameForm.getStructuralClass();
    if (! schema.hasObjectClass(structuralClass.getOID()))
    {
@@ -2063,6 +2142,14 @@
      throw new DirectoryException(ResultCode.UNWILLING_TO_PERFORM, message,
                                   msgID);
    }
    if (structuralClass.isObsolete())
    {
      int    msgID   = MSGID_SCHEMA_MODIFY_NF_OC_OBSOLETE;
      String message = getMessage(msgID, nameForm.getNameOrOID(),
                                  structuralClass.getNameOrOID());
      throw new DirectoryException(ResultCode.UNWILLING_TO_PERFORM, message,
                                   msgID);
    }
    NameForm existingNFForClass = schema.getNameForm(structuralClass);
    if ((existingNFForClass != null) && (existingNFForClass != existingNF))
@@ -2085,6 +2172,14 @@
        throw new DirectoryException(ResultCode.UNWILLING_TO_PERFORM, message,
                                     msgID);
      }
      else if (at.isObsolete())
      {
        int    msgID   = MSGID_SCHEMA_MODIFY_NF_OBSOLETE_REQUIRED_ATTR;
        String message = getMessage(msgID, nameForm.getNameOrOID(),
                                    at.getNameOrOID());
        throw new DirectoryException(ResultCode.CONSTRAINT_VIOLATION, message,
                                     msgID);
      }
    }
    for (AttributeType at : nameForm.getOptionalAttributes())
@@ -2097,6 +2192,14 @@
        throw new DirectoryException(ResultCode.UNWILLING_TO_PERFORM, message,
                                     msgID);
      }
      else if (at.isObsolete())
      {
        int    msgID   = MSGID_SCHEMA_MODIFY_NF_OBSOLETE_OPTIONAL_ATTR;
        String message = getMessage(msgID, nameForm.getNameOrOID(),
                                    at.getNameOrOID());
        throw new DirectoryException(ResultCode.CONSTRAINT_VIOLATION, message,
                                     msgID);
      }
    }
@@ -2220,7 +2323,7 @@
        NameForm nf;
        try
        {
          nf = NameFormSyntax.decodeNameForm(v.getValue(), schema);
          nf = NameFormSyntax.decodeNameForm(v.getValue(), schema, false);
        }
        catch (DirectoryException de)
        {
@@ -2363,6 +2466,15 @@
                                   msgID);
    }
    if (structuralClass.isObsolete())
    {
      int    msgID   = MSGID_SCHEMA_MODIFY_DCR_STRUCTURAL_OC_OBSOLETE;
      String message = getMessage(msgID, ditContentRule.getName(),
                                  structuralClass.getNameOrOID());
      throw new DirectoryException(ResultCode.CONSTRAINT_VIOLATION, message,
                                   msgID);
    }
    for (ObjectClass oc : ditContentRule.getAuxiliaryClasses())
    {
      if (! schema.hasObjectClass(oc.getOID()))
@@ -2373,6 +2485,22 @@
        throw new DirectoryException(ResultCode.UNWILLING_TO_PERFORM, message,
                                     msgID);
      }
      if (oc.getObjectClassType() != ObjectClassType.AUXILIARY)
      {
        int    msgID   = MSGID_SCHEMA_MODIFY_DCR_OC_NOT_AUXILIARY;
        String message = getMessage(msgID, ditContentRule.getName(),
                                    oc.getNameOrOID());
        throw new DirectoryException(ResultCode.UNWILLING_TO_PERFORM, message,
                                     msgID);
      }
      if (oc.isObsolete())
      {
        int    msgID   = MSGID_SCHEMA_MODIFY_DCR_OBSOLETE_AUXILIARY_OC;
        String message = getMessage(msgID, ditContentRule.getName(),
                                    oc.getNameOrOID());
        throw new DirectoryException(ResultCode.UNWILLING_TO_PERFORM, message,
                                     msgID);
      }
    }
    for (AttributeType at : ditContentRule.getRequiredAttributes())
@@ -2385,6 +2513,14 @@
        throw new DirectoryException(ResultCode.UNWILLING_TO_PERFORM, message,
                                     msgID);
      }
      else if (at.isObsolete())
      {
        int    msgID   = MSGID_SCHEMA_MODIFY_DCR_OBSOLETE_REQUIRED_ATTR;
        String message = getMessage(msgID, ditContentRule.getName(),
                                    at.getNameOrOID());
        throw new DirectoryException(ResultCode.CONSTRAINT_VIOLATION, message,
                                     msgID);
      }
    }
    for (AttributeType at : ditContentRule.getOptionalAttributes())
@@ -2397,6 +2533,14 @@
        throw new DirectoryException(ResultCode.UNWILLING_TO_PERFORM, message,
                                     msgID);
      }
      else if (at.isObsolete())
      {
        int    msgID   = MSGID_SCHEMA_MODIFY_DCR_OBSOLETE_OPTIONAL_ATTR;
        String message = getMessage(msgID, ditContentRule.getName(),
                                    at.getNameOrOID());
        throw new DirectoryException(ResultCode.CONSTRAINT_VIOLATION, message,
                                     msgID);
      }
    }
    for (AttributeType at : ditContentRule.getProhibitedAttributes())
@@ -2409,6 +2553,14 @@
        throw new DirectoryException(ResultCode.UNWILLING_TO_PERFORM, message,
                                     msgID);
      }
      else if (at.isObsolete())
      {
        int    msgID   = MSGID_SCHEMA_MODIFY_DCR_OBSOLETE_PROHIBITED_ATTR;
        String message = getMessage(msgID, ditContentRule.getName(),
                                    at.getNameOrOID());
        throw new DirectoryException(ResultCode.CONSTRAINT_VIOLATION, message,
                                     msgID);
      }
    }
@@ -2616,6 +2768,29 @@
      throw new DirectoryException(ResultCode.UNWILLING_TO_PERFORM, message,
                                   msgID);
    }
    if (nameForm.isObsolete())
    {
      int    msgID   = MSGID_SCHEMA_MODIFY_DSR_OBSOLETE_NAME_FORM;
      String message = getMessage(msgID, ditStructureRule.getNameOrRuleID(),
                                  nameForm.getNameOrOID());
      throw new DirectoryException(ResultCode.CONSTRAINT_VIOLATION, message,
                                   msgID);
    }
    // If there are any superior rules, then make sure none of them are marked
    // OBSOLETE.
    for (DITStructureRule dsr : ditStructureRule.getSuperiorRules())
    {
      if (dsr.isObsolete())
      {
        int    msgID   = MSGID_SCHEMA_MODIFY_DSR_OBSOLETE_SUPERIOR_RULE;
        String message = getMessage(msgID, ditStructureRule.getNameOrRuleID(),
                                    dsr.getNameOrRuleID());
        throw new DirectoryException(ResultCode.CONSTRAINT_VIOLATION, message,
                                     msgID);
      }
    }
    // If there is no existing rule, then we're adding a new DIT structure rule.
@@ -2867,6 +3042,15 @@
                                   msgID);
    }
    if (matchingRule.isObsolete())
    {
      int    msgID   = MSGID_SCHEMA_MODIFY_MRU_OBSOLETE_MR;
      String message = getMessage(msgID, matchingRuleUse.getName(),
                                  matchingRule.getNameOrOID());
      throw new DirectoryException(ResultCode.CONSTRAINT_VIOLATION, message,
                                   msgID);
    }
    // Make sure that the new matching rule use doesn't reference an undefined
    // attribute type.
@@ -2880,6 +3064,14 @@
        throw new DirectoryException(ResultCode.UNWILLING_TO_PERFORM, message,
                                     msgID);
      }
      else if (at.isObsolete())
      {
        int    msgID   = MSGID_SCHEMA_MODIFY_MRU_OBSOLETE_ATTR;
        String message = getMessage(msgID, matchingRuleUse.getName(),
                                    matchingRule.getNameOrOID());
        throw new DirectoryException(ResultCode.CONSTRAINT_VIOLATION, message,
                                     msgID);
      }
    }
opendj-sdk/opends/src/server/org/opends/server/core/AddOperation.java
@@ -1470,7 +1470,8 @@
        if (DirectoryServer.checkSchema())
        {
          StringBuilder invalidReason = new StringBuilder();
          if (! entry.conformsToSchema(parentEntry, true, invalidReason))
          if (! entry.conformsToSchema(parentEntry, true, true, true,
                                       invalidReason))
          {
            setResultCode(ResultCode.OBJECTCLASS_VIOLATION);
            setErrorMessage(invalidReason);
@@ -1599,6 +1600,48 @@
                break;
            }
          }
          // See if the entry contains any attributes or object classes marked
          // OBSOLETE.  If so, then reject the entry.
          for (AttributeType at : userAttributes.keySet())
          {
            if (at.isObsolete())
            {
              int    msgID   = MSGID_ADD_ATTR_IS_OBSOLETE;
              String message = getMessage(msgID, String.valueOf(entryDN),
                                          at.getNameOrOID());
              appendErrorMessage(message);
              setResultCode(ResultCode.CONSTRAINT_VIOLATION);
              break addProcessing;
            }
          }
          for (AttributeType at : operationalAttributes.keySet())
          {
            if (at.isObsolete())
            {
              int    msgID   = MSGID_ADD_ATTR_IS_OBSOLETE;
              String message = getMessage(msgID, String.valueOf(entryDN),
                                          at.getNameOrOID());
              appendErrorMessage(message);
              setResultCode(ResultCode.CONSTRAINT_VIOLATION);
              break addProcessing;
            }
          }
          for (ObjectClass oc : objectClasses.keySet())
          {
            if (oc.isObsolete())
            {
              int    msgID   = MSGID_ADD_OC_IS_OBSOLETE;
              String message = getMessage(msgID, String.valueOf(entryDN),
                                          oc.getNameOrOID());
              appendErrorMessage(message);
              setResultCode(ResultCode.CONSTRAINT_VIOLATION);
              break addProcessing;
            }
          }
        }
        // Check to see if the client has permission to perform the add.
opendj-sdk/opends/src/server/org/opends/server/core/DirectoryServer.java
@@ -2952,7 +2952,41 @@
      objectClass = new ObjectClass(definition, name,
                                    Collections.singleton(name), oid, null,
                                    getTopObjectClass(), null, null,
                                    ObjectClassType.ABSTRACT, false, null);
                                    ObjectClassType.STRUCTURAL, false, null);
    }
    return objectClass;
  }
  /**
   * Causes the Directory Server to construct a new auxiliary objectclass
   * definition with the provided name and with no required or allowed
   * attributes. This should only be used if there is no objectclass for the
   * specified name. It will not register the created objectclass with the
   * Directory Server.
   *
   * @param  name  The name to use for the objectclass, as provided by the user.
   *
   * @return  The constructed objectclass definition.
   */
  public static ObjectClass getDefaultAuxiliaryObjectClass(String name)
  {
    assert debugEnter(CLASS_NAME, "getDefaultObjectClass",
                      String.valueOf(name));
    String lowerName = toLowerCase(name);
    ObjectClass objectClass = directoryServer.schema.getObjectClass(lowerName);
    if (objectClass == null)
    {
      String oid        = lowerName + "-oid";
      String definition = "( " + oid + " NAME '" + name + "' ABSTRACT )";
      objectClass = new ObjectClass(definition, name,
                                    Collections.singleton(name), oid, null,
                                    getTopObjectClass(), null, null,
                                    ObjectClassType.AUXILIARY, false, null);
    }
    return objectClass;
opendj-sdk/opends/src/server/org/opends/server/core/ModifyDNOperation.java
@@ -1486,7 +1486,8 @@
        if (DirectoryServer.checkSchema())
        {
          StringBuilder invalidReason = new StringBuilder();
          if (! newEntry.conformsToSchema(null, false, invalidReason))
          if (! newEntry.conformsToSchema(null, false, true, true,
                                          invalidReason))
          {
            setResultCode(ResultCode.OBJECTCLASS_VIOLATION);
            appendErrorMessage(getMessage(MSGID_MODDN_VIOLATES_SCHEMA,
@@ -1494,6 +1495,19 @@
                                          String.valueOf(invalidReason)));
            break modifyDNProcessing;
          }
          for (int i=0; i < newRDNValues; i++)
          {
            AttributeType at = newRDN.getAttributeType(i);
            if (at.isObsolete())
            {
              setResultCode(ResultCode.CONSTRAINT_VIOLATION);
              appendErrorMessage(getMessage(MSGID_MODDN_NEWRDN_ATTR_IS_OBSOLETE,
                                            String.valueOf(entryDN),
                                            at.getNameOrOID()));
              break modifyDNProcessing;
            }
          }
        }
@@ -1697,7 +1711,8 @@
          if (DirectoryServer.checkSchema())
          {
            StringBuilder invalidReason = new StringBuilder();
            if (! newEntry.conformsToSchema(null, false, invalidReason))
            if (! newEntry.conformsToSchema(null, false, true, true,
                                            invalidReason))
            {
              setResultCode(ResultCode.OBJECTCLASS_VIOLATION);
opendj-sdk/opends/src/server/org/opends/server/core/ModifyOperation.java
@@ -1350,6 +1350,26 @@
            }
          }
          // If the attribute type is marked "OBSOLETE" and the modification
          // is setting new values, then fail unless this is an internal
          // operation or is related to synchronization in some way.
          if (t.isObsolete())
          {
            if (a.hasValue() &&
                (m.getModificationType() != ModificationType.DELETE))
            {
              if (! (isInternalOperation() || isSynchronizationOperation() ||
                     m.isInternal()))
              {
                setResultCode(ResultCode.CONSTRAINT_VIOLATION);
                appendErrorMessage(getMessage(MSGID_MODIFY_ATTR_IS_OBSOLETE,
                                              String.valueOf(entryDN),
                                              a.getName()));
                break modifyProcessing;
              }
            }
          }
          // If the modification is updating the password attribute, then
          // perform any necessary password policy processing.  This processing
@@ -2312,7 +2332,8 @@
        if (DirectoryServer.checkSchema())
        {
          StringBuilder invalidReason = new StringBuilder();
          if (! modifiedEntry.conformsToSchema(null, false, invalidReason))
          if (! modifiedEntry.conformsToSchema(null, false, false, false,
                                               invalidReason))
          {
            setResultCode(ResultCode.OBJECTCLASS_VIOLATION);
            appendErrorMessage(getMessage(MSGID_MODIFY_VIOLATES_SCHEMA,
opendj-sdk/opends/src/server/org/opends/server/core/SchemaConfigManager.java
@@ -986,7 +986,7 @@
            try
            {
              attrType = attrTypeSyntax.decodeAttributeType(v.getValue(),
                                                            schema);
                                                            schema, false);
            }
            catch (DirectoryException de)
            {
@@ -1058,7 +1058,7 @@
            ObjectClass oc;
            try
            {
              oc = ocSyntax.decodeObjectClass(v.getValue(), schema);
              oc = ocSyntax.decodeObjectClass(v.getValue(), schema, false);
            }
            catch (DirectoryException de)
            {
@@ -1130,7 +1130,7 @@
            NameForm nf;
            try
            {
              nf = nfSyntax.decodeNameForm(v.getValue(), schema);
              nf = nfSyntax.decodeNameForm(v.getValue(), schema, false);
              nf.getExtraProperties().remove(SCHEMA_PROPERTY_FILENAME);
              nf.setSchemaFile(schemaFile);
            }
@@ -1204,7 +1204,7 @@
            DITContentRule dcr;
            try
            {
              dcr = dcrSyntax.decodeDITContentRule(v.getValue(), schema);
              dcr = dcrSyntax.decodeDITContentRule(v.getValue(), schema, false);
              dcr.getExtraProperties().remove(SCHEMA_PROPERTY_FILENAME);
              dcr.setSchemaFile(schemaFile);
            }
@@ -1353,7 +1353,8 @@
            MatchingRuleUse mru;
            try
            {
              mru = mruSyntax.decodeMatchingRuleUse(v.getValue(), schema);
              mru = mruSyntax.decodeMatchingRuleUse(v.getValue(), schema,
                                                    false);
              mru.getExtraProperties().remove(SCHEMA_PROPERTY_FILENAME);
              mru.setSchemaFile(schemaFile);
            }
opendj-sdk/opends/src/server/org/opends/server/messages/BackendMessages.java
@@ -2962,6 +2962,215 @@
  /**
   * The message ID for the message that will be used if an attempt is made to
   * add an attribute type whose superior type is OBSOLETE.  This takes two
   * arguments, which are the name or OID of the attribute type and the name or
   * OID of the superior type.
   */
  public static final int MSGID_SCHEMA_MODIFY_OBSOLETE_SUPERIOR_ATTRIBUTE_TYPE =
       CATEGORY_MASK_BACKEND | SEVERITY_MASK_MILD_ERROR | 274;
  /**
   * The message ID for the message that will be used if an attempt is made to
   * add an attribute type with a matching rule that is OBSOLETE.  This takes
   * two arguments, which are the name or OID of the attribute type and the name
   * or OID of the matching rule.
   */
  public static final int MSGID_SCHEMA_MODIFY_ATTRTYPE_OBSOLETE_MR =
       CATEGORY_MASK_BACKEND | SEVERITY_MASK_MILD_ERROR | 275;
  /**
   * The message ID for the message that will be used if an attempt is made to
   * add an object class whose superior class is OBSOLETE.  This takes two
   * arguments, which are the name or OID of the object class and the name or
   * OID of the superior class.
   */
  public static final int MSGID_SCHEMA_MODIFY_OBSOLETE_SUPERIOR_OBJECTCLASS =
       CATEGORY_MASK_BACKEND | SEVERITY_MASK_MILD_ERROR | 276;
  /**
   * The message ID for the message that will be used if an attempt is made to
   * add an object class that requires an OBSOLETE attribute type.  This takes
   * two arguments, which are the name or OID of the object class and the name
   * or OID of the required attribute type.
   */
  public static final int MSGID_SCHEMA_MODIFY_OC_OBSOLETE_REQUIRED_ATTR =
       CATEGORY_MASK_BACKEND | SEVERITY_MASK_MILD_ERROR | 277;
  /**
   * The message ID for the message that will be used if an attempt is made to
   * add an object class that allows an OBSOLETE attribute type.  This takes
   * two arguments, which are the name or OID of the object class and the name
   * or OID of the optional attribute type.
   */
  public static final int MSGID_SCHEMA_MODIFY_OC_OBSOLETE_OPTIONAL_ATTR =
       CATEGORY_MASK_BACKEND | SEVERITY_MASK_MILD_ERROR | 278;
  /**
   * The message ID for the message that will be used if an attempt is made to
   * add a name form whose structural object class is marked OBSOLETE.  This
   * takes two arguments, which are the name or OID of the name form and the
   * name or OID of the structural object class.
   */
  public static final int MSGID_SCHEMA_MODIFY_NF_OC_OBSOLETE =
       CATEGORY_MASK_BACKEND | SEVERITY_MASK_MILD_ERROR | 279;
  /**
   * The message ID for the message that will be used if an attempt is made to
   * add a name form that requires an attribute type which is marked OBSOLETE.
   * This takes two arguments, which are the name or OID of the name form and
   * the name or OID of the required attribute type.
   */
  public static final int MSGID_SCHEMA_MODIFY_NF_OBSOLETE_REQUIRED_ATTR =
       CATEGORY_MASK_BACKEND | SEVERITY_MASK_MILD_ERROR | 280;
  /**
   * The message ID for the message that will be used if an attempt is made to
   * add a name form that allows an attribute type which is marked OBSOLETE.
   * This takes two arguments, which are the name or OID of the name form and
   * the  name or OID of the optional attribute type.
   */
  public static final int MSGID_SCHEMA_MODIFY_NF_OBSOLETE_OPTIONAL_ATTR =
       CATEGORY_MASK_BACKEND | SEVERITY_MASK_MILD_ERROR | 281;
  /**
   * The message ID for the message that will be used if an attempt is made to
   * add a DIT content rule whose structural object class is marked OBSOLETE.
   * This takes two arguments, which are the name of the DIT content rule and
   * the name or OID of the structural object class.
   */
  public static final int MSGID_SCHEMA_MODIFY_DCR_STRUCTURAL_OC_OBSOLETE =
       CATEGORY_MASK_BACKEND | SEVERITY_MASK_MILD_ERROR | 282;
  /**
   * The message ID for the message that will be used if an attempt is made to
   * add a DIT content rule with an auxiliary object class that is not declared
   * auxiliary.  This takes two arguments, which are the name of the DIT content
   * rule and the name or OID of the object class.
   */
  public static final int MSGID_SCHEMA_MODIFY_DCR_OC_NOT_AUXILIARY =
       CATEGORY_MASK_BACKEND | SEVERITY_MASK_MILD_ERROR | 283;
  /**
   * The message ID for the message that will be used if an attempt is made to
   * add a DIT content rule with an AUXILIARY object class that is marked
   * OBSOLETE.  This takes two arguments, which are the name of the DIT content
   * rule and the name or OID of the auxiliary object class.
   */
  public static final int MSGID_SCHEMA_MODIFY_DCR_AUXILIARY_OC_OBSOLETE =
       CATEGORY_MASK_BACKEND | SEVERITY_MASK_MILD_ERROR | 284;
  /**
   * The message ID for the message that will be used if an attempt is made to
   * add a DIT content rule that requires an attribute type that is marked
   * OBSOLETE.  This takes two arguments, which are the name of the DIT content
   * rule and the name or OID of the attribute type.
   */
  public static final int MSGID_SCHEMA_MODIFY_DCR_OBSOLETE_REQUIRED_ATTR =
       CATEGORY_MASK_BACKEND | SEVERITY_MASK_MILD_ERROR | 285;
  /**
   * The message ID for the message that will be used if an attempt is made to
   * add a DIT content rule that allows an attribute type that is marked
   * OBSOLETE.  This takes two arguments, which are the name of the DIT content
   * rule and the name or OID of the attribute type.
   */
  public static final int MSGID_SCHEMA_MODIFY_DCR_OBSOLETE_OPTIONAL_ATTR =
       CATEGORY_MASK_BACKEND | SEVERITY_MASK_MILD_ERROR | 286;
  /**
   * The message ID for the message that will be used if an attempt is made to
   * add a DIT content rule that prohibits an attribute type that is marked
   * OBSOLETE.  This takes two arguments, which are the name of the DIT content
   * rule and the name or OID of the attribute type.
   */
  public static final int MSGID_SCHEMA_MODIFY_DCR_OBSOLETE_PROHIBITED_ATTR =
       CATEGORY_MASK_BACKEND | SEVERITY_MASK_MILD_ERROR | 287;
  /**
   * The message ID for the message that will be used if an attempt is made to
   * add a DIT structure rule whose associated name form is marked OBSOLETE.
   * This takes two arguments, which are the name or rule ID of the DIT
   * structure rule and the name or OID of the name form.
   */
  public static final int MSGID_SCHEMA_MODIFY_DSR_OBSOLETE_NAME_FORM =
       CATEGORY_MASK_BACKEND | SEVERITY_MASK_MILD_ERROR | 288;
  /**
   * The message ID for the message that will be used if an attempt is made to
   * add a DIT structure rule with a superior rule that is marked OBSOLETE.
   * This takes two arguments, which are the name or rule ID of the DIT
   * structure rule and the name or rule ID of the superior rule.
   */
  public static final int MSGID_SCHEMA_MODIFY_DSR_OBSOLETE_SUPERIOR_RULE =
       CATEGORY_MASK_BACKEND | SEVERITY_MASK_MILD_ERROR | 289;
  /**
   * The message ID for the message that will be used if an attempt is made to
   * add a matching rule use with a matching rule that is marked OBSOLETE.  This
   * takes two arguments, which are the name of the matching rule use and the
   * name or OID of the matching rule.
   */
  public static final int MSGID_SCHEMA_MODIFY_MRU_OBSOLETE_MR =
       CATEGORY_MASK_BACKEND | SEVERITY_MASK_MILD_ERROR | 290;
  /**
   * The message ID for the message that will be used if an attempt is made to
   * add a matching rule use with an attribute type that is marked OBSOLETE.
   * This takes two arguments, which are the name of the matching rule use and
   * the name or OID of the attribute type.
   */
  public static final int MSGID_SCHEMA_MODIFY_MRU_OBSOLETE_ATTR =
       CATEGORY_MASK_BACKEND | SEVERITY_MASK_MILD_ERROR | 291;
  /**
   * The message ID for the message that will be used if an attempt is made to
   * add a DIT content rule with an auxiliary object class that is declared
   * OBSOLETE.  This takes two arguments, which are the name of the DIT content
   * rule and the name or OID of the object class.
   */
  public static final int MSGID_SCHEMA_MODIFY_DCR_OBSOLETE_AUXILIARY_OC =
       CATEGORY_MASK_BACKEND | SEVERITY_MASK_MILD_ERROR | 292;
  /**
   * Associates a set of generic messages with the message IDs defined in this
   * class.
   */
@@ -3492,6 +3701,76 @@
    registerMessage(MSGID_SCHEMA_MODIFY_REMOVE_NO_SUCH_MR_USE,
                    "Unable to remove matching rule use %s from the server " +
                    "schema because no such matching rule use is defined.");
    registerMessage(MSGID_SCHEMA_MODIFY_OBSOLETE_SUPERIOR_ATTRIBUTE_TYPE,
                    "Unable to add attribute type %s because the superior " +
                    "type %s is marked as OBSOLETE in the server schema.");
    registerMessage(MSGID_SCHEMA_MODIFY_ATTRTYPE_OBSOLETE_MR,
                    "Unable to add attribute type %s because the associated " +
                    "matching rule %s is marked as OBSOLETE in the server " +
                    "schema.");
    registerMessage(MSGID_SCHEMA_MODIFY_OBSOLETE_SUPERIOR_OBJECTCLASS,
                    "Unable to add object class %s because the superior " +
                    "class %s is marked as OBSOLETE in the server schema.");
    registerMessage(MSGID_SCHEMA_MODIFY_OC_OBSOLETE_REQUIRED_ATTR,
                    "Unable to add object class %s because required " +
                    "attribute %s is marked as OBSOLETE in the server schema.");
    registerMessage(MSGID_SCHEMA_MODIFY_OC_OBSOLETE_OPTIONAL_ATTR,
                    "Unable to add object class %s because optional " +
                    "attribute %s is marked as OBSOLETE in the server schema.");
    registerMessage(MSGID_SCHEMA_MODIFY_NF_OC_OBSOLETE,
                    "Unable to add name form %s because its structural " +
                    "object class %s is marked as OBSOLETE in the server " +
                    "schema.");
    registerMessage(MSGID_SCHEMA_MODIFY_NF_OBSOLETE_REQUIRED_ATTR,
                    "Unable to add name form %s because it requires " +
                    "attribute type %s which is marked as OBSOLETE in the " +
                    "server schema.");
    registerMessage(MSGID_SCHEMA_MODIFY_NF_OBSOLETE_OPTIONAL_ATTR,
                    "Unable to add name form %s because it allows " +
                    "attribute type %s which is marked as OBSOLETE in the " +
                    "server schema.");
    registerMessage(MSGID_SCHEMA_MODIFY_DCR_STRUCTURAL_OC_OBSOLETE,
                    "Unable to add DIT content rule %s because its " +
                    "structural object class %s is marked as OBSOLETE in " +
                    "the server schema.");
    registerMessage(MSGID_SCHEMA_MODIFY_DCR_OC_NOT_AUXILIARY,
                    "Unable to add DIT content rule %s because it references " +
                    "auxiliary object class %s which is defined in the " +
                    "server schema but is not an auxiliary class.");
    registerMessage(MSGID_SCHEMA_MODIFY_DCR_OBSOLETE_AUXILIARY_OC,
                    "Unable to add DIT content rule %s because it references " +
                    "auxiliary object class %s which is marked as OBSOLETE " +
                    "in the server schema.");
    registerMessage(MSGID_SCHEMA_MODIFY_DCR_AUXILIARY_OC_OBSOLETE,
                    "Unable to add DIT content rule %s because it allows " +
                    "auxiliary object class %s which is marked as OBSOLETE " +
                    "in the server schema.");
    registerMessage(MSGID_SCHEMA_MODIFY_DCR_OBSOLETE_REQUIRED_ATTR,
                    "Unable to add DIT content rule %s because it requires " +
                    "attribute type %s which is marked as OBSOLETE in the " +
                    "server schema.");
    registerMessage(MSGID_SCHEMA_MODIFY_DCR_OBSOLETE_OPTIONAL_ATTR,
                    "Unable to add DIT content rule %s because it allows " +
                    "attribute type %s which is marked as OBSOLETE in the " +
                    "server schema.");
    registerMessage(MSGID_SCHEMA_MODIFY_DCR_OBSOLETE_PROHIBITED_ATTR,
                    "Unable to add DIT content rule %s because it prohibits " +
                    "attribute type %s which is marked as OBSOLETE in the " +
                    "server schema.");
    registerMessage(MSGID_SCHEMA_MODIFY_DSR_OBSOLETE_NAME_FORM,
                    "Unable to add DIT structure rule %s because its name " +
                    "form %s is marked OBSOLETE in the server schema.");
    registerMessage(MSGID_SCHEMA_MODIFY_DSR_OBSOLETE_SUPERIOR_RULE,
                    "Unable to add DIT structure rule %s because it " +
                    "references superior rule %s whihc is marked as OBSOLETE " +
                    "in the server schema.");
    registerMessage(MSGID_SCHEMA_MODIFY_MRU_OBSOLETE_MR,
                    "Unable to add matching rule use %s because its matching " +
                    "rule %s is marked OBSOLETE in the server schema.");
    registerMessage(MSGID_SCHEMA_MODIFY_MRU_OBSOLETE_ATTR,
                    "Unable to add matching rule use %s because it " +
                    "references attribute type %s which is marked as " +
                    "OBSOLETE in the server schema.");
    registerMessage(MSGID_SCHEMA_RESTORE_NO_SUCH_BACKUP,
opendj-sdk/opends/src/server/org/opends/server/messages/CoreMessages.java
@@ -2193,9 +2193,8 @@
  /**
   * The message ID for the message that will be used if an entry could not be
   * checked against a DIT structure rule because the server was unable to
   * obtain a read lock on the parent entry.  This takes three arguments, which
   * are the DN of the entry, the name of the DIT structure rule, and the DN of
   * the parent entry.
   * obtain a read lock on the parent entry.  This takes two arguments, which
   * are the DN of the entry and the DN of the parent entry.
   */
  public static final int MSGID_ENTRY_SCHEMA_DSR_COULD_NOT_LOCK_PARENT =
       CATEGORY_MASK_CORE | SEVERITY_MASK_MILD_ERROR | 212;
@@ -2205,9 +2204,8 @@
  /**
   * The message ID for the message that will be used if an entry could not be
   * checked against a DIT structure rule because the server was unable to
   * retrieve its parent entry.  This takes three arguments, which are the DN of
   * the entry, the name of the DIT structure rule, and the DN of the parent
   * entry.
   * retrieve its parent entry.  This takes two arguments, which are the DN of
   * the entry and the DN of the parent entry.
   */
  public static final int MSGID_ENTRY_SCHEMA_DSR_NO_PARENT_ENTRY =
       CATEGORY_MASK_CORE | SEVERITY_MASK_MILD_ERROR | 213;
@@ -2217,9 +2215,8 @@
  /**
   * The message ID for the message that will be used if an entry could not be
   * checked against a DIT structure rule because its parent entry did not
   * contain a single structural objectclass.  This takes three arguments, which
   * are the DN of the entry, the name of the DIT structure rule, and the DN of
   * the parent entry.
   * contain a single structural objectclass.  This takes two arguments, which
   * are the DN of the entry and the DN of the parent entry.
   */
  public static final int MSGID_ENTRY_SCHEMA_DSR_NO_PARENT_OC =
       CATEGORY_MASK_CORE | SEVERITY_MASK_MILD_ERROR | 214;
@@ -6077,6 +6074,82 @@
  /**
   * The message ID for the message that will be used if an attempt is made to
   * add an entry with an attribute type that is marked OBSOLETE.  This takes
   * two arguments, which are the DN of the entry and the name of the attribute
   * type.
   */
  public static final int MSGID_ADD_ATTR_IS_OBSOLETE =
       CATEGORY_MASK_CORE | SEVERITY_MASK_SEVERE_WARNING | 581;
  /**
   * The message ID for the message that will be used if an attempt is made to
   * add an entry with an objectclass that is marked OBSOLETE.  This takes two
   * arguments, which are the DN of the entry and the name of the objectclass.
   */
  public static final int MSGID_ADD_OC_IS_OBSOLETE =
       CATEGORY_MASK_CORE | SEVERITY_MASK_SEVERE_WARNING | 582;
  /**
   * The message ID for the message that will be used if an entry cannot be
   * modified because one of the targeted attributes was marked OBSOLETE.  This
   * takes two arguments, which are the DN of the target entry and the name of
   * the attribute.
   */
  public static final int MSGID_MODIFY_ATTR_IS_OBSOLETE =
       CATEGORY_MASK_CORE | SEVERITY_MASK_MILD_ERROR | 583;
  /**
   * The message ID for the message that will be used if an attempt is made to
   * add an OBSOLETE objectclass to an entry.  This takes two arguments, which
   * are the name of the objectclass and the DN of the entry.
   */
  public static final int MSGID_ENTRY_ADD_OBSOLETE_OC =
       CATEGORY_MASK_CORE | SEVERITY_MASK_MILD_ERROR | 584;
  /**
   * The message ID for the response message that will be used if a modify DN
   * operation fails because the new RDN contains an attribute type which is
   * marked OBSOLETE in the server schema.  This takes two arguments, which are
   * the DN of the current entry and the name or OID of the obsolete attribute
   * type.
   */
  public static final int MSGID_MODDN_NEWRDN_ATTR_IS_OBSOLETE =
       CATEGORY_MASK_CORE | SEVERITY_MASK_MILD_ERROR | 585;
  /**
   * The message ID for the message that will be used if there was no DIT
   * structure rule associated with an entry, but there was a DIT structure rule
   * for its parent.  This takes two arguments, which are the DN of the entry
   * and the DN of the parent entry.
   */
  public static final int MSGID_ENTRY_SCHEMA_VIOLATES_PARENT_DSR =
       CATEGORY_MASK_CORE | SEVERITY_MASK_MILD_ERROR | 586;
  /**
   * The message ID for the message that will be used if an unexpected error
   * occurs while attempting to evaluate a DIT structure rule for an entry's
   * parent.  This takes two arguments, which are the DN of the entry and a
   * string representation of the exception that was caught.
   */
  public static final int MSGID_ENTRY_SCHEMA_COULD_NOT_CHECK_PARENT_DSR =
       CATEGORY_MASK_CORE | SEVERITY_MASK_MILD_ERROR | 587;
  /**
   * Associates a set of generic messages with the message IDs defined
   * in this class.
   */
@@ -6509,19 +6582,24 @@
                    "%s that is not allowed by DIT content rule %s.");
    registerMessage(MSGID_ENTRY_SCHEMA_DSR_COULD_NOT_LOCK_PARENT,
                    "The Directory Server was unable to evaluate entry %s to " +
                    "determine whether it was compliant with DIT structure " +
                    "rule %s because it was unable to obtain a read lock " +
                    "on parent entry %s.");
                    "determine whether it was compliant with the DIT " +
                    "structure rule configuration because it was unable to " +
                    "obtain a read lock on parent entry %s.");
    registerMessage(MSGID_ENTRY_SCHEMA_DSR_NO_PARENT_ENTRY,
                    "The Directory Server was unable to evaluate entry %s to " +
                    "determine whether it was compliant with DIT structure " +
                    "rule %s because parent entry %s either does not exist " +
                    "or could not be retrieved.");
                    "determine whether it was compliant with the DIT " +
                    "structure rule configuration because parent entry %s " +
                    "either does not exist or could not be retrieved.");
    registerMessage(MSGID_ENTRY_SCHEMA_DSR_NO_PARENT_OC,
                    "The Directory Server was unable to evaluate entry %s to " +
                    "determine whether it was compliant with DIT structure " +
                    "rule %s because the parent entry %s does not appear to " +
                    "contain a valid structural objectclass.");
                    "determine whether it was compliant with the DIT " +
                    "rule configuration because the parent entry %s does not " +
                    "appear to contain a valid structural objectclass.");
    registerMessage(MSGID_ENTRY_SCHEMA_VIOLATES_PARENT_DSR,
                    "Entry %s is invalid according to the server schema " +
                    "because there is no DIT structure rule that applies " +
                    "to that entry, but there is a DIT structure rule for " +
                    "the parent entry %s.");
    registerMessage(MSGID_ENTRY_SCHEMA_DSR_DISALLOWED_SUPERIOR_OC,
                    "Entry %s violates the Directory Server schema " +
                    "configuration because DIT structure rule %s does not " +
@@ -6530,6 +6608,10 @@
    registerMessage(MSGID_ENTRY_SCHEMA_COULD_NOT_CHECK_DSR,
                    "An unexpected error occurred while attempting to check " +
                    "entry %s against DIT structure rule %s:  %s.");
    registerMessage(MSGID_ENTRY_SCHEMA_COULD_NOT_CHECK_PARENT_DSR,
                    "An unexpected error occurred while attempting to " +
                    "perform DIT structure rule processing for the parent of " +
                    "entry %s:  %s.");
    registerMessage(MSGID_ENTRY_SET_UNKNOWN_OC,
                    "Objectclass %s cannot be used in entry %s because that " +
                    "class is not defined in the Directory Server schema.");
@@ -6539,6 +6621,9 @@
    registerMessage(MSGID_ENTRY_ADD_DUPLICATE_OC,
                    "Objectclass %s is already present in entry %s and " +
                    "cannot be added a second time.");
    registerMessage(MSGID_ENTRY_ADD_OBSOLETE_OC,
                    "Objectclass %s added to entry %s is marked OBSOLETE in " +
                    "the server schema.");
    registerMessage(MSGID_ENTRY_DUPLICATE_VALUES,
                    "Unable to add one or more values to attribute %s " +
                    "because at least one of the values already exists.");
@@ -6780,6 +6865,14 @@
                    "Entry \"%s\" contains an value \"%s\" for attribute %s " +
                    "that is invalid according to the syntax for that " +
                    "attribute:  %s.");
    registerMessage(MSGID_ADD_ATTR_IS_OBSOLETE,
                    "Entry \"%s\" cannot be added because it contains " +
                    "attribute type %s which is declared OBSOLETE in the " +
                    "server schema.");
    registerMessage(MSGID_ADD_OC_IS_OBSOLETE,
                    "Entry \"%s\" cannot be added because it contains " +
                    "objectclass %s which is declared OBSOLETE in the server " +
                    "schema.");
    registerMessage(MSGID_ADD_INVALID_PWPOLICY_DN_SYNTAX,
                    "Entry \"%s\" cannot be added because it contains an " +
                    "invalid password policy subentry DN:  %s.");
@@ -7115,6 +7208,10 @@
                    "The modify DN operation for entry %s cannot be " +
                    "performed because the change would have violated the " +
                    "server schema:  %s.");
    registerMessage(MSGID_MODDN_NEWRDN_ATTR_IS_OBSOLETE,
                    "The modify DN operation for entry %s cannot be " +
                    "performed because the new RDN includes attribute type " +
                    "%s which is declared OBSOLETE in the server schema.");
    registerMessage(MSGID_MODDN_PREOP_INCREMENT_NO_ATTR,
                    "The modify DN operation for entry %s cannot be " +
                    "performed because a pre-operation plugin attempted to " +
@@ -7194,6 +7291,10 @@
                    "Entry %s cannot be modified because the modification " +
                    "attempted to update attribute %s which is defined as " +
                    "NO-USER-MODIFICATION in the server schema.");
    registerMessage(MSGID_MODIFY_ATTR_IS_OBSOLETE,
                    "Entry %s cannot be modified because the modification " +
                    "attempted to set one or more new values for attribute " +
                    "%s which is marked OBSOLETE in the server schema.");
    registerMessage(MSGID_MODIFY_PASSWORDS_CANNOT_HAVE_OPTIONS,
                    "Attributes used to hold user passwords are not allowed " +
                    "to have any attribute options.");
opendj-sdk/opends/src/server/org/opends/server/messages/SchemaMessages.java
@@ -2964,6 +2964,115 @@
       MSGID_ATTR_SYNTAX_ATTRSYNTAX_INVALID_EXTENSION =
            CATEGORY_MASK_SCHEMA | SEVERITY_MASK_MILD_ERROR | 265;
  /**
   * The message ID for the message that will be used if an objectclass has
   * an invalid superior type.  This takes four arguments, which are the OID of
   * the objectclass, the objectclass type for that class, the objectclass type
   * type of the superior class, and the name or OID of the superior class.
   */
  public static final int MSGID_ATTR_SYNTAX_OBJECTCLASS_INVALID_SUPERIOR_TYPE =
       CATEGORY_MASK_SCHEMA | SEVERITY_MASK_SEVERE_WARNING | 266;
  /**
   * The message ID for the message that will be used if a structural
   * objectclass does not have a superior chain that includes the "top"
   * objectclass.  This takes a single argument, which is the OID for that
   * objectclass.
   */
  public static final int
       MSGID_ATTR_SYNTAX_OBJECTCLASS_STRUCTURAL_SUPERIOR_NOT_TOP =
            CATEGORY_MASK_SCHEMA | SEVERITY_MASK_SEVERE_WARNING | 267;
  /**
   * The message ID for the message that will be used if an attribute type
   * has a usage that is not the same as the usage of its superior type.  This
   * takes three arguments, which is the OID of the attribute type, its
   * attribute usage, and the name or OID of the superior type.
   */
  public static final int MSGID_ATTR_SYNTAX_ATTRTYPE_INVALID_SUPERIOR_USAGE =
       CATEGORY_MASK_SCHEMA | SEVERITY_MASK_SEVERE_WARNING | 268;
  /**
   * The message ID for the message that will be used if an attribute type
   * is defined as collective but the superior type is not collective.  This
   * takes two arguments, which are the OID of the attribute type and the name
   * or OID of the superior type.
   */
  public static final int
       MSGID_ATTR_SYNTAX_ATTRTYPE_COLLECTIVE_FROM_NONCOLLECTIVE =
            CATEGORY_MASK_SCHEMA | SEVERITY_MASK_SEVERE_WARNING | 269;
  /**
   * The message ID for the message that will be used if an attribute type
   * is not defined as collective but the superior type is collective.  This
   * takes two arguments, which are the OID of the attribute type and the name
   * or OID of the superior type.
   */
  public static final int
       MSGID_ATTR_SYNTAX_ATTRTYPE_NONCOLLECTIVE_FROM_COLLECTIVE =
            CATEGORY_MASK_SCHEMA | SEVERITY_MASK_SEVERE_WARNING | 270;
  /**
   * The message ID for the message that will be used if a DIT content rule
   * description value is invalid because it prohibits an attribute type that is
   * required by the rule's structural object class.  This takes three
   * arguments, which are the definition of the DIT content rule, the name or
   * OID of the prohibited attribute type, and the name or OID of the structural
   * object class that requires it.
   */
  public static final int
       MSGID_ATTR_SYNTAX_DCR_PROHIBITED_REQUIRED_BY_STRUCTURAL =
            CATEGORY_MASK_SCHEMA | SEVERITY_MASK_MILD_ERROR | 271;
  /**
   * The message ID for the message that will be used if a DIT content rule
   * description value is invalid because it prohibits an attribute type that is
   * required by one the rule's allowed auxiliary object classes.  This takes
   * three arguments, which are the definition of the DIT content rule, the name
   * or OID of the prohibited attribute type, and the name or OID of the
   * auxiliary object class that requires it.
   */
  public static final int
       MSGID_ATTR_SYNTAX_DCR_PROHIBITED_REQUIRED_BY_AUXILIARY =
            CATEGORY_MASK_SCHEMA | SEVERITY_MASK_MILD_ERROR | 272;
  /**
   * The message ID for the message that will be used if an attribute type
   * is defined as collective but has a usage other than userApplications.  This
   * takes a single argument, which is the OID of the attribute type.
   */
  public static final int MSGID_ATTR_SYNTAX_ATTRTYPE_COLLECTIVE_IS_OPERATIONAL =
       CATEGORY_MASK_SCHEMA | SEVERITY_MASK_SEVERE_WARNING | 273;
  /**
   * The message ID for the message that will be used if an attribute type
   * is defined as NO-USER-MODIFICATION but does not have an operational usage.
   * This takes a single argument, which is the OID of the attribute type.
   */
  public static final int
       MSGID_ATTR_SYNTAX_ATTRTYPE_NO_USER_MOD_NOT_OPERATIONAL =
            CATEGORY_MASK_SCHEMA | SEVERITY_MASK_SEVERE_WARNING | 274;
  /**
   * Associates a set of generic messages with the message IDs defined in this
   * class.
@@ -3244,46 +3353,60 @@
                    "The definition for the attribute type with OID %s " +
                    "declared a superior type with an OID of %s.  No " +
                    "attribute type with this OID exists in the server " +
                    "schema, so the Directory Server will use a generic " +
                    "attribute type as the superior type for this definition.");
                    "schema.");
    registerMessage(MSGID_ATTR_SYNTAX_ATTRTYPE_UNKNOWN_APPROXIMATE_MR,
                    "The definition for the attribute type with OID %s " +
                    "declared that approximate matching should be performed " +
                    "using the matching rule \"%s\".  No such approximate " +
                    "matching rule is configured for use in the Directory " +
                    "Server, so the default approximate matching rule for " +
                    "the attribute's syntax will be used.");
                    "Server.");
    registerMessage(MSGID_ATTR_SYNTAX_ATTRTYPE_UNKNOWN_EQUALITY_MR,
                    "The definition for the attribute type with OID %s " +
                    "declared that equality matching should be performed " +
                    "using the matching rule \"%s\".  No such equality " +
                    "matching rule is configured for use in the Directory " +
                    "Server, so the default equality matching rule for the " +
                    "attribute's syntax will be used.");
                    "Server.");
    registerMessage(MSGID_ATTR_SYNTAX_ATTRTYPE_UNKNOWN_ORDERING_MR,
                    "The definition for the attribute type with OID %s " +
                    "declared that ordering matching should be performed " +
                    "using the matching rule \"%s\".  No such ordering " +
                    "matching rule is configured for use in the Directory " +
                    "Server, so the default ordering matching rule for the " +
                    "attribute's syntax will be used.");
                    "Server.");
    registerMessage(MSGID_ATTR_SYNTAX_ATTRTYPE_UNKNOWN_SUBSTRING_MR,
                    "The definition for the attribute type with OID %s " +
                    "declared that substring matching should be performed " +
                    "using the matching rule \"%s\".  No such substring " +
                    "matching rule is configured for use in the Directory " +
                    "Server, so the default substring matching rule for the " +
                    "attribute's syntax will be used.");
                    "Server.");
    registerMessage(MSGID_ATTR_SYNTAX_ATTRTYPE_UNKNOWN_SYNTAX,
                    "The definition for the attribute type with OID %s " +
                    "declared that it should have a syntax with OID %s.  No " +
                    "such syntax is configured for use in the Directory " +
                    "Server, so the default attribute syntax will be used.");
                    "Server.");
    registerMessage(MSGID_ATTR_SYNTAX_ATTRTYPE_INVALID_ATTRIBUTE_USAGE,
                    "The definition for the attribute type with OID %s " +
                    "declared that it should have an attribute usage of " +
                    "%s.  This is an invalid usage, so the default usage of " +
                    "%s will be used.");
                    "%s.  This is an invalid usage.");
    registerMessage(MSGID_ATTR_SYNTAX_ATTRTYPE_INVALID_SUPERIOR_USAGE,
                    "The definition for attribute type %s is invalid because " +
                    "its attribute usage %s is not the same as the usage for " +
                    "its superior type %s.");
    registerMessage(MSGID_ATTR_SYNTAX_ATTRTYPE_COLLECTIVE_FROM_NONCOLLECTIVE,
                    "The definition for attribute type %s is invalid because " +
                    "it is defined as a collective type but the superior " +
                    "type %s is not collective.");
    registerMessage(MSGID_ATTR_SYNTAX_ATTRTYPE_NONCOLLECTIVE_FROM_COLLECTIVE,
                    "The definition for attribute type %s is invalid because " +
                    "it is not defined as a collective type but the superior " +
                    "type %s is collective.");
    registerMessage(MSGID_ATTR_SYNTAX_ATTRTYPE_COLLECTIVE_IS_OPERATIONAL,
                    "The definition for attribute type %s is invalid because " +
                    "it is declared COLLECTIVE but does not have a usage " +
                    "of userApplications.");
    registerMessage(MSGID_ATTR_SYNTAX_ATTRTYPE_NO_USER_MOD_NOT_OPERATIONAL,
                    "The definition for attribute type %s is invalid because " +
                    "it is declared NO-USER-MODIFICATION but does not have " +
                    "an operational usage.");
    registerMessage(MSGID_ATTR_SYNTAX_ATTRTYPE_EXPECTED_QUOTE_AT_POS,
                    "The provided value \"%s\" could not be parsed as an " +
                    "attribute type description because a single quote was " +
@@ -3333,9 +3456,7 @@
    registerMessage(MSGID_ATTR_SYNTAX_OBJECTCLASS_UNKNOWN_SUPERIOR_CLASS,
                    "The definition for the objectclass with OID %s declared " +
                    "a superior objectclass with an OID of %s.  No " +
                    "objectclass with this OID exists in the server schema, " +
                    "so the Directory Server will assume it to be an empty " +
                    "objectclass with no required or optional attributes.");
                    "objectclass with this OID exists in the server schema.");
    registerMessage(MSGID_ATTR_SYNTAX_OBJECTCLASS_EXPECTED_QUOTE_AT_POS,
                    "The provided value \"%s\" could not be parsed as an " +
                    "objectclass description because a single quote was " +
@@ -3345,14 +3466,20 @@
                    "The definition for the objectclass with OID %s declared " +
                    "that it should include required attribute \"%s\".  No " +
                    "attribute type matching this name or OID exists in the " +
                    "server schema, so a default attribute type with the " +
                    "directory string syntax will be used.");
                    "server schema.");
    registerMessage(MSGID_ATTR_SYNTAX_OBJECTCLASS_UNKNOWN_OPTIONAL_ATTR,
                    "The definition for the objectclass with OID %s declared " +
                    "that it should include optional attribute \"%s\".  No " +
                    "attribute type matching this name or OID exists in the " +
                    "server schema, so a default attribute type with the " +
                    "directory string syntax will be used.");
                    "server schema.");
    registerMessage(MSGID_ATTR_SYNTAX_OBJECTCLASS_INVALID_SUPERIOR_TYPE,
                    "The definition for objectclass %s is invalid because it " +
                    "has an objectclass type of %s but this is incompatible " +
                    "with the objectclass type %s for the superior class %s.");
    registerMessage(MSGID_ATTR_SYNTAX_OBJECTCLASS_STRUCTURAL_SUPERIOR_NOT_TOP,
                    "The definition for objectclass %s is invalid because " +
                    "it is defined as a structural class but its superior " +
                    "chain does not include the \"top\" objectclass.");
    registerMessage(MSGID_ATTR_SYNTAX_IA5_ILLEGAL_CHARACTER,
@@ -3557,8 +3684,7 @@
    registerMessage(MSGID_ATTR_SYNTAX_DCR_UNKNOWN_STRUCTURAL_CLASS,
                    "The DIT content rule \"%s\" is associated with a " +
                    "structural objectclass %s that is not defined in the " +
                    "server schema.  A default objectclass will be created " +
                    "with this OID.");
                    "server schema.");
    registerMessage(MSGID_ATTR_SYNTAX_DCR_STRUCTURAL_CLASS_NOT_STRUCTURAL,
                    "The DIT content rule \"%s\" is associated with the " +
                    "objectclass with OID %s (%s).  This objectclass exists " +
@@ -3575,8 +3701,7 @@
    registerMessage(MSGID_ATTR_SYNTAX_DCR_UNKNOWN_AUXILIARY_CLASS,
                    "The DIT content rule \"%s\" is associated with an " +
                    "auxiliary objectclass %s that is not defined in the " +
                    "server schema.  A default objectclass will be created " +
                    "with this OID.");
                    "server schema.");
    registerMessage(MSGID_ATTR_SYNTAX_DCR_AUXILIARY_CLASS_NOT_AUXILIARY,
                    "The DIT content rule \"%s\" is associated with an " +
                    "auxiliary objectclass %s.  This objectclass exists " +
@@ -3585,18 +3710,23 @@
    registerMessage(MSGID_ATTR_SYNTAX_DCR_UNKNOWN_REQUIRED_ATTR,
                    "The DIT content rule \"%s\" is associated with a " +
                    "required attribute type %s that is not defined in the " +
                    "server schema.  A default attribute type will be " +
                    "created with this name.");
                    "server schema.");
    registerMessage(MSGID_ATTR_SYNTAX_DCR_UNKNOWN_OPTIONAL_ATTR,
                    "The DIT content rule \"%s\" is associated with an " +
                    "optional attribute type %s that is not defined in the " +
                    "server schema.  A default attribute type will be " +
                    "created with this name.");
                    "server schema.");
    registerMessage(MSGID_ATTR_SYNTAX_DCR_UNKNOWN_PROHIBITED_ATTR,
                    "The DIT content rule \"%s\" is associated with a " +
                    "prohibited attribute type %s that is not defined in the " +
                    "server schema.  A default attribute type will be " +
                    "created with this name.");
                    "server schema.");
    registerMessage(MSGID_ATTR_SYNTAX_DCR_PROHIBITED_REQUIRED_BY_STRUCTURAL,
                    "The DIT content rule \"%s\" is not valid because it " +
                    "prohibits the use of attribute type %s which is " +
                    "required by the associated structural object class %s.");
    registerMessage(MSGID_ATTR_SYNTAX_DCR_PROHIBITED_REQUIRED_BY_AUXILIARY,
                    "The DIT content rule \"%s\" is not valid because it " +
                    "prohibits the use of attribute type %s which is " +
                    "required by the associated auxiliary object class %s.");
    registerMessage(MSGID_ATTR_SYNTAX_DCR_EXPECTED_QUOTE_AT_POS,
                    "The provided value \"%s\" could not be parsed as a DIT " +
                    "content rule description because a single quote was " +
@@ -3641,8 +3771,7 @@
    registerMessage(MSGID_ATTR_SYNTAX_NAME_FORM_UNKNOWN_STRUCTURAL_CLASS,
                    "The name form description \"%s\" is associated with a " +
                    "structural objectclass %s that is not defined in the " +
                    "server schema.  A default objectclass will be created " +
                    "with this OID.");
                    "server schema.");
    registerMessage(MSGID_ATTR_SYNTAX_NAME_FORM_STRUCTURAL_CLASS_NOT_STRUCTURAL,
                    "The name form description \"%s\" is associated with the " +
                    "objectclass with OID %s (%s).  This objectclass exists " +
@@ -3652,14 +3781,12 @@
                    "The definition for the name form with OID %s declared " +
                    "that it should include required attribute \"%s\".  No " +
                    "attribute type matching this name or OID exists in the " +
                    "server schema, so a default attribute type with the " +
                    "directory string syntax will be used.");
                    "server schema.");
    registerMessage(MSGID_ATTR_SYNTAX_NAME_FORM_UNKNOWN_OPTIONAL_ATTR,
                    "The definition for the name form with OID %s declared " +
                    "that it should include optional attribute \"%s\".  No " +
                    "attribute type matching this name or OID exists in the " +
                    "server schema, so a default attribute type with the " +
                    "directory string syntax will be used.");
                    "server schema.");
    registerMessage(MSGID_ATTR_SYNTAX_NAME_FORM_NO_STRUCTURAL_CLASS,
                    "The provided value \"%s\" could not be parsed as a name " +
                    "form description because it does not specify the " +
opendj-sdk/opends/src/server/org/opends/server/schema/AttributeTypeSyntax.java
@@ -45,13 +45,11 @@
import org.opends.server.types.AttributeUsage;
import org.opends.server.types.ByteString;
import org.opends.server.types.DirectoryException;
import org.opends.server.types.ErrorLogCategory;
import org.opends.server.types.ErrorLogSeverity;
import org.opends.server.types.InitializationException;
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.*;
@@ -103,17 +101,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));
@@ -122,36 +113,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_ATTRIBUTE_TYPE_NAME);
      int    msgID   = MSGID_ATTR_SYNTAX_UNKNOWN_EQUALITY_MATCHING_RULE;
      String message = getMessage(msgID, EMR_CASE_IGNORE_OID,
                                  SYNTAX_ATTRIBUTE_TYPE_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_ATTRIBUTE_TYPE_NAME);
      int    msgID   = MSGID_ATTR_SYNTAX_UNKNOWN_ORDERING_MATCHING_RULE;
      String message = getMessage(msgID, OMR_CASE_IGNORE_OID,
                                  SYNTAX_ATTRIBUTE_TYPE_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_ATTRIBUTE_TYPE_NAME);
      int    msgID   = MSGID_ATTR_SYNTAX_UNKNOWN_SUBSTRING_MATCHING_RULE;
      String message = getMessage(msgID, SMR_CASE_IGNORE_OID,
                                  SYNTAX_ATTRIBUTE_TYPE_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()
  {
@@ -163,9 +155,7 @@
  /**
   * Retrieves the OID for this attribute syntax.
   *
   * @return  The OID for this attribute syntax.
   * {@inheritDoc}
   */
  public String getOID()
  {
@@ -177,9 +167,7 @@
  /**
   * Retrieves a description for this attribute syntax.
   *
   * @return  A description for this attribute syntax.
   * {@inheritDoc}
   */
  public String getDescription()
  {
@@ -191,12 +179,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()
  {
@@ -208,12 +191,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()
  {
@@ -225,12 +203,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()
  {
@@ -242,12 +215,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()
  {
@@ -260,16 +228,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)
@@ -282,7 +241,7 @@
    // acceptable.
    try
    {
      decodeAttributeType(value, DirectoryServer.getSchema());
      decodeAttributeType(value, DirectoryServer.getSchema(), true);
      return true;
    }
    catch (DirectoryException de)
@@ -303,10 +262,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 superior attribute type which are
   *                               not defined in the server schema. This should
   *                               only be true when called by
   *                               {@code valueIsAcceptable}.
   *
   * @return  The decoded attribute type definition.
   *
@@ -314,7 +279,8 @@
   *                              attribute type definition.
   */
  public static AttributeType decodeAttributeType(ByteString value,
                                                  Schema schema)
                                                  Schema schema,
                                                  boolean allowUnknownElements)
         throws DirectoryException
  {
    assert debugEnter(CLASS_NAME, "decodeAttributeType", String.valueOf(value));
@@ -596,17 +562,21 @@
        superiorType = schema.getAttributeType(woidBuffer.toString());
        if (superiorType == null)
        {
          // This is bad because we don't know what the superior attribute type
          // is so we can't base this attribute type on it.  Log a message and
          // just go with the default type.
          if (allowUnknownElements)
          {
            superiorType = DirectoryServer.getDefaultAttributeType(
                                                woidBuffer.toString());
          }
          else
          {
            // This is bad because we don't know what the superior attribute
            // type is so we can't base this attribute type on it.
          int    msgID   = MSGID_ATTR_SYNTAX_ATTRTYPE_UNKNOWN_SUPERIOR_TYPE;
          String message = getMessage(msgID, String.valueOf(oid),
                                      String.valueOf(woidBuffer));
          logError(ErrorLogCategory.SCHEMA, ErrorLogSeverity.SEVERE_WARNING,
            throw new DirectoryException(ResultCode.CONSTRAINT_VIOLATION,
                   message, msgID);
          superiorType =
               DirectoryServer.getDefaultAttributeType(woidBuffer.toString());
          }
        }
@@ -640,12 +610,11 @@
        if (emr == null)
        {
          // This is bad because we have no idea what the equality matching
          // rule should be.  Log a message and go with the default matching
          // rule for the associated syntax.
          // rule should be.
          int    msgID   = MSGID_ATTR_SYNTAX_ATTRTYPE_UNKNOWN_EQUALITY_MR;
          String message = getMessage(msgID, String.valueOf(oid),
                                      String.valueOf(woidBuffer));
          logError(ErrorLogCategory.SCHEMA, ErrorLogSeverity.SEVERE_WARNING,
          throw new DirectoryException(ResultCode.CONSTRAINT_VIOLATION,
                   message, msgID);
        }
        else
@@ -664,12 +633,11 @@
        if (omr == null)
        {
          // This is bad because we have no idea what the ordering matching
          // rule should be.  Log a message and go with the default matching
          // rule for the associated syntax.
          // rule should be.
          int    msgID   = MSGID_ATTR_SYNTAX_ATTRTYPE_UNKNOWN_ORDERING_MR;
          String message = getMessage(msgID, String.valueOf(oid),
                                      String.valueOf(woidBuffer));
          logError(ErrorLogCategory.SCHEMA, ErrorLogSeverity.SEVERE_WARNING,
          throw new DirectoryException(ResultCode.CONSTRAINT_VIOLATION,
                   message, msgID);
        }
        else
@@ -688,12 +656,11 @@
        if (smr == null)
        {
          // This is bad because we have no idea what the substring matching
          // rule should be.  Log a message and go with the default matching
          // rule for the associated syntax.
          // rule should be.
          int    msgID   = MSGID_ATTR_SYNTAX_ATTRTYPE_UNKNOWN_SUBSTRING_MR;
          String message = getMessage(msgID, String.valueOf(oid),
                                      String.valueOf(woidBuffer));
          logError(ErrorLogCategory.SCHEMA, ErrorLogSeverity.SEVERE_WARNING,
          throw new DirectoryException(ResultCode.CONSTRAINT_VIOLATION,
                   message, msgID);
        }
        else
@@ -794,10 +761,8 @@
          int    msgID   = MSGID_ATTR_SYNTAX_ATTRTYPE_UNKNOWN_SYNTAX;
          String message = getMessage(msgID, String.valueOf(oid),
                                      String.valueOf(oidBuffer));
          logError(ErrorLogCategory.SCHEMA, ErrorLogSeverity.SEVERE_WARNING,
          throw new DirectoryException(ResultCode.CONSTRAINT_VIOLATION,
                   message, msgID);
          syntax = DirectoryServer.getDefaultAttributeSyntax();
        }
        if (approximateMatchingRule == null)
@@ -878,14 +843,14 @@
        }
        else
        {
          // This must be an illegal usage.  Log a message and use the default.
          // This must be an illegal usage.
          attributeUsage = AttributeUsage.USER_APPLICATIONS;
          int    msgID   = MSGID_ATTR_SYNTAX_ATTRTYPE_INVALID_ATTRIBUTE_USAGE;
          String message = getMessage(msgID, String.valueOf(oid),
                                      String.valueOf(usageBuffer),
                                      String.valueOf(attributeUsage));
          logError(ErrorLogCategory.SCHEMA, ErrorLogSeverity.SEVERE_WARNING,
          throw new DirectoryException(ResultCode.INVALID_ATTRIBUTE_SYNTAX,
                   message, msgID);
        }
      }
@@ -911,13 +876,12 @@
      if (amr == null)
      {
        // This is bad because we have no idea what the approximate matching
        // rule should be.  Log a message and go with the default matching
        // rule for the associated syntax.
        // rule should be.
        int    msgID   = MSGID_ATTR_SYNTAX_ATTRTYPE_UNKNOWN_APPROXIMATE_MR;
        String message = getMessage(msgID, String.valueOf(oid),
                                    String.valueOf(ruleName));
        logError(ErrorLogCategory.SCHEMA, ErrorLogSeverity.SEVERE_WARNING,
                 message, msgID);
        throw new DirectoryException(ResultCode.CONSTRAINT_VIOLATION, message,
                                     msgID);
      }
      else
      {
@@ -926,6 +890,62 @@
    }
    // If there is a superior type, then it must have the same usage as the
    // subordinate type.  Also, if the superior type is collective, then so must
    // the subordinate type be collective.
    if (superiorType != null)
    {
      if (superiorType.getUsage() != attributeUsage)
      {
        int    msgID   = MSGID_ATTR_SYNTAX_ATTRTYPE_INVALID_SUPERIOR_USAGE;
        String message = getMessage(msgID, oid, String.valueOf(attributeUsage),
                                    superiorType.getNameOrOID());
        throw new DirectoryException(ResultCode.CONSTRAINT_VIOLATION, message,
                                     msgID);
      }
      if (superiorType.isCollective() != isCollective)
      {
        int msgID;
        if (isCollective)
        {
          msgID = MSGID_ATTR_SYNTAX_ATTRTYPE_COLLECTIVE_FROM_NONCOLLECTIVE;
        }
        else
        {
          msgID = MSGID_ATTR_SYNTAX_ATTRTYPE_NONCOLLECTIVE_FROM_COLLECTIVE;
        }
        String message = getMessage(msgID, oid, superiorType.getNameOrOID());
        throw new DirectoryException(ResultCode.CONSTRAINT_VIOLATION, message,
                                     msgID);
      }
    }
    // If the attribute type is COLLECTIVE, then it must have a usage of
    // userApplications.
    if (isCollective && (attributeUsage != AttributeUsage.USER_APPLICATIONS))
    {
      int    msgID   = MSGID_ATTR_SYNTAX_ATTRTYPE_COLLECTIVE_IS_OPERATIONAL;
      String message = getMessage(msgID, oid);
      throw new DirectoryException(ResultCode.CONSTRAINT_VIOLATION, message,
                                   msgID);
    }
    // If the attribute type is NO-USER-MODIFICATION, then it must not have a
    // usage of userApplications.
    if (isNoUserModification &&
        (attributeUsage == AttributeUsage.USER_APPLICATIONS))
    {
      int    msgID   = MSGID_ATTR_SYNTAX_ATTRTYPE_NO_USER_MOD_NOT_OPERATIONAL;
      String message = getMessage(msgID, oid);
      throw new DirectoryException(ResultCode.CONSTRAINT_VIOLATION, message,
                                   msgID);
    }
    return new AttributeType(value.stringValue(), primaryName, typeNames, oid,
                             description, superiorType, syntax,
                             approximateMatchingRule, equalityMatchingRule,
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)
    {
      if (allowUnknownElements)
      {
        structuralClass = DirectoryServer.getDefaultObjectClass(oid);
      }
      else
      {
      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);
        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,24 +597,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.
              // 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());
              logError(ErrorLogCategory.SCHEMA, ErrorLogSeverity.SEVERE_WARNING,
                throw new DirectoryException(ResultCode.CONSTRAINT_VIOLATION,
                       message, msgID);
              oc = DirectoryServer.getDefaultObjectClass(woidBuffer.toString());
              }
            }
            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,
                                          woidBuffer.toString(),
                                          oc.getObjectClassType().toString());
              throw new DirectoryException(ResultCode.CONSTRAINT_VIOLATION,
                       message, msgID);
            }
@@ -676,22 +651,28 @@
          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.
            // 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());
            logError(ErrorLogCategory.SCHEMA, ErrorLogSeverity.SEVERE_WARNING,
              String message = getMessage(msgID, valueStr,
                                          woidBuffer.toString());
              throw new DirectoryException(ResultCode.CONSTRAINT_VIOLATION,
                     message, msgID);
            oc = DirectoryServer.getDefaultObjectClass(woidBuffer.toString());
            }
          }
          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,
            String message = getMessage(msgID, valueStr, woidBuffer.toString(),
                                        oc.getObjectClassType().toString());
            throw new DirectoryException(ResultCode.CONSTRAINT_VIOLATION,
                     message, msgID);
          }
@@ -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.
              if (allowUnknownElements)
              {
                attr = DirectoryServer.getDefaultAttributeType(
                                            woidBuffer.toString());
              }
              else
              {
              int    msgID   = MSGID_ATTR_SYNTAX_DCR_UNKNOWN_REQUIRED_ATTR;
              String message = getMessage(msgID, valueStr,
                                          woidBuffer.toString());
              logError(ErrorLogCategory.SCHEMA, ErrorLogSeverity.SEVERE_WARNING,
                throw new DirectoryException(ResultCode.CONSTRAINT_VIOLATION,
                       message, msgID);
              attr = DirectoryServer.getDefaultAttributeType(
                                          woidBuffer.toString());
              }
            }
            attrs.add(attr);
@@ -762,17 +746,21 @@
          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);
            // 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.
              // 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());
              logError(ErrorLogCategory.SCHEMA, ErrorLogSeverity.SEVERE_WARNING,
                throw new DirectoryException(ResultCode.CONSTRAINT_VIOLATION,
                       message, msgID);
              attr = DirectoryServer.getDefaultAttributeType(
                                          woidBuffer.toString());
              }
            }
            attrs.add(attr);
@@ -841,16 +832,21 @@
          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);
            // 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.
              if (allowUnknownElements)
              {
                attr = DirectoryServer.getDefaultAttributeType(
                                            woidBuffer.toString());
              }
              else
              {
              int    msgID   = MSGID_ATTR_SYNTAX_DCR_UNKNOWN_PROHIBITED_ATTR;
              String message = getMessage(msgID, valueStr,
                                          woidBuffer.toString());
              logError(ErrorLogCategory.SCHEMA, ErrorLogSeverity.SEVERE_WARNING,
                throw new DirectoryException(ResultCode.CONSTRAINT_VIOLATION,
                       message, msgID);
              attr = DirectoryServer.getDefaultAttributeType(
                                          woidBuffer.toString());
              }
            }
            attrs.add(attr);
@@ -920,16 +919,20 @@
          {
            // 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);
            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,
opendj-sdk/opends/src/server/org/opends/server/schema/DITStructureRuleSyntax.java
@@ -44,14 +44,12 @@
import org.opends.server.types.ByteString;
import org.opends.server.types.DirectoryException;
import org.opends.server.types.DITStructureRule;
import org.opends.server.types.ErrorLogCategory;
import org.opends.server.types.ErrorLogSeverity;
import org.opends.server.types.InitializationException;
import org.opends.server.types.NameForm;
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.*;
@@ -102,17 +100,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));
@@ -121,36 +112,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_STRUCTURE_RULE_NAME);
      int    msgID   = MSGID_ATTR_SYNTAX_UNKNOWN_EQUALITY_MATCHING_RULE;
      String message = getMessage(msgID, EMR_CASE_IGNORE_OID,
                                  SYNTAX_DIT_STRUCTURE_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_STRUCTURE_RULE_NAME);
      int    msgID   = MSGID_ATTR_SYNTAX_UNKNOWN_ORDERING_MATCHING_RULE;
      String message = getMessage(msgID, OMR_CASE_IGNORE_OID,
                                  SYNTAX_DIT_STRUCTURE_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_STRUCTURE_RULE_NAME);
      int    msgID   = MSGID_ATTR_SYNTAX_UNKNOWN_SUBSTRING_MATCHING_RULE;
      String message = getMessage(msgID, SMR_CASE_IGNORE_OID,
                                  SYNTAX_DIT_STRUCTURE_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()
  {
@@ -162,9 +154,7 @@
  /**
   * Retrieves the OID for this attribute syntax.
   *
   * @return  The OID for this attribute syntax.
   * {@inheritDoc}
   */
  public String getOID()
  {
@@ -176,9 +166,7 @@
  /**
   * Retrieves a description for this attribute syntax.
   *
   * @return  A description for this attribute syntax.
   * {@inheritDoc}
   */
  public String getDescription()
  {
@@ -190,12 +178,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()
  {
@@ -207,12 +190,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()
  {
@@ -224,12 +202,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()
  {
@@ -241,12 +214,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()
  {
@@ -259,16 +227,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)
opendj-sdk/opends/src/server/org/opends/server/schema/MatchingRuleUseSyntax.java
@@ -45,14 +45,12 @@
import org.opends.server.types.AttributeType;
import org.opends.server.types.ByteString;
import org.opends.server.types.DirectoryException;
import org.opends.server.types.ErrorLogCategory;
import org.opends.server.types.ErrorLogSeverity;
import org.opends.server.types.InitializationException;
import org.opends.server.types.MatchingRuleUse;
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.*;
@@ -103,17 +101,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));
@@ -122,36 +113,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_MATCHING_RULE_USE_NAME);
      int    msgID   = MSGID_ATTR_SYNTAX_UNKNOWN_EQUALITY_MATCHING_RULE;
      String message = getMessage(msgID, EMR_CASE_IGNORE_OID,
                                  SYNTAX_MATCHING_RULE_USE_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_MATCHING_RULE_USE_NAME);
      int    msgID   = MSGID_ATTR_SYNTAX_UNKNOWN_ORDERING_MATCHING_RULE;
      String message = getMessage(msgID, OMR_CASE_IGNORE_OID,
                                  SYNTAX_MATCHING_RULE_USE_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_MATCHING_RULE_USE_NAME);
      int    msgID   = MSGID_ATTR_SYNTAX_UNKNOWN_SUBSTRING_MATCHING_RULE;
      String message = getMessage(msgID, SMR_CASE_IGNORE_OID,
                                  SYNTAX_MATCHING_RULE_USE_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()
  {
@@ -163,9 +155,7 @@
  /**
   * Retrieves the OID for this attribute syntax.
   *
   * @return  The OID for this attribute syntax.
   * {@inheritDoc}
   */
  public String getOID()
  {
@@ -177,9 +167,7 @@
  /**
   * Retrieves a description for this attribute syntax.
   *
   * @return  A description for this attribute syntax.
   * {@inheritDoc}
   */
  public String getDescription()
  {
@@ -191,12 +179,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()
  {
@@ -208,12 +191,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()
  {
@@ -225,12 +203,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()
  {
@@ -242,12 +215,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()
  {
@@ -260,16 +228,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)
@@ -282,7 +241,7 @@
    // acceptable.
    try
    {
      decodeMatchingRuleUse(value, DirectoryServer.getSchema());
      decodeMatchingRuleUse(value, DirectoryServer.getSchema(), true);
      return true;
    }
    catch (DirectoryException de)
@@ -303,10 +262,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 matching rule use definition.
   *
@@ -314,7 +279,8 @@
   *                              matching rule use definition.
   */
  public static MatchingRuleUse decodeMatchingRuleUse(ByteString value,
                                                      Schema schema)
                                     Schema schema,
                                     boolean allowUnknownElements)
         throws DirectoryException
  {
    assert debugEnter(CLASS_NAME, "decodeMatchingRuleUse",
@@ -610,16 +576,19 @@
            {
              // This isn't good because it means that the matching rule use
              // specifies 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_MRUSE_UNKNOWN_ATTR;
              String message = getMessage(msgID, oid, woidBuffer.toString());
              logError(ErrorLogCategory.SCHEMA, ErrorLogSeverity.SEVERE_WARNING,
                       message, msgID);
              if (allowUnknownElements)
              {
              attr = DirectoryServer.getDefaultAttributeType(
                                          woidBuffer.toString());
            }
              else
              {
                int msgID = MSGID_ATTR_SYNTAX_MRUSE_UNKNOWN_ATTR;
                String message = getMessage(msgID, oid, woidBuffer.toString());
                throw new DirectoryException(ResultCode.CONSTRAINT_VIOLATION,
                                             message, msgID);
              }
            }
            attrs.add(attr);
@@ -651,16 +620,19 @@
          {
            // This isn't good because it means that the matching rule use
            // specifies 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_MRUSE_UNKNOWN_ATTR;
            String message = getMessage(msgID, oid, woidBuffer.toString());
            logError(ErrorLogCategory.SCHEMA, ErrorLogSeverity.SEVERE_WARNING,
                     message, msgID);
            if (allowUnknownElements)
            {
            attr = DirectoryServer.getDefaultAttributeType(
                                        woidBuffer.toString());
          }
            else
            {
              int msgID = MSGID_ATTR_SYNTAX_MRUSE_UNKNOWN_ATTR;
              String message = getMessage(msgID, oid, woidBuffer.toString());
              throw new DirectoryException(ResultCode.CONSTRAINT_VIOLATION,
                                           message, msgID);
            }
          }
          attrs.add(attr);
        }
opendj-sdk/opends/src/server/org/opends/server/schema/NameFormSyntax.java
@@ -44,8 +44,7 @@
import org.opends.server.types.AttributeType;
import org.opends.server.types.ByteString;
import org.opends.server.types.DirectoryException;
import org.opends.server.types.ErrorLogCategory;
import org.opends.server.types.ErrorLogSeverity;
import org.opends.server.types.InitializationException;
import org.opends.server.types.NameForm;
import org.opends.server.types.ObjectClass;
import org.opends.server.types.ObjectClassType;
@@ -53,7 +52,6 @@
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_NAME_FORM_NAME);
      int    msgID   = MSGID_ATTR_SYNTAX_UNKNOWN_EQUALITY_MATCHING_RULE;
      String message = getMessage(msgID, EMR_CASE_IGNORE_OID,
                                  SYNTAX_NAME_FORM_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_NAME_FORM_NAME);
      int    msgID   = MSGID_ATTR_SYNTAX_UNKNOWN_ORDERING_MATCHING_RULE;
      String message = getMessage(msgID, OMR_CASE_IGNORE_OID,
                                  SYNTAX_NAME_FORM_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_NAME_FORM_NAME);
      int    msgID   = MSGID_ATTR_SYNTAX_UNKNOWN_SUBSTRING_MATCHING_RULE;
      String message = getMessage(msgID, SMR_CASE_IGNORE_OID,
                                  SYNTAX_NAME_FORM_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
    {
      decodeNameForm(value, DirectoryServer.getSchema());
      decodeNameForm(value, DirectoryServer.getSchema(), true);
      return true;
    }
    catch (DirectoryException de)
@@ -303,17 +262,25 @@
   * octet string value does not need to be normalized (and in fact, it 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 reference to the Directory Server schema to use to
   *                 decode the name form information.
   * @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 structural objectclass and/or
   *                               required or optional attribute types which
   *                               are not defined in the server schema.  This
   *                               should only be true when called by
   *                               {@code valueIsAcceptable}.
   *
   * @return  The decoded name form definition.
   *
   * @throws  DirectoryException  If the provided value cannot be decoded as an
   *                              name form definition.
   */
  public static NameForm decodeNameForm(ByteString value, Schema schema)
  public static NameForm decodeNameForm(ByteString value, Schema schema,
                                        boolean allowUnknownElements)
         throws DirectoryException
  {
    assert debugEnter(CLASS_NAME, "decodeNameForm", String.valueOf(value));
@@ -589,29 +556,34 @@
        if (structuralClass == null)
        {
          // This is bad because we don't know what the structural objectclass
          // is.  Log a message and create a default objectclass with the
          // specified name.
          // is.
          if (allowUnknownElements)
          {
            structuralClass = DirectoryServer.getDefaultObjectClass(
                                                   woidBuffer.toString());
          }
          else
          {
          int    msgID   = MSGID_ATTR_SYNTAX_NAME_FORM_UNKNOWN_STRUCTURAL_CLASS;
          String message = getMessage(msgID, String.valueOf(oid),
                                      String.valueOf(woidBuffer));
          logError(ErrorLogCategory.SCHEMA, ErrorLogSeverity.SEVERE_ERROR,
            throw new DirectoryException(ResultCode.CONSTRAINT_VIOLATION,
                   message, msgID);
          structuralClass =
               DirectoryServer.getDefaultObjectClass(woidBuffer.toString());
          }
        }
        else if (structuralClass.getObjectClassType() !=
                 ObjectClassType.STRUCTURAL)
        {
          // This is bad because the associated structural class type is not
          // structural.  Log a message and continue.
          // structural.
          int msgID =
               MSGID_ATTR_SYNTAX_NAME_FORM_STRUCTURAL_CLASS_NOT_STRUCTURAL;
          String message =
               getMessage(msgID, String.valueOf(oid),
                          String.valueOf(woidBuffer),
                          String.valueOf(structuralClass.getObjectClassType()));
          logError(ErrorLogCategory.SCHEMA, ErrorLogSeverity.SEVERE_ERROR,
                   message, msgID);
          throw new DirectoryException(ResultCode.CONSTRAINT_VIOLATION, message,
                                       msgID);
        }
      }
      else if (lowerTokenName.equals("must"))
@@ -634,17 +606,20 @@
            if (attr == null)
            {
              // This isn't good because it means that the name form 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_NAME_FORM_UNKNOWN_REQUIRED_ATTR;
              String message = getMessage(msgID, oid, woidBuffer.toString());
              logError(ErrorLogCategory.SCHEMA, ErrorLogSeverity.SEVERE_WARNING,
                       message, msgID);
              // an attribute type that we don't know anything about.
              if (allowUnknownElements)
              {
              attr = DirectoryServer.getDefaultAttributeType(
                                          woidBuffer.toString());
            }
              else
              {
                int msgID = MSGID_ATTR_SYNTAX_NAME_FORM_UNKNOWN_REQUIRED_ATTR;
                String message = getMessage(msgID, oid, woidBuffer.toString());
                throw new DirectoryException(ResultCode.CONSTRAINT_VIOLATION,
                                             message, msgID);
              }
            }
            attrs.add(attr);
@@ -675,16 +650,20 @@
          if (attr == null)
          {
            // This isn't good because it means that the name form 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_NAME_FORM_UNKNOWN_REQUIRED_ATTR;
            String message = getMessage(msgID, oid, woidBuffer.toString());
            logError(ErrorLogCategory.SCHEMA, ErrorLogSeverity.SEVERE_WARNING,
                     message, msgID);
            // attribute type that we don't know anything about.
            if (allowUnknownElements)
            {
            attr = DirectoryServer.getDefaultAttributeType(
                                        woidBuffer.toString());
          }
            else
            {
              int msgID = MSGID_ATTR_SYNTAX_NAME_FORM_UNKNOWN_REQUIRED_ATTR;
              String message = getMessage(msgID, oid, woidBuffer.toString());
              throw new DirectoryException(ResultCode.CONSTRAINT_VIOLATION,
                                           message, msgID);
            }
          }
          attrs.add(attr);
        }
@@ -711,17 +690,20 @@
            if (attr == null)
            {
              // This isn't good because it means that the name form 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_NAME_FORM_UNKNOWN_OPTIONAL_ATTR;
              String message = getMessage(msgID, oid, woidBuffer.toString());
              logError(ErrorLogCategory.SCHEMA, ErrorLogSeverity.SEVERE_WARNING,
                       message, msgID);
              // attribute type that we don't know anything about.
              if (allowUnknownElements)
              {
              attr = DirectoryServer.getDefaultAttributeType(
                                          woidBuffer.toString());
            }
              else
              {
                int msgID = MSGID_ATTR_SYNTAX_NAME_FORM_UNKNOWN_OPTIONAL_ATTR;
                String message = getMessage(msgID, oid, woidBuffer.toString());
                throw new DirectoryException(ResultCode.CONSTRAINT_VIOLATION,
                                             message, msgID);
              }
            }
            attrs.add(attr);
@@ -752,16 +734,20 @@
          if (attr == null)
          {
            // This isn't good because it means that the name form 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_NAME_FORM_UNKNOWN_OPTIONAL_ATTR;
            String message = getMessage(msgID, oid, woidBuffer.toString());
            logError(ErrorLogCategory.SCHEMA, ErrorLogSeverity.SEVERE_WARNING,
                     message, msgID);
            // attribute type that we don't know anything about.
            if (allowUnknownElements)
            {
            attr = DirectoryServer.getDefaultAttributeType(
                                        woidBuffer.toString());
          }
            else
            {
              int msgID = MSGID_ATTR_SYNTAX_NAME_FORM_UNKNOWN_OPTIONAL_ATTR;
              String message = getMessage(msgID, oid, woidBuffer.toString());
              throw new DirectoryException(ResultCode.CONSTRAINT_VIOLATION,
                                           message, msgID);
            }
          }
          attrs.add(attr);
        }
opendj-sdk/opends/src/server/org/opends/server/schema/ObjectClassSyntax.java
@@ -46,18 +46,17 @@
import org.opends.server.types.AttributeType;
import org.opends.server.types.ByteString;
import org.opends.server.types.DirectoryException;
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.*;
import static org.opends.server.util.ServerConstants.*;
import static org.opends.server.util.StaticUtils.*;
@@ -105,17 +104,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));
@@ -124,36 +116,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_OBJECTCLASS_NAME);
      int    msgID   = MSGID_ATTR_SYNTAX_UNKNOWN_EQUALITY_MATCHING_RULE;
      String message = getMessage(msgID, EMR_CASE_IGNORE_OID,
                                  SYNTAX_OBJECTCLASS_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_OBJECTCLASS_NAME);
      int    msgID   = MSGID_ATTR_SYNTAX_UNKNOWN_ORDERING_MATCHING_RULE;
      String message = getMessage(msgID, OMR_CASE_IGNORE_OID,
                                  SYNTAX_OBJECTCLASS_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_OBJECTCLASS_NAME);
      int    msgID   = MSGID_ATTR_SYNTAX_UNKNOWN_SUBSTRING_MATCHING_RULE;
      String message = getMessage(msgID, SMR_CASE_IGNORE_OID,
                                  SYNTAX_OBJECTCLASS_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()
  {
@@ -165,9 +158,7 @@
  /**
   * Retrieves the OID for this attribute syntax.
   *
   * @return  The OID for this attribute syntax.
   * {@inheritDoc}
   */
  public String getOID()
  {
@@ -179,9 +170,7 @@
  /**
   * Retrieves a description for this attribute syntax.
   *
   * @return  A description for this attribute syntax.
   * {@inheritDoc}
   */
  public String getDescription()
  {
@@ -193,12 +182,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()
  {
@@ -210,12 +194,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()
  {
@@ -227,12 +206,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()
  {
@@ -244,12 +218,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()
  {
@@ -262,16 +231,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)
@@ -284,7 +244,7 @@
    // acceptable.
    try
    {
      decodeObjectClass(value, DirectoryServer.getSchema());
      decodeObjectClass(value, DirectoryServer.getSchema(), true);
      return true;
    }
    catch (DirectoryException de)
@@ -304,17 +264,25 @@
   * octet string value does not need to be normalized (and in fact, it 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 superior class or required or
   *                               optional attribute types which are not
   *                               defined in the server schema.  This should
   *                               only be true when called by
   *                               {@code valueIsAcceptable}.
   *
   * @return  The decoded objectclass definition.
   *
   * @throws  DirectoryException  If the provided value cannot be decoded as an
   *                              objectclass definition.
   */
  public static ObjectClass decodeObjectClass(ByteString value, Schema schema)
  public static ObjectClass decodeObjectClass(ByteString value, Schema schema,
                                              boolean allowUnknownElements)
         throws DirectoryException
  {
    assert debugEnter(CLASS_NAME, "decodeObjectClass", String.valueOf(value));
@@ -593,17 +561,21 @@
        superiorClass = schema.getObjectClass(woidBuffer.toString());
        if (superiorClass == null)
        {
          if (allowUnknownElements)
          {
            superiorClass =
                 DirectoryServer.getDefaultObjectClass(woidBuffer.toString());
          }
          else
          {
          // This is bad because we don't know what the superior objectclass
          // is so we can't base this objectclass on it.  Log a message and
          // just create a default empty superior class.
            // is so we can't base this objectclass on it.
          int    msgID   = MSGID_ATTR_SYNTAX_OBJECTCLASS_UNKNOWN_SUPERIOR_CLASS;
          String message = getMessage(msgID, String.valueOf(oid),
                                      String.valueOf(woidBuffer));
          logError(ErrorLogCategory.SCHEMA, ErrorLogSeverity.SEVERE_WARNING,
            throw new DirectoryException(ResultCode.CONSTRAINT_VIOLATION,
                   message, msgID);
          superiorClass =
               DirectoryServer.getDefaultObjectClass(woidBuffer.toString());
          }
        }
@@ -652,18 +624,21 @@
            AttributeType attr = schema.getAttributeType(woidBuffer.toString());
            if (attr == null)
            {
              // This isn't good because it means that the objectclass 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_OBJECTCLASS_UNKNOWN_REQUIRED_ATTR;
              String message = getMessage(msgID, oid, woidBuffer.toString());
              logError(ErrorLogCategory.SCHEMA, ErrorLogSeverity.SEVERE_WARNING,
                       message, msgID);
              if (allowUnknownElements)
              {
              attr = DirectoryServer.getDefaultAttributeType(
                                          woidBuffer.toString());
            }
              else
              {
                // This isn't good because it means that the objectclass
                // requires an attribute type that we don't know anything about.
                int msgID = MSGID_ATTR_SYNTAX_OBJECTCLASS_UNKNOWN_REQUIRED_ATTR;
                String message = getMessage(msgID, oid, woidBuffer.toString());
                throw new DirectoryException(ResultCode.CONSTRAINT_VIOLATION,
                                             message, msgID);
              }
            }
            attrs.add(attr);
@@ -693,17 +668,21 @@
          AttributeType attr = schema.getAttributeType(woidBuffer.toString());
          if (attr == null)
          {
            // This isn't good because it means that the objectclass 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_OBJECTCLASS_UNKNOWN_REQUIRED_ATTR;
            String message = getMessage(msgID, oid, woidBuffer.toString());
            logError(ErrorLogCategory.SCHEMA, ErrorLogSeverity.SEVERE_WARNING,
                     message, msgID);
            if (allowUnknownElements)
            {
            attr = DirectoryServer.getDefaultAttributeType(
                                        woidBuffer.toString());
          }
            else
            {
              // This isn't good because it means that the objectclass requires
              // an attribute type that we don't know anything about.
              int msgID = MSGID_ATTR_SYNTAX_OBJECTCLASS_UNKNOWN_REQUIRED_ATTR;
              String message = getMessage(msgID, oid, woidBuffer.toString());
              throw new DirectoryException(ResultCode.CONSTRAINT_VIOLATION,
                                           message, msgID);
            }
          }
          attrs.add(attr);
        }
@@ -729,18 +708,21 @@
            AttributeType attr = schema.getAttributeType(woidBuffer.toString());
            if (attr == null)
            {
              // This isn't good because it means that the objectclass 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_OBJECTCLASS_UNKNOWN_OPTIONAL_ATTR;
              String message = getMessage(msgID, oid, woidBuffer.toString());
              logError(ErrorLogCategory.SCHEMA, ErrorLogSeverity.SEVERE_WARNING,
                       message, msgID);
              if (allowUnknownElements)
              {
              attr = DirectoryServer.getDefaultAttributeType(
                                          woidBuffer.toString());
            }
              else
              {
                // This isn't good because it means that the objectclass allows
                // an attribute type that we don't know anything about.
                int msgID = MSGID_ATTR_SYNTAX_OBJECTCLASS_UNKNOWN_OPTIONAL_ATTR;
                String message = getMessage(msgID, oid, woidBuffer.toString());
                throw new DirectoryException(ResultCode.CONSTRAINT_VIOLATION,
                                             message, msgID);
              }
            }
            attrs.add(attr);
@@ -770,17 +752,21 @@
          AttributeType attr = schema.getAttributeType(woidBuffer.toString());
          if (attr == null)
          {
            // This isn't good because it means that the objectclass 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_OBJECTCLASS_UNKNOWN_OPTIONAL_ATTR;
            String message = getMessage(msgID, oid, woidBuffer.toString());
            logError(ErrorLogCategory.SCHEMA, ErrorLogSeverity.SEVERE_WARNING,
                     message, msgID);
            if (allowUnknownElements)
            {
            attr = DirectoryServer.getDefaultAttributeType(
                                        woidBuffer.toString());
          }
            else
            {
              // This isn't good because it means that the objectclass allows an
              // attribute type that we don't know anything about.
              int msgID = MSGID_ATTR_SYNTAX_OBJECTCLASS_UNKNOWN_OPTIONAL_ATTR;
              String message = getMessage(msgID, oid, woidBuffer.toString());
              throw new DirectoryException(ResultCode.CONSTRAINT_VIOLATION,
                                           message, msgID);
            }
          }
          attrs.add(attr);
        }
@@ -800,11 +786,73 @@
    }
    // This should only happen for the "top" objectclass.
    if (superiorClass.getOID().equals(oid))
    {
      // This should only happen for the "top" objectclass.
      superiorClass = null;
    }
    else
    {
      // Make sure that the inheritance configuration is acceptable.
      ObjectClassType superiorType = superiorClass.getObjectClassType();
      switch (objectClassType)
      {
        case ABSTRACT:
          // Abstract classes may only inherit from other abstract classes.
          if (superiorType != ObjectClassType.ABSTRACT)
          {
            int msgID = MSGID_ATTR_SYNTAX_OBJECTCLASS_INVALID_SUPERIOR_TYPE;
            String message = getMessage(msgID, oid, objectClassType.toString(),
                                        superiorType.toString(),
                                        superiorClass.getNameOrOID());
            throw new DirectoryException(ResultCode.CONSTRAINT_VIOLATION,
                                         message, msgID);
          }
          break;
        case AUXILIARY:
          // Auxiliary classes may only inherit from abstract classes or other
          // auxiliary classes.
          if ((superiorType != ObjectClassType.ABSTRACT) &&
              (superiorType != ObjectClassType.AUXILIARY))
          {
            int msgID = MSGID_ATTR_SYNTAX_OBJECTCLASS_INVALID_SUPERIOR_TYPE;
            String message = getMessage(msgID, oid, objectClassType.toString(),
                                        superiorType.toString(),
                                        superiorClass.getNameOrOID());
            throw new DirectoryException(ResultCode.CONSTRAINT_VIOLATION,
                                         message, msgID);
          }
          break;
        case STRUCTURAL:
          // Structural classes may only inherit from abstract classes or other
          // structural classes.
          if ((superiorType != ObjectClassType.ABSTRACT) &&
              (superiorType != ObjectClassType.STRUCTURAL))
          {
            int msgID = MSGID_ATTR_SYNTAX_OBJECTCLASS_INVALID_SUPERIOR_TYPE;
            String message = getMessage(msgID, oid, objectClassType.toString(),
                                        superiorType.toString(),
                                        superiorClass.getNameOrOID());
            throw new DirectoryException(ResultCode.CONSTRAINT_VIOLATION,
                                         message, msgID);
          }
          // Structural classes must have the "top" objectclass somewhere in the
          // superior chain.
          if (! superiorChainIncludesTop(superiorClass))
          {
            int msgID =
                 MSGID_ATTR_SYNTAX_OBJECTCLASS_STRUCTURAL_SUPERIOR_NOT_TOP;
            String message = getMessage(msgID, oid);
            throw new DirectoryException(ResultCode.CONSTRAINT_VIOLATION,
                                         message, msgID);
          }
          break;
      }
    }
    return new ObjectClass(value.stringValue(), primaryName, names, oid,
@@ -1341,5 +1389,35 @@
    return startPos;
  }
  /**
   * Indicates whether the provided objectclass or any of its superiors is equal
   * to the "top" objectclass.
   *
   * @param  superiorClass  The objectclass for which to make the determination.
   *
   * @return  {@code true} if the provided class or any of its superiors is
   *          equal to the "top" objectclass, or {@code false} if not.
   */
  private static boolean superiorChainIncludesTop(ObjectClass superiorClass)
  {
    assert debugEnter(CLASS_NAME, "superiorChainIncludesTop",
                      String.valueOf(superiorClass));
    if (superiorClass == null)
    {
      return false;
    }
    else if (superiorClass.hasName(OC_TOP))
    {
      return true;
    }
    else
    {
      return superiorChainIncludesTop(superiorClass.getSuperiorClass());
    }
  }
}
opendj-sdk/opends/src/server/org/opends/server/types/AttributeType.java
@@ -404,7 +404,8 @@
    Schema     schema = DirectoryServer.getSchema();
    AttributeType at =
         AttributeTypeSyntax.decodeAttributeType(value, schema);
         AttributeTypeSyntax.decodeAttributeType(value, schema,
                                              false);
    at.setSchemaFile(getSchemaFile());
    return at;
opendj-sdk/opends/src/server/org/opends/server/types/DITContentRule.java
@@ -257,7 +257,8 @@
    Schema     schema = DirectoryConfig.getSchema();
    DITContentRule dcr =
         DITContentRuleSyntax.decodeDITContentRule(value, schema);
         DITContentRuleSyntax.decodeDITContentRule(value, schema,
                                                   false);
    dcr.setSchemaFile(getSchemaFile());
    return dcr;
opendj-sdk/opends/src/server/org/opends/server/types/Entry.java
@@ -487,6 +487,14 @@
                                     message, msgID);
      }
      if (oc.isObsolete())
      {
        int    msgID   = MSGID_ENTRY_ADD_OBSOLETE_OC;
        String message = getMessage(msgID, name, String.valueOf(dn));
        throw new DirectoryException(ResultCode.OBJECTCLASS_VIOLATION,
                                     message, msgID);
      }
      tmpOCMap.put(oc, name);
    }
@@ -2144,34 +2152,142 @@
   *       forms, DIT content rules, and DIT structure rules.</LI>
   * </UL>
   *
   * @param  parentEntry     The entry that is the immediate parent of
   *                         this entry, which may be checked for DIT
   *                         structure rule conformance.  This may be
   *                         <CODE>null</CODE> if there is no parent
   *                         or if it is unavailable to the caller.
   * @param  parentProvided  Indicates whether the caller attempted to
   *                         provide the parent  If not, then the
   *                         parent entry will be loaded on demand if
   *                         it is required.
   * @param  invalidReason   The buffer to which an explanation will
   *                         be appended if this entry does not
   *                         conform to the server's schema
   * @param  parentEntry             The entry that is the immediate
   *                                 parent of this entry, which may
   *                                 be checked for DIT structure rule
   *                                 conformance.  This may be
   *                                 {@code null} if there is no
   *                                 parent or if it is unavailable
   *                                to the caller.
   * @param  parentProvided          Indicates whether the caller
   *                                 attempted to provide the parent.
   *                                 If not, then the parent entry
   *                                 will be loaded on demand if it is
   *                                 required.
   * @param  validateNameForms       Indicates whether to validate the
   *                                 entry against name form
   *                                 definitions.  This should only be
   *                                 {@code true} for add and modify
   *                                 DN operations, as well as for
   *                                 for imports.
   * @param  validateStructureRules  Indicates whether to validate the
   *                                 entry against DIT structure rule
   *                                 definitions.  This should only
   *                                 be {@code true} for add and
   *                                 modify DN operations.
   * @param  invalidReason           The buffer to which an
   *                                 explanation will be appended if
   *                                 this entry does not conform to
   *                                 the server's schema
   *                         configuration.
   *
   * @return  <CODE>true</CODE> if this entry conforms to the server's
   *          schema requirements, or <CODE>false</CODE> if it does
   *          not.
   * @return  {@code true} if this entry conforms to the server's
   *          schema requirements, or {@code false} if it does not.
   */
  public boolean conformsToSchema(Entry parentEntry,
                                  boolean parentProvided,
                                  boolean validateNameForms,
                                  boolean validateStructureRules,
                                  StringBuilder invalidReason)
  {
    assert debugEnter(CLASS_NAME, "conformsToSchema",
                      "java.lang.StringBuilder");
    // First, make sure that we recognize all of the objectclasses and
    // that all of the required attributes are present.
    // Get the structural objectclass for the entry.  If there isn't
    // one, or if there's more than one, then see if that's OK.
    AcceptRejectWarn structuralPolicy =
         DirectoryServer.getSingleStructuralObjectClassPolicy();
    ObjectClass structuralClass = null;
    boolean multipleOCErrorLogged = false;
    for (ObjectClass oc : objectClasses.keySet())
    {
      if (oc.getObjectClassType() == ObjectClassType.STRUCTURAL)
      {
        if ((structuralClass == null) ||
            oc.isDescendantOf(structuralClass))
        {
          structuralClass = oc;
        }
        else if (! structuralClass.isDescendantOf(oc))
        {
          int msgID = MSGID_ENTRY_SCHEMA_MULTIPLE_STRUCTURAL_CLASSES;
          String message = getMessage(msgID, String.valueOf(dn),
                                structuralClass.getNameOrOID(),
                                oc.getNameOrOID());
          if (structuralPolicy == AcceptRejectWarn.REJECT)
          {
            invalidReason.append(message);
            return false;
          }
          else if (structuralPolicy == AcceptRejectWarn.WARN)
          {
            if (! multipleOCErrorLogged)
            {
              logError(ErrorLogCategory.SCHEMA,
                       ErrorLogSeverity.SEVERE_WARNING, message,
                       msgID);
              multipleOCErrorLogged = true;
            }
          }
        }
      }
    }
    NameForm         nameForm         = null;
    DITContentRule   ditContentRule   = null;
    DITStructureRule ditStructureRule = null;
    if (structuralClass == null)
    {
      int msgID = MSGID_ENTRY_SCHEMA_NO_STRUCTURAL_CLASS;
      String message = getMessage(msgID, String.valueOf(dn));
      if (structuralPolicy == AcceptRejectWarn.REJECT)
      {
        invalidReason.append(message);
        return false;
      }
      else if (structuralPolicy == AcceptRejectWarn.WARN)
      {
        logError(ErrorLogCategory.SCHEMA,
                 ErrorLogSeverity.SEVERE_WARNING, message, msgID);
      }
    }
    else
    {
      ditContentRule =
           DirectoryServer.getDITContentRule(structuralClass);
      if ((ditContentRule != null) && ditContentRule.isObsolete())
      {
        ditContentRule = null;
      }
      if (validateNameForms)
      {
        nameForm = DirectoryServer.getNameForm(structuralClass);
        if ((nameForm != null) && nameForm.isObsolete())
        {
          nameForm = null;
        }
        if (validateStructureRules && (nameForm != null))
        {
          ditStructureRule =
               DirectoryServer.getDITStructureRule(nameForm);
          if ((ditStructureRule != null) &&
              ditStructureRule.isObsolete())
          {
            ditStructureRule = null;
          }
        }
      }
    }
    // Make sure that we recognize all of the objectclasses, that all
    // auxiliary classes are allowed by the DIT content rule, and that
    // all attributes required by the object classes are present.
    for (ObjectClass o : objectClasses.keySet())
    {
      if (DirectoryServer.getObjectClass(o.getOID()) == null)
@@ -2183,6 +2299,26 @@
        return false;
      }
      if ((o.getObjectClassType() == ObjectClassType.AUXILIARY) &&
          (ditContentRule != null) &&
          (! ditContentRule.getAuxiliaryClasses().contains(o)))
      {
        int msgID = MSGID_ENTRY_SCHEMA_DISALLOWED_AUXILIARY_CLASS;
        String message = getMessage(msgID, String.valueOf(dn),
                                    o.getNameOrOID(),
                                    ditContentRule.getName());
        if (structuralPolicy == AcceptRejectWarn.REJECT)
        {
          invalidReason.append(message);
          return false;
        }
        else if (structuralPolicy == AcceptRejectWarn.WARN)
        {
          logError(ErrorLogCategory.SCHEMA,
                   ErrorLogSeverity.SEVERE_WARNING, message, msgID);
        }
      }
      for (AttributeType t : o.getRequiredAttributes())
      {
        if (! (userAttributes.containsKey(t) ||
@@ -2200,9 +2336,9 @@
    }
    // Next, make sure all the user attributes are allowed, and make
    // sure that if they are single-valued that they properly conform
    // to that.
    // Make sure all the user attributes are allowed, and make sure
    // that if they are single-valued that they properly conform to
    // that.
    for (AttributeType t : userAttributes.keySet())
    {
      boolean found = false;
@@ -2215,6 +2351,14 @@
        }
      }
      if ((! found) && (ditContentRule != null))
      {
        if (ditContentRule.isRequiredOrOptional(t))
        {
          found = true;
        }
      }
      if (! found)
      {
        int msgID = MSGID_ENTRY_SCHEMA_DISALLOWED_USER_ATTR_FOR_OC;
@@ -2272,82 +2416,9 @@
    }
    // Optionally, make sure that the entry contains exactly one
    // structural objectclass.
    AcceptRejectWarn structuralPolicy =
         DirectoryServer.getSingleStructuralObjectClassPolicy();
    if ((structuralPolicy == AcceptRejectWarn.REJECT) ||
        (structuralPolicy == AcceptRejectWarn.WARN))
    {
      ObjectClass structuralClass = null;
      for (ObjectClass oc : objectClasses.keySet())
      {
        if (oc.getObjectClassType() == ObjectClassType.STRUCTURAL)
        {
          if (structuralClass == null)
          {
            structuralClass = oc;
          }
          else
          {
            if (oc.isDescendantOf(structuralClass))
            {
              // This is acceptable, but we want to make the class the
              // new structural class.
              structuralClass = oc;
            }
            else if (! structuralClass.isDescendantOf(oc))
            {
              // This is not acceptable because there are multiple
              // conflicting structural classes.
              int msgID =
                   MSGID_ENTRY_SCHEMA_MULTIPLE_STRUCTURAL_CLASSES;
              String message = getMessage(msgID, String.valueOf(dn),
                                    structuralClass.getNameOrOID(),
                                    oc.getNameOrOID());
              if (structuralPolicy == AcceptRejectWarn.REJECT)
              {
                invalidReason.append(message);
                return false;
              }
              else
              {
                logError(ErrorLogCategory.SCHEMA,
                         ErrorLogSeverity.SEVERE_WARNING, message,
                         msgID);
                break;
              }
            }
          }
        }
      }
      if (structuralClass == null)
      {
        // This is not acceptable because the entry does not contain a
        // structural objectclass.
        int msgID = MSGID_ENTRY_SCHEMA_NO_STRUCTURAL_CLASS;
        String message = getMessage(msgID, String.valueOf(dn));
        if (structuralPolicy == AcceptRejectWarn.REJECT)
        {
          invalidReason.append(message);
          return false;
        }
        else
        {
          logError(ErrorLogCategory.SCHEMA,
                   ErrorLogSeverity.SEVERE_WARNING, message, msgID);
        }
      }
      else
      {
        // See if there is an applicable name form definition.  If so,
        // then make sure that the entry is compliant.
        NameForm nameForm =
             DirectoryServer.getNameForm(structuralClass);
        if ((nameForm != null) && (! nameForm.isObsolete()))
    // If there is a name form for this entry, then make sure that the
    // RDN for the entry is in compliance with it.
    if (nameForm != null)
        {
          RDN rdn = dn.getRDN();
          if (rdn != null)
@@ -2357,8 +2428,7 @@
            {
              if (! rdn.hasAttributeType(t))
              {
                int    msgID   =
                     MSGID_ENTRY_SCHEMA_RDN_MISSING_REQUIRED_ATTR;
            int msgID = MSGID_ENTRY_SCHEMA_RDN_MISSING_REQUIRED_ATTR;
                String message = getMessage(msgID, String.valueOf(dn),
                                            t.getNameOrOID(),
                                            nameForm.getNameOrOID());
@@ -2368,7 +2438,7 @@
                  invalidReason.append(message);
                  return false;
                }
                else
            else if (structuralPolicy == AcceptRejectWarn.WARN)
                {
                  logError(ErrorLogCategory.SCHEMA,
                           ErrorLogSeverity.SEVERE_WARNING, message,
@@ -2394,7 +2464,7 @@
                  invalidReason.append(message);
                  return false;
                }
                else
            else if (structuralPolicy == AcceptRejectWarn.WARN)
                {
                  logError(ErrorLogCategory.SCHEMA,
                           ErrorLogSeverity.SEVERE_WARNING, message,
@@ -2403,28 +2473,77 @@
              }
            }
          }
    }
          // See if there is a DIT structure rule that corresponds to
          // this name form.  If so, then make sure that the entry is
          // acceptable according to that structure rule.  Note that
          // we will perform this check for entries that have a
          // parent, meaning that structure rules will not be
          // evaluated for suffix entries.  We will also only perform
          // validation for structure rules that have superior rules,
          // so make sure that is the case as well.
          DITStructureRule dsr =
               DirectoryServer.getDITStructureRule(nameForm);
          if ((dsr != null) && (! dsr.isObsolete()) &&
              dsr.hasSuperiorRules())
    // If there is a DIT content rule for this entry, then make sure
    // that the entry is in compliance with it.
    if (ditContentRule != null)
    {
      // Make sure that all of the required attributes are present.
      for (AttributeType t : ditContentRule.getRequiredAttributes())
      {
        if (! (userAttributes.containsKey(t) ||
               operationalAttributes.containsKey(t) ||
               t.isObjectClassType()))
        {
          int msgID =
               MSGID_ENTRY_SCHEMA_MISSING_REQUIRED_ATTR_FOR_DCR;
          String message = getMessage(msgID, String.valueOf(dn),
                                      t.getNameOrOID(),
                                      ditContentRule.getName());
          if (structuralPolicy == AcceptRejectWarn.REJECT)
          {
            invalidReason.append(message);
            return false;
          }
          else if (structuralPolicy == AcceptRejectWarn.WARN)
          {
            logError(ErrorLogCategory.SCHEMA,
                     ErrorLogSeverity.SEVERE_WARNING, message, msgID);
          }
        }
      }
      // Make sure that none of the prohibited attributes are present.
      for (AttributeType t : ditContentRule.getProhibitedAttributes())
      {
        if (userAttributes.containsKey(t) ||
            operationalAttributes.containsKey(t))
        {
          int    msgID   = MSGID_ENTRY_SCHEMA_PROHIBITED_ATTR_FOR_DCR;
          String message = getMessage(msgID, String.valueOf(dn),
                                      t.getNameOrOID(),
                                      ditContentRule.getName());
          if (structuralPolicy == AcceptRejectWarn.REJECT)
          {
            invalidReason.append(message);
            return false;
          }
          else if (structuralPolicy == AcceptRejectWarn.WARN)
          {
            logError(ErrorLogCategory.SCHEMA,
                     ErrorLogSeverity.SEVERE_WARNING, message, msgID);
          }
        }
      }
    }
    // If there is a DIT structure rule for this entry, then make sure
    // that the entry is in compliance with it.
    if ((ditStructureRule != null) &&
        ditStructureRule.hasSuperiorRules())
          {
            if (parentProvided)
            {
              if (parentEntry != null)
              {
                boolean dsrValid =
                     validateDITStructureRule(dsr, structuralClass,
                                              parentEntry,
               validateDITStructureRule(ditStructureRule,
                                        structuralClass, parentEntry,
                                              structuralPolicy,
                                              invalidReason);
                if (! dsrValid)
@@ -2439,8 +2558,7 @@
              DN parentDN = dn.getParentDNInSuffix();
              if (parentDN != null)
              {
                // Get the parent entry and check its structural
                // class.
          // Get the parent entry and check its structural class.
                Lock lock = null;
                for (int i=0; i < 3; i++)
                {
@@ -2453,11 +2571,8 @@
                if (lock == null)
                {
                  int    msgID   =
                       MSGID_ENTRY_SCHEMA_DSR_COULD_NOT_LOCK_PARENT;
                  String message = getMessage(msgID,
                                        String.valueOf(dn),
                                        dsr.getNameOrRuleID(),
            int msgID = MSGID_ENTRY_SCHEMA_DSR_COULD_NOT_LOCK_PARENT;
            String message = getMessage(msgID, String.valueOf(dn),
                                        String.valueOf(parentDN));
                  if (structuralPolicy == AcceptRejectWarn.REJECT)
@@ -2465,7 +2580,7 @@
                    invalidReason.append(message);
                    return false;
                  }
                  else
            else if (structuralPolicy == AcceptRejectWarn.WARN)
                  {
                    logError(ErrorLogCategory.SCHEMA,
                             ErrorLogSeverity.SEVERE_WARNING, message,
@@ -2479,11 +2594,9 @@
                    parentEntry = DirectoryServer.getEntry(parentDN);
                    if (parentEntry == null)
                    {
                      int    msgID   =
                           MSGID_ENTRY_SCHEMA_DSR_NO_PARENT_ENTRY;
                      String message = getMessage(msgID,
                                            String.valueOf(dn),
                                            dsr.getNameOrRuleID(),
                int msgID = MSGID_ENTRY_SCHEMA_DSR_NO_PARENT_ENTRY;
                String message =
                     getMessage(msgID, String.valueOf(dn),
                                            String.valueOf(parentDN));
                      if (structuralPolicy == AcceptRejectWarn.REJECT)
@@ -2491,17 +2604,17 @@
                        invalidReason.append(message);
                        return false;
                      }
                      else
                else if (structuralPolicy == AcceptRejectWarn.WARN)
                      {
                        logError(ErrorLogCategory.SCHEMA,
                                 ErrorLogSeverity.SEVERE_WARNING,
                                 message, msgID);
                           ErrorLogSeverity.SEVERE_WARNING, message,
                           msgID);
                      }
                    }
                    else
                    {
                      boolean dsrValid =
                           validateDITStructureRule(dsr,
                     validateDITStructureRule(ditStructureRule,
                                                    structuralClass,
                                                    parentEntry,
                                                    structuralPolicy,
@@ -2514,14 +2627,13 @@
                  }
                  catch (Exception e)
                  {
                    assert debugException(CLASS_NAME,
                                          "conformsToSchema", e);
              assert debugException(CLASS_NAME, "conformsToSchema",
                                    e);
                    int    msgID   =
                         MSGID_ENTRY_SCHEMA_COULD_NOT_CHECK_DSR;
              int    msgID   = MSGID_ENTRY_SCHEMA_COULD_NOT_CHECK_DSR;
                    String message =
                         getMessage(msgID, String.valueOf(dn),
                                    dsr.getNameOrRuleID(),
                              ditStructureRule.getNameOrRuleID(),
                                    stackTraceToSingleLineString(e));
                    if (structuralPolicy == AcceptRejectWarn.REJECT)
@@ -2529,11 +2641,11 @@
                      invalidReason.append(message);
                      return false;
                    }
                    else
              else if (structuralPolicy == AcceptRejectWarn.WARN)
                    {
                      logError(ErrorLogCategory.SCHEMA,
                               ErrorLogSeverity.SEVERE_WARNING,
                               message, msgID);
                         ErrorLogSeverity.SEVERE_WARNING, message,
                         msgID);
                    }
                  }
                  finally
@@ -2544,119 +2656,156 @@
              }
            }
          }
    else if (validateStructureRules)
    {
      // There is no DIT structure rule for this entry, but there may
      // be one for the parent entry.  If there is such a rule for the
      // parent entry, then this entry will not be valid.
      boolean parentExists = false;
      ObjectClass parentStructuralClass = null;
      if (parentEntry != null)
      {
        parentExists = true;
        parentStructuralClass =
             parentEntry.getStructuralObjectClass();
        }
        // See if there is an applicable DIT content rule.  If so,
        // then make sure that the entry is compliant.
        DITContentRule dcr =
             DirectoryServer.getDITContentRule(structuralClass);
        if ((dcr != null) && (! dcr.isObsolete()))
      else if (! parentProvided)
        {
          // Make sure that the entry contains all required
          // attributes.
          for (AttributeType t : dcr.getRequiredAttributes())
        DN parentDN = getDN().getParentDNInSuffix();
        if (parentDN != null)
          {
            if (userAttributes.containsKey(t) ||
                operationalAttributes.containsKey(t) ||
                t.isObjectClassType())
          // Get the parent entry and check its structural class.
          Lock lock = null;
          for (int i=0; i < 3; i++)
          {
            lock = LockManager.lockRead(parentDN);
            if (lock != null)
            {
              break;
            }
            else
          }
          if (lock == null)
            {
              int    msgID   =
                   MSGID_ENTRY_SCHEMA_MISSING_REQUIRED_ATTR_FOR_DCR;
            int msgID = MSGID_ENTRY_SCHEMA_DSR_COULD_NOT_LOCK_PARENT;
              String message = getMessage(msgID, String.valueOf(dn),
                                          t.getNameOrOID(),
                                          dcr.getName());
                                  String.valueOf(parentDN));
              if (structuralPolicy == AcceptRejectWarn.REJECT)
              {
                invalidReason.append(message);
                return false;
              }
              else
            else if (structuralPolicy == AcceptRejectWarn.WARN)
              {
                logError(ErrorLogCategory.SCHEMA,
                         ErrorLogSeverity.SEVERE_WARNING, message,
                         msgID);
              }
            }
          }
          // Make sure that the entry does not contain any prohibited
          // attributes.
          for (AttributeType t : dcr.getProhibitedAttributes())
          else
          {
            if (userAttributes.containsKey(t) ||
                operationalAttributes.containsKey(t))
            try
            {
              int    msgID   =
                   MSGID_ENTRY_SCHEMA_PROHIBITED_ATTR_FOR_DCR;
              String message = getMessage(msgID, String.valueOf(dn),
                                          t.getNameOrOID(),
                                          dcr.getName());
              parentEntry = DirectoryServer.getEntry(parentDN);
              if (parentEntry == null)
              {
                int msgID = MSGID_ENTRY_SCHEMA_DSR_NO_PARENT_ENTRY;
                String message =
                     getMessage(msgID, String.valueOf(dn),
                                String.valueOf(parentDN));
              if (structuralPolicy == AcceptRejectWarn.REJECT)
              {
                invalidReason.append(message);
                return false;
              }
              else
                else if (structuralPolicy == AcceptRejectWarn.WARN)
              {
                logError(ErrorLogCategory.SCHEMA,
                         ErrorLogSeverity.SEVERE_WARNING, message,
                         msgID);
              }
            }
              else
              {
                parentExists = true;
                parentStructuralClass =
                     parentEntry.getStructuralObjectClass();
          }
            }
            catch (Exception e)
            {
              assert debugException(CLASS_NAME, "conformsToSchema",
                                    e);
          // Make sure that all user attributes are allowed.
          for (AttributeType t : userAttributes.keySet())
          {
            if (! dcr.isRequiredOrOptional(t, true))
            {
              int    msgID   =
                   MSGID_ENTRY_SCHEMA_DISALLOWED_USER_ATTR_FOR_DCR;
              String message = getMessage(msgID, String.valueOf(dn),
                                          t.getNameOrOID(),
                                          dcr.getName());
                   MSGID_ENTRY_SCHEMA_COULD_NOT_CHECK_PARENT_DSR;
              String message =
                   getMessage(msgID, String.valueOf(dn),
                              stackTraceToSingleLineString(e));
              if (structuralPolicy == AcceptRejectWarn.REJECT)
              {
                invalidReason.append(message);
                return false;
              }
              else
              else if (structuralPolicy == AcceptRejectWarn.WARN)
              {
                logError(ErrorLogCategory.SCHEMA,
                         ErrorLogSeverity.SEVERE_WARNING, message,
                         msgID);
              }
            }
            finally
            {
              LockManager.unlock(parentDN, lock);
            }
          }
        }
          }
          // Make sure that all auxiliary objectclasses are allowed.
          for (ObjectClass oc : objectClasses.keySet())
      if (parentExists)
          {
            if (oc.getObjectClassType() == ObjectClassType.AUXILIARY)
        if (parentStructuralClass == null)
            {
              if (! dcr.isAllowedAuxiliaryClass(oc))
              {
                int    msgID   =
                     MSGID_ENTRY_SCHEMA_DISALLOWED_AUXILIARY_CLASS;
          int    msgID   = MSGID_ENTRY_SCHEMA_DSR_NO_PARENT_OC;
                String message = getMessage(msgID, String.valueOf(dn),
                                            oc.getNameOrOID(),
                                            dcr.getName());
                                String.valueOf(parentEntry.getDN()));
                if (structuralPolicy == AcceptRejectWarn.REJECT)
                {
                  invalidReason.append(message);
                  return false;
                }
          else if (structuralPolicy == AcceptRejectWarn.WARN)
          {
            logError(ErrorLogCategory.SCHEMA,
                     ErrorLogSeverity.SEVERE_WARNING, message, msgID);
          }
        }
                else
                {
          NameForm parentNF =
               DirectoryServer.getNameForm(parentStructuralClass);
          if ((parentNF != null) && (! parentNF.isObsolete()))
          {
            DITStructureRule parentDSR =
                 DirectoryServer.getDITStructureRule(parentNF);
            if ((parentDSR != null) && (! parentDSR.isObsolete()))
            {
              int    msgID   = MSGID_ENTRY_SCHEMA_VIOLATES_PARENT_DSR;
              String message =
                   getMessage(msgID, String.valueOf(dn),
                              String.valueOf(parentEntry.getDN()));
              if (structuralPolicy == AcceptRejectWarn.REJECT)
              {
                invalidReason.append(message);
                return false;
              }
              else if (structuralPolicy == AcceptRejectWarn.WARN)
              {
                  logError(ErrorLogCategory.SCHEMA,
                           ErrorLogSeverity.SEVERE_WARNING, message,
                           msgID);
@@ -2666,8 +2815,9 @@
          }
        }
      }
    }
    // If we've gotten here, then the entry is acceptable.
    return true;
  }
@@ -2702,7 +2852,6 @@
    {
      int    msgID   = MSGID_ENTRY_SCHEMA_DSR_NO_PARENT_OC;
      String message = getMessage(msgID, String.valueOf(dn),
                            dsr.getNameOrRuleID(),
                            String.valueOf(parentEntry.getDN()));
      if (structuralPolicy == AcceptRejectWarn.REJECT)
@@ -2710,7 +2859,7 @@
        invalidReason.append(message);
        return false;
      }
      else
      else if (structuralPolicy == AcceptRejectWarn.WARN)
      {
        logError(ErrorLogCategory.SCHEMA,
                 ErrorLogSeverity.SEVERE_WARNING, message,
@@ -2740,7 +2889,7 @@
        invalidReason.append(message);
        return false;
      }
      else
      else if (structuralPolicy == AcceptRejectWarn.WARN)
      {
        logError(ErrorLogCategory.SCHEMA,
                 ErrorLogSeverity.SEVERE_WARNING, message, msgID);
opendj-sdk/opends/src/server/org/opends/server/types/MatchingRuleUse.java
@@ -201,7 +201,8 @@
    Schema     schema = DirectoryConfig.getSchema();
    MatchingRuleUse mru =
         MatchingRuleUseSyntax.decodeMatchingRuleUse(value, schema);
         MatchingRuleUseSyntax.decodeMatchingRuleUse(value, schema,
                                                     false);
    mru.setSchemaFile(getSchemaFile());
    return mru;
opendj-sdk/opends/src/server/org/opends/server/types/NameForm.java
@@ -217,7 +217,7 @@
    ByteString value  = ByteStringFactory.create(definition);
    Schema     schema = DirectoryConfig.getSchema();
    NameForm nf = NameFormSyntax.decodeNameForm(value, schema);
    NameForm nf = NameFormSyntax.decodeNameForm(value, schema, false);
    nf.setSchemaFile(getSchemaFile());
    return nf;
opendj-sdk/opends/src/server/org/opends/server/types/ObjectClass.java
@@ -260,7 +260,7 @@
    Schema     schema = DirectoryConfig.getSchema();
    ObjectClass oc = ObjectClassSyntax.decodeObjectClass(value,
                                                         schema);
                                            schema, false);
    oc.setSchemaFile(getSchemaFile());
    return oc;
opendj-sdk/opends/src/server/org/opends/server/util/LDIFReader.java
@@ -310,7 +310,7 @@
      if (checkSchema)
      {
        StringBuilder invalidReason = new StringBuilder();
        if (! entry.conformsToSchema(null, false, invalidReason))
        if (! entry.conformsToSchema(null, false, true, false, invalidReason))
        {
          int    msgID   = MSGID_LDIF_SCHEMA_VIOLATION;
          String message = getMessage(msgID, String.valueOf(entryDN),
opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/backends/SchemaBackendTestCase.java
@@ -835,6 +835,283 @@
  /**
   * Tests the behavior of the schema backend when attempting to add a new
   * attribute type with an undefined syntax.
   *
   * @throws  Exception  If an unexpected problem occurs.
   */
  @Test()
  public void testAddAttributeTypeUndefinedSyntax()
         throws Exception
  {
    String path = TestCaseUtils.createTempFile(
         "dn: cn=schema",
         "changetype: modify",
         "add: attributeTypes",
         "attributeTypes: ( testaddatundefinedsyntax-oid " +
              "NAME 'testAddATUndefinedSyntax' " +
              "SYNTAX 1.3.6.1.4.1.1466.115.121.1.99999 SINGLE-VALUE " +
              "X-ORGIN 'SchemaBackendTestCase' )");
    String[] args =
    {
      "-h", "127.0.0.1",
      "-p", String.valueOf(TestCaseUtils.getServerLdapPort()),
      "-D", "cn=Directory Manager",
      "-w", "password",
      "-f", path
    };
    assertFalse(LDAPModify.mainModify(args, false, null, System.err) == 0);
  }
  /**
   * Tests the behavior of the schema backend when attempting to add a new
   * attribute type with an undefined equality matching rule.
   *
   * @throws  Exception  If an unexpected problem occurs.
   */
  @Test()
  public void testAddAttributeTypeUndefinedEMR()
         throws Exception
  {
    String path = TestCaseUtils.createTempFile(
         "dn: cn=schema",
         "changetype: modify",
         "add: attributeTypes",
         "attributeTypes: ( testaddatundefinedemr-oid " +
              "NAME 'testAddATUndefinedEMR' EQUALITY xxxundefinedxxx " +
              "SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE " +
              "X-ORGIN 'SchemaBackendTestCase' )");
    String[] args =
    {
      "-h", "127.0.0.1",
      "-p", String.valueOf(TestCaseUtils.getServerLdapPort()),
      "-D", "cn=Directory Manager",
      "-w", "password",
      "-f", path
    };
    assertFalse(LDAPModify.mainModify(args, false, null, System.err) == 0);
  }
  /**
   * Tests the behavior of the schema backend when attempting to add a new
   * attribute type with an undefined ordering matching rule.
   *
   * @throws  Exception  If an unexpected problem occurs.
   */
  @Test()
  public void testAddAttributeTypeUndefinedOMR()
         throws Exception
  {
    String path = TestCaseUtils.createTempFile(
         "dn: cn=schema",
         "changetype: modify",
         "add: attributeTypes",
         "attributeTypes: ( testaddatundefinedomr-oid " +
              "NAME 'testAddATUndefinedOMR' ORDERING xxxundefinedxxx " +
              "SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE " +
              "X-ORGIN 'SchemaBackendTestCase' )");
    String[] args =
    {
      "-h", "127.0.0.1",
      "-p", String.valueOf(TestCaseUtils.getServerLdapPort()),
      "-D", "cn=Directory Manager",
      "-w", "password",
      "-f", path
    };
    assertFalse(LDAPModify.mainModify(args, false, null, System.err) == 0);
  }
  /**
   * Tests the behavior of the schema backend when attempting to add a new
   * attribute type with an undefined substring matching rule.
   *
   * @throws  Exception  If an unexpected problem occurs.
   */
  @Test()
  public void testAddAttributeTypeUndefinedSMR()
         throws Exception
  {
    String path = TestCaseUtils.createTempFile(
         "dn: cn=schema",
         "changetype: modify",
         "add: attributeTypes",
         "attributeTypes: ( testaddatundefinedsmr-oid " +
              "NAME 'testAddATUndefinedSMR' SUBSTR xxxundefinedxxx " +
              "SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE " +
              "X-ORGIN 'SchemaBackendTestCase' )");
    String[] args =
    {
      "-h", "127.0.0.1",
      "-p", String.valueOf(TestCaseUtils.getServerLdapPort()),
      "-D", "cn=Directory Manager",
      "-w", "password",
      "-f", path
    };
    assertFalse(LDAPModify.mainModify(args, false, null, System.err) == 0);
  }
  /**
   * Tests the behavior of the schema backend when attempting to add a new
   * attribute type with an undefined approximate matching rule.
   *
   * @throws  Exception  If an unexpected problem occurs.
   */
  @Test()
  public void testAddAttributeTypeUndefinedAMR()
         throws Exception
  {
    String path = TestCaseUtils.createTempFile(
         "dn: cn=schema",
         "changetype: modify",
         "add: attributeTypes",
         "attributeTypes: ( testaddatundefinedamr-oid " +
              "NAME 'testAddATUndefinedAMR' " +
              "SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE " +
              "X-APPROX 'xxxundefinedxxx' X-ORGIN 'SchemaBackendTestCase' )");
    String[] args =
    {
      "-h", "127.0.0.1",
      "-p", String.valueOf(TestCaseUtils.getServerLdapPort()),
      "-D", "cn=Directory Manager",
      "-w", "password",
      "-f", path
    };
    assertFalse(LDAPModify.mainModify(args, false, null, System.err) == 0);
  }
  /**
   * Tests the behavior of the schema backend when attempting to add a new
   * attribute type with an invalid usage.
   *
   * @throws  Exception  If an unexpected problem occurs.
   */
  @Test()
  public void testAddAttributeTypeInvalidUsage()
         throws Exception
  {
    String path = TestCaseUtils.createTempFile(
         "dn: cn=schema",
         "changetype: modify",
         "add: attributeTypes",
         "attributeTypes: ( testaddatundefinedsyntax-oid " +
              "NAME 'testAddATUndefinedSyntax' " +
              "SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE " +
              "USAGE xxxinvalidxxx X-ORGIN 'SchemaBackendTestCase' )");
    String[] args =
    {
      "-h", "127.0.0.1",
      "-p", String.valueOf(TestCaseUtils.getServerLdapPort()),
      "-D", "cn=Directory Manager",
      "-w", "password",
      "-f", path
    };
    assertFalse(LDAPModify.mainModify(args, false, null, System.err) == 0);
  }
  /**
   * Tests the behavior of the schema backend when attempting to add a new
   * attribute type whose superior type is marked OBSOLETE in the server schema.
   *
   * @throws  Exception  If an unexpected problem occurs.
   */
  @Test()
  public void testAddAttributeTypeObsoleteSuperior()
         throws Exception
  {
    String path = TestCaseUtils.createTempFile(
         "dn: cn=schema",
         "changetype: modify",
         "add: attributeTypes",
         "attributeTypes: ( testaddatobsoletesuperiorsup-oid " +
              "NAME 'testAddATObsoleteSuperiorSup' OBSOLETE " +
              "SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE " +
              "X-ORGIN 'SchemaBackendTestCase' )",
         "attributeTypes: ( testaddatobsoletesuperior-oid " +
              "NAME 'testAddATObsoleteSuperior' " +
              "SUP testAddATObsoleteSuperiorSup " +
              "SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE " +
              "X-ORGIN 'SchemaBackendTestCase' )");
    String[] args =
    {
      "-h", "127.0.0.1",
      "-p", String.valueOf(TestCaseUtils.getServerLdapPort()),
      "-D", "cn=Directory Manager",
      "-w", "password",
      "-f", path
    };
    assertFalse(LDAPModify.mainModify(args, false, null, System.err) == 0);
  }
  /**
   * Tests the behavior of the schema backend when attempting to add a new
   * attribute type whose equality matching rule is marked OBSOLETE in the
   * server schema.
   *
   * @throws  Exception  If an unexpected problem occurs.
   */
  @Test()
  public void testAddAttributeTypeObsoleteEMR()
         throws Exception
  {
    SchemaTestMatchingRule matchingRule =
         new SchemaTestMatchingRule("testAddATObsoleteEMRMatch",
                                    "1.3.6.1.4.1.26027.1.999.20", true);
    DirectoryServer.registerMatchingRule(matchingRule, false);
    String path = TestCaseUtils.createTempFile(
         "dn: cn=schema",
         "changetype: modify",
         "add: attributeTypes",
         "attributeTypes: ( testaddatobsoleteemr-oid " +
              "NAME 'testAddATObsoleteEMR' " +
              "EQUALITY testAddATObsoleteEMRMatch " +
              "SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE " +
              "X-ORGIN 'SchemaBackendTestCase' )");
    String[] args =
    {
      "-h", "127.0.0.1",
      "-p", String.valueOf(TestCaseUtils.getServerLdapPort()),
      "-D", "cn=Directory Manager",
      "-w", "password",
      "-f", path
    };
    assertFalse(LDAPModify.mainModify(args, false, null, System.err) == 0);
  }
  /**
   * Tests the behavior of the schema backend when attempting to add a new
   * attribute type that conflicts with multiple existing types.
   *
   * @throws  Exception  If an unexpected problem occurs.
@@ -1594,6 +1871,120 @@
  /**
   * Tests the behavior of the schema backend when attempting to add a new
   * objectclass that references an obsolete superior class.
   *
   * @throws  Exception  If an unexpected problem occurs.
   */
  @Test()
  public void testAddObjectClassObsoleteSuperiorClass()
         throws Exception
  {
    String path = TestCaseUtils.createTempFile(
         "dn: cn=schema",
         "changetype: modify",
         "add: objectClasses",
         "objectClasses: ( testaddocobsoletesuperiorsup-oid " +
              "NAME 'testAddOCObsoleteSuperiorSup' OBSOLETE STRUCTURAL " +
              "MUST cn X-ORIGIN 'SchemaBackendTestCase' )",
         "objectClasses: ( testaddocobsoletesuperior-oid " +
              "NAME 'testAddOCObsoleteSuperior' OBSOLETE " +
              "SUP testAddOCObsoleteSuperiorSup STRUCTURAL MUST cn " +
              "X-ORIGIN 'SchemaBackendTestCase' )");
    String[] args =
    {
      "-h", "127.0.0.1",
      "-p", String.valueOf(TestCaseUtils.getServerLdapPort()),
      "-D", "cn=Directory Manager",
      "-w", "password",
      "-f", path
    };
    assertFalse(LDAPModify.mainModify(args, false, null, null) == 0);
  }
  /**
   * Tests the behavior of the schema backend when attempting to add a new
   * objectclass that references an obsolete required attribute type.
   *
   * @throws  Exception  If an unexpected problem occurs.
   */
  @Test()
  public void testAddObjectClassObsoleteRequiredAttribute()
         throws Exception
  {
    String path = TestCaseUtils.createTempFile(
         "dn: cn=schema",
         "changetype: modify",
         "add: attributeTypes",
         "attributeTypes: ( testaddocobsoleterequiredattrat-oid " +
              "NAME 'testAddOCObsoleteRequiredAttrAT' OBSOLETE " +
              "SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE " +
              "X-ORIGIN 'SchemaBackendTestCase' )",
         "-",
         "add: objectClasses",
         "objectClasses: ( testaddocobsoleterequiredattroc-oid " +
              "NAME 'testAddOCObsoleteRequiredAttrOC' " +
              "STRUCTURAL MUST testAddOCObsoleteRequiredAttrAT " +
              "X-ORIGIN 'SchemaBackendTestCase' )");
    String[] args =
    {
      "-h", "127.0.0.1",
      "-p", String.valueOf(TestCaseUtils.getServerLdapPort()),
      "-D", "cn=Directory Manager",
      "-w", "password",
      "-f", path
    };
    assertFalse(LDAPModify.mainModify(args, false, null, null) == 0);
  }
  /**
   * Tests the behavior of the schema backend when attempting to add a new
   * objectclass that references an obsolete optional attribute type.
   *
   * @throws  Exception  If an unexpected problem occurs.
   */
  @Test()
  public void testAddObjectClassObsoleteOptionalAttribute()
         throws Exception
  {
    String path = TestCaseUtils.createTempFile(
         "dn: cn=schema",
         "changetype: modify",
         "add: attributeTypes",
         "attributeTypes: ( testaddocobsoleteoptionalattrat-oid " +
              "NAME 'testAddOCObsoleteOptionalAttrAT' OBSOLETE " +
              "SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE " +
              "X-ORIGIN 'SchemaBackendTestCase' )",
         "-",
         "add: objectClasses",
         "objectClasses: ( testaddocobsoleteoptionalattroc-oid " +
              "NAME 'testAddOCObsoleteOptionalAttrOC' " +
              "STRUCTURAL MAY testAddOCObsoleteOptionalAttrAT " +
              "X-ORIGIN 'SchemaBackendTestCase' )");
    String[] args =
    {
      "-h", "127.0.0.1",
      "-p", String.valueOf(TestCaseUtils.getServerLdapPort()),
      "-D", "cn=Directory Manager",
      "-w", "password",
      "-f", path
    };
    assertFalse(LDAPModify.mainModify(args, false, null, null) == 0);
  }
  /**
   * Tests the behavior of the schema backend when attempting to add a new
   * objectclass that references an undefined required attribute.
   *
   * @throws  Exception  If an unexpected problem occurs.
@@ -1626,6 +2017,40 @@
  /**
   * Tests the behavior of the schema backend when attempting to add a new
   * objectclass that references an undefined required attribute when multiple
   * required attributes were provided.
   *
   * @throws  Exception  If an unexpected problem occurs.
   */
  @Test()
  public void testAddObjectClassMultipleUndefinedRequiredAttribute()
         throws Exception
  {
    String path = TestCaseUtils.createTempFile(
         "dn: cn=schema",
         "changetype: modify",
         "add: objectClasses",
         "objectClasses: ( testaddocmultipleundefinedrequired-oid NAME " +
              "'testAddOCMultipleUndefinedRequired' SUP top STRUCTURAL " +
              "MUST ( cn $ xxxundefinedxxx ) " +
              "X-ORIGIN 'SchemaBackendTestCase' )");
    String[] args =
    {
      "-h", "127.0.0.1",
      "-p", String.valueOf(TestCaseUtils.getServerLdapPort()),
      "-D", "cn=Directory Manager",
      "-w", "password",
      "-f", path
    };
    assertFalse(LDAPModify.mainModify(args, false, null, null) == 0);
  }
  /**
   * Tests the behavior of the schema backend when attempting to add a new
   * objectclass that references an undefined optional attribute.
   *
   * @throws  Exception  If an unexpected problem occurs.
@@ -1657,6 +2082,136 @@
  /**
   * Tests the behavior of the schema backend when attempting to add a new
   * objectclass that references an undefined optional attribute when multiple
   * optional attributes were provided.
   *
   * @throws  Exception  If an unexpected problem occurs.
   */
  @Test()
  public void testAddObjectClassMultipleUndefinedOptionalAttribute()
         throws Exception
  {
    String path = TestCaseUtils.createTempFile(
         "dn: cn=schema",
         "changetype: modify",
         "add: objectClasses",
         "objectClasses: ( testaddocmultipleundefinedoptional-oid NAME " +
              "'testAddOCMultipleUndefinedOptional' SUP top STRUCTURAL " +
              "MAY ( cn $ xxxundefinedxxx ) " +
              "X-ORIGIN 'SchemaBackendTestCase' )");
    String[] args =
    {
      "-h", "127.0.0.1",
      "-p", String.valueOf(TestCaseUtils.getServerLdapPort()),
      "-D", "cn=Directory Manager",
      "-w", "password",
      "-f", path
    };
    assertFalse(LDAPModify.mainModify(args, false, null, null) == 0);
  }
  /**
   * Tests the behavior of the schema backend when attempting to add a new
   * abstract objectclass whose superior class is not abstract.
   *
   * @throws  Exception  If an unexpected problem occurs.
   */
  @Test()
  public void testAddAbstractObjectClassWithNonAbstractSuperior()
         throws Exception
  {
    String path = TestCaseUtils.createTempFile(
         "dn: cn=schema",
         "changetype: modify",
         "add: objectClasses",
         "objectClasses: ( testaddabstractocwithnonabstractsuperior-oid NAME " +
              "'testAddAbstractOCWithNonAbstractSuperior' SUP person " +
              "ABSTRACT MAY description X-ORIGIN 'SchemaBackendTestCase' )");
    String[] args =
    {
      "-h", "127.0.0.1",
      "-p", String.valueOf(TestCaseUtils.getServerLdapPort()),
      "-D", "cn=Directory Manager",
      "-w", "password",
      "-f", path
    };
    assertFalse(LDAPModify.mainModify(args, false, null, null) == 0);
  }
  /**
   * Tests the behavior of the schema backend when attempting to add a new
   * auxiliary objectclass whose superior class is structural.
   *
   * @throws  Exception  If an unexpected problem occurs.
   */
  @Test()
  public void testAddAuxiliaryObjectClassWithStructuralSuperior()
         throws Exception
  {
    String path = TestCaseUtils.createTempFile(
         "dn: cn=schema",
         "changetype: modify",
         "add: objectClasses",
         "objectClasses: ( testaddauxiliaryocwithstructuralsuperior-oid NAME " +
              "'testAddAuxiliaryOCWithStructuralSuperior' SUP person " +
              "AUXILIARY MAY description X-ORIGIN 'SchemaBackendTestCase' )");
    String[] args =
    {
      "-h", "127.0.0.1",
      "-p", String.valueOf(TestCaseUtils.getServerLdapPort()),
      "-D", "cn=Directory Manager",
      "-w", "password",
      "-f", path
    };
    assertFalse(LDAPModify.mainModify(args, false, null, null) == 0);
  }
  /**
   * Tests the behavior of the schema backend when attempting to add a new
   * structural objectclass whose superior class is auxiliary.
   *
   * @throws  Exception  If an unexpected problem occurs.
   */
  @Test()
  public void testAddStructuralObjectClassWithAuxiliarySuperior()
         throws Exception
  {
    String path = TestCaseUtils.createTempFile(
         "dn: cn=schema",
         "changetype: modify",
         "add: objectClasses",
         "objectClasses: ( testaddstructuralocwithauxiliarysuperior-oid NAME " +
              "'testAddStructuralOCWithAuxiliarySuperior' SUP posixAccount " +
              "STRUCTURAL MAY description X-ORIGIN 'SchemaBackendTestCase' )");
    String[] args =
    {
      "-h", "127.0.0.1",
      "-p", String.valueOf(TestCaseUtils.getServerLdapPort()),
      "-D", "cn=Directory Manager",
      "-w", "password",
      "-f", path
    };
    assertFalse(LDAPModify.mainModify(args, false, null, null) == 0);
  }
  /**
   * Tests the behavior of the schema backend when attempting to remove an
   * objectclass that exists and for which there are no dependencies.
   *
@@ -1942,7 +2497,7 @@
              "MUST cn X-ORIGIN 'SchemaBackendTestCase')",
         "-",
         "add: nameForms",
         "nameForms: ( testaddnameformwithundefinereqdat-oid " +
         "nameForms: ( testaddnameformwithundefinedreqat-oid " +
              "NAME 'testAddNameFormWithUndefinedReqAT' " +
              "OC testAddNameFormWithUndefinedReqATOC MUST xxxundefinedxxx " +
              "X-ORIGIN 'SchemaBackendTestCase' )");
@@ -1967,6 +2522,50 @@
  /**
   * Tests the behavior of the schema backend when attempting to add a new name
   * form that references a required attribute type not defined in the server
   * schema when multiple required attributes were given.
   *
   * @throws  Exception  If an unexpected problem occurs.
   */
  @Test()
  public void testAddNameFormWithMultipleUndefinedReqAT()
         throws Exception
  {
    String path = TestCaseUtils.createTempFile(
         "dn: cn=schema",
         "changetype: modify",
         "add: objectClasses",
         "objectClasses:  ( testaddnameformwithmultipleundefinedreqatoc-oid " +
              "NAME 'testAddNameFormWithMultipleUndefinedReqATOC' SUP top " +
              "STRUCTURAL MUST cn X-ORIGIN 'SchemaBackendTestCase')",
         "-",
         "add: nameForms",
         "nameForms: ( testaddnameformwithmultipleundefinedreqat-oid " +
              "NAME 'testAddNameFormWithMultipleUndefinedReqAT' " +
              "OC testAddNameFormWithMultipleUndefinedReqATOC " +
              "MUST ( cn $ xxxundefinedxxx ) " +
              "X-ORIGIN 'SchemaBackendTestCase' )");
    String nameFormName = "testaddnameformwithmultipleundefinedreqat";
    assertFalse(DirectoryServer.getSchema().hasNameForm(nameFormName));
    String[] args =
    {
      "-h", "127.0.0.1",
      "-p", String.valueOf(TestCaseUtils.getServerLdapPort()),
      "-D", "cn=Directory Manager",
      "-w", "password",
      "-f", path
    };
    assertFalse(LDAPModify.mainModify(args, false, null, null) == 0);
    assertFalse(DirectoryServer.getSchema().hasNameForm(nameFormName));
  }
  /**
   * Tests the behavior of the schema backend when attempting to add a new name
   * form that references an optional attribute type not defined in the server
   * schema.
   *
@@ -1985,7 +2584,7 @@
              "MUST cn X-ORIGIN 'SchemaBackendTestCase')",
         "-",
         "add: nameForms",
         "nameForms: ( testaddnameformwithundefineoptdat-oid " +
         "nameForms: ( testaddnameformwithundefinedoptat-oid " +
              "NAME 'testAddNameFormWithUndefinedOptAT' " +
              "OC testAddNameFormWithUndefinedOptATOC MUST cn " +
              "MAY xxxundefinedxxx X-ORIGIN 'SchemaBackendTestCase' )");
@@ -2010,6 +2609,50 @@
  /**
   * Tests the behavior of the schema backend when attempting to add a new name
   * form that references an optional attribute type not defined in the server
   * schema when multiple optional attribute types were provided.
   *
   * @throws  Exception  If an unexpected problem occurs.
   */
  @Test()
  public void testAddNameFormWithMultipleUndefinedOptAT()
         throws Exception
  {
    String path = TestCaseUtils.createTempFile(
         "dn: cn=schema",
         "changetype: modify",
         "add: objectClasses",
         "objectClasses:  ( testaddnameformwithmultipleundefinedoptatoc-oid " +
              "NAME 'testAddNameFormWithMultipleUndefinedOptATOC' SUP top " +
              "STRUCTURAL MUST cn X-ORIGIN 'SchemaBackendTestCase')",
         "-",
         "add: nameForms",
         "nameForms: ( testaddnameformwithmultipleundefinedoptat-oid " +
              "NAME 'testAddNameFormWithMultipleUndefinedOptAT' " +
              "OC testAddNameFormWithMultipleUndefinedOptATOC MUST cn " +
              "MAY ( description $ xxxundefinedxxx ) " +
              "X-ORIGIN 'SchemaBackendTestCase' )");
    String nameFormName = "testaddnameformwithmultipleundefinedoptat";
    assertFalse(DirectoryServer.getSchema().hasNameForm(nameFormName));
    String[] args =
    {
      "-h", "127.0.0.1",
      "-p", String.valueOf(TestCaseUtils.getServerLdapPort()),
      "-D", "cn=Directory Manager",
      "-w", "password",
      "-f", path
    };
    assertFalse(LDAPModify.mainModify(args, false, null, null) == 0);
    assertFalse(DirectoryServer.getSchema().hasNameForm(nameFormName));
  }
  /**
   * Tests the behavior of the schema backend when attempting to add a new name
   * form whose structural objectclass is not defined in the server schema.
   *
   * @throws  Exception  If an unexpected problem occurs.
@@ -2088,6 +2731,136 @@
  /**
   * Tests the behavior of the schema backend when attempting to add a new name
   * form whose structural objectclass is OBSOLETE rather than structural.
   *
   * @throws  Exception  If an unexpected problem occurs.
   */
  @Test()
  public void testAddNameFormWithObsoleteOC()
         throws Exception
  {
    String path = TestCaseUtils.createTempFile(
         "dn: cn=schema",
         "changetype: modify",
         "add: objectClasses",
         "objectClasses:  ( testaddnameformwithobsoleteococ-oid " +
              "NAME 'testAddNameFormWithObsoleteOCOC' OBSOLETE SUP top " +
              "STRUCTURAL MUST cn X-ORIGIN 'SchemaBackendTestCase')",
         "-",
         "add: nameForms",
         "nameForms: ( testaddnameformwithobsoleteoc-oid " +
              "NAME 'testAddNameFormWithObsoleteOC' " +
              "OC testAddNameFormWithObsoleteOCOC MUST cn " +
              "X-ORIGIN 'SchemaBackendTestCase' )");
    String nameFormName = "testaddnameformwithobsoleteoc";
    assertFalse(DirectoryServer.getSchema().hasNameForm(nameFormName));
    String[] args =
    {
      "-h", "127.0.0.1",
      "-p", String.valueOf(TestCaseUtils.getServerLdapPort()),
      "-D", "cn=Directory Manager",
      "-w", "password",
      "-f", path
    };
    assertFalse(LDAPModify.mainModify(args, false, null, null) == 0);
    assertFalse(DirectoryServer.getSchema().hasNameForm(nameFormName));
  }
  /**
   * Tests the behavior of the schema backend when attempting to add a new name
   * form with a required attribute type that is declared OBSOLETE.
   *
   * @throws  Exception  If an unexpected problem occurs.
   */
  @Test()
  public void testAddNameFormWithObsoleteReqAT()
         throws Exception
  {
    String path = TestCaseUtils.createTempFile(
         "dn: cn=schema",
         "changetype: modify",
         "add: attributeTypes",
         "attributeTypes: ( testaddnfwithobsoletereqatat-oid " +
              "NAME 'testAddNFWithObsoleteReqATAT' OBSOLETE " +
              "X-ORIGIN 'SchemaBackendTestCase' )",
         "-",
         "add: objectClasses",
         "objectClasses:  ( testaddnfwithobsoletereqatoc-oid " +
              "NAME 'testAddNFWithObsoleteReqATOC' SUP top STRUCTURAL " +
              "MUST cn X-ORIGIN 'SchemaBackendTestCase' )",
         "-",
         "add: nameForms",
         "nameForms: ( testaddnfwithobsoletereqatnf-oid " +
              "NAME 'testAddNFWithObsoleteReqATNF' " +
              "OC testAddNFWithObsoleteReqATOC " +
              "MUST testAddNFWithObsoleteReqATAT " +
              "X-ORIGIN 'SchemaBackendTestCase' )");
    String[] args =
    {
      "-h", "127.0.0.1",
      "-p", String.valueOf(TestCaseUtils.getServerLdapPort()),
      "-D", "cn=Directory Manager",
      "-w", "password",
      "-f", path
    };
    assertFalse(LDAPModify.mainModify(args, false, null, null) == 0);
  }
  /**
   * Tests the behavior of the schema backend when attempting to add a new name
   * form with an optional attribute type that is declared OBSOLETE.
   *
   * @throws  Exception  If an unexpected problem occurs.
   */
  @Test()
  public void testAddNameFormWithObsoleteOptAT()
         throws Exception
  {
    String path = TestCaseUtils.createTempFile(
         "dn: cn=schema",
         "changetype: modify",
         "add: attributeTypes",
         "attributeTypes: ( testaddnfwithobsoleteoptatat-oid " +
              "NAME 'testAddNFWithObsoleteOptATAT' OBSOLETE " +
              "X-ORIGIN 'SchemaBackendTestCase' )",
         "-",
         "add: objectClasses",
         "objectClasses:  ( testaddnfwithobsoleteoptatoc-oid " +
              "NAME 'testAddNFWithObsoleteOptATOC' SUP top STRUCTURAL " +
              "MUST cn X-ORIGIN 'SchemaBackendTestCase' )",
         "-",
         "add: nameForms",
         "nameForms: ( testaddnfwithobsoleteoptatnf-oid " +
              "NAME 'testAddNFWithObsoleteOptATNF' " +
              "OC testAddNFWithObsoleteOptATOC " +
              "MUST cn MAY testAddNFWithObsoleteOptATAT " +
              "X-ORIGIN 'SchemaBackendTestCase' )");
    String[] args =
    {
      "-h", "127.0.0.1",
      "-p", String.valueOf(TestCaseUtils.getServerLdapPort()),
      "-D", "cn=Directory Manager",
      "-w", "password",
      "-f", path
    };
    assertFalse(LDAPModify.mainModify(args, false, null, null) == 0);
  }
  /**
   * Tests the behavior of the schema backend when attempting to add a new name
   * form that references a structural objectclass already referenced by another
   * name form.
   *
@@ -2585,6 +3358,43 @@
  /**
   * Tests the behavior of the schema backend when attempting to add a new DIT
   * content rule whose structural objectclass is OBSOLETE.
   *
   * @throws  Exception  If an unexpected problem occurs.
   */
  @Test()
  public void testAddDITContentRuleObsoleteOC()
         throws Exception
  {
    String path = TestCaseUtils.createTempFile(
         "dn: cn=schema",
         "changetype: modify",
         "add: objectClasses",
         "objectClasses:  ( testaddditcontentruleobsoleteococ-oid " +
              "NAME 'testAddDITContentRuleObsoleteOCOC' OBSOLETE SUP top " +
              "STRUCTURAL MUST cn X-ORIGIN 'SchemaBackendTestCase')",
         "-",
         "add: ditContentRules",
         "ditContentRules: ( testaddditcontentruleobsoleteococ-oid " +
              "NAME 'testAddDITContentRuleObsoleteOC' NOT description " +
              "X-ORIGIN 'SchemaBackendTestCase' )");
    String[] args =
    {
      "-h", "127.0.0.1",
      "-p", String.valueOf(TestCaseUtils.getServerLdapPort()),
      "-D", "cn=Directory Manager",
      "-w", "password",
      "-f", path
    };
    assertFalse(LDAPModify.mainModify(args, false, null, null) == 0);
  }
  /**
   * Tests the behavior of the schema backend when attempting to add a new DIT
   * content rule whose structural objectclass is already referenced by an
   * existing DIT content rule.
   *
@@ -2667,6 +3477,162 @@
  /**
   * Tests the behavior of the schema backend when attempting to add a new DIT
   * content rule with an undefined auxiliary objectclass when multiple
   * auxiliary classes were provided.
   *
   * @throws  Exception  If an unexpected problem occurs.
   */
  @Test()
  public void testAddDITContentRuleMultipleUndefinedAuxOC()
         throws Exception
  {
    String path = TestCaseUtils.createTempFile(
         "dn: cn=schema",
         "changetype: modify",
         "add: objectClasses",
         "objectClasses:  ( testaddditcontentrulemultundefinedauxococ-oid " +
              "NAME 'testAddDITContentRuleMultUndefinedAuxOCOC' SUP top " +
              "STRUCTURAL MUST cn X-ORIGIN 'SchemaBackendTestCase')",
         "-",
         "add: ditContentRules",
         "ditContentRules: ( testaddditcontentrulemultundefinedauxococ-oid " +
              "NAME 'testAddDITContentRuleMultUndefinedAuxOC' " +
              "AUX ( posixAccount $ xxxundefinedxxx ) " +
              "X-ORIGIN 'SchemaBackendTestCase' )");
    String[] args =
    {
      "-h", "127.0.0.1",
      "-p", String.valueOf(TestCaseUtils.getServerLdapPort()),
      "-D", "cn=Directory Manager",
      "-w", "password",
      "-f", path
    };
    assertFalse(LDAPModify.mainModify(args, false, null, null) == 0);
  }
  /**
   * Tests the behavior of the schema backend when attempting to add a new DIT
   * content rule with an auxiliary objectclass that is not auxiliary.
   *
   * @throws  Exception  If an unexpected problem occurs.
   */
  @Test()
  public void testAddDITContentRuleAuxOCNotAux()
         throws Exception
  {
    String path = TestCaseUtils.createTempFile(
         "dn: cn=schema",
         "changetype: modify",
         "add: objectClasses",
         "objectClasses:  ( testaddditcontentruleauxocnotauxoc-oid " +
              "NAME 'testAddDITContentRuleAuxOCNotAuxOC' SUP top " +
              "STRUCTURAL MUST cn X-ORIGIN 'SchemaBackendTestCase')",
         "-",
         "add: ditContentRules",
         "ditContentRules: ( testaddditcontentruleauxocnotaux-oid " +
              "NAME 'testAddDITContentRuleAuxOCNotAuxOC' " +
              "AUX person X-ORIGIN 'SchemaBackendTestCase' )");
    String[] args =
    {
      "-h", "127.0.0.1",
      "-p", String.valueOf(TestCaseUtils.getServerLdapPort()),
      "-D", "cn=Directory Manager",
      "-w", "password",
      "-f", path
    };
    assertFalse(LDAPModify.mainModify(args, false, null, null) == 0);
  }
  /**
   * Tests the behavior of the schema backend when attempting to add a new DIT
   * content rule with an auxiliary objectclass that is not auxiliary when
   * multiple auxiliary classes were provided.
   *
   * @throws  Exception  If an unexpected problem occurs.
   */
  @Test()
  public void testAddDITContentRuleMultipleAuxOCNotAux()
         throws Exception
  {
    String path = TestCaseUtils.createTempFile(
         "dn: cn=schema",
         "changetype: modify",
         "add: objectClasses",
         "objectClasses:  ( testaddditcontentrulemultipleauxocnotauxoc-oid " +
              "NAME 'testAddDITContentRuleMultipleAuxOCNotAuxOC' SUP top " +
              "STRUCTURAL MUST cn X-ORIGIN 'SchemaBackendTestCase')",
         "-",
         "add: ditContentRules",
         "ditContentRules: ( testaddditcontentrulemultipleauxocnotaux-oid " +
              "NAME 'testAddDITContentRuleMultipleAuxOCNotAuxOC' " +
              "AUX ( posixAccount $ person ) " +
              "X-ORIGIN 'SchemaBackendTestCase' )");
    String[] args =
    {
      "-h", "127.0.0.1",
      "-p", String.valueOf(TestCaseUtils.getServerLdapPort()),
      "-D", "cn=Directory Manager",
      "-w", "password",
      "-f", path
    };
    assertFalse(LDAPModify.mainModify(args, false, null, null) == 0);
  }
  /**
   * Tests the behavior of the schema backend when attempting to add a new DIT
   * content rule with an auxiliary objectclass that is OBSOLETE.
   *
   * @throws  Exception  If an unexpected problem occurs.
   */
  @Test()
  public void testAddDITContentRuleObsoleteAuxOC()
         throws Exception
  {
    String path = TestCaseUtils.createTempFile(
         "dn: cn=schema",
         "changetype: modify",
         "add: objectClasses",
         "objectClasses:  ( testaddditcontentruleobsoleteauxstructural-oid " +
              "NAME 'testAddDITContentRuleObsoleteAuxOCStructural' SUP top " +
              "STRUCTURAL MUST cn X-ORIGIN 'SchemaBackendTestCase' )",
         "objectClasses:  ( testaddditcontentruleobsoleteauxauxiliary-oid " +
              "NAME 'testAddDITContentRuleObsoleteAuxOCAuxiliary' OBSOLETE " +
              "SUP top AUXILIARY MUST cn X-ORIGIN 'SchemaBackendTestCase' )",
         "-",
         "add: ditContentRules",
         "ditContentRules: ( testaddditcontentruleobsoleteauxstructural-oid " +
              "NAME 'testAddDITContentRuleObsoleteAuxOC' " +
              "AUX testAddDITContentRuleObsoleteAuxOCAuxiliary " +
              "X-ORIGIN 'SchemaBackendTestCase' )");
    String[] args =
    {
      "-h", "127.0.0.1",
      "-p", String.valueOf(TestCaseUtils.getServerLdapPort()),
      "-D", "cn=Directory Manager",
      "-w", "password",
      "-f", path
    };
    assertFalse(LDAPModify.mainModify(args, false, null, null) == 0);
  }
  /**
   * Tests the behavior of the schema backend when attempting to add a new DIT
   * content rule that references an undefined required attribute type.
   *
   * @throws  Exception  If an unexpected problem occurs.
@@ -2680,8 +3646,8 @@
         "changetype: modify",
         "add: objectClasses",
         "objectClasses:  ( testaddditcontentruleundefinedreqatoc-oid " +
              "NAME 'testAddDITContentRuleAuxiliaryOCOC' SUP top STRUCTURAL " +
              "MUST cn X-ORIGIN 'SchemaBackendTestCase')",
              "NAME 'testAddDITContentRuleUndefinedReqATOC' SUP top " +
              "STRUCTURAL MUST cn X-ORIGIN 'SchemaBackendTestCase')",
         "-",
         "add: ditContentRules",
         "ditContentRules: ( testaddditcontentruleundefinedreqatoc-oid " +
@@ -2704,6 +3670,45 @@
  /**
   * Tests the behavior of the schema backend when attempting to add a new DIT
   * content rule that references an undefined required attribute type when
   * multiple required attributes were provided.
   *
   * @throws  Exception  If an unexpected problem occurs.
   */
  @Test()
  public void testAddDITContentRuleMultipleUndefinedReqAT()
         throws Exception
  {
    String path = TestCaseUtils.createTempFile(
         "dn: cn=schema",
         "changetype: modify",
         "add: objectClasses",
         "objectClasses:  ( testaddditcontentrulemultundefinedreqatoc-oid " +
              "NAME 'testAddDITContentRuleMultUndefinedReqATOC' SUP top " +
              "STRUCTURAL MUST cn X-ORIGIN 'SchemaBackendTestCase')",
         "-",
         "add: ditContentRules",
         "ditContentRules: ( testaddditcontentrulemultundefinedreqatoc-oid " +
              "NAME 'testAddDITContentMultRuleUndefinedReqAT' " +
              "MUST ( cn $ xxxundefinedxxx ) " +
              "X-ORIGIN 'SchemaBackendTestCase' )");
    String[] args =
    {
      "-h", "127.0.0.1",
      "-p", String.valueOf(TestCaseUtils.getServerLdapPort()),
      "-D", "cn=Directory Manager",
      "-w", "password",
      "-f", path
    };
    assertFalse(LDAPModify.mainModify(args, false, null, null) == 0);
  }
  /**
   * Tests the behavior of the schema backend when attempting to add a new DIT
   * content rule that references an undefined optional attribute type.
   *
   * @throws  Exception  If an unexpected problem occurs.
@@ -2717,8 +3722,8 @@
         "changetype: modify",
         "add: objectClasses",
         "objectClasses:  ( testaddditcontentruleundefinedoptatoc-oid " +
              "NAME 'testAddDITContentRuleAuxiliaryOCOC' SUP top STRUCTURAL " +
              "MUST cn X-ORIGIN 'SchemaBackendTestCase')",
              "NAME 'testAddDITContentRuleUndefinedOptATOC' SUP top " +
              "STRUCTURAL MUST cn X-ORIGIN 'SchemaBackendTestCase')",
         "-",
         "add: ditContentRules",
         "ditContentRules: ( testaddditcontentruleundefinedoptatoc-oid " +
@@ -2741,6 +3746,45 @@
  /**
   * Tests the behavior of the schema backend when attempting to add a new DIT
   * content rule that references an undefined optional attribute type when
   * multiple optional attributes were provided.
   *
   * @throws  Exception  If an unexpected problem occurs.
   */
  @Test()
  public void testAddDITContentRuleMultipleUndefinedOptAT()
         throws Exception
  {
    String path = TestCaseUtils.createTempFile(
         "dn: cn=schema",
         "changetype: modify",
         "add: objectClasses",
         "objectClasses:  ( testaddditcontentrulemultundefinedoptatoc-oid " +
              "NAME 'testAddDITContentRuleMultUndefinedOptATOC' SUP top " +
              "STRUCTURAL MUST cn X-ORIGIN 'SchemaBackendTestCase')",
         "-",
         "add: ditContentRules",
         "ditContentRules: ( testaddditcontentrulemultundefinedoptatoc-oid " +
              "NAME 'testAddDITContentRuleMultUndefinedOptAT' " +
              "MAY ( cn $ xxxundefinedxxx ) " +
              "X-ORIGIN 'SchemaBackendTestCase' )");
    String[] args =
    {
      "-h", "127.0.0.1",
      "-p", String.valueOf(TestCaseUtils.getServerLdapPort()),
      "-D", "cn=Directory Manager",
      "-w", "password",
      "-f", path
    };
    assertFalse(LDAPModify.mainModify(args, false, null, null) == 0);
  }
  /**
   * Tests the behavior of the schema backend when attempting to add a new DIT
   * content rule that references an undefined prohibited attribute type.
   *
   * @throws  Exception  If an unexpected problem occurs.
@@ -2754,8 +3798,8 @@
         "changetype: modify",
         "add: objectClasses",
         "objectClasses:  ( testaddditcontentruleundefinednotatoc-oid " +
              "NAME 'testAddDITContentRuleAuxiliaryOCOC' SUP top STRUCTURAL " +
              "MUST cn X-ORIGIN 'SchemaBackendTestCase')",
              "NAME 'testAddDITContentRuleUndefinedNotATOC' SUP top " +
              "STRUCTURAL MUST cn X-ORIGIN 'SchemaBackendTestCase')",
         "-",
         "add: ditContentRules",
         "ditContentRules: ( testaddditcontentruleundefinednotatoc-oid " +
@@ -2777,6 +3821,250 @@
  /**
   * Tests the behavior of the schema backend when attempting to add a new DIT
   * content rule that references an undefined prohibited attribute type when
   * multiple prohibited attributes were provided.
   *
   * @throws  Exception  If an unexpected problem occurs.
   */
  @Test()
  public void testAddDITContentRuleMultipleUndefinedNotAT()
         throws Exception
  {
    String path = TestCaseUtils.createTempFile(
         "dn: cn=schema",
         "changetype: modify",
         "add: objectClasses",
         "objectClasses:  ( testaddditcontentrulemultundefinednotatoc-oid " +
              "NAME 'testAddDITContentRuleMultUndefinedNotATOC' SUP top " +
              "STRUCTURAL MUST cn X-ORIGIN 'SchemaBackendTestCase')",
         "-",
         "add: ditContentRules",
         "ditContentRules: ( testaddditcontentrulemultundefinednotatoc-oid " +
              "NAME 'testAddDITContentRuleMultUndefinedNotAT' " +
              "NOT ( description $ xxxundefinedxxx ) " +
              "X-ORIGIN 'SchemaBackendTestCase' )");
    String[] args =
    {
      "-h", "127.0.0.1",
      "-p", String.valueOf(TestCaseUtils.getServerLdapPort()),
      "-D", "cn=Directory Manager",
      "-w", "password",
      "-f", path
    };
    assertFalse(LDAPModify.mainModify(args, false, null, null) == 0);
  }
  /**
   * Tests the behavior of the schema backend when attempting to add a new DIT
   * content rule that prohibits an attribute type that is required by the
   * structural object class.
   *
   * @throws  Exception  If an unexpected problem occurs.
   */
  @Test()
  public void testAddDITContentRuleProhibitRequiredStructuralAttribute()
         throws Exception
  {
    String path = TestCaseUtils.createTempFile(
         "dn: cn=schema",
         "changetype: modify",
         "add: objectClasses",
         "objectClasses:  ( testadddcrprohibitreqstructuralatoc-oid " +
              "NAME 'testAddDCRProhibitReqStructuralATOC' SUP top " +
              "STRUCTURAL MUST cn X-ORIGIN 'SchemaBackendTestCase')",
         "-",
         "add: ditContentRules",
         "ditContentRules: ( testadddcrprohibitreqstructuralatoc-oid " +
              "NAME 'testAddDCRProhibitReqStructuralAT' " +
              "NOT cn X-ORIGIN 'SchemaBackendTestCase' )");
    String[] args =
    {
      "-h", "127.0.0.1",
      "-p", String.valueOf(TestCaseUtils.getServerLdapPort()),
      "-D", "cn=Directory Manager",
      "-w", "password",
      "-f", path
    };
    assertFalse(LDAPModify.mainModify(args, false, null, null) == 0);
  }
  /**
   * Tests the behavior of the schema backend when attempting to add a new DIT
   * content rule that prohibits an attribute type that is required by an
   * associated auxiliary object class.
   *
   * @throws  Exception  If an unexpected problem occurs.
   */
  @Test()
  public void testAddDITContentRuleProhibitRequiredAuxiliaryAttribute()
         throws Exception
  {
    String path = TestCaseUtils.createTempFile(
         "dn: cn=schema",
         "changetype: modify",
         "add: objectClasses",
         "objectClasses:  ( testadddcrprohibitreqauxiliaryatoc-oid " +
              "NAME 'testAddDCRProhibitReqAuxiliaryATOC' SUP top " +
              "STRUCTURAL MUST cn X-ORIGIN 'SchemaBackendTestCase')",
         "-",
         "add: ditContentRules",
         "ditContentRules: ( testadddcrprohibitreqauxiliaryatoc-oid " +
              "NAME 'testAddDCRProhibitReqAuxiliaryAT' AUX posixAccount " +
              "NOT uid X-ORIGIN 'SchemaBackendTestCase' )");
    String[] args =
    {
      "-h", "127.0.0.1",
      "-p", String.valueOf(TestCaseUtils.getServerLdapPort()),
      "-D", "cn=Directory Manager",
      "-w", "password",
      "-f", path
    };
    assertFalse(LDAPModify.mainModify(args, false, null, null) == 0);
  }
  /**
   * Tests the behavior of the schema backend when attempting to add a new DIT
   * content rule with an OBSOLETE required attribute type.
   *
   * @throws  Exception  If an unexpected problem occurs.
   */
  @Test()
  public void testAddDITContentRuleObsoleteRequiredAttributeType()
         throws Exception
  {
    String path = TestCaseUtils.createTempFile(
         "dn: cn=schema",
         "changetype: modify",
         "add: attributeTypes",
         "attributeTypes: ( testadddcrobsoletereqatat-oid " +
              "NAME 'testAddDCRObsoleteReqATAT' OBSOLETE " +
              "X-ORIGIN 'SchemaBackendTestCase' )",
         "-",
         "add: objectClasses",
         "objectClasses:  ( testadddcrobsoletereqatoc-oid " +
              "NAME 'testAddDCRObsoleteReqATOC' SUP top " +
              "STRUCTURAL MUST cn X-ORIGIN 'SchemaBackendTestCase')",
         "-",
         "add: ditContentRules",
         "ditContentRules: ( testadddcrobsoletereqatoc-oid " +
              "NAME 'testAddDCRObsoleteReqATDCR' " +
              "MUST testAddDCRObsoleteReqATAT " +
              "X-ORIGIN 'SchemaBackendTestCase' )");
    String[] args =
    {
      "-h", "127.0.0.1",
      "-p", String.valueOf(TestCaseUtils.getServerLdapPort()),
      "-D", "cn=Directory Manager",
      "-w", "password",
      "-f", path
    };
    assertFalse(LDAPModify.mainModify(args, false, null, null) == 0);
  }
  /**
   * Tests the behavior of the schema backend when attempting to add a new DIT
   * content rule with an OBSOLETE optional attribute type.
   *
   * @throws  Exception  If an unexpected problem occurs.
   */
  @Test()
  public void testAddDITContentRuleObsoleteOptionalAttributeType()
         throws Exception
  {
    String path = TestCaseUtils.createTempFile(
         "dn: cn=schema",
         "changetype: modify",
         "add: attributeTypes",
         "attributeTypes: ( testadddcrobsoleteoptatat-oid " +
              "NAME 'testAddDCRObsoleteOptATAT' OBSOLETE " +
              "X-ORIGIN 'SchemaBackendTestCase' )",
         "-",
         "add: objectClasses",
         "objectClasses:  ( testadddcrobsoleteoptatoc-oid " +
              "NAME 'testAddDCRObsoleteOptATOC' SUP top " +
              "STRUCTURAL MUST cn X-ORIGIN 'SchemaBackendTestCase')",
         "-",
         "add: ditContentRules",
         "ditContentRules: ( testadddcrobsoleteoptatoc-oid " +
              "NAME 'testAddDCRObsoleteOptATDCR' " +
              "MAY testAddDCRObsoleteOptATAT " +
              "X-ORIGIN 'SchemaBackendTestCase' )");
    String[] args =
    {
      "-h", "127.0.0.1",
      "-p", String.valueOf(TestCaseUtils.getServerLdapPort()),
      "-D", "cn=Directory Manager",
      "-w", "password",
      "-f", path
    };
    assertFalse(LDAPModify.mainModify(args, false, null, null) == 0);
  }
  /**
   * Tests the behavior of the schema backend when attempting to add a new DIT
   * content rule with an OBSOLETE prohibited attribute type.
   *
   * @throws  Exception  If an unexpected problem occurs.
   */
  @Test()
  public void testAddDITContentRuleObsoleteProhibitedAttributeType()
         throws Exception
  {
    String path = TestCaseUtils.createTempFile(
         "dn: cn=schema",
         "changetype: modify",
         "add: attributeTypes",
         "attributeTypes: ( testadddcrobsoletenotatat-oid " +
              "NAME 'testAddDCRObsoleteNotATAT' OBSOLETE " +
              "X-ORIGIN 'SchemaBackendTestCase' )",
         "-",
         "add: objectClasses",
         "objectClasses:  ( testadddcrobsoletenotatoc-oid " +
              "NAME 'testAddDCRObsoleteNotATOC' SUP top " +
              "STRUCTURAL MUST cn X-ORIGIN 'SchemaBackendTestCase')",
         "-",
         "add: ditContentRules",
         "ditContentRules: ( testadddcrobsoletenotatoc-oid " +
              "NAME 'testAddDCRObsoleteNotATDCR' " +
              "NOT testAddDCRObsoleteNotATAT " +
              "X-ORIGIN 'SchemaBackendTestCase' )");
    String[] args =
    {
      "-h", "127.0.0.1",
      "-p", String.valueOf(TestCaseUtils.getServerLdapPort()),
      "-D", "cn=Directory Manager",
      "-w", "password",
      "-f", path
    };
    assertFalse(LDAPModify.mainModify(args, false, null, null) == 0);
  }
  /**
   * Tests the behavior of the schema backend when attempting to remove an
   * existing DIT content rule.
   *
@@ -3141,6 +4429,105 @@
  /**
   * Tests the behavior of the schema backend when attempting to add a new
   * DIT structure rule that references a name form which is OBSOLETE.
   *
   * @throws  Exception  If an unexpected problem occurs.
   */
  @Test()
  public void testAddDITStructureRuleObsoleteNameForm()
         throws Exception
  {
    String path = TestCaseUtils.createTempFile(
         "dn: cn=schema",
         "changetype: modify",
         "add: objectClasses",
         "objectClasses:  ( testaddditstructureruleobsoletenameformoc-oid " +
              "NAME 'testAddDITStructureRuleObsoleteNameFormOC' SUP top " +
              "STRUCTURAL MUST cn X-ORIGIN 'SchemaBackendTestCase')",
         "-",
         "add: nameForms",
         "nameForms: ( testaddditstructureruleobsoletenameformnf-oid " +
              "NAME 'testAddDITStructureRuleObsoleteNameFormNF' OBSOLETE " +
              "OC testAddDITStructureRuleObsoleteNameFormOC MUST cn " +
              "X-ORIGIN 'SchemaBackendTestCase' )",
         "-",
         "add: ditStructureRules",
         "ditStructureRules: ( 999011 " +
              "NAME 'testAddDITStructureRuleObsoleteNameForm' " +
              "FORM testAddDITStructureRuleObsoleteNameFormNF " +
              "X-ORIGIN 'SchemaBackendTestCase' )");
    String[] args =
    {
      "-h", "127.0.0.1",
      "-p", String.valueOf(TestCaseUtils.getServerLdapPort()),
      "-D", "cn=Directory Manager",
      "-w", "password",
      "-f", path
    };
    assertFalse(LDAPModify.mainModify(args, false, null, null) == 0);
  }
  /**
   * Tests the behavior of the schema backend when attempting to add a new
   * DIT structure rule that references a superior rule which is OBSOLETE.
   *
   * @throws  Exception  If an unexpected problem occurs.
   */
  @Test()
  public void testAddDITStructureRuleObsoleteSuperiorRule()
         throws Exception
  {
    String path = TestCaseUtils.createTempFile(
         "dn: cn=schema",
         "changetype: modify",
         "add: objectClasses",
         "objectClasses:  ( testaddditstructureruleobsoletesuperioroc1-oid " +
              "NAME 'testAddDITStructureRuleObsoleteSuperiorOC1' SUP top " +
              "STRUCTURAL MUST cn X-ORIGIN 'SchemaBackendTestCase')",
         "objectClasses:  ( testaddditstructureruleobsoletesuperioroc2-oid " +
              "NAME 'testAddDITStructureRuleObsoleteSuperiorOC2' SUP top " +
              "STRUCTURAL MUST cn X-ORIGIN 'SchemaBackendTestCase')",
         "-",
         "add: nameForms",
         "nameForms: ( testaddditstructureruleobsoletesuperiornf1-oid " +
              "NAME 'testAddDITStructureRuleObsoleteSuperiorNF1' " +
              "OC testAddDITStructureRuleObsoleteSuperiorOC1 MUST cn " +
              "X-ORIGIN 'SchemaBackendTestCase' )",
         "nameForms: ( testaddditstructureruleobsoletesuperiornf2-oid " +
              "NAME 'testAddDITStructureRuleObsoleteSuperiorNF2' " +
              "OC testAddDITStructureRuleObsoleteSuperiorOC2 MUST cn " +
              "X-ORIGIN 'SchemaBackendTestCase' )",
         "-",
         "add: ditStructureRules",
         "ditStructureRules: ( 999012 " +
              "NAME 'testAddDITStructureRuleObsoleteSuperiorSup' OBSOLETE " +
              "FORM testAddDITStructureRuleObsoleteSuperiorNF1 " +
              "X-ORIGIN 'SchemaBackendTestCase' )",
         "ditStructureRules: ( 999013 " +
              "NAME 'testAddDITStructureRuleObsoleteSuperiorSub' " +
              "FORM testAddDITStructureRuleObsoleteSuperiorNF2 SUP 999012 " +
              "X-ORIGIN 'SchemaBackendTestCase' )");
    String[] args =
    {
      "-h", "127.0.0.1",
      "-p", String.valueOf(TestCaseUtils.getServerLdapPort()),
      "-D", "cn=Directory Manager",
      "-w", "password",
      "-f", path
    };
    assertFalse(LDAPModify.mainModify(args, false, null, null) == 0);
  }
  /**
   * Tests the behavior of the schema backend when attempting to remove an
   * existing DIT structure rule definition.
   *
@@ -3623,6 +5010,132 @@
  /**
   * Tests the behavior of the schema backend when attempting to add a new
   * matching rule use that references an undefined attribute type.
   *
   * @throws  Exception  If an unexpected problem occurs.
   */
  @Test()
  public void testAddMatchingRuleUseAttributeTypeMultipleUndefined()
         throws Exception
  {
    SchemaTestMatchingRule matchingRule =
         new SchemaTestMatchingRule("testAddMRUATMultipleUndefinedMatch",
                                    "1.3.6.1.4.1.26027.1.999.19");
    DirectoryServer.registerMatchingRule(matchingRule, false);
    String path = TestCaseUtils.createTempFile(
         "dn: cn=schema",
         "changetype: modify",
         "add: matchingRuleUse",
         "matchingRuleUse: ( 1.3.6.1.4.1.26027.1.999.19 " +
              "NAME 'testAddMatchingRuleUseATMultipleUndefined' " +
              "APPLIES ( cn $ xxxundefinedxxx ) " +
              "X-ORIGIN 'SchemaBackendTestCase' )");
    assertFalse(DirectoryServer.getSchema().hasMatchingRuleUse(matchingRule));
    String[] args =
    {
      "-h", "127.0.0.1",
      "-p", String.valueOf(TestCaseUtils.getServerLdapPort()),
      "-D", "cn=Directory Manager",
      "-w", "password",
      "-f", path
    };
    assertFalse(LDAPModify.mainModify(args, false, null, null) == 0);
  }
  /**
   * Tests the behavior of the schema backend when attempting to add a new
   * matching rule whose matching rule is OBSOLETE.
   *
   * @throws  Exception  If an unexpected problem occurs.
   */
  @Test()
  public void testAddMatchingRuleUseObsoleteMatchingRule()
         throws Exception
  {
    SchemaTestMatchingRule matchingRule =
         new SchemaTestMatchingRule("testAddMRUObsoleteMRMatch",
                                    "1.3.6.1.4.1.26027.1.999.21", true);
    DirectoryServer.registerMatchingRule(matchingRule, false);
    String path = TestCaseUtils.createTempFile(
         "dn: cn=schema",
         "changetype: modify",
         "add: matchingRuleUse",
         "matchingRuleUse: ( 1.3.6.1.4.1.26027.1.999.21 " +
              "NAME 'testAddMatchingRuleUseObsoleteMatchingRule' " +
              "APPLIES cn X-ORIGIN 'SchemaBackendTestCase' )");
    assertFalse(DirectoryServer.getSchema().hasMatchingRuleUse(matchingRule));
    String[] args =
    {
      "-h", "127.0.0.1",
      "-p", String.valueOf(TestCaseUtils.getServerLdapPort()),
      "-D", "cn=Directory Manager",
      "-w", "password",
      "-f", path
    };
    assertFalse(LDAPModify.mainModify(args, false, null, null) == 0);
  }
  /**
   * Tests the behavior of the schema backend when attempting to add a new
   * matching rule with an associated attribute type that is marked OBSOLETE.
   *
   * @throws  Exception  If an unexpected problem occurs.
   */
  @Test()
  public void testAddMatchingRuleUseObsoleteAttributeType()
         throws Exception
  {
    SchemaTestMatchingRule matchingRule =
         new SchemaTestMatchingRule("testAddMRUObsoleteATMatch",
                                    "1.3.6.1.4.1.26027.1.999.22");
    DirectoryServer.registerMatchingRule(matchingRule, false);
    String path = TestCaseUtils.createTempFile(
         "dn: cn=schema",
         "changetype: modify",
         "add: attributeTypes",
         "attributeTypes: ( testaddmruobsoleteat-oid " +
              "NAME 'testAddMRUObsoleteAT' OBSOLETE )",
         "-",
         "add: matchingRuleUse",
         "matchingRuleUse: ( 1.3.6.1.4.1.26027.1.999.22 " +
              "NAME 'testAddMatchingRuleUseObsoleteAttributeType' " +
              "APPLIES testAddMRUObsoleteAT " +
              "X-ORIGIN 'SchemaBackendTestCase' )");
    assertFalse(DirectoryServer.getSchema().hasMatchingRuleUse(matchingRule));
    String[] args =
    {
      "-h", "127.0.0.1",
      "-p", String.valueOf(TestCaseUtils.getServerLdapPort()),
      "-D", "cn=Directory Manager",
      "-w", "password",
      "-f", path
    };
    assertFalse(LDAPModify.mainModify(args, false, null, null) == 0);
  }
  /**
   * Tests the behavior of the schema backend when attempting to remove an
   * existing matching rule use.
   *
opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/backends/SchemaTestMatchingRule.java
@@ -47,6 +47,9 @@
public class SchemaTestMatchingRule
       extends EqualityMatchingRule
{
  // Indicates whether this matching rule should be considered OBSOLETE.
  private boolean isObsolete;
  // The matching rule that will do all the real work behind the scenes.
  private CaseIgnoreEqualityMatchingRule caseIgnoreMatchingRule;
@@ -76,6 +79,32 @@
    caseIgnoreMatchingRule = new CaseIgnoreEqualityMatchingRule();
    caseIgnoreMatchingRule.initializeMatchingRule(null);
    isObsolete = false;
  }
  /**
   * Creates a new instance of this matching rule with the provided information.
   *
   * @param  name        The name to use for this matching rule.
   * @param  oid         The OID to use for this matching rule.
   * @param  isObsolete  Indicates whether this matching rule should be marked
   *                     OBSOLETE.
   *
   * @throws  Exception  If an unexpected problem occurs.
   */
  public SchemaTestMatchingRule(String name, String oid, boolean isObsolete)
         throws Exception
  {
    super();
    this.name       = name;
    this.oid        = oid;
    this.isObsolete = isObsolete;
    caseIgnoreMatchingRule = new CaseIgnoreEqualityMatchingRule();
    caseIgnoreMatchingRule.initializeMatchingRule(null);
  }
@@ -154,6 +183,16 @@
  /**
   * {@inheritDoc}
   */
  public boolean isObsolete()
  {
    return isObsolete;
  }
  /**
   * Retrieves the normalized form of the provided value, which is best suited
   * for efficiently performing matching operations on that value.
   *
opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/core/AddOperationTestCase.java
@@ -53,6 +53,7 @@
import org.opends.server.protocols.ldap.BindResponseProtocolOp;
import org.opends.server.protocols.ldap.LDAPAttribute;
import org.opends.server.protocols.ldap.LDAPMessage;
import org.opends.server.tools.LDAPModify;
import org.opends.server.types.Attribute;
import org.opends.server.types.AttributeType;
import org.opends.server.types.AttributeValue;
@@ -2271,5 +2272,180 @@
      s.close();
    } catch (Exception e) {}
  }
  /**
   * Tests an add operation that attempts to add an entry with a user attribute
   * marked OBSOLETE in the server schema.
   *
   * @throws  Exception  If an unexpected problem occurs.
   */
  @Test()
  public void testAddObsoleteUserAttribute()
         throws Exception
  {
    TestCaseUtils.initializeTestBackend(false);
    String path = TestCaseUtils.createTempFile(
         "dn: cn=schema",
         "changetype: modify",
         "add: attributeTypes",
         "attributeTypes: ( testaddobsoleteuserattribute-oid " +
              "NAME 'testAddObsoleteUserAttribute' OBSOLETE " +
              "SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE " +
              "X-ORGIN 'SchemaBackendTestCase' )");
    String attrName = "testaddobsoleteuserattribute";
    assertFalse(DirectoryServer.getSchema().hasAttributeType(attrName));
    String[] args =
    {
      "-h", "127.0.0.1",
      "-p", String.valueOf(TestCaseUtils.getServerLdapPort()),
      "-D", "cn=Directory Manager",
      "-w", "password",
      "-f", path
    };
    assertEquals(LDAPModify.mainModify(args, false, null, System.err), 0);
    assertTrue(DirectoryServer.getSchema().hasAttributeType(attrName));
    path = TestCaseUtils.createTempFile(
         "dn: o=test",
         "changetype: add",
         "objectClass: top",
         "objectClass: organization",
         "objectClass: extensibleObject",
         "o: test",
         "testAddObsoleteUserAttribute: foo");
    args = new String[]
    {
      "-h", "127.0.0.1",
      "-p", String.valueOf(TestCaseUtils.getServerLdapPort()),
      "-D", "cn=Directory Manager",
      "-w", "password",
      "-f", path
    };
    assertFalse(LDAPModify.mainModify(args, false, null, null) == 0);
  }
  /**
   * Tests an add operation that attempts to add an entry with an operational
   * attribute marked OBSOLETE in the server schema.
   *
   * @throws  Exception  If an unexpected problem occurs.
   */
  @Test()
  public void testAddObsoleteOperationalAttribute()
         throws Exception
  {
    TestCaseUtils.initializeTestBackend(false);
    String path = TestCaseUtils.createTempFile(
         "dn: cn=schema",
         "changetype: modify",
         "add: attributeTypes",
         "attributeTypes: ( testaddobsoleteoperationalattribute-oid " +
              "NAME 'testAddObsoleteOperationalAttribute' OBSOLETE " +
              "SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE " +
              "USAGE directoryOperation X-ORGIN 'SchemaBackendTestCase' )");
    String attrName = "testaddobsoleteoperationalattribute";
    assertFalse(DirectoryServer.getSchema().hasAttributeType(attrName));
    String[] args =
    {
      "-h", "127.0.0.1",
      "-p", String.valueOf(TestCaseUtils.getServerLdapPort()),
      "-D", "cn=Directory Manager",
      "-w", "password",
      "-f", path
    };
    assertEquals(LDAPModify.mainModify(args, false, null, System.err), 0);
    assertTrue(DirectoryServer.getSchema().hasAttributeType(attrName));
    path = TestCaseUtils.createTempFile(
         "dn: o=test",
         "changetype: add",
         "objectClass: top",
         "objectClass: organization",
         "objectClass: extensibleObject",
         "o: test",
         "testAddObsoleteOperationalAttribute: foo");
    args = new String[]
    {
      "-h", "127.0.0.1",
      "-p", String.valueOf(TestCaseUtils.getServerLdapPort()),
      "-D", "cn=Directory Manager",
      "-w", "password",
      "-f", path
    };
    assertFalse(LDAPModify.mainModify(args, false, null, null) == 0);
  }
  /**
   * Tests an add operation that attempts to add an entry with an auxiliary
   * objectclass marked OBSOLETE in the server schema.
   *
   * @throws  Exception  If an unexpected problem occurs.
   */
  @Test()
  public void testAddObsoleteObjectClass()
         throws Exception
  {
    TestCaseUtils.initializeTestBackend(false);
    String path = TestCaseUtils.createTempFile(
         "dn: cn=schema",
         "changetype: modify",
         "add: objectClasses",
         "objectClasses: ( testaddobsoleteobjectclass-oid " +
              "NAME 'testAddObsoleteObjectClass' OBSOLETE AUXILIARY " +
              "MAY description X-ORGIN 'SchemaBackendTestCase' )");
    String ocName = "testaddobsoleteobjectclass";
    assertFalse(DirectoryServer.getSchema().hasObjectClass(ocName));
    String[] args =
    {
      "-h", "127.0.0.1",
      "-p", String.valueOf(TestCaseUtils.getServerLdapPort()),
      "-D", "cn=Directory Manager",
      "-w", "password",
      "-f", path
    };
    assertEquals(LDAPModify.mainModify(args, false, null, System.err), 0);
    assertTrue(DirectoryServer.getSchema().hasObjectClass(ocName));
    path = TestCaseUtils.createTempFile(
         "dn: o=test",
         "changetype: add",
         "objectClass: top",
         "objectClass: organization",
         "objectClass: testAddObsoleteObjectClass",
         "o: test");
    args = new String[]
    {
      "-h", "127.0.0.1",
      "-p", String.valueOf(TestCaseUtils.getServerLdapPort()),
      "-D", "cn=Directory Manager",
      "-w", "password",
      "-f", path
    };
    assertFalse(LDAPModify.mainModify(args, false, null, null) == 0);
  }
}
opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/core/ModifyOperationTestCase.java
@@ -55,6 +55,7 @@
import org.opends.server.protocols.ldap.LDAPMessage;
import org.opends.server.protocols.ldap.LDAPModification;
import org.opends.server.protocols.ldap.LDAPFilter;
import org.opends.server.tools.LDAPModify;
import org.opends.server.types.*;
import static org.testng.Assert.*;
@@ -4384,5 +4385,122 @@
    } catch (Exception e) {}
  }
  /**
   * Tests a modify operation that attemtps to set a value for an attribute type
   * that is marked OBSOLETE in the server schema.
   *
   * @param  baseDN  The base DN for the test backend.
   *
   * @throws  Exception  If an unexpected problem occurs.
   */
  @Test(dataProvider = "baseDNs")
  public void testModifyObsoleteAttribute(String baseDN)
         throws Exception
  {
    String path = TestCaseUtils.createTempFile(
         "dn: cn=schema",
         "changetype: modify",
         "add: attributeTypes",
         "attributeTypes: ( testmodifyobsoleteattribute-oid " +
              "NAME 'testModifyObsoleteAttribute' OBSOLETE " +
              "SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE " +
              "X-ORGIN 'SchemaBackendTestCase' )");
    String attrName = "testmodifyobsoleteattribute";
    assertFalse(DirectoryServer.getSchema().hasAttributeType(attrName));
    String[] args =
    {
      "-h", "127.0.0.1",
      "-p", String.valueOf(TestCaseUtils.getServerLdapPort()),
      "-D", "cn=Directory Manager",
      "-w", "password",
      "-f", path
    };
    assertEquals(LDAPModify.mainModify(args, false, null, System.err), 0);
    assertTrue(DirectoryServer.getSchema().hasAttributeType(attrName));
    TestCaseUtils.clearJEBackend(true,"userRoot",baseDN);
    path = TestCaseUtils.createTempFile(
         "dn: " + baseDN,
         "changetype: modify",
         "add: objectClass",
         "objectClass: extensibleObject",
         "-",
         "replace: testModifyObsoleteAttribute",
         "testModifyObsoleteAttribute: foo");
    args = new String[]
    {
      "-h", "127.0.0.1",
      "-p", String.valueOf(TestCaseUtils.getServerLdapPort()),
      "-D", "cn=Directory Manager",
      "-w", "password",
      "-f", path
    };
    assertFalse(LDAPModify.mainModify(args, false, null, null) == 0);
  }
  /**
   * Tests a modify operation that attemtps to add an OBSOLETE object class to
   * an entry.
   *
   * @param  baseDN  The base DN for the test backend.
   *
   * @throws  Exception  If an unexpected problem occurs.
   */
  @Test(dataProvider = "baseDNs")
  public void testModifyAddObsoleteObjectClass(String baseDN)
         throws Exception
  {
    String path = TestCaseUtils.createTempFile(
         "dn: cn=schema",
         "changetype: modify",
         "add: objectClasses",
         "objectClasses: ( testmodifyaddobsoleteobjectclass-oid " +
              "NAME 'testModifyAddObsoleteObjectClass' OBSOLETE " +
              "AUXILIARY MAY description X-ORGIN 'SchemaBackendTestCase' )");
    String ocName = "testmodifyaddobsoleteobjectclass";
    assertFalse(DirectoryServer.getSchema().hasObjectClass(ocName));
    String[] args =
    {
      "-h", "127.0.0.1",
      "-p", String.valueOf(TestCaseUtils.getServerLdapPort()),
      "-D", "cn=Directory Manager",
      "-w", "password",
      "-f", path
    };
    assertEquals(LDAPModify.mainModify(args, false, null, System.err), 0);
    assertTrue(DirectoryServer.getSchema().hasObjectClass(ocName));
    TestCaseUtils.clearJEBackend(true,"userRoot",baseDN);
    path = TestCaseUtils.createTempFile(
         "dn: " + baseDN,
         "changetype: modify",
         "add: objectClass",
         "objectClass: testModifyAddObsoleteObjectClass");
    args = new String[]
    {
      "-h", "127.0.0.1",
      "-p", String.valueOf(TestCaseUtils.getServerLdapPort()),
      "-D", "cn=Directory Manager",
      "-w", "password",
      "-f", path
    };
    assertFalse(LDAPModify.mainModify(args, false, null, null) == 0);
  }
}
opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/core/TestModifyDNOperation.java
@@ -45,6 +45,7 @@
import org.opends.server.controls.LDAPAssertionRequestControl;
import org.opends.server.plugins.InvocationCounterPlugin;
import org.opends.server.plugins.ShortCircuitPlugin;
import org.opends.server.tools.LDAPModify;
import java.util.ArrayList;
import java.util.List;
@@ -1208,4 +1209,69 @@
    }
  }
  /**
   * Tests performing a modify DN operation in which the new RDN contains an
   * attribute type marked OBSOLETE in the server schema.
   *
   * @throws  Exception  If an unexpected problem occurs.
   */
  @Test()
  public void testModifyDNWithObsoleteAttribute()
         throws Exception
  {
    TestCaseUtils.initializeTestBackend(true);
    String path = TestCaseUtils.createTempFile(
         "dn: cn=schema",
         "changetype: modify",
         "add: attributeTypes",
         "attributeTypes: ( testmodifydnwithobsoleteattribute-oid " +
              "NAME 'testModifyDNWithObsoleteAttribute' OBSOLETE " +
              "SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE " +
              "X-ORGIN 'SchemaBackendTestCase' )");
    String attrName = "testmodifydnwithobsoleteattribute";
    assertFalse(DirectoryServer.getSchema().hasAttributeType(attrName));
    String[] args =
    {
      "-h", "127.0.0.1",
      "-p", String.valueOf(TestCaseUtils.getServerLdapPort()),
      "-D", "cn=Directory Manager",
      "-w", "password",
      "-f", path
    };
    assertEquals(LDAPModify.mainModify(args, false, null, System.err), 0);
    assertTrue(DirectoryServer.getSchema().hasAttributeType(attrName));
    path = TestCaseUtils.createTempFile(
         "dn: cn=oldrdn,o=test",
         "changetype: add",
         "objectClass: top",
         "objectClass: device",
         "objectClass: extensibleObject",
         "cn: oldrdn",
         "",
         "dn: cn=oldrdn,o=test",
         "changetype: moddn",
         "newRDN: testModifyDNWithObsoleteAttribute=foo",
         "deleteOldRDN: 0"
    );
    args = new String[]
    {
      "-h", "127.0.0.1",
      "-p", String.valueOf(TestCaseUtils.getServerLdapPort()),
      "-D", "cn=Directory Manager",
      "-w", "password",
      "-f", path
    };
    assertFalse(LDAPModify.mainModify(args, false, null, null) == 0);
}
}
opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/schema/AttributeTypeSyntaxTest.java
@@ -61,14 +61,46 @@
  public Object[][] createAcceptableValues()
  {
    return new Object [][] {
        {"(1.2.8.5 NAME 'testtype' DESC 'full type' OBSOLETE SUP 1.2" +
          " EQUALITY 2.3 ORDERING 5.6 SUBSTR 7.8 SYNTAX 9.1 SINGLE-VALUE" +
          " COLLECTIVE NO-USER-MODIFICATION USAGE directoryOperations )",
        {"(1.2.8.5 NAME 'testtype' DESC 'full type' OBSOLETE SUP cn " +
          " EQUALITY caseIgnoreMatch ORDERING caseIgnoreOrderingMatch" +
          " SUBSTR caseIgnoreSubstringsMatch" +
          " SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE" +
          " USAGE userApplications )",
          true},
        {"(1.2.8.5 NAME 'testtype' DESC 'full type' OBSOLETE " +
          " EQUALITY caseIgnoreMatch ORDERING caseIgnoreOrderingMatch" +
          " SUBSTR caseIgnoreSubstringsMatch" +
          " SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE" +
          " COLLECTIVE USAGE userApplications )",
          true},
        {"(1.2.8.5 NAME 'testtype' DESC 'full type')",
              true},
        {"(1.2.8.5 USAGE directoryOperations )",
        {"(1.2.8.5 USAGE directoryOperation )",
              true},
        {"(1.2.8.5 NAME 'testtype' DESC 'full type' OBSOLETE SUP cn " +
          " EQUALITY caseIgnoreMatch ORDERING caseIgnoreOrderingMatch" +
          " SUBSTR caseIgnoreSubstringsMatch" +
          " SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE" +
          " COLLECTIVE USAGE userApplications )",
          false}, // Collective can't inherit from non-collective
        {"(1.2.8.5 NAME 'testtype' DESC 'full type' OBSOLETE " +
          " EQUALITY caseIgnoreMatch ORDERING caseIgnoreOrderingMatch" +
          " SUBSTR caseIgnoreSubstringsMatch" +
          " SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE" +
          " COLLECTIVE USAGE directoryOperation )",
          false}, // Collective can't be operational
        {"(1.2.8.5 NAME 'testtype' DESC 'full type' OBSOLETE SUP cn " +
          " EQUALITY caseIgnoreMatch ORDERING caseIgnoreOrderingMatch" +
          " SUBSTR caseIgnoreSubstringsMatch" +
          " SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE" +
          " NO-USER-MODIFICATION USAGE directoryOperation )",
          false}, // directoryOperation can't inherit from userApplications
        {"(1.2.8.5 NAME 'testtype' DESC 'full type' OBSOLETE " +
          " EQUALITY caseIgnoreMatch ORDERING caseIgnoreOrderingMatch" +
          " SUBSTR caseIgnoreSubstringsMatch" +
          " SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE" +
          " NO-USER-MODIFICATION USAGE userApplications )",
          false}, // NO-USER-MODIFICATION can't have non-operational usage
    };
  }
@@ -113,7 +145,8 @@
    // correct approximate matching rule.
    AttributeType attrType =
         AttributeTypeSyntax.decodeAttributeType(definition,
                                                 DirectoryServer.getSchema());
                                                 DirectoryServer.getSchema(),
                                                 false);
    assertNotNull(attrType);
    assertNotNull(attrType.getApproximateMatchingRule());
    assertEquals(attrType.getApproximateMatchingRule(), testApproxRule);
opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/schema/DITContentRuleSyntaxTest.java
@@ -53,21 +53,21 @@
             + "( x121Address $ telexNumber ) )", true},
        {"( 2.5.6.4 NAME 'full rule' DESC 'rule with all possible fields' "
              + " OBSOLETE"
              + " AUX ( person )"
              + " AUX ( posixAccount )"
              + " MUST ( cn $ sn )"
              + " MAY ( dc )"
              + " NOT ( x121Address $ telexNumber ) )"
                , true},
        {"( 2.5.6.4 NAME 'full rule' DESC 'ommit parenthesis' "
                  + " OBSOLETE"
                  + " AUX person "
                  + " AUX posixAccount "
                  + " MUST cn "
                  + " MAY dc "
                  + " NOT x121Address )"
              , true},
         {"( 2.5.6.4 NAME 'full rule' DESC 'use numeric OIDs' "
                + " OBSOLETE"
                + " AUX 2.5.6.6"
                + " AUX 1.3.6.1.1.1.2.0"
                + " MUST cn "
                + " MAY dc "
                + " NOT x121Address )"
@@ -88,7 +88,7 @@
                 , false},
         {"( 2.5.6.4 NAME 'full rule' DESC 'missing closing parenthesis' "
                 + " OBSOLETE"
                 + " AUX person "
                 + " AUX posixAccount"
                 + " MUST cn "
                 + " MAY dc "
                 + " NOT x121Address"
opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/types/EntrySchemaCheckingTestCase.java
New file
@@ -0,0 +1,1433 @@
/*
 * 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.LinkedHashSet;
import java.util.LinkedList;
import org.testng.annotations.Test;
import org.opends.server.TestCaseUtils;
import org.opends.server.core.DirectoryServer;
import org.opends.server.tools.LDAPModify;
import org.opends.server.types.Attribute;
import org.opends.server.types.AttributeType;
import org.opends.server.types.AttributeValue;
import static org.testng.Assert.*;
import static org.opends.server.types.AcceptRejectWarn.*;
/**
 * This class provides a set of test cases that cover the schema validation
 * processing that should be performed on entries during add, modify, and
 * modify DN operations.
 */
public class EntrySchemaCheckingTestCase
       extends TypesTestCase
{
  /**
   * Ensures that the provided entry fails schema checking validation with
   * strict compliance enabled, but will pass in a more relaxed configuration.
   *
   * @param  e  The entry to be tested.
   */
  private void failOnlyForStrictEvaluation(Entry e)
  {
    try
    {
      StringBuilder invalidReason = new StringBuilder();
      DirectoryServer.setSingleStructuralObjectClassPolicy(REJECT);
      assertFalse(e.conformsToSchema(null, false, true, true, invalidReason),
                  "Entry validation succeeded with REJECT policy");
      DirectoryServer.setSingleStructuralObjectClassPolicy(WARN);
      assertTrue(e.conformsToSchema(null, false, true, true, invalidReason),
                 "Entry validation failed with WARN policy:  " +
                 invalidReason.toString());
      DirectoryServer.setSingleStructuralObjectClassPolicy(ACCEPT);
      assertTrue(e.conformsToSchema(null, false, true, true, invalidReason),
                 "Entry validation failed with ACCEPT policy:  " +
                 invalidReason.toString());
    }
    finally
    {
      DirectoryServer.setSingleStructuralObjectClassPolicy(REJECT);
    }
  }
  /**
   * Tests schema checking for an entry with a valid single structural
   * objectclass.
   *
   * @throws  Exception  If an unexpected problem occurs.
   */
  @Test()
  public void testValidSingleStructuralClass()
         throws Exception
  {
    Entry e = TestCaseUtils.makeEntry(
         "dn: dc=example,dc=com",
         "objectClass: top",
         "objectClass: domain",
         "dc: example");
    StringBuilder invalidReason = new StringBuilder();
    assertTrue(e.conformsToSchema(null, true, true, true, invalidReason),
               invalidReason.toString());
  }
  /**
   * Tests schema checking for an entry (not covered by a DIT content rule)
   * with a valid single structural objectclass as well as an auxiliary
   * objectclass.
   *
   * @throws  Exception  If an unexpected problem occurs.
   */
  @Test()
  public void testValidSingleStructuralClassAndAuxiliaryClass()
         throws Exception
  {
    Entry e = TestCaseUtils.makeEntry(
         "dn: dc=example,dc=com",
         "objectClass: top",
         "objectClass: organization",
         "objectClass: dcObject",
         "dc: example",
         "o: Example Org");
    StringBuilder invalidReason = new StringBuilder();
    assertTrue(e.conformsToSchema(null, true, true, true, invalidReason),
               invalidReason.toString());
  }
  /**
   * Tests schema checking for an entry that does not contain a structural
   * objectclass.
   *
   * @throws  Exception  If an unexpected problem occurs.
   */
  @Test()
  public void testNoStructuralClass()
         throws Exception
  {
    Entry e = TestCaseUtils.makeEntry(
         "dn: dc=example,dc=com",
         "objectClass: top",
         "objectClass: dcObject",
         "dc: example");
    failOnlyForStrictEvaluation(e);
  }
  /**
   * Tests schema checking for an entry that contains multiple structural
   * objectclasses.
   *
   * @throws  Exception  If an unexpected problem occurs.
   */
  @Test()
  public void testMultipleStructuralClasses()
         throws Exception
  {
    TestCaseUtils.initializeTestBackend(true);
    Entry e = TestCaseUtils.makeEntry(
         "dn: uid=test.user,o=test",
         "objectClass: top",
         "objectClass: person",
         "objectClass: organizationalPerson",
         "objectClass: inetOrgPerson",
         "objectClass: account",
         "uid: test.user",
         "givenName: Test",
         "sn: User",
         "cn: Test User");
    failOnlyForStrictEvaluation(e);
  }
  /**
   * Tests schema checking for an entry that contains an undefined objectclass
   * with no other structural class.
   *
   * @throws  Exception  If an unexpected problem occurs.
   */
  @Test()
  public void testUndefinedStructuralObjectClass()
         throws Exception
  {
    TestCaseUtils.initializeTestBackend(true);
    Entry e = TestCaseUtils.makeEntry(
         "dn: cn=test,o=test",
         "objectClass: top",
         "objectClass: xxxundefinedstructuralxxx",
         "cn: test");
    assertFalse(e.conformsToSchema(null, false, true, true,
                                   new StringBuilder()));
  }
  /**
   * Tests schema checking for an entry that contains an undefined objectclass
   * as well as a valid structural class.
   *
   * @throws  Exception  If an unexpected problem occurs.
   */
  @Test()
  public void testUndefinedAuxiliaryObjectClass()
         throws Exception
  {
    TestCaseUtils.initializeTestBackend(true);
    Entry e = TestCaseUtils.makeEntry(
         "dn: cn=test,o=test",
         "objectClass: top",
         "objectClass: device",
         "objectClass: xxxundefinedauxiliaryxxx",
         "cn: test");
    assertFalse(e.conformsToSchema(null, false, true, true,
                                   new StringBuilder()));
  }
  /**
   * Tests schema checking for an entry that is missing an attribute required
   * by its structural object class.
   *
   * @throws  Exception  If an unexpected problem occurs.
   */
  @Test()
  public void testMissingAttributeRequiredByStructuralClass()
         throws Exception
  {
    TestCaseUtils.initializeTestBackend(true);
    String path = TestCaseUtils.createTempFile(
         "dn: cn=schema",
         "changetype: modify",
         "add: objectClasses",
         "objectClasses:  ( testmissingatrequiredbystructuraloc-oid " +
              "NAME 'testMissingATRequiredByStructuralOC' SUP top STRUCTURAL " +
              "MUST ( cn $ description ) " +
              "X-ORIGIN 'EntrySchemaCheckingTestCase')");
    String[] args =
    {
      "-h", "127.0.0.1",
      "-p", String.valueOf(TestCaseUtils.getServerLdapPort()),
      "-D", "cn=Directory Manager",
      "-w", "password",
      "-f", path
    };
    assertEquals(LDAPModify.mainModify(args, false, null, System.err), 0);
    Entry e = TestCaseUtils.makeEntry(
         "dn: cn=test,o=test",
         "objectClass: top",
         "objectClass: testMissingATRequiredByStructuralOC",
         "cn: test");
    assertFalse(e.conformsToSchema(null, false, true, true,
                                   new StringBuilder()));
  }
  /**
   * Tests schema checking for an entry that is missing an attribute required
   * by an auxiliary object class.
   *
   * @throws  Exception  If an unexpected problem occurs.
   */
  @Test()
  public void testMissingAttributeRequiredByAuxiliaryClass()
         throws Exception
  {
    TestCaseUtils.initializeTestBackend(true);
    String path = TestCaseUtils.createTempFile(
         "dn: cn=schema",
         "changetype: modify",
         "add: objectClasses",
         "objectClasses:  ( testmissingatrequiredbyauxiliaryoc-oid " +
              "NAME 'testMissingATRequiredByAuxiliaryOC' SUP top AUXILIARY " +
              "MUST ( cn $ description ) " +
              "X-ORIGIN 'EntrySchemaCheckingTestCase')");
    String[] args =
    {
      "-h", "127.0.0.1",
      "-p", String.valueOf(TestCaseUtils.getServerLdapPort()),
      "-D", "cn=Directory Manager",
      "-w", "password",
      "-f", path
    };
    assertEquals(LDAPModify.mainModify(args, false, null, System.err), 0);
    Entry e = TestCaseUtils.makeEntry(
         "dn: cn=test,o=test",
         "objectClass: top",
         "objectClass: device",
         "objectClass: testMissingATRequiredByAuxiliaryOC",
         "cn: test");
    assertFalse(e.conformsToSchema(null, false, true, true,
                                   new StringBuilder()));
  }
  /**
   * Tests schema checking for an entry that includes an attribute type that
   * is not allowed by any of its object classes.
   *
   * @throws  Exception  If an unexpected problem occurs.
   */
  @Test()
  public void testDisallowedAttributeType()
         throws Exception
  {
    TestCaseUtils.initializeTestBackend(true);
    String path = TestCaseUtils.createTempFile(
         "dn: cn=schema",
         "changetype: modify",
         "add: objectClasses",
         "objectClasses:  ( testdisallowedattributetypeoc-oid " +
              "NAME 'testDisallowedAttributeTypeOC' SUP top STRUCTURAL " +
              "MUST cn X-ORIGIN 'EntrySchemaCheckingTestCase')");
    String[] args =
    {
      "-h", "127.0.0.1",
      "-p", String.valueOf(TestCaseUtils.getServerLdapPort()),
      "-D", "cn=Directory Manager",
      "-w", "password",
      "-f", path
    };
    assertEquals(LDAPModify.mainModify(args, false, null, System.err), 0);
    Entry e = TestCaseUtils.makeEntry(
         "dn: cn=test,o=test",
         "objectClass: top",
         "objectClass: testDisallowedAttributeTypeOC",
         "cn: test",
         "description: foo");
    assertFalse(e.conformsToSchema(null, false, true, true,
                                   new StringBuilder()));
  }
  /**
   * Tests schema checking for an entry that includes multiple values for a
   * multivalued attribute.
   *
   * @throws  Exception  If an unexpected problem occurs.
   */
  @Test()
  public void testMultipleValuesForMultiValuedAttribute()
         throws Exception
  {
    Entry e = TestCaseUtils.makeEntry(
         "dn: o=test",
         "objectClass: top",
         "objectClass: organization",
         "o: test",
         "o: foo");
    StringBuilder invalidReason = new StringBuilder();
    assertTrue(e.conformsToSchema(null, true, true, true, invalidReason),
               invalidReason.toString());
  }
  /**
   * Tests schema checking for an entry that includes multiple values for a
   * single-valued attribute.
   *
   * @throws  Exception  If an unexpected problem occurs.
   */
  @Test()
  public void testMultipleValuesForSingleValuedAttribute()
         throws Exception
  {
    // The LDIF reader won't let us do this directly, so we have to hack around
    // it.
    Entry e = TestCaseUtils.makeEntry(
         "dn: dc=example,dc=com",
         "objectClass: top",
         "objectClass: domain",
         "dc: example");
    e.addAttribute(new Attribute("dc", "foo"),
                   new LinkedList<AttributeValue>());
    assertFalse(e.conformsToSchema(null, false, true, true, new StringBuilder()));
  }
  /**
   * Tests schema checking for an entry that includes multiple values for a
   * single-valued operational attribute.
   *
   * @throws  Exception  If an unexpected problem occurs.
   */
  @Test()
  public void testMultipleValuesForSingleValuedOperationalAttribute()
         throws Exception
  {
    // The LDIF reader won't let us do this directly, so we have to hack around
    // it.
    Entry e = TestCaseUtils.makeEntry(
         "dn: dc=example,dc=com",
         "objectClass: top",
         "objectClass: domain",
         "dc: example");
    AttributeType creatorsNameType =
         DirectoryServer.getAttributeType("creatorsname");
    assertTrue(creatorsNameType.isOperational());
    LinkedHashSet<AttributeValue> values = new LinkedHashSet<AttributeValue>(2);
    values.add(new AttributeValue(creatorsNameType, "cn=Directory Manager"));
    values.add(new AttributeValue(creatorsNameType, "cn=Another User"));
    e.addAttribute(new Attribute(creatorsNameType, "creatorsName", values),
                   new LinkedList<AttributeValue>());
    assertFalse(e.conformsToSchema(null, false, true, true, new StringBuilder()));
  }
  /**
   * Tests schema checking for an entry that contains structural and auxiliary
   * objectclasses where the auxiliary class is allowed by a DIT content rule.
   *
   * @throws  Exception  If an unexpected problem occurs.
   */
  @Test()
  public void testAuxiliaryClassAllowedByDCR()
         throws Exception
  {
    TestCaseUtils.initializeTestBackend(true);
    String path = TestCaseUtils.createTempFile(
         "dn: cn=schema",
         "changetype: modify",
         "add: objectClasses",
         "objectClasses:  ( testauxiliaryclassallowedbydcroc-oid " +
              "NAME 'testAuxiliaryClassAllowedByDCROC' SUP top STRUCTURAL " +
              "MUST cn X-ORIGIN 'EntrySchemaCheckingTestCase')",
         "objectClasses:  ( testauxiliaryclassallowedbydcrocaux-oid " +
              "NAME 'testAuxiliaryClassAllowedByDCROCAux' SUP top AUXILIARY " +
              "MAY description X-ORIGIN 'EntrySchemaCheckingTestCase')",
         "-",
         "add: ditContentRules",
         "ditContentRules: ( testauxiliaryclassallowedbydcroc-oid " +
              "NAME 'testAuxiliaryClassAllowedByDCR' " +
              "AUX testAuxiliaryClassAllowedByDCROCAux " +
              "X-ORIGIN 'EntrySchemaCheckingTestCase' )");
    String[] args =
    {
      "-h", "127.0.0.1",
      "-p", String.valueOf(TestCaseUtils.getServerLdapPort()),
      "-D", "cn=Directory Manager",
      "-w", "password",
      "-f", path
    };
    assertEquals(LDAPModify.mainModify(args, false, null, System.err), 0);
    Entry e = TestCaseUtils.makeEntry(
         "dn: cn=test,o=test",
         "objectClass: top",
         "objectClass: testAuxiliaryClassAllowedByDCROC",
         "objectClass: testAuxiliaryClassAllowedByDCROCAux",
         "cn: test");
    StringBuilder invalidReason = new StringBuilder();
    assertTrue(e.conformsToSchema(null, false, true, true, invalidReason),
               invalidReason.toString());
  }
  /**
   * Tests schema checking for an entry that contains structural and auxiliary
   * objectclasses where the auxiliary class is not allowed by the associated
   * DIT content rule.
   *
   * @throws  Exception  If an unexpected problem occurs.
   */
  @Test()
  public void testAuxiliaryClassNotAllowedByDCR()
         throws Exception
  {
    TestCaseUtils.initializeTestBackend(true);
    String path = TestCaseUtils.createTempFile(
         "dn: cn=schema",
         "changetype: modify",
         "add: objectClasses",
         "objectClasses:  ( testauxiliaryclassnotallowedbydcroc-oid " +
              "NAME 'testAuxiliaryClassNotAllowedByDCROC' SUP top STRUCTURAL " +
              "MUST cn X-ORIGIN 'EntrySchemaCheckingTestCase')",
         "objectClasses:  ( testauxiliaryclassnotallowedbydcrocaux-oid " +
              "NAME 'testAuxiliaryClassNotAllowedByDCROCAux' SUP top " +
              "AUXILIARY MAY description " +
              "X-ORIGIN 'EntrySchemaCheckingTestCase')",
         "-",
         "add: ditContentRules",
         "ditContentRules: ( testauxiliaryclassnotallowedbydcroc-oid " +
              "NAME 'testAuxiliaryClassNotAllowedByDCR' " +
              "X-ORIGIN 'EntrySchemaCheckingTestCase' )");
    String[] args =
    {
      "-h", "127.0.0.1",
      "-p", String.valueOf(TestCaseUtils.getServerLdapPort()),
      "-D", "cn=Directory Manager",
      "-w", "password",
      "-f", path
    };
    assertEquals(LDAPModify.mainModify(args, false, null, System.err), 0);
    Entry e = TestCaseUtils.makeEntry(
         "dn: cn=test,o=test",
         "objectClass: top",
         "objectClass: testAuxiliaryClassNotAllowedByDCROC",
         "objectClass: testAuxiliaryClassNotAllowedByDCROCAux",
         "cn: test");
    failOnlyForStrictEvaluation(e);
  }
  /**
   * Tests schema checking for an entry covered by a DIT content rule to
   * ensure that attributes required by the DIT content rule are allowed even
   * if not directly allowed by any of the entry's objectclasses.
   *
   * @throws  Exception  If an unexpected problem occurs.
   */
  @Test()
  public void testAllowAttributeRequiredByDCR()
         throws Exception
  {
    TestCaseUtils.initializeTestBackend(true);
    String path = TestCaseUtils.createTempFile(
         "dn: cn=schema",
         "changetype: modify",
         "add: objectClasses",
         "objectClasses:  ( testallowatrequiredbydcroc-oid " +
              "NAME 'testAllowATRequiredByDCROC' SUP top STRUCTURAL " +
              "MUST cn X-ORIGIN 'EntrySchemaCheckingTestCase')",
         "-",
         "add: ditContentRules",
         "ditContentRules: ( testallowatrequiredbydcroc-oid " +
              "NAME 'testAllowATRequiredByDCR' MUST description " +
              "X-ORIGIN 'EntrySchemaCheckingTestCase' )");
    String[] args =
    {
      "-h", "127.0.0.1",
      "-p", String.valueOf(TestCaseUtils.getServerLdapPort()),
      "-D", "cn=Directory Manager",
      "-w", "password",
      "-f", path
    };
    assertEquals(LDAPModify.mainModify(args, false, null, System.err), 0);
    Entry e = TestCaseUtils.makeEntry(
         "dn: cn=test,o=test",
         "objectClass: top",
         "objectClass: testAllowATRequiredByDCROC",
         "cn: test",
         "description: foo");
    StringBuilder invalidReason = new StringBuilder();
    assertTrue(e.conformsToSchema(null, false, true, true, invalidReason),
               invalidReason.toString());
  }
  /**
   * Tests schema checking for an entry covered by a DIT content rule to
   * ensure that attributes required by the DIT content rule are required even
   * if not directly allowed by any of the entry's objectclasses.
   *
   * @throws  Exception  If an unexpected problem occurs.
   */
  @Test()
  public void testRequireAttributeRequiredByDCR()
         throws Exception
  {
    TestCaseUtils.initializeTestBackend(true);
    String path = TestCaseUtils.createTempFile(
         "dn: cn=schema",
         "changetype: modify",
         "add: objectClasses",
         "objectClasses:  ( testrequireatrequiredbydcroc-oid " +
              "NAME 'testRequireATRequiredByDCROC' SUP top STRUCTURAL " +
              "MUST cn X-ORIGIN 'EntrySchemaCheckingTestCase')",
         "-",
         "add: ditContentRules",
         "ditContentRules: ( testrequireatrequiredbydcroc-oid " +
              "NAME 'testRequireATRequiredByDCR' MUST description " +
              "X-ORIGIN 'EntrySchemaCheckingTestCase' )");
    String[] args =
    {
      "-h", "127.0.0.1",
      "-p", String.valueOf(TestCaseUtils.getServerLdapPort()),
      "-D", "cn=Directory Manager",
      "-w", "password",
      "-f", path
    };
    assertEquals(LDAPModify.mainModify(args, false, null, System.err), 0);
    Entry e = TestCaseUtils.makeEntry(
         "dn: cn=test,o=test",
         "objectClass: top",
         "objectClass: testRequireATRequiredByDCROC",
         "cn: test");
    failOnlyForStrictEvaluation(e);
  }
  /**
   * Tests schema checking for an entry for which there is a DIT content rule
   * covering the structural objectclass but that DIT content rule is marked
   * OBSOLETE.  In this case, any attribute types required by the DIT content
   * rule should not be required for the entry.
   *
   * @throws  Exception  If an unexpected problem occurs.
   */
  @Test()
  public void testDontRequireAttributeRequiredByObsoleteDCR()
         throws Exception
  {
    TestCaseUtils.initializeTestBackend(true);
    String path = TestCaseUtils.createTempFile(
         "dn: cn=schema",
         "changetype: modify",
         "add: objectClasses",
         "objectClasses:  ( testdontrequireatrequiredbyobsoletedcroc-oid " +
              "NAME 'testDontRequireATRequiredByObsoleteDCROC' SUP top " +
              "STRUCTURAL MUST cn X-ORIGIN 'EntrySchemaCheckingTestCase')",
         "-",
         "add: ditContentRules",
         "ditContentRules: ( testdontrequireatrequiredbyobsoletedcroc-oid " +
              "NAME 'testDontRequireATRequiredByObsoleteDCR' OBSOLETE " +
              "MUST description X-ORIGIN 'EntrySchemaCheckingTestCase' )");
    String[] args =
    {
      "-h", "127.0.0.1",
      "-p", String.valueOf(TestCaseUtils.getServerLdapPort()),
      "-D", "cn=Directory Manager",
      "-w", "password",
      "-f", path
    };
    assertEquals(LDAPModify.mainModify(args, false, null, System.err), 0);
    Entry e = TestCaseUtils.makeEntry(
         "dn: cn=test,o=test",
         "objectClass: top",
         "objectClass: testDontRequireATRequiredByObsoleteDCROC",
         "cn: test");
    StringBuilder invalidReason = new StringBuilder();
    assertTrue(e.conformsToSchema(null, false, true, true, invalidReason),
               invalidReason.toString());
  }
  /**
   * Tests schema checking for an entry covered by a DIT content rule to
   * ensure that attributes allowed by the DIT content rule are allowed even
   * if not directly allowed by any of the entry's objectclasses.
   *
   * @throws  Exception  If an unexpected problem occurs.
   */
  @Test()
  public void testAllowAttributeAllowedByDCR()
         throws Exception
  {
    TestCaseUtils.initializeTestBackend(true);
    String path = TestCaseUtils.createTempFile(
         "dn: cn=schema",
         "changetype: modify",
         "add: objectClasses",
         "objectClasses:  ( testallowatallowedbydcroc-oid " +
              "NAME 'testAllowATAllowedByDCROC' SUP top STRUCTURAL " +
              "MUST cn X-ORIGIN 'EntrySchemaCheckingTestCase')",
         "-",
         "add: ditContentRules",
         "ditContentRules: ( testallowatallowedbydcroc-oid " +
              "NAME 'testAllowATAllowedByDCR' MAY description " +
              "X-ORIGIN 'EntrySchemaCheckingTestCase' )");
    String[] args =
    {
      "-h", "127.0.0.1",
      "-p", String.valueOf(TestCaseUtils.getServerLdapPort()),
      "-D", "cn=Directory Manager",
      "-w", "password",
      "-f", path
    };
    assertEquals(LDAPModify.mainModify(args, false, null, System.err), 0);
    Entry e = TestCaseUtils.makeEntry(
         "dn: cn=test,o=test",
         "objectClass: top",
         "objectClass: testAllowATAllowedByDCROC",
         "cn: test",
         "description: foo");
    StringBuilder invalidReason = new StringBuilder();
    assertTrue(e.conformsToSchema(null, false, true, true, invalidReason),
               invalidReason.toString());
  }
  /**
   * Tests schema checking for an entry covered by a DIT content rule to
   * ensure that attributes allowed by the DIT content rule are allowed but
   * not required if they are not required by any of the associated object
   * classes.
   *
   * @throws  Exception  If an unexpected problem occurs.
   */
  @Test()
  public void testDontRequireAttributeAllowedByDCR()
         throws Exception
  {
    TestCaseUtils.initializeTestBackend(true);
    String path = TestCaseUtils.createTempFile(
         "dn: cn=schema",
         "changetype: modify",
         "add: objectClasses",
         "objectClasses:  ( testdontrequireatallowedbydcroc-oid " +
              "NAME 'testDontRequireATAllowedByDCROC' SUP top STRUCTURAL " +
              "MUST cn X-ORIGIN 'EntrySchemaCheckingTestCase')",
         "-",
         "add: ditContentRules",
         "ditContentRules: ( testdontrequireatallowedbydcroc-oid " +
              "NAME 'testDontRequireATAllowedByDCR' MAY description " +
              "X-ORIGIN 'EntrySchemaCheckingTestCase' )");
    String[] args =
    {
      "-h", "127.0.0.1",
      "-p", String.valueOf(TestCaseUtils.getServerLdapPort()),
      "-D", "cn=Directory Manager",
      "-w", "password",
      "-f", path
    };
    assertEquals(LDAPModify.mainModify(args, false, null, System.err), 0);
    Entry e = TestCaseUtils.makeEntry(
         "dn: cn=test,o=test",
         "objectClass: top",
         "objectClass: testDontRequireATAllowedByDCROC",
         "cn: test");
    StringBuilder invalidReason = new StringBuilder();
    assertTrue(e.conformsToSchema(null, false, true, true, invalidReason),
               invalidReason.toString());
  }
  /**
   * Tests schema checking for an entry covered by a DIT content rule to
   * ensure that attributes prohibited by the DIT content rule are not allowed
   * even if they are allowed by the associated object classes.
   *
   * @throws  Exception  If an unexpected problem occurs.
   */
  @Test()
  public void testDontAllowAttributeProhibitedByDCR()
         throws Exception
  {
    TestCaseUtils.initializeTestBackend(true);
    String path = TestCaseUtils.createTempFile(
         "dn: cn=schema",
         "changetype: modify",
         "add: objectClasses",
         "objectClasses:  ( testdontallowattributeprohibitedbydcroc-oid " +
              "NAME 'testDontAllowAttributeProhibitedByDCROC' SUP top " +
              "STRUCTURAL MUST cn MAY description " +
              "X-ORIGIN 'EntrySchemaCheckingTestCase')",
         "-",
         "add: ditContentRules",
         "ditContentRules: ( testdontallowattributeprohibitedbydcroc-oid " +
              "NAME 'testDontAllowAttributeProhibitedByDCR' NOT description " +
              "X-ORIGIN 'EntrySchemaCheckingTestCase' )");
    String[] args =
    {
      "-h", "127.0.0.1",
      "-p", String.valueOf(TestCaseUtils.getServerLdapPort()),
      "-D", "cn=Directory Manager",
      "-w", "password",
      "-f", path
    };
    assertEquals(LDAPModify.mainModify(args, false, null, System.err), 0);
    Entry e = TestCaseUtils.makeEntry(
         "dn: cn=test,o=test",
         "objectClass: top",
         "objectClass: testDontAllowAttributeProhibitedByDCROC",
         "cn: test",
         "description: foo");
    failOnlyForStrictEvaluation(e);
  }
  /**
   * Tests that an entry covered by a name form will be accepted if its
   * single-valued RDN component is compliant with that name form.
   *
   * @throws  Exception  If an unexpected problem occurs.
   */
  @Test()
  public void testSatisfiesSingleValuedNameForm()
         throws Exception
  {
    TestCaseUtils.initializeTestBackend(true);
    String path = TestCaseUtils.createTempFile(
         "dn: cn=schema",
         "changetype: modify",
         "add: objectClasses",
         "objectClasses:  ( testsatisfiessinglevaluednameformoc-oid " +
              "NAME 'testSatisfiesSingleValuedNameFormOC' SUP top STRUCTURAL " +
              "MUST cn X-ORIGIN 'EntrySchemaCheckingTestCase')",
         "-",
         "add: nameForms",
         "nameForms: ( testsatisfiessinglevaluednameform-oid " +
              "NAME 'testSatisfiesSingleValuedNameForm' " +
              "OC testSatisfiesSingleValuedNameFormOC MUST cn " +
              "X-ORIGIN 'EntrySchemaCheckingTestCase' )");
    String[] args =
    {
      "-h", "127.0.0.1",
      "-p", String.valueOf(TestCaseUtils.getServerLdapPort()),
      "-D", "cn=Directory Manager",
      "-w", "password",
      "-f", path
    };
    assertEquals(LDAPModify.mainModify(args, false, null, System.err), 0);
    Entry e = TestCaseUtils.makeEntry(
         "dn: cn=test,o=test",
         "objectClass: top",
         "objectClass: testSatisfiesSingleValuedNameFormOC",
         "cn: test");
    StringBuilder invalidReason = new StringBuilder();
    assertTrue(e.conformsToSchema(null, false, true, true, invalidReason),
               invalidReason.toString());
  }
  /**
   * Tests that an entry covered by a name form will be rejected if its
   * single-valued RDN component violates that name form.
   *
   * @throws  Exception  If an unexpected problem occurs.
   */
  @Test()
  public void testViolatesSingleValuedNameForm()
         throws Exception
  {
    TestCaseUtils.initializeTestBackend(true);
    String path = TestCaseUtils.createTempFile(
         "dn: cn=schema",
         "changetype: modify",
         "add: objectClasses",
         "objectClasses:  ( testviolatessinglevaluednameformoc-oid " +
              "NAME 'testViolatesSingleValuedNameFormOC' SUP top STRUCTURAL " +
              "MUST cn MAY description X-ORIGIN 'EntrySchemaCheckingTestCase')",
         "-",
         "add: nameForms",
         "nameForms: ( testviolatessinglevaluednameform-oid " +
              "NAME 'testViolatesSingleValuedNameForm' " +
              "OC testViolatesSingleValuedNameFormOC MUST cn " +
              "X-ORIGIN 'EntrySchemaCheckingTestCase' )");
    String[] args =
    {
      "-h", "127.0.0.1",
      "-p", String.valueOf(TestCaseUtils.getServerLdapPort()),
      "-D", "cn=Directory Manager",
      "-w", "password",
      "-f", path
    };
    assertEquals(LDAPModify.mainModify(args, false, null, System.err), 0);
    Entry e = TestCaseUtils.makeEntry(
         "dn: description=foo,o=test",
         "objectClass: top",
         "objectClass: testViolatesSingleValuedNameFormOC",
         "cn: test",
         "description: foo");
    failOnlyForStrictEvaluation(e);
  }
  /**
   * Tests that an entry covered by a name form will be rejected if its
   * multivalued RDN component violates that name form which only allows a
   * single value.
   *
   * @throws  Exception  If an unexpected problem occurs.
   */
  @Test()
  public void testMVViolatesSingleValuedNameForm()
         throws Exception
  {
    TestCaseUtils.initializeTestBackend(true);
    String path = TestCaseUtils.createTempFile(
         "dn: cn=schema",
         "changetype: modify",
         "add: objectClasses",
         "objectClasses:  ( testmvviolatessinglevaluednameformoc-oid " +
              "NAME 'testMVViolatesSingleValuedNameFormOC' SUP top STRUCTURAL " +
              "MUST cn MAY description X-ORIGIN 'EntrySchemaCheckingTestCase')",
         "-",
         "add: nameForms",
         "nameForms: ( testmvviolatessinglevaluednameform-oid " +
              "NAME 'testMVViolatesSingleValuedNameForm' " +
              "OC testMVViolatesSingleValuedNameFormOC MUST cn " +
              "X-ORIGIN 'EntrySchemaCheckingTestCase' )");
    String[] args =
    {
      "-h", "127.0.0.1",
      "-p", String.valueOf(TestCaseUtils.getServerLdapPort()),
      "-D", "cn=Directory Manager",
      "-w", "password",
      "-f", path
    };
    assertEquals(LDAPModify.mainModify(args, false, null, System.err), 0);
    Entry e = TestCaseUtils.makeEntry(
         "dn: cn=test+description=foo,o=test",
         "objectClass: top",
         "objectClass: testMVViolatesSingleValuedNameFormOC",
         "cn: test",
         "description: foo");
    failOnlyForStrictEvaluation(e);
  }
  /**
   * Tests that an entry covered by a name form will not be rejected if its
   * single-valued RDN component violates that name form but the name form is
   * declared OBSOLETE.
   *
   * @throws  Exception  If an unexpected problem occurs.
   */
  @Test()
  public void testViolatesSingleValuedObsoleteNameForm()
         throws Exception
  {
    TestCaseUtils.initializeTestBackend(true);
    String path = TestCaseUtils.createTempFile(
         "dn: cn=schema",
         "changetype: modify",
         "add: objectClasses",
         "objectClasses:  ( testviolatessinglevaluedobsoletenameformoc-oid " +
              "NAME 'testViolatesSingleValuedObsoleteNameFormOC' SUP top " +
              "STRUCTURAL MUST cn MAY description " +
              "X-ORIGIN 'EntrySchemaCheckingTestCase')",
         "-",
         "add: nameForms",
         "nameForms: ( testviolatessinglevaluedobsoletenameform-oid " +
              "NAME 'testViolatesSingleValuedObsoleteNameForm' OBSOLETE " +
              "OC testViolatesSingleValuedObsoleteNameFormOC MUST cn " +
              "X-ORIGIN 'EntrySchemaCheckingTestCase' )");
    String[] args =
    {
      "-h", "127.0.0.1",
      "-p", String.valueOf(TestCaseUtils.getServerLdapPort()),
      "-D", "cn=Directory Manager",
      "-w", "password",
      "-f", path
    };
    assertEquals(LDAPModify.mainModify(args, false, null, System.err), 0);
    Entry e = TestCaseUtils.makeEntry(
         "dn: description=foo,o=test",
         "objectClass: top",
         "objectClass: testViolatesSingleValuedObsoleteNameFormOC",
         "cn: test",
         "description: foo");
    StringBuilder invalidReason = new StringBuilder();
    assertTrue(e.conformsToSchema(null, false, true, true, invalidReason),
               invalidReason.toString());
  }
  /**
   * Tests that an entry covered by a name form will be accepted if its
   * multivalued RDN component is compliant with that name form which requires
   * multiple values.
   *
   * @throws  Exception  If an unexpected problem occurs.
   */
  @Test()
  public void testSatisfiesRequiredMultiValuedNameForm()
         throws Exception
  {
    TestCaseUtils.initializeTestBackend(true);
    String path = TestCaseUtils.createTempFile(
         "dn: cn=schema",
         "changetype: modify",
         "add: objectClasses",
         "objectClasses:  ( testsatisfiesrequiredmultivaluednameformoc-oid " +
              "NAME 'testSatisfiesRequiredMultiValuedNameFormOC' SUP top " +
              "STRUCTURAL MUST cn MAY description " +
              "X-ORIGIN 'EntrySchemaCheckingTestCase')",
         "-",
         "add: nameForms",
         "nameForms: ( testsatisfiesrequiredmultivaluednameform-oid " +
              "NAME 'testSatisfiesRequiredMultiValuedNameForm' " +
              "OC testSatisfiesRequiredMultiValuedNameFormOC " +
              "MUST ( cn $ description ) " +
              "X-ORIGIN 'EntrySchemaCheckingTestCase' )");
    String[] args =
    {
      "-h", "127.0.0.1",
      "-p", String.valueOf(TestCaseUtils.getServerLdapPort()),
      "-D", "cn=Directory Manager",
      "-w", "password",
      "-f", path
    };
    assertEquals(LDAPModify.mainModify(args, false, null, System.err), 0);
    Entry e = TestCaseUtils.makeEntry(
         "dn: cn=test+description=foo,o=test",
         "objectClass: top",
         "objectClass: testSatisfiesRequiredMultiValuedNameFormOC",
         "cn: test",
         "description: foo");
    StringBuilder invalidReason = new StringBuilder();
    assertTrue(e.conformsToSchema(null, false, true, true, invalidReason),
               invalidReason.toString());
  }
  /**
   * Tests that an entry covered by a name form will be accepted if its
   * single-valued RDN component only contains one of the multiple required
   * attribute types.
   *
   * @throws  Exception  If an unexpected problem occurs.
   */
  @Test()
  public void testViolatesRequiredMultiValuedNameForm()
         throws Exception
  {
    TestCaseUtils.initializeTestBackend(true);
    String path = TestCaseUtils.createTempFile(
         "dn: cn=schema",
         "changetype: modify",
         "add: objectClasses",
         "objectClasses:  ( testviolatesrequiredmultivaluednameformoc-oid " +
              "NAME 'testViolatesRequiredMultiValuedNameFormOC' SUP top " +
              "STRUCTURAL MUST cn MAY description " +
              "X-ORIGIN 'EntrySchemaCheckingTestCase')",
         "-",
         "add: nameForms",
         "nameForms: ( testviolatesrequiredmultivaluednameform-oid " +
              "NAME 'testViolatesRequiredMultiValuedNameForm' " +
              "OC testViolatesRequiredMultiValuedNameFormOC " +
              "MUST ( cn $ description ) " +
              "X-ORIGIN 'EntrySchemaCheckingTestCase' )");
    String[] args =
    {
      "-h", "127.0.0.1",
      "-p", String.valueOf(TestCaseUtils.getServerLdapPort()),
      "-D", "cn=Directory Manager",
      "-w", "password",
      "-f", path
    };
    assertEquals(LDAPModify.mainModify(args, false, null, System.err), 0);
    Entry e = TestCaseUtils.makeEntry(
         "dn: cn=test,o=test",
         "objectClass: top",
         "objectClass: testViolatesRequiredMultiValuedNameFormOC",
         "cn: test",
         "description: foo");
    failOnlyForStrictEvaluation(e);
  }
  /**
   * Tests that an entry covered by a name form will be accepted if its
   * single-valued RDN component is compliant with that name form which requires
   * one value but allows other values.
   *
   * @throws  Exception  If an unexpected problem occurs.
   */
  @Test()
  public void testSVSatisfiesOptionalMultiValuedNameForm()
         throws Exception
  {
    TestCaseUtils.initializeTestBackend(true);
    String path = TestCaseUtils.createTempFile(
         "dn: cn=schema",
         "changetype: modify",
         "add: objectClasses",
         "objectClasses:  ( testsvsatisfiesoptionalmultivaluednameformoc-oid " +
              "NAME 'testSVSatisfiesOptionalMultiValuedNameFormOC' SUP top " +
              "STRUCTURAL MUST cn MAY description " +
              "X-ORIGIN 'EntrySchemaCheckingTestCase')",
         "-",
         "add: nameForms",
         "nameForms: ( testsvsatisfiesoptionalmultivaluednameform-oid " +
              "NAME 'testSVSatisfiesOptionalMultiValuedNameForm' " +
              "OC testSVSatisfiesOptionalMultiValuedNameFormOC MUST cn " +
              "MAY description X-ORIGIN 'EntrySchemaCheckingTestCase' )");
    String[] args =
    {
      "-h", "127.0.0.1",
      "-p", String.valueOf(TestCaseUtils.getServerLdapPort()),
      "-D", "cn=Directory Manager",
      "-w", "password",
      "-f", path
    };
    assertEquals(LDAPModify.mainModify(args, false, null, System.err), 0);
    Entry e = TestCaseUtils.makeEntry(
         "dn: cn=test,o=test",
         "objectClass: top",
         "objectClass: testSVSatisfiesOptionalMultiValuedNameFormOC",
         "cn: test",
         "description: foo");
    StringBuilder invalidReason = new StringBuilder();
    assertTrue(e.conformsToSchema(null, false, true, true, invalidReason),
               invalidReason.toString());
  }
  /**
   * Tests that an entry covered by a name form will be accepted if its
   * multivalued RDN component is compliant with that name form which requires
   * one value but allows other values.
   *
   * @throws  Exception  If an unexpected problem occurs.
   */
  @Test()
  public void testMVSatisfiesOptionalMultiValuedNameForm()
         throws Exception
  {
    TestCaseUtils.initializeTestBackend(true);
    String path = TestCaseUtils.createTempFile(
         "dn: cn=schema",
         "changetype: modify",
         "add: objectClasses",
         "objectClasses:  ( testmvsatisfiesoptionalmultivaluednameformoc-oid " +
              "NAME 'testMVSatisfiesOptionalMultiValuedNameFormOC' SUP top " +
              "STRUCTURAL MUST cn MAY description " +
              "X-ORIGIN 'EntrySchemaCheckingTestCase')",
         "-",
         "add: nameForms",
         "nameForms: ( testmvsatisfiesoptionalmultivaluednameform-oid " +
              "NAME 'testMVSatisfiesOptionalMultiValuedNameForm' " +
              "OC testMVSatisfiesOptionalMultiValuedNameFormOC MUST cn " +
              "MAY description X-ORIGIN 'EntrySchemaCheckingTestCase' )");
    String[] args =
    {
      "-h", "127.0.0.1",
      "-p", String.valueOf(TestCaseUtils.getServerLdapPort()),
      "-D", "cn=Directory Manager",
      "-w", "password",
      "-f", path
    };
    assertEquals(LDAPModify.mainModify(args, false, null, System.err), 0);
    Entry e = TestCaseUtils.makeEntry(
         "dn: cn=test+description=foo,o=test",
         "objectClass: top",
         "objectClass: testMVSatisfiesOptionalMultiValuedNameFormOC",
         "cn: test",
         "description: foo");
    StringBuilder invalidReason = new StringBuilder();
    assertTrue(e.conformsToSchema(null, false, true, true, invalidReason),
               invalidReason.toString());
  }
  /**
   * Tests that an entry covered by a name form will be accepted if its
   * single-valued RDN component violates that name form which requires
   * one value but allows other values.
   *
   * @throws  Exception  If an unexpected problem occurs.
   */
  @Test()
  public void testSVViolatesOptionalMultiValuedNameForm()
         throws Exception
  {
    TestCaseUtils.initializeTestBackend(true);
    String path = TestCaseUtils.createTempFile(
         "dn: cn=schema",
         "changetype: modify",
         "add: objectClasses",
         "objectClasses:  ( testsvviolatesoptionalmultivaluednameformoc-oid " +
              "NAME 'testSVViolatesOptionalMultiValuedNameFormOC' SUP top " +
              "STRUCTURAL MUST cn MAY description " +
              "X-ORIGIN 'EntrySchemaCheckingTestCase')",
         "-",
         "add: nameForms",
         "nameForms: ( testsvviolatesoptionalmultivaluednameform-oid " +
              "NAME 'testSVViolatesOptionalMultiValuedNameForm' " +
              "OC testSVViolatesOptionalMultiValuedNameFormOC MUST cn " +
              "MAY description X-ORIGIN 'EntrySchemaCheckingTestCase' )");
    String[] args =
    {
      "-h", "127.0.0.1",
      "-p", String.valueOf(TestCaseUtils.getServerLdapPort()),
      "-D", "cn=Directory Manager",
      "-w", "password",
      "-f", path
    };
    assertEquals(LDAPModify.mainModify(args, false, null, System.err), 0);
    Entry e = TestCaseUtils.makeEntry(
         "dn: description=foo,o=test",
         "objectClass: top",
         "objectClass: testSVViolatesOptionalMultiValuedNameFormOC",
         "cn: test",
         "description: foo");
    failOnlyForStrictEvaluation(e);
  }
  /**
   * Performs various tests to ensure that the server appropriately enforces DIT
   * structure rule constraints.
   *
   * @throws  Exception  If an unexpected problem occurs.
   */
  @Test()
  public void testDITStructureRuleConstraints()
         throws Exception
  {
    TestCaseUtils.initializeTestBackend(true);
    String path = TestCaseUtils.createTempFile(
         "dn: cn=schema",
         "changetype: modify",
         "add: objectClasses",
         "objectClasses:  ( testditstructureruleconstraintssupoc-oid " +
              "NAME 'testDITStructureRuleConstraintsSupOC' SUP top " +
              "STRUCTURAL MUST ou X-ORIGIN 'SchemaBackendTestCase')",
         "objectClasses:  ( testditstructureruleconstraintssuboc-oid " +
              "NAME 'testDITStructureRuleConstraintsSubOC' SUP top " +
              "STRUCTURAL MUST cn X-ORIGIN 'SchemaBackendTestCase')",
         "-",
         "add: nameForms",
         "nameForms: ( testditstructureruleconstraintsupsnf-oid " +
              "NAME 'testDITStructureRuleConstraintsSupNF' " +
              "OC testDITStructureRuleConstraintsSupOC MUST ou " +
              "X-ORIGIN 'SchemaBackendTestCase' )",
         "nameForms: ( testditstructureruleconstraintsubsnf-oid " +
              "NAME 'testDITStructureRuleConstraintsSubNF' " +
              "OC testDITStructureRuleConstraintsSubOC MUST cn " +
              "X-ORIGIN 'SchemaBackendTestCase' )",
         "-",
         "add: ditStructureRules",
         "ditStructureRules: ( 999014 " +
              "NAME 'testDITStructureRuleConstraintsSup' " +
              "FORM testDITStructureRuleConstraintsSupNF " +
              "X-ORIGIN 'SchemaBackendTestCase' )",
         "ditStructureRules: ( 999015 " +
              "NAME 'testDITStructureRuleConstraintsSub' " +
              "FORM testDITStructureRuleConstraintsSubNF SUP 999014 " +
              "X-ORIGIN 'SchemaBackendTestCase' )");
    String[] args =
    {
      "-h", "127.0.0.1",
      "-p", String.valueOf(TestCaseUtils.getServerLdapPort()),
      "-D", "cn=Directory Manager",
      "-w", "password",
      "-f", path
    };
    assertEquals(LDAPModify.mainModify(args, false, null, System.err), 0);
    Entry e = TestCaseUtils.makeEntry(
         "dn: cn=child,ou=parent,o=test",
         "objectClass: top",
         "objectClass: testDITStructureRuleConstraintsSubOC",
         "cn: child");
    failOnlyForStrictEvaluation(e);
    path = TestCaseUtils.createTempFile(
         "dn: ou=parent,o=test",
         "changetype: add",
         "objectClass: top",
         "objectClass: testDITStructureRuleConstraintsSupOC",
         "ou: parent");
    args = new String[]
    {
      "-h", "127.0.0.1",
      "-p", String.valueOf(TestCaseUtils.getServerLdapPort()),
      "-D", "cn=Directory Manager",
      "-w", "password",
      "-f", path
    };
    assertEquals(LDAPModify.mainModify(args, false, null, System.err), 0);
    StringBuilder invalidReason = new StringBuilder();
    assertTrue(e.conformsToSchema(null, false, true, true, invalidReason),
               invalidReason.toString());
    e = TestCaseUtils.makeEntry(
         "dn: cn=not below valid parent,o=test",
         "objectClass: top",
         "objectClass: testDITStructureRuleConstraintsSubOC",
         "cn: not below valid parent");
    failOnlyForStrictEvaluation(e);
    e = TestCaseUtils.makeEntry(
         "dn: cn=invalid entry below parent covered by DSR,ou=parent,o=test",
         "objectClass: top",
         "objectClass: device",
         "cn: invalid entry below parent covered by DSR");
    invalidReason = new StringBuilder();
    failOnlyForStrictEvaluation(e);
  }
}
opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/types/TestEntry.java
@@ -275,7 +275,7 @@
        + "SYNTAX 1.3.6.1.4.1.1466.115.121.1.45 )";
    AttributeType type = AttributeTypeSyntax.decodeAttributeType(
        new ASN1OctetString(string), DirectoryServer.getSchema());
        new ASN1OctetString(string), DirectoryServer.getSchema(), false);
    // Test values.
    String[] values = new String[] { "{ }",