opendj-sdk/opendj-core/clirr-ignored-api-changes.xml
@@ -390,4 +390,10 @@ <to>*toIrreversibleNormalizedByteString()</to> <justification>OPENDJ-1585 Function has been renamed to avoid abuse</justification> </difference> <difference> <className>%regex[org/forgerock/opendj/ldap/schema/Schema(Builder)?]</className> <differenceType>7002</differenceType> <method>%regex[(boolean|org.forgerock.opendj.ldap.schema.SchemaBuilder) allow(.)*\((boolean)?\)]</method> <justification>OPENDJ-1478 Make it easier to add compatibility options to schemas</justification> </difference> </differences> opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/AttributeDescription.java
@@ -27,9 +27,6 @@ package org.forgerock.opendj.ldap; import static com.forgerock.opendj.util.StaticUtils.toLowerCase; import static com.forgerock.opendj.ldap.CoreMessages.*; import java.util.Arrays; import java.util.Iterator; import java.util.LinkedHashMap; @@ -50,6 +47,11 @@ import com.forgerock.opendj.util.ASCIICharProp; import com.forgerock.opendj.util.Iterators; import static org.forgerock.opendj.ldap.schema.SchemaOptions.*; import static com.forgerock.opendj.ldap.CoreMessages.*; import static com.forgerock.opendj.util.StaticUtils.*; /** * An attribute description as defined in RFC 4512 section 2.5. Attribute * descriptions are used to identify an attribute in an entry and are composed @@ -740,9 +742,8 @@ } /** Uncached valueOf implementation. */ private static AttributeDescription valueOf0(final String attributeDescription, final Schema schema) { final boolean allowMalformedNamesAndOptions = schema.allowMalformedNamesAndOptions(); private static AttributeDescription valueOf0(final String attributeDescription, final Schema schema) { final boolean allowMalformedNamesAndOptions = schema.getOption(ALLOW_MALFORMED_NAMES_AND_OPTIONS); int i = 0; final int length = attributeDescription.length(); char c = 0; opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/Option.java
New file @@ -0,0 +1,91 @@ /* * 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 legal-notices/CDDLv1_0.txt * or http://forgerock.org/license/CDDLv1.0.html. * 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 legal-notices/CDDLv1_0.txt. * 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 * * * Copyright 2014 ForgeRock AS */ package org.forgerock.opendj.ldap; /** * Public API for defining new options. * * @param <T> The option type. */ public final class Option<T> { private final Class<T> type; private final T defaultValue; /** * Defines a new {@link Boolean} option with the provided default value. * * @param defaultValue * The {@link Boolean} default value of this option. * @return A new {@link Boolean} option with the provided default value. */ public static Option<Boolean> withDefault(boolean defaultValue) { return of(Boolean.class, defaultValue); } /** * Defines a new option of the provided type with the provided default * value. * * @param <T> * The type of this option. * @param type * The type of the option. * @param defaultValue * The new option default value. * @return A new option of the provided type with the provided default * value. */ public static <T> Option<T> of(Class<T> type, T defaultValue) { return new Option<T>(type, defaultValue); } private Option(Class<T> type, T defaultValue) { this.type = type; this.defaultValue = defaultValue; } /** * Returns the type of this option. * * @return the type of this option. */ public Class<T> getType() { return type; } /** * Returns the provided value if not {@code null}, otherwise returns the * default one. * * @param value * The option which overrides the default one if not null. * @return The provided value if not {@code null}, otherwise return the * default one. */ public T getValue(Object value) { return value != null ? type.cast(value) : defaultValue; } } opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/schema/AttributeTypeSyntaxImpl.java
@@ -26,10 +26,6 @@ */ package org.forgerock.opendj.ldap.schema; import static com.forgerock.opendj.ldap.CoreMessages.*; import static org.forgerock.opendj.ldap.schema.SchemaConstants.*; import org.forgerock.i18n.LocalizableMessage; import org.forgerock.i18n.LocalizableMessageBuilder; import org.forgerock.i18n.slf4j.LocalizedLogger; import org.forgerock.opendj.ldap.ByteSequence; @@ -37,6 +33,12 @@ import com.forgerock.opendj.util.SubstringReader; import static org.forgerock.opendj.ldap.schema.SchemaConstants.*; import static org.forgerock.opendj.ldap.schema.SchemaOptions.*; import static org.forgerock.opendj.ldap.schema.SchemaUtils.*; import static com.forgerock.opendj.ldap.CoreMessages.*; /** * This class defines the attribute type description syntax, which is used to * hold attribute type definitions in the server schema. The format of this @@ -51,43 +53,39 @@ return EMR_OID_FIRST_COMPONENT_OID; } @Override public String getName() { return SYNTAX_ATTRIBUTE_TYPE_NAME; } @Override public boolean isHumanReadable() { return true; } @Override public boolean valueIsAcceptable(final Schema schema, final ByteSequence value, final LocalizableMessageBuilder invalidReason) { final String definition = value.toString(); try { final SubstringReader reader = new SubstringReader(definition); final boolean allowMalformedNamesAndOptions = schema.getOption(ALLOW_MALFORMED_NAMES_AND_OPTIONS); // We'll do this a character at a time. First, skip over any // leading whitespace. reader.skipWhitespaces(); if (reader.remaining() <= 0) { // This means that the definition was empty or contained only // whitespace. That is illegal. final LocalizableMessage message = ERR_ATTR_SYNTAX_ATTRTYPE_EMPTY_VALUE1.get(definition); final DecodeException e = DecodeException.error(message); logger.debug(LocalizableMessage.raw("%s", e)); throw e; // Value was empty or contained only whitespace. This is illegal. throwDecodeException(logger, ERR_ATTR_SYNTAX_ATTRTYPE_EMPTY_VALUE1.get(definition)); } // The next character must be an open parenthesis. If it is not, // then that is an error. final char c = reader.read(); if (c != '(') { final DecodeException e = DecodeException.error( ERR_ATTR_SYNTAX_ATTRTYPE_EXPECTED_OPEN_PARENTHESIS.get( definition, reader.pos() - 1, String.valueOf(c))); logger.debug(LocalizableMessage.raw("%s", e)); throw e; throwDecodeException(logger, ERR_ATTR_SYNTAX_ATTRTYPE_EXPECTED_OPEN_PARENTHESIS.get( definition, reader.pos() - 1, String.valueOf(c))); } // Skip over any spaces immediately following the opening @@ -95,7 +93,7 @@ reader.skipWhitespaces(); // The next set of characters must be the OID. SchemaUtils.readOID(reader, schema.allowMalformedNamesAndOptions()); readOID(reader, allowMalformedNamesAndOptions); // At this point, we should have a pretty specific syntax that // describes what may come next, but some of the components are @@ -112,12 +110,12 @@ // No more tokens. break; } else if ("name".equalsIgnoreCase(tokenName)) { SchemaUtils.readNameDescriptors(reader, schema.allowMalformedNamesAndOptions()); readNameDescriptors(reader, allowMalformedNamesAndOptions); } else if ("desc".equalsIgnoreCase(tokenName)) { // This specifies the description for the attribute type. It // is an arbitrary string of characters enclosed in single // quotes. SchemaUtils.readQuotedString(reader); readQuotedString(reader); } else if ("obsolete".equalsIgnoreCase(tokenName)) { // This indicates whether the attribute type should be // considered obsolete. We do not need to do any more @@ -126,19 +124,19 @@ // This specifies the name or OID of the superior attribute // type from which this attribute type should inherit its // properties. SchemaUtils.readOID(reader, schema.allowMalformedNamesAndOptions()); readOID(reader, allowMalformedNamesAndOptions); } else if ("equality".equalsIgnoreCase(tokenName)) { // This specifies the name or OID of the equality matching // rule to use for this attribute type. SchemaUtils.readOID(reader, schema.allowMalformedNamesAndOptions()); readOID(reader, allowMalformedNamesAndOptions); } else if ("ordering".equalsIgnoreCase(tokenName)) { // This specifies the name or OID of the ordering matching // rule to use for this attribute type. SchemaUtils.readOID(reader, schema.allowMalformedNamesAndOptions()); readOID(reader, allowMalformedNamesAndOptions); } else if ("substr".equalsIgnoreCase(tokenName)) { // This specifies the name or OID of the substring matching // rule to use for this attribute type. SchemaUtils.readOID(reader, schema.allowMalformedNamesAndOptions()); readOID(reader, allowMalformedNamesAndOptions); } else if ("syntax".equalsIgnoreCase(tokenName)) { // This specifies the numeric OID of the syntax for this // matching rule. It may optionally be immediately followed @@ -150,7 +148,7 @@ // does // not impose any practical limit on the length of attribute // values. SchemaUtils.readOIDLen(reader, schema.allowMalformedNamesAndOptions()); readOIDLen(reader, allowMalformedNamesAndOptions); } else if ("single-definition".equalsIgnoreCase(tokenName)) { // This indicates that attributes of this type are allowed to // have at most one definition. We do not need any more @@ -187,12 +185,8 @@ && !"directoryoperation".equalsIgnoreCase(usageStr) && !"distributedoperation".equalsIgnoreCase(usageStr) && !"dsaoperation".equalsIgnoreCase(usageStr)) { final LocalizableMessage message = WARN_ATTR_SYNTAX_ATTRTYPE_INVALID_ATTRIBUTE_USAGE1.get(definition, usageStr); final DecodeException e = DecodeException.error(message); logger.debug(LocalizableMessage.raw("%s", e)); throw e; throwDecodeException(logger, WARN_ATTR_SYNTAX_ATTRTYPE_INVALID_ATTRIBUTE_USAGE1.get(definition, usageStr)); } } else if (tokenName.matches("^X-[A-Za-z_-]+$")) { // This must be a non-standard property and it must be @@ -202,11 +196,8 @@ // parenthesis. SchemaUtils.readExtensions(reader); } else { final LocalizableMessage message = ERR_ATTR_SYNTAX_ATTRTYPE_ILLEGAL_TOKEN1.get(definition, tokenName); final DecodeException e = DecodeException.error(message); logger.debug(LocalizableMessage.raw("%s", e)); throw e; throwDecodeException(logger, ERR_ATTR_SYNTAX_ATTRTYPE_ILLEGAL_TOKEN1.get(definition, tokenName)); } } return true; opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/schema/CertificateSyntaxImpl.java
@@ -38,6 +38,7 @@ import static org.forgerock.opendj.ldap.schema.SchemaConstants.EMR_CERTIFICATE_EXACT_OID; import static org.forgerock.opendj.ldap.schema.SchemaConstants.OMR_OCTET_STRING_OID; import static org.forgerock.opendj.ldap.schema.SchemaConstants.SYNTAX_CERTIFICATE_NAME; import static org.forgerock.opendj.ldap.schema.SchemaOptions.*; import static org.forgerock.opendj.io.ASN1.*; import com.forgerock.opendj.util.StaticUtils; @@ -89,7 +90,7 @@ public boolean valueIsAcceptable(final Schema schema, final ByteSequence value, final LocalizableMessageBuilder invalidReason) { // Skip validation if strict validation is disabled. if (schema.allowMalformedCertificates()) { if (schema.getOption(ALLOW_MALFORMED_CERTIFICATES)) { return true; } opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/schema/DITContentRuleSyntaxImpl.java
@@ -26,10 +26,6 @@ */ package org.forgerock.opendj.ldap.schema; import static com.forgerock.opendj.ldap.CoreMessages.*; import static org.forgerock.opendj.ldap.schema.SchemaConstants.*; import org.forgerock.i18n.LocalizableMessage; import org.forgerock.i18n.LocalizableMessageBuilder; import org.forgerock.i18n.slf4j.LocalizedLogger; import org.forgerock.opendj.ldap.ByteSequence; @@ -37,6 +33,12 @@ import com.forgerock.opendj.util.SubstringReader; import static org.forgerock.opendj.ldap.schema.SchemaConstants.*; import static org.forgerock.opendj.ldap.schema.SchemaOptions.*; import static org.forgerock.opendj.ldap.schema.SchemaUtils.*; import static com.forgerock.opendj.ldap.CoreMessages.*; /** * This class implements the DIT content rule description syntax, which is used * to hold DIT content rule definitions in the server schema. The format of this @@ -75,28 +77,24 @@ if (reader.remaining() <= 0) { // This means that the value was empty or contained only // whitespace. That is illegal. final LocalizableMessage message = ERR_ATTR_SYNTAX_DCR_EMPTY_VALUE1.get(definition); final DecodeException e = DecodeException.error(message); logger.debug(LocalizableMessage.raw("%s", e)); throw e; throwDecodeException(logger, ERR_ATTR_SYNTAX_DCR_EMPTY_VALUE1.get(definition)); } // The next character must be an open parenthesis. If it is not, // then that is an error. final char c = reader.read(); if (c != '(') { final DecodeException e = DecodeException.error( ERR_ATTR_SYNTAX_DCR_EXPECTED_OPEN_PARENTHESIS.get(definition, reader.pos() - 1, c)); logger.debug(LocalizableMessage.raw("%s", e)); throw e; throwDecodeException(logger, ERR_ATTR_SYNTAX_DCR_EXPECTED_OPEN_PARENTHESIS.get(definition, reader.pos() - 1, c)); } // Skip over any spaces immediately following the opening // parenthesis. reader.skipWhitespaces(); final boolean allowMalformedNamesAndOptions = schema.getOption(ALLOW_MALFORMED_NAMES_AND_OPTIONS); // The next set of characters must be the OID. SchemaUtils.readOID(reader, schema.allowMalformedNamesAndOptions()); readOID(reader, allowMalformedNamesAndOptions); // At this point, we should have a pretty specific syntax that // describes what may come next, but some of the components are @@ -107,49 +105,44 @@ // the end of the value. But before we start, set default values // for everything else we might need to know. while (true) { final String tokenName = SchemaUtils.readTokenName(reader); final String tokenName = readTokenName(reader); if (tokenName == null) { // No more tokens. break; } else if ("name".equalsIgnoreCase(tokenName)) { SchemaUtils.readNameDescriptors(reader, schema.allowMalformedNamesAndOptions()); readNameDescriptors(reader, allowMalformedNamesAndOptions); } else if ("desc".equalsIgnoreCase(tokenName)) { // This specifies the description for the attribute type. It // is an arbitrary string of characters enclosed in single // quotes. SchemaUtils.readQuotedString(reader); readQuotedString(reader); } else if ("obsolete".equalsIgnoreCase(tokenName)) { // This indicates whether the attribute type should be // considered obsolete. We do not need to do any more // parsing for this token. } else if ("aux".equalsIgnoreCase(tokenName)) { SchemaUtils.readOIDs(reader, schema.allowMalformedNamesAndOptions()); readOIDs(reader, allowMalformedNamesAndOptions); } else if ("must".equalsIgnoreCase(tokenName)) { SchemaUtils.readOIDs(reader, schema.allowMalformedNamesAndOptions()); readOIDs(reader, allowMalformedNamesAndOptions); } else if ("may".equalsIgnoreCase(tokenName)) { SchemaUtils.readOIDs(reader, schema.allowMalformedNamesAndOptions()); readOIDs(reader, allowMalformedNamesAndOptions); } else if ("not".equalsIgnoreCase(tokenName)) { SchemaUtils.readOIDs(reader, schema.allowMalformedNamesAndOptions()); readOIDs(reader, allowMalformedNamesAndOptions); } else if (tokenName.matches("^X-[A-Za-z_-]+$")) { // This must be a non-standard property and it must be // followed by either a single definition in single quotes // or an open parenthesis followed by one or more values in // single quotes separated by spaces followed by a close // parenthesis. SchemaUtils.readExtensions(reader); readExtensions(reader); } else { final LocalizableMessage message = ERR_ATTR_SYNTAX_DCR_ILLEGAL_TOKEN1.get(definition, tokenName); final DecodeException e = DecodeException.error(message); logger.debug(LocalizableMessage.raw("%s", e)); throw e; throwDecodeException(logger, ERR_ATTR_SYNTAX_DCR_ILLEGAL_TOKEN1.get(definition, tokenName)); } } return true; } catch (final DecodeException de) { invalidReason.append(ERR_ATTR_SYNTAX_DCR_INVALID1 .get(definition, de.getMessageObject())); invalidReason.append(ERR_ATTR_SYNTAX_DCR_INVALID1.get(definition, de.getMessageObject())); return false; } } opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/schema/DITStructureRuleSyntaxImpl.java
@@ -26,10 +26,6 @@ */ package org.forgerock.opendj.ldap.schema; import static com.forgerock.opendj.ldap.CoreMessages.*; import static org.forgerock.opendj.ldap.schema.SchemaConstants.*; import org.forgerock.i18n.LocalizableMessage; import org.forgerock.i18n.LocalizableMessageBuilder; import org.forgerock.i18n.slf4j.LocalizedLogger; import org.forgerock.opendj.ldap.ByteSequence; @@ -37,6 +33,12 @@ import com.forgerock.opendj.util.SubstringReader; import static org.forgerock.opendj.ldap.schema.SchemaConstants.*; import static org.forgerock.opendj.ldap.schema.SchemaOptions.*; import static org.forgerock.opendj.ldap.schema.SchemaUtils.*; import static com.forgerock.opendj.ldap.CoreMessages.*; /** * This class implements the DIT structure rule description syntax, which is * used to hold DIT structure rule definitions in the server schema. The format @@ -51,14 +53,17 @@ return EMR_INTEGER_FIRST_COMPONENT_OID; } @Override public String getName() { return SYNTAX_DIT_STRUCTURE_RULE_NAME; } @Override public boolean isHumanReadable() { return true; } @Override public boolean valueIsAcceptable(final Schema schema, final ByteSequence value, final LocalizableMessageBuilder invalidReason) { // We'll use the decodeDITStructureRule method to determine if the @@ -72,22 +77,16 @@ reader.skipWhitespaces(); if (reader.remaining() <= 0) { // This means that the value was empty or contained only // whitespace. That is illegal. final LocalizableMessage message = ERR_ATTR_SYNTAX_DSR_EMPTY_VALUE1.get(definition); final DecodeException e = DecodeException.error(message); logger.debug(LocalizableMessage.raw("%s", e)); throw e; // Value was empty or contained only whitespace. This is illegal. throwDecodeException(logger, ERR_ATTR_SYNTAX_DSR_EMPTY_VALUE1.get(definition)); } // The next character must be an open parenthesis. If it is not, // then that is an error. final char c = reader.read(); if (c != '(') { final DecodeException e = DecodeException.error( ERR_ATTR_SYNTAX_DSR_EXPECTED_OPEN_PARENTHESIS.get(definition, reader.pos() - 1, c)); logger.debug(LocalizableMessage.raw("%s", e)); throw e; throwDecodeException(logger, ERR_ATTR_SYNTAX_DSR_EXPECTED_OPEN_PARENTHESIS.get(definition, reader.pos() - 1, c)); } // Skip over any spaces immediately following the opening @@ -95,7 +94,7 @@ reader.skipWhitespaces(); // The next set of characters must be the OID. SchemaUtils.readRuleID(reader); readRuleID(reader); String nameForm = null; @@ -108,52 +107,44 @@ // the end of the value. But before we start, set default values // for everything else we might need to know. while (true) { final String tokenName = SchemaUtils.readTokenName(reader); final String tokenName = readTokenName(reader); if (tokenName == null) { // No more tokens. break; } else if ("name".equalsIgnoreCase(tokenName)) { SchemaUtils.readNameDescriptors(reader, schema.allowMalformedNamesAndOptions()); readNameDescriptors(reader, schema.getOption(ALLOW_MALFORMED_NAMES_AND_OPTIONS)); } else if ("desc".equalsIgnoreCase(tokenName)) { // This specifies the description for the attribute type. It // is an arbitrary string of characters enclosed in single // quotes. SchemaUtils.readQuotedString(reader); readQuotedString(reader); } else if ("obsolete".equalsIgnoreCase(tokenName)) { // This indicates whether the attribute type should be // considered obsolete. We do not need to do any more // parsing for this token. } else if ("form".equalsIgnoreCase(tokenName)) { nameForm = SchemaUtils.readOID(reader, schema.allowMalformedNamesAndOptions()); nameForm = readOID(reader, schema.getOption(ALLOW_MALFORMED_NAMES_AND_OPTIONS)); } else if ("sup".equalsIgnoreCase(tokenName)) { SchemaUtils.readRuleIDs(reader); readRuleIDs(reader); } else if (tokenName.matches("^X-[A-Za-z_-]+$")) { // This must be a non-standard property and it must be // followed by either a single definition in single quotes // or an open parenthesis followed by one or more values in // single quotes separated by spaces followed by a close // parenthesis. SchemaUtils.readExtensions(reader); readExtensions(reader); } else { final LocalizableMessage message = ERR_ATTR_SYNTAX_DSR_ILLEGAL_TOKEN1.get(definition, tokenName); final DecodeException e = DecodeException.error(message); logger.debug(LocalizableMessage.raw("%s", e)); throw e; throwDecodeException(logger, ERR_ATTR_SYNTAX_DSR_ILLEGAL_TOKEN1.get(definition, tokenName)); } } if (nameForm == null) { final LocalizableMessage message = ERR_ATTR_SYNTAX_DSR_NO_NAME_FORM.get(definition); final DecodeException e = DecodeException.error(message); logger.debug(LocalizableMessage.raw("%s", e)); throw e; throwDecodeException(logger, ERR_ATTR_SYNTAX_DSR_NO_NAME_FORM.get(definition)); } return true; } catch (final DecodeException de) { invalidReason.append(ERR_ATTR_SYNTAX_DSR_INVALID1 .get(definition, de.getMessageObject())); invalidReason.append(ERR_ATTR_SYNTAX_DSR_INVALID1.get(definition, de.getMessageObject())); return false; } } opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/schema/DirectoryStringSyntaxImpl.java
@@ -29,6 +29,7 @@ import static com.forgerock.opendj.ldap.CoreMessages.ERR_ATTR_SYNTAX_DIRECTORYSTRING_INVALID_ZEROLENGTH_VALUE; import static org.forgerock.opendj.ldap.schema.SchemaConstants.*; import static org.forgerock.opendj.ldap.schema.SchemaOptions.*; import org.forgerock.i18n.LocalizableMessageBuilder; import org.forgerock.opendj.ldap.ByteSequence; @@ -84,11 +85,10 @@ */ public boolean valueIsAcceptable(final Schema schema, final ByteSequence value, final LocalizableMessageBuilder invalidReason) { if (value.length() > 0 || schema.allowZeroLengthDirectoryStrings()) { if (value.length() > 0 || schema.getOption(ALLOW_ZERO_LENGTH_DIRECTORY_STRINGS)) { return true; } else { invalidReason.append(ERR_ATTR_SYNTAX_DIRECTORYSTRING_INVALID_ZEROLENGTH_VALUE.get()); return false; } invalidReason.append(ERR_ATTR_SYNTAX_DIRECTORYSTRING_INVALID_ZEROLENGTH_VALUE.get()); return false; } } opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/schema/EnhancedGuideSyntaxImpl.java
@@ -29,9 +29,12 @@ import static com.forgerock.opendj.util.StaticUtils.toLowerCase; import static com.forgerock.opendj.ldap.CoreMessages.*; import static org.forgerock.opendj.ldap.schema.SchemaConstants.EMR_OCTET_STRING_OID; import static org.forgerock.opendj.ldap.schema.SchemaConstants.OMR_OCTET_STRING_OID; import static org.forgerock.opendj.ldap.schema.SchemaConstants.SYNTAX_ENHANCED_GUIDE_NAME; import static org.forgerock.opendj.ldap.schema.SchemaOptions.*; import static org.forgerock.opendj.ldap.schema.SchemaUtils.*; import org.forgerock.i18n.LocalizableMessageBuilder; import org.forgerock.opendj.ldap.ByteSequence; @@ -50,6 +53,7 @@ return EMR_OCTET_STRING_OID; } @Override public String getName() { return SYNTAX_ENHANCED_GUIDE_NAME; } @@ -59,6 +63,7 @@ return OMR_OCTET_STRING_OID; } @Override public boolean isHumanReadable() { return true; } @@ -77,8 +82,9 @@ * @return <CODE>true</CODE> if the provided value is acceptable for use * with this syntax, or <CODE>false</CODE> if not. */ @Override public boolean valueIsAcceptable(final Schema schema, final ByteSequence value, final LocalizableMessageBuilder invalidReason) { final LocalizableMessageBuilder invalidReason) { // Get a lowercase string version of the provided value. final String valueStr = toLowerCase(value.toString()); @@ -99,8 +105,8 @@ } try { SchemaUtils.readOID(new SubstringReader(ocName.substring(ocLength)), schema .allowMalformedNamesAndOptions()); readOID(new SubstringReader(ocName.substring(ocLength)), schema.getOption(ALLOW_MALFORMED_NAMES_AND_OPTIONS)); } catch (final DecodeException de) { invalidReason.append(de.getMessageObject()); return false; @@ -116,12 +122,12 @@ final String scopeStr = valueStr.substring(lastSharpPos + 1).trim(); if (!"baseobject".equals(scopeStr) && !"onelevel".equals(scopeStr) && !"wholesubtree".equals(scopeStr) && !"subordinatesubtree".equals(scopeStr)) { && !"wholesubtree".equals(scopeStr) && !"subordinatesubtree".equals(scopeStr)) { if (scopeStr.length() == 0) { invalidReason.append(ERR_ATTR_SYNTAX_ENHANCEDGUIDE_NO_SCOPE.get(valueStr)); } else { invalidReason.append(ERR_ATTR_SYNTAX_ENHANCEDGUIDE_INVALID_SCOPE.get(valueStr, scopeStr)); scopeStr)); } return false; } opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/schema/GuideSyntaxImpl.java
@@ -29,9 +29,12 @@ import static com.forgerock.opendj.util.StaticUtils.toLowerCase; import static com.forgerock.opendj.ldap.CoreMessages.*; import static org.forgerock.opendj.ldap.schema.SchemaConstants.EMR_OCTET_STRING_OID; import static org.forgerock.opendj.ldap.schema.SchemaConstants.OMR_OCTET_STRING_OID; import static org.forgerock.opendj.ldap.schema.SchemaConstants.SYNTAX_GUIDE_NAME; import static org.forgerock.opendj.ldap.schema.SchemaOptions.*; import static org.forgerock.opendj.ldap.schema.SchemaUtils.*; import org.forgerock.i18n.LocalizableMessageBuilder; import org.forgerock.opendj.ldap.ByteSequence; @@ -180,8 +183,8 @@ return false; } else { try { SchemaUtils.readOID(new SubstringReader(criteria.substring(0, dollarPos)), schema .allowMalformedNamesAndOptions()); readOID(new SubstringReader(criteria.substring(0, dollarPos)), schema.getOption(ALLOW_MALFORMED_NAMES_AND_OPTIONS)); } catch (final DecodeException de) { invalidReason.append(de.getMessageObject()); return false; @@ -272,6 +275,7 @@ return EMR_OCTET_STRING_OID; } @Override public String getName() { return SYNTAX_GUIDE_NAME; } @@ -281,6 +285,7 @@ return OMR_OCTET_STRING_OID; } @Override public boolean isHumanReadable() { return true; } @@ -299,6 +304,7 @@ * @return <CODE>true</CODE> if the provided value is acceptable for use * with this syntax, or <CODE>false</CODE> if not. */ @Override public boolean valueIsAcceptable(final Schema schema, final ByteSequence value, final LocalizableMessageBuilder invalidReason) { // Get a lowercase string version of the provided value. @@ -320,8 +326,8 @@ } try { SchemaUtils.readOID(new SubstringReader(ocName.substring(0, ocLength)), schema .allowMalformedNamesAndOptions()); readOID(new SubstringReader(ocName.substring(0, ocLength)), schema.getOption(ALLOW_MALFORMED_NAMES_AND_OPTIONS)); } catch (final DecodeException de) { invalidReason.append(de.getMessageObject()); return false; opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/schema/JPEGSyntaxImpl.java
@@ -30,6 +30,7 @@ import org.forgerock.opendj.ldap.ByteSequence; import static org.forgerock.opendj.ldap.schema.SchemaConstants.*; import static org.forgerock.opendj.ldap.schema.SchemaOptions.*; /** * This class implements the JPEG attribute syntax. This is actually @@ -75,7 +76,7 @@ @Override public boolean valueIsAcceptable(final Schema schema, final ByteSequence value, final LocalizableMessageBuilder invalidReason) { return schema.allowMalformedJPEGPhotos() || isValidJfif(value) || isValidExif(value); return schema.getOption(ALLOW_MALFORMED_JPEG_PHOTOS) || isValidJfif(value) || isValidExif(value); } /** opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/schema/LDAPSyntaxDescriptionSyntaxImpl.java
@@ -26,9 +26,6 @@ */ package org.forgerock.opendj.ldap.schema; import static com.forgerock.opendj.ldap.CoreMessages.*; import static org.forgerock.opendj.ldap.schema.SchemaConstants.*; import java.util.Collections; import java.util.HashMap; import java.util.Iterator; @@ -36,7 +33,6 @@ import java.util.Map; import java.util.regex.Pattern; import org.forgerock.i18n.LocalizableMessage; import org.forgerock.i18n.LocalizableMessageBuilder; import org.forgerock.i18n.slf4j.LocalizedLogger; import org.forgerock.opendj.ldap.ByteSequence; @@ -44,6 +40,12 @@ import com.forgerock.opendj.util.SubstringReader; import static org.forgerock.opendj.ldap.schema.SchemaConstants.*; import static org.forgerock.opendj.ldap.schema.SchemaOptions.*; import static org.forgerock.opendj.ldap.schema.SchemaUtils.*; import static com.forgerock.opendj.ldap.CoreMessages.*; /** * This class defines the LDAP syntax description syntax, which is used to hold * attribute syntax definitions in the schema. The format of this syntax is @@ -58,14 +60,17 @@ return EMR_OID_FIRST_COMPONENT_OID; } @Override public String getName() { return SYNTAX_LDAP_SYNTAX_NAME; } @Override public boolean isHumanReadable() { return true; } @Override public boolean valueIsAcceptable(final Schema schema, final ByteSequence value, final LocalizableMessageBuilder invalidReason) { // We'll use the decodeNameForm method to determine if the value is @@ -79,23 +84,16 @@ reader.skipWhitespaces(); if (reader.remaining() <= 0) { // This means that the value was empty or contained only // whitespace. That is illegal. final LocalizableMessage message = ERR_ATTR_SYNTAX_ATTRSYNTAX_EMPTY_VALUE1.get(definition); final DecodeException e = DecodeException.error(message); logger.debug(LocalizableMessage.raw("%s", e)); throw e; // Value was empty or contained only whitespace. This is illegal. throwDecodeException(logger, ERR_ATTR_SYNTAX_ATTRSYNTAX_EMPTY_VALUE1.get(definition)); } // The next character must be an open parenthesis. If it is not, // then that is an error. final char c = reader.read(); if (c != '(') { final DecodeException e = DecodeException.error( ERR_ATTR_SYNTAX_ATTRSYNTAX_EXPECTED_OPEN_PARENTHESIS.get(definition, reader.pos() - 1, c)); logger.debug(LocalizableMessage.raw("%s", e)); throw e; throwDecodeException(logger, ERR_ATTR_SYNTAX_ATTRSYNTAX_EXPECTED_OPEN_PARENTHESIS.get(definition, reader.pos() - 1, c)); } // Skip over any spaces immediately following the opening @@ -103,7 +101,7 @@ reader.skipWhitespaces(); // The next set of characters must be the OID. final String oid = SchemaUtils.readOID(reader, schema.allowMalformedNamesAndOptions()); final String oid = readOID(reader, schema.getOption(ALLOW_MALFORMED_NAMES_AND_OPTIONS)); Map<String, List<String>> extraProperties = Collections.emptyMap(); // At this point, we should have a pretty specific syntax that @@ -135,11 +133,7 @@ } extraProperties.put(tokenName, SchemaUtils.readExtensions(reader)); } else { final LocalizableMessage message = ERR_ATTR_SYNTAX_ATTRSYNTAX_ILLEGAL_TOKEN1.get(definition, tokenName); final DecodeException e = DecodeException.error(message); logger.debug(LocalizableMessage.raw("%s", e)); throw e; throwDecodeException(logger, ERR_ATTR_SYNTAX_ATTRSYNTAX_ILLEGAL_TOKEN1.get(definition, tokenName)); } } @@ -151,12 +145,8 @@ try { Pattern.compile(values.next()); } catch (final Exception e) { final LocalizableMessage message = WARN_ATTR_SYNTAX_LDAPSYNTAX_REGEX_INVALID_PATTERN.get(oid, pattern); final DecodeException de = DecodeException.error(message, e); logger.debug(LocalizableMessage.raw("%s", e)); throw de; throwDecodeException(logger, WARN_ATTR_SYNTAX_LDAPSYNTAX_REGEX_INVALID_PATTERN.get(oid, pattern)); } break; } @@ -166,11 +156,8 @@ final String entry = values.get(i); for (int j = i + 1; j < values.size(); j++) { if (entry.equals(values.get(j))) { final LocalizableMessage message = WARN_ATTR_SYNTAX_LDAPSYNTAX_ENUM_DUPLICATE_VALUE.get(oid, entry, j); final DecodeException e = DecodeException.error(message); logger.debug(LocalizableMessage.raw("%s", e)); throw e; throwDecodeException(logger, WARN_ATTR_SYNTAX_LDAPSYNTAX_ENUM_DUPLICATE_VALUE.get(oid, entry, j)); } } } @@ -179,8 +166,7 @@ return true; } catch (final DecodeException de) { invalidReason.append(ERR_ATTR_SYNTAX_ATTRSYNTAX_INVALID1.get(definition, de .getMessageObject())); invalidReason.append(ERR_ATTR_SYNTAX_ATTRSYNTAX_INVALID1.get(definition, de.getMessageObject())); return false; } } opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/schema/MatchingRuleSyntaxImpl.java
@@ -26,10 +26,6 @@ */ package org.forgerock.opendj.ldap.schema; import static com.forgerock.opendj.ldap.CoreMessages.*; import static org.forgerock.opendj.ldap.schema.SchemaConstants.*; import org.forgerock.i18n.LocalizableMessage; import org.forgerock.i18n.LocalizableMessageBuilder; import org.forgerock.i18n.slf4j.LocalizedLogger; import org.forgerock.opendj.ldap.ByteSequence; @@ -37,6 +33,12 @@ import com.forgerock.opendj.util.SubstringReader; import static org.forgerock.opendj.ldap.schema.SchemaConstants.*; import static org.forgerock.opendj.ldap.schema.SchemaOptions.*; import static org.forgerock.opendj.ldap.schema.SchemaUtils.*; import static com.forgerock.opendj.ldap.CoreMessages.*; /** * This class implements the matching rule description syntax, which is used to * hold matching rule definitions in the server schema. The format of this @@ -51,10 +53,12 @@ return EMR_OID_FIRST_COMPONENT_OID; } @Override public String getName() { return SYNTAX_MATCHING_RULE_NAME; } @Override public boolean isHumanReadable() { return true; } @@ -73,6 +77,7 @@ * @return <CODE>true</CODE> if the provided value is acceptable for use * with this syntax, or <CODE>false</CODE> if not. */ @Override public boolean valueIsAcceptable(final Schema schema, final ByteSequence value, final LocalizableMessageBuilder invalidReason) { // We'll use the decodeMatchingRule method to determine if the value @@ -86,23 +91,16 @@ reader.skipWhitespaces(); if (reader.remaining() <= 0) { // This means that the value was empty or contained only // whitespace. That is illegal. final LocalizableMessage message = ERR_ATTR_SYNTAX_MR_EMPTY_VALUE1.get(definition); final DecodeException e = DecodeException.error(message); logger.debug(LocalizableMessage.raw("%s", e)); throw e; // Value was empty or contained only whitespace. This is illegal. throwDecodeException(logger, ERR_ATTR_SYNTAX_MR_EMPTY_VALUE1.get(definition)); } // The next character must be an open parenthesis. If it is not, // then that is an error. final char c = reader.read(); if (c != '(') { final LocalizableMessage message = ERR_ATTR_SYNTAX_MR_EXPECTED_OPEN_PARENTHESIS.get(definition, reader.pos() - 1, c); final DecodeException e = DecodeException.error(message); logger.debug(LocalizableMessage.raw("%s", e)); throw e; throwDecodeException(logger, ERR_ATTR_SYNTAX_MR_EXPECTED_OPEN_PARENTHESIS.get(definition, reader.pos() - 1, c)); } // Skip over any spaces immediately following the opening @@ -110,7 +108,8 @@ reader.skipWhitespaces(); // The next set of characters must be the OID. SchemaUtils.readOID(reader, schema.allowMalformedNamesAndOptions()); final boolean allowMalformedNamesAndOptions = schema.getOption(ALLOW_MALFORMED_NAMES_AND_OPTIONS); readOID(reader, allowMalformedNamesAndOptions); String syntax = null; // At this point, we should have a pretty specific syntax that @@ -128,46 +127,38 @@ // No more tokens. break; } else if ("name".equalsIgnoreCase(tokenName)) { SchemaUtils.readNameDescriptors(reader, schema.allowMalformedNamesAndOptions()); readNameDescriptors(reader, allowMalformedNamesAndOptions); } else if ("desc".equalsIgnoreCase(tokenName)) { // This specifies the description for the matching rule. It // is // an arbitrary string of characters enclosed in single // quotes. SchemaUtils.readQuotedString(reader); readQuotedString(reader); } else if ("obsolete".equalsIgnoreCase(tokenName)) { // This indicates whether the matching rule should be // considered obsolete. We do not need to do any more // parsing for this token. } else if ("syntax".equalsIgnoreCase(tokenName)) { syntax = SchemaUtils.readOID(reader, schema.allowMalformedNamesAndOptions()); syntax = readOID(reader, allowMalformedNamesAndOptions); } else if (tokenName.matches("^X-[A-Za-z_-]+$")) { // This must be a non-standard property and it must be // followed by either a single definition in single quotes // or an open parenthesis followed by one or more values in // single quotes separated by spaces followed by a close // parenthesis. SchemaUtils.readExtensions(reader); readExtensions(reader); } else { final LocalizableMessage message = ERR_ATTR_SYNTAX_MR_ILLEGAL_TOKEN1.get(definition, tokenName); final DecodeException e = DecodeException.error(message); logger.debug(LocalizableMessage.raw("%s", e)); throw e; throwDecodeException(logger, ERR_ATTR_SYNTAX_MR_ILLEGAL_TOKEN1.get(definition, tokenName)); } } // Make sure that a syntax was specified. if (syntax == null) { final LocalizableMessage message = ERR_ATTR_SYNTAX_MR_NO_SYNTAX.get(definition); final DecodeException e = DecodeException.error(message); logger.debug(LocalizableMessage.raw("%s", e)); throw e; throwDecodeException(logger, ERR_ATTR_SYNTAX_MR_NO_SYNTAX.get(definition)); } return true; } catch (final DecodeException de) { invalidReason .append(ERR_ATTR_SYNTAX_MR_INVALID1.get(definition, de.getMessageObject())); invalidReason.append(ERR_ATTR_SYNTAX_MR_INVALID1.get(definition, de.getMessageObject())); return false; } } opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/schema/MatchingRuleUseSyntaxImpl.java
@@ -26,13 +26,8 @@ */ package org.forgerock.opendj.ldap.schema; import static com.forgerock.opendj.ldap.CoreMessages.*; import static org.forgerock.opendj.ldap.schema.SchemaConstants.EMR_OID_FIRST_COMPONENT_OID; import static org.forgerock.opendj.ldap.schema.SchemaConstants.SYNTAX_MATCHING_RULE_USE_NAME; import java.util.Set; import org.forgerock.i18n.LocalizableMessage; import org.forgerock.i18n.LocalizableMessageBuilder; import org.forgerock.i18n.slf4j.LocalizedLogger; import org.forgerock.opendj.ldap.ByteSequence; @@ -40,6 +35,12 @@ import com.forgerock.opendj.util.SubstringReader; import static org.forgerock.opendj.ldap.schema.SchemaConstants.*; import static org.forgerock.opendj.ldap.schema.SchemaOptions.*; import static org.forgerock.opendj.ldap.schema.SchemaUtils.*; import static com.forgerock.opendj.ldap.CoreMessages.*; /** * This class implements the matching rule use description syntax, which is used * to hold matching rule use definitions in the server schema. The format of @@ -54,10 +55,12 @@ return EMR_OID_FIRST_COMPONENT_OID; } @Override public String getName() { return SYNTAX_MATCHING_RULE_USE_NAME; } @Override public boolean isHumanReadable() { return true; } @@ -76,6 +79,7 @@ * @return <CODE>true</CODE> if the provided value is acceptable for use * with this syntax, or <CODE>false</CODE> if not. */ @Override public boolean valueIsAcceptable(final Schema schema, final ByteSequence value, final LocalizableMessageBuilder invalidReason) { // We'll use the decodeAttributeType method to determine if the @@ -89,24 +93,16 @@ reader.skipWhitespaces(); if (reader.remaining() <= 0) { // This means that the value was empty or contained only // whitespace. That is illegal. final LocalizableMessage message = ERR_ATTR_SYNTAX_MRUSE_EMPTY_VALUE1.get(definition); final DecodeException e = DecodeException.error(message); logger.debug(LocalizableMessage.raw("%s", e)); throw e; // Value was empty or contained only whitespace. This is illegal. throwDecodeException(logger, ERR_ATTR_SYNTAX_MRUSE_EMPTY_VALUE1.get(definition)); } // The next character must be an open parenthesis. If it is not, // then that is an error. final char c = reader.read(); if (c != '(') { final LocalizableMessage message = ERR_ATTR_SYNTAX_MRUSE_EXPECTED_OPEN_PARENTHESIS.get(definition, reader.pos() - 1, c); final DecodeException e = DecodeException.error(message); logger.debug(LocalizableMessage.raw("%s", e)); throw e; throwDecodeException(logger, ERR_ATTR_SYNTAX_MRUSE_EXPECTED_OPEN_PARENTHESIS.get(definition, reader.pos() - 1, c)); } // Skip over any spaces immediately following the opening @@ -114,7 +110,8 @@ reader.skipWhitespaces(); // The next set of characters must be the OID. SchemaUtils.readOID(reader, schema.allowMalformedNamesAndOptions()); final boolean allowMalformedNamesAndOptions = schema.getOption(ALLOW_MALFORMED_NAMES_AND_OPTIONS); readOID(reader, allowMalformedNamesAndOptions); // At this point, we should have a pretty specific syntax that // describes what may come next, but some of the components are @@ -126,52 +123,43 @@ // for everything else we might need to know. Set<String> attributes = null; while (true) { final String tokenName = SchemaUtils.readTokenName(reader); final String tokenName = readTokenName(reader); if (tokenName == null) { // No more tokens. break; } else if ("name".equalsIgnoreCase(tokenName)) { SchemaUtils.readNameDescriptors(reader, schema.allowMalformedNamesAndOptions()); readNameDescriptors(reader, allowMalformedNamesAndOptions); } else if ("desc".equalsIgnoreCase(tokenName)) { // This specifies the description for the attribute type. It // is an arbitrary string of characters enclosed in single // quotes. SchemaUtils.readQuotedString(reader); readQuotedString(reader); } else if ("obsolete".equalsIgnoreCase(tokenName)) { // This indicates whether the attribute type should be // considered obsolete. We do not need to do any more // parsing for this token. } else if ("applies".equalsIgnoreCase(tokenName)) { attributes = SchemaUtils.readOIDs(reader, schema.allowMalformedNamesAndOptions()); attributes = readOIDs(reader, allowMalformedNamesAndOptions); } else if (tokenName.matches("^X-[A-Za-z_-]+$")) { // This must be a non-standard property and it must be // followed by either a single definition in single quotes // or an open parenthesis followed by one or more values in // single quotes separated by spaces followed by a close // parenthesis. SchemaUtils.readExtensions(reader); readExtensions(reader); } else { final LocalizableMessage message = ERR_ATTR_SYNTAX_MRUSE_ILLEGAL_TOKEN1.get(definition, tokenName); final DecodeException e = DecodeException.error(message); logger.debug(LocalizableMessage.raw("%s", e)); throw e; throwDecodeException(logger, ERR_ATTR_SYNTAX_MRUSE_ILLEGAL_TOKEN1.get(definition, tokenName)); } } // Make sure that the set of attributes was defined. if (attributes == null || attributes.size() == 0) { final LocalizableMessage message = ERR_ATTR_SYNTAX_MRUSE_NO_ATTR.get(definition); final DecodeException e = DecodeException.error(message); logger.debug(LocalizableMessage.raw("%s", e)); throw e; throwDecodeException(logger, ERR_ATTR_SYNTAX_MRUSE_NO_ATTR.get(definition)); } return true; } catch (final DecodeException de) { invalidReason.append(ERR_ATTR_SYNTAX_MRUSE_INVALID1.get(definition, de .getMessageObject())); invalidReason.append(ERR_ATTR_SYNTAX_MRUSE_INVALID1.get(definition, de.getMessageObject())); return false; } } opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/schema/NameFormSyntaxImpl.java
@@ -26,13 +26,8 @@ */ package org.forgerock.opendj.ldap.schema; import static com.forgerock.opendj.ldap.CoreMessages.*; import static org.forgerock.opendj.ldap.schema.SchemaConstants.EMR_OID_FIRST_COMPONENT_OID; import static org.forgerock.opendj.ldap.schema.SchemaConstants.SYNTAX_NAME_FORM_NAME; import java.util.Set; import org.forgerock.i18n.LocalizableMessage; import org.forgerock.i18n.LocalizableMessageBuilder; import org.forgerock.i18n.slf4j.LocalizedLogger; import org.forgerock.opendj.ldap.ByteSequence; @@ -40,6 +35,12 @@ import com.forgerock.opendj.util.SubstringReader; import static org.forgerock.opendj.ldap.schema.SchemaConstants.*; import static org.forgerock.opendj.ldap.schema.SchemaOptions.*; import static org.forgerock.opendj.ldap.schema.SchemaUtils.*; import static com.forgerock.opendj.ldap.CoreMessages.*; /** * This class implements the name form description syntax, which is used to hold * name form definitions in the server schema. The format of this syntax is @@ -77,22 +78,15 @@ if (reader.remaining() <= 0) { // This means that the value was empty or contained only // whitespace. That is illegal. final LocalizableMessage message = ERR_ATTR_SYNTAX_NAME_FORM_EMPTY_VALUE1.get(definition); final DecodeException e = DecodeException.error(message); logger.debug(LocalizableMessage.raw("%s", e)); throw e; throwDecodeException(logger, ERR_ATTR_SYNTAX_NAME_FORM_EMPTY_VALUE1.get(definition)); } // The next character must be an open parenthesis. If it is not, // then that is an error. final char c = reader.read(); if (c != '(') { final LocalizableMessage message = ERR_ATTR_SYNTAX_NAME_FORM_EXPECTED_OPEN_PARENTHESIS.get(definition, reader.pos() - 1, c); final DecodeException e = DecodeException.error(message); logger.debug(LocalizableMessage.raw("%s", e)); throw e; throwDecodeException(logger, ERR_ATTR_SYNTAX_NAME_FORM_EXPECTED_OPEN_PARENTHESIS.get(definition, reader.pos() - 1, c)); } // Skip over any spaces immediately following the opening @@ -100,7 +94,8 @@ reader.skipWhitespaces(); // The next set of characters must be the OID. SchemaUtils.readOID(reader, schema.allowMalformedNamesAndOptions()); final boolean allowMalformedNamesAndOptions = schema.getOption(ALLOW_MALFORMED_NAMES_AND_OPTIONS); readOID(reader, allowMalformedNamesAndOptions); String structuralClass = null; Set<String> requiredAttributes = null; @@ -114,67 +109,52 @@ // the end of the value. But before we start, set default values // for everything else we might need to know. while (true) { final String tokenName = SchemaUtils.readTokenName(reader); final String tokenName = readTokenName(reader); if (tokenName == null) { // No more tokens. break; } else if ("name".equalsIgnoreCase(tokenName)) { SchemaUtils.readNameDescriptors(reader, schema.allowMalformedNamesAndOptions()); readNameDescriptors(reader, allowMalformedNamesAndOptions); } else if ("desc".equalsIgnoreCase(tokenName)) { // This specifies the description for the attribute type. It // is an arbitrary string of characters enclosed in single // quotes. SchemaUtils.readQuotedString(reader); readQuotedString(reader); } else if ("obsolete".equalsIgnoreCase(tokenName)) { // This indicates whether the attribute type should be // considered obsolete. We do not need to do any more // parsing for this token. } else if ("oc".equalsIgnoreCase(tokenName)) { structuralClass = SchemaUtils.readOID(reader, schema.allowMalformedNamesAndOptions()); structuralClass = readOID(reader, allowMalformedNamesAndOptions); } else if ("must".equalsIgnoreCase(tokenName)) { requiredAttributes = SchemaUtils.readOIDs(reader, schema.allowMalformedNamesAndOptions()); requiredAttributes = readOIDs(reader, allowMalformedNamesAndOptions); } else if ("may".equalsIgnoreCase(tokenName)) { SchemaUtils.readOIDs(reader, schema.allowMalformedNamesAndOptions()); readOIDs(reader, allowMalformedNamesAndOptions); } else if (tokenName.matches("^X-[A-Za-z_-]+$")) { // This must be a non-standard property and it must be // followed by either a single definition in single quotes // or an open parenthesis followed by one or more values in // single quotes separated by spaces followed by a close // parenthesis. SchemaUtils.readExtensions(reader); readExtensions(reader); } else { final LocalizableMessage message = ERR_ATTR_SYNTAX_NAME_FORM_ILLEGAL_TOKEN1.get(definition, tokenName); final DecodeException e = DecodeException.error(message); logger.debug(LocalizableMessage.raw("%s", e)); throw e; throwDecodeException(logger, ERR_ATTR_SYNTAX_NAME_FORM_ILLEGAL_TOKEN1.get(definition, tokenName)); } } // Make sure that a structural class was specified. If not, then // it cannot be valid. if (structuralClass == null) { final LocalizableMessage message = ERR_ATTR_SYNTAX_NAME_FORM_NO_STRUCTURAL_CLASS1.get(definition); final DecodeException e = DecodeException.error(message); logger.debug(LocalizableMessage.raw("%s", e)); throw e; throwDecodeException(logger, ERR_ATTR_SYNTAX_NAME_FORM_NO_STRUCTURAL_CLASS1.get(definition)); } if (requiredAttributes == null || requiredAttributes.size() == 0) { final LocalizableMessage message = ERR_ATTR_SYNTAX_NAME_FORM_NO_REQUIRED_ATTR.get(definition); final DecodeException e = DecodeException.error(message); logger.debug(LocalizableMessage.raw("%s", e)); throw e; throwDecodeException(logger, ERR_ATTR_SYNTAX_NAME_FORM_NO_REQUIRED_ATTR.get(definition)); } return true; } catch (final DecodeException de) { invalidReason.append(ERR_ATTR_SYNTAX_NAME_FORM_INVALID1.get(definition, de .getMessageObject())); invalidReason.append(ERR_ATTR_SYNTAX_NAME_FORM_INVALID1.get(definition, de.getMessageObject())); return false; } } opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/schema/OIDSyntaxImpl.java
@@ -30,6 +30,7 @@ import static org.forgerock.opendj.ldap.schema.SchemaConstants.EMR_OID_OID; import static org.forgerock.opendj.ldap.schema.SchemaConstants.SMR_CASE_IGNORE_OID; import static org.forgerock.opendj.ldap.schema.SchemaConstants.SYNTAX_OID_NAME; import static org.forgerock.opendj.ldap.schema.SchemaOptions.*; import org.forgerock.i18n.LocalizableMessageBuilder; import org.forgerock.opendj.ldap.ByteSequence; @@ -77,8 +78,8 @@ public boolean valueIsAcceptable(final Schema schema, final ByteSequence value, final LocalizableMessageBuilder invalidReason) { try { SchemaUtils.readOID(new SubstringReader(value.toString()), schema .allowMalformedNamesAndOptions()); SchemaUtils.readOID(new SubstringReader(value.toString()), schema.getOption(ALLOW_MALFORMED_NAMES_AND_OPTIONS)); return true; } catch (final DecodeException de) { invalidReason.append(de.getMessageObject()); opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/schema/ObjectClassSyntaxImpl.java
@@ -26,11 +26,6 @@ */ package org.forgerock.opendj.ldap.schema; import static com.forgerock.opendj.ldap.CoreMessages.*; import static org.forgerock.opendj.ldap.schema.SchemaConstants.EMR_OID_FIRST_COMPONENT_OID; import static org.forgerock.opendj.ldap.schema.SchemaConstants.SYNTAX_OBJECTCLASS_NAME; import org.forgerock.i18n.LocalizableMessage; import org.forgerock.i18n.LocalizableMessageBuilder; import org.forgerock.i18n.slf4j.LocalizedLogger; import org.forgerock.opendj.ldap.ByteSequence; @@ -38,6 +33,12 @@ import com.forgerock.opendj.util.SubstringReader; import static org.forgerock.opendj.ldap.schema.SchemaConstants.*; import static org.forgerock.opendj.ldap.schema.SchemaOptions.*; import static org.forgerock.opendj.ldap.schema.SchemaUtils.*; import static com.forgerock.opendj.ldap.CoreMessages.*; /** * This class implements the object class description syntax, which is used to * hold objectclass definitions in the server schema. The format of this syntax @@ -52,14 +53,17 @@ return EMR_OID_FIRST_COMPONENT_OID; } @Override public String getName() { return SYNTAX_OBJECTCLASS_NAME; } @Override public boolean isHumanReadable() { return true; } @Override public boolean valueIsAcceptable(final Schema schema, final ByteSequence value, final LocalizableMessageBuilder invalidReason) { // We'll use the decodeObjectClass method to determine if the value @@ -73,24 +77,16 @@ reader.skipWhitespaces(); if (reader.remaining() <= 0) { // This means that the value was empty or contained only // whitespace. That is illegal. final LocalizableMessage message = ERR_ATTR_SYNTAX_OBJECTCLASS_EMPTY_VALUE1.get(definition); final DecodeException e = DecodeException.error(message); logger.debug(LocalizableMessage.raw("%s", e)); throw e; // Value was empty or contained only whitespace. This is illegal. throwDecodeException(logger, ERR_ATTR_SYNTAX_OBJECTCLASS_EMPTY_VALUE1.get(definition)); } // The next character must be an open parenthesis. If it is not, // then that is an error. final char c = reader.read(); if (c != '(') { final LocalizableMessage message = ERR_ATTR_SYNTAX_OBJECTCLASS_EXPECTED_OPEN_PARENTHESIS1.get(definition, reader.pos() - 1, c); final DecodeException e = DecodeException.error(message); logger.debug(LocalizableMessage.raw("%s", e)); throw e; throwDecodeException(logger, ERR_ATTR_SYNTAX_OBJECTCLASS_EXPECTED_OPEN_PARENTHESIS1.get(definition, reader.pos() - 1, c)); } // Skip over any spaces immediately following the opening @@ -98,7 +94,8 @@ reader.skipWhitespaces(); // The next set of characters must be the OID. SchemaUtils.readOID(reader, schema.allowMalformedNamesAndOptions()); final boolean allowMalformedNamesAndOptions = schema.getOption(ALLOW_MALFORMED_NAMES_AND_OPTIONS); readOID(reader, allowMalformedNamesAndOptions); // At this point, we should have a pretty specific syntax that // describes what may come next, but some of the components are @@ -109,24 +106,24 @@ // the end of the value. But before we start, set default values // for everything else we might need to know. while (true) { final String tokenName = SchemaUtils.readTokenName(reader); final String tokenName = readTokenName(reader); if (tokenName == null) { // No more tokens. break; } else if ("name".equalsIgnoreCase(tokenName)) { SchemaUtils.readNameDescriptors(reader, schema.allowMalformedNamesAndOptions()); readNameDescriptors(reader, allowMalformedNamesAndOptions); } else if ("desc".equalsIgnoreCase(tokenName)) { // This specifies the description for the attribute type. It // is an arbitrary string of characters enclosed in single // quotes. SchemaUtils.readQuotedString(reader); readQuotedString(reader); } else if ("obsolete".equalsIgnoreCase(tokenName)) { // This indicates whether the attribute type should be // considered obsolete. We do not need to do any more // parsing for this token. } else if ("sup".equalsIgnoreCase(tokenName)) { SchemaUtils.readOIDs(reader, schema.allowMalformedNamesAndOptions()); readOIDs(reader, allowMalformedNamesAndOptions); } else if ("abstract".equalsIgnoreCase(tokenName)) { // This indicates that entries must not include this // objectclass unless they also include a non-abstract @@ -139,28 +136,23 @@ // This indicates that this is an auxiliary objectclass. // We do not need any more parsing for this token. } else if ("must".equalsIgnoreCase(tokenName)) { SchemaUtils.readOIDs(reader, schema.allowMalformedNamesAndOptions()); readOIDs(reader, allowMalformedNamesAndOptions); } else if ("may".equalsIgnoreCase(tokenName)) { SchemaUtils.readOIDs(reader, schema.allowMalformedNamesAndOptions()); readOIDs(reader, allowMalformedNamesAndOptions); } else if (tokenName.matches("^X-[A-Za-z_-]+$")) { // This must be a non-standard property and it must be // followed by either a single definition in single quotes // or an open parenthesis followed by one or more values in // single quotes separated by spaces followed by a close // parenthesis. SchemaUtils.readExtensions(reader); readExtensions(reader); } else { final LocalizableMessage message = ERR_ATTR_SYNTAX_OBJECTCLASS_ILLEGAL_TOKEN1.get(definition, tokenName); final DecodeException e = DecodeException.error(message); logger.debug(LocalizableMessage.raw("%s", e)); throw e; throwDecodeException(logger, ERR_ATTR_SYNTAX_OBJECTCLASS_ILLEGAL_TOKEN1.get(definition, tokenName)); } } return true; } catch (final DecodeException de) { invalidReason.append(ERR_ATTR_SYNTAX_OBJECTCLASS_INVALID1.get(definition, de .getMessageObject())); invalidReason.append(ERR_ATTR_SYNTAX_OBJECTCLASS_INVALID1.get(definition, de.getMessageObject())); return false; } } opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/schema/ObjectIdentifierEqualityMatchingRuleImpl.java
@@ -34,6 +34,9 @@ import com.forgerock.opendj.util.StaticUtils; import com.forgerock.opendj.util.SubstringReader; import static org.forgerock.opendj.ldap.schema.SchemaOptions.*; import static org.forgerock.opendj.ldap.schema.SchemaUtils.*; /** * This class defines the objectIdentifierMatch matching rule defined in X.520 * and referenced in RFC 2252. This expects to work on OIDs and will match @@ -81,7 +84,7 @@ throws DecodeException { final String definition = assertionValue.toString(); final SubstringReader reader = new SubstringReader(definition); final String oid = SchemaUtils.readOID(reader, schema.allowMalformedNamesAndOptions()); final String oid = readOID(reader, schema.getOption(ALLOW_MALFORMED_NAMES_AND_OPTIONS)); final String normalized = resolveNames(schema, oid); return DefaultAssertion.equality(ByteString.valueOf(normalized)); } @@ -90,7 +93,7 @@ throws DecodeException { final String definition = value.toString(); final SubstringReader reader = new SubstringReader(definition); final String oid = SchemaUtils.readOID(reader, schema.allowMalformedNamesAndOptions()); final String oid = readOID(reader, schema.getOption(ALLOW_MALFORMED_NAMES_AND_OPTIONS)); final String normalized = resolveNames(schema, oid); return ByteString.valueOf(normalized); } opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/schema/ObjectIdentifierFirstComponentEqualityMatchingRuleImpl.java
@@ -37,6 +37,9 @@ import com.forgerock.opendj.util.SubstringReader; import static org.forgerock.opendj.ldap.schema.SchemaOptions.*; import static org.forgerock.opendj.ldap.schema.SchemaUtils.*; /** * This class implements the objectIdentifierFirstComponentMatch matching rule * defined in X.520 and referenced in RFC 2252. This rule is intended for use @@ -52,11 +55,12 @@ throws DecodeException { final String definition = assertionValue.toString(); final SubstringReader reader = new SubstringReader(definition); final String oid = SchemaUtils.readOID(reader, schema.allowMalformedNamesAndOptions()); final String oid = readOID(reader, schema.getOption(ALLOW_MALFORMED_NAMES_AND_OPTIONS)); final String normalized = ObjectIdentifierEqualityMatchingRuleImpl.resolveNames(schema, oid); return DefaultAssertion.equality(ByteString.valueOf(normalized)); } @Override public ByteString normalizeAttributeValue(final Schema schema, final ByteSequence value) throws DecodeException { final String definition = value.toString(); @@ -67,8 +71,7 @@ reader.skipWhitespaces(); if (reader.remaining() <= 0) { // This means that the value was empty or contained only // whitespace. That is illegal. // Value was empty or contained only whitespace. This is illegal. final LocalizableMessage message = ERR_ATTR_SYNTAX_EMPTY_VALUE.get(); throw DecodeException.error(message); } @@ -85,9 +88,8 @@ reader.skipWhitespaces(); // The next set of characters must be the OID. final String normalized = ObjectIdentifierEqualityMatchingRuleImpl.resolveNames(schema, SchemaUtils.readOID( reader, schema.allowMalformedNamesAndOptions())); final String normalized = ObjectIdentifierEqualityMatchingRuleImpl.resolveNames(schema, readOID(reader, schema.getOption(ALLOW_MALFORMED_NAMES_AND_OPTIONS))); return ByteString.valueOf(normalized); } } opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/schema/Schema.java
@@ -47,6 +47,7 @@ import org.forgerock.opendj.ldap.LdapException; import org.forgerock.opendj.ldap.LdapPromise; import org.forgerock.opendj.ldap.LinkedAttribute; import org.forgerock.opendj.ldap.Option; import org.forgerock.opendj.ldap.RDN; import org.forgerock.util.Reject; import org.forgerock.util.promise.Function; @@ -54,7 +55,6 @@ import com.forgerock.opendj.util.StaticUtils; import static org.forgerock.opendj.ldap.AttributeDescription.*; import static com.forgerock.opendj.ldap.CoreMessages.*; /** @@ -77,15 +77,7 @@ Schema asStrictSchema(); boolean allowMalformedNamesAndOptions(); boolean allowMalformedJPEGPhotos(); boolean allowMalformedCertificates(); boolean allowNonStandardTelephoneNumbers(); boolean allowZeroLengthDirectoryStrings(); SchemaOptions getOptions(); MatchingRule getDefaultMatchingRule(); @@ -186,28 +178,8 @@ } @Override public boolean allowMalformedNamesAndOptions() { return strictImpl.allowMalformedNamesAndOptions(); } @Override public boolean allowMalformedJPEGPhotos() { return strictImpl.allowMalformedJPEGPhotos(); } @Override public boolean allowMalformedCertificates() { return strictImpl.allowMalformedCertificates(); } @Override public boolean allowNonStandardTelephoneNumbers() { return strictImpl.allowNonStandardTelephoneNumbers(); } @Override public boolean allowZeroLengthDirectoryStrings() { return strictImpl.allowZeroLengthDirectoryStrings(); public SchemaOptions getOptions() { return strictImpl.getOptions(); } @Override @@ -439,21 +411,14 @@ private final Map<String, List<NameForm>> objectClass2NameForms; private final List<LocalizableMessage> warnings; private final String schemaName; private final boolean allowMalformedJPEGPhotos; private final boolean allowMalformedCertificates; private final boolean allowNonStandardTelephoneNumbers; private final boolean allowZeroLengthDirectoryStrings; private final boolean allowMalformedNamesAndOptions; private final SchemaOptions options; private final Syntax defaultSyntax; private final MatchingRule defaultMatchingRule; private final Schema strictSchema; private final Schema nonStrictSchema; StrictImpl(final String schemaName, final boolean allowMalformedNamesAndOptions, final boolean allowMalformedJPEGPhotos, final boolean allowMalformedCertificates, final boolean allowNonStandardTelephoneNumbers, final boolean allowZeroLengthDirectoryStrings, StrictImpl(final String schemaName, final SchemaOptions options, final Syntax defaultSyntax, final MatchingRule defaultMatchingRule, final Map<String, Syntax> numericOID2Syntaxes, @@ -475,17 +440,12 @@ final Map<String, List<DITStructureRule>> nameForm2StructureRules, final List<LocalizableMessage> warnings) { this.schemaName = schemaName; this.allowMalformedNamesAndOptions = allowMalformedNamesAndOptions; this.allowMalformedJPEGPhotos = allowMalformedJPEGPhotos; this.allowMalformedCertificates = allowMalformedCertificates; this.allowNonStandardTelephoneNumbers = allowNonStandardTelephoneNumbers; this.allowZeroLengthDirectoryStrings = allowZeroLengthDirectoryStrings; this.options = SchemaOptions.unmodifiable(options); this.defaultSyntax = defaultSyntax; this.defaultMatchingRule = defaultMatchingRule; this.numericOID2Syntaxes = Collections.unmodifiableMap(numericOID2Syntaxes); this.numericOID2MatchingRules = Collections.unmodifiableMap(numericOID2MatchingRules); this.numericOID2MatchingRuleUses = Collections.unmodifiableMap(numericOID2MatchingRuleUses); this.numericOID2MatchingRuleUses = Collections.unmodifiableMap(numericOID2MatchingRuleUses); this.numericOID2AttributeTypes = Collections.unmodifiableMap(numericOID2AttributeTypes); this.numericOID2ObjectClasses = Collections.unmodifiableMap(numericOID2ObjectClasses); this.numericOID2NameForms = Collections.unmodifiableMap(numericOID2NameForms); @@ -516,28 +476,8 @@ } @Override public boolean allowMalformedNamesAndOptions() { return allowMalformedNamesAndOptions; } @Override public boolean allowMalformedJPEGPhotos() { return allowMalformedJPEGPhotos; } @Override public boolean allowMalformedCertificates() { return allowMalformedCertificates; } @Override public boolean allowNonStandardTelephoneNumbers() { return allowNonStandardTelephoneNumbers; } @Override public boolean allowZeroLengthDirectoryStrings() { return allowZeroLengthDirectoryStrings; public SchemaOptions getOptions() { return options; } @Override @@ -1116,91 +1056,6 @@ } /** * Returns {@code true} if this schema allows certain illegal characters in * OIDs and attribute options. When this compatibility option is set to * {@code true} the following illegal characters will be permitted in * addition to those permitted in section 1.4 of RFC 4512: * * <pre> * USCORE = %x5F ; underscore ("_") * DOT = %x2E ; period (".") * </pre> * * By default this compatibility option is set to {@code true} because these * characters are often used for naming purposes (such as collation rules). * * @return {@code true} if this schema allows certain illegal characters in * OIDs and attribute options. * @see <a href="http://tools.ietf.org/html/rfc4512">RFC 4512 - Lightweight * Directory Access Protocol (LDAP): Directory Information Models </a> */ public boolean allowMalformedNamesAndOptions() { return impl.allowMalformedNamesAndOptions(); } /** * Returns {@code true} if the JPEG Photo syntax defined for this * schema allows values which do not conform to the JFIF or Exif * specifications. * <p> * By default this compatibility option is set to {@code true}. * * @return {@code true} if the JPEG Photo syntax defined for this * schema allows values which do not conform to the JFIF * of Exit specifications. */ public boolean allowMalformedJPEGPhotos() { return impl.allowMalformedJPEGPhotos(); } /** * Returns {@code true} if the Certificate syntax defined for this * schema allows values which do not conform to the X.509 * specifications. * <p> * By default this compatibility option is set to {@code true}. * * @return {@code true} if the Certificate syntax defined for this * schema allows values which do not conform to the X.509 * specifications. */ public boolean allowMalformedCertificates() { return impl.allowMalformedCertificates(); } /** * Returns {@code true} if the Telephone Number syntax defined for this * schema allows values which do not conform to the E.123 international * telephone number format. * <p> * By default this compatibility option is set to {@code true}. * * @return {@code true} if the Telephone Number syntax defined for this * schema allows values which do not conform to the E.123 * international telephone number format. */ public boolean allowNonStandardTelephoneNumbers() { return impl.allowNonStandardTelephoneNumbers(); } /** * Returns {@code true} if zero-length values will be allowed by the * Directory String syntax defined for this schema. This is technically * forbidden by the LDAP specification, but it was allowed in earlier * versions of the server, and the discussion of the directory string syntax * in RFC 2252 does not explicitly state that they are not allowed. * <p> * By default this compatibility option is set to {@code false}. * * @return {@code true} if zero-length values will be allowed by the * Directory String syntax defined for this schema, or {@code false} * if not. */ public boolean allowZeroLengthDirectoryStrings() { return impl.allowZeroLengthDirectoryStrings(); } /** * Returns a non-strict view of this schema. * <p> * See the description of {@link #isStrict()} for more details. @@ -1224,25 +1079,11 @@ return impl.asStrictSchema(); } /** * Returns the default matching rule which will be used when parsing * unrecognized attributes. * * @return The default matching rule which will be used when parsing * unrecognized attributes. */ public MatchingRule getDefaultMatchingRule() { MatchingRule getDefaultMatchingRule() { return impl.getDefaultMatchingRule(); } /** * Returns the default syntax which will be used when parsing unrecognized * attributes. * * @return The default syntax which will be used when parsing unrecognized * attributes. */ public Syntax getDefaultSyntax() { Syntax getDefaultSyntax() { return impl.getDefaultSyntax(); } @@ -1574,6 +1415,25 @@ } /** * Returns the value associated to the provided {@link Option} or the option * default value, if there is no such option in this schema. * * @param <T> * The option type. * @param option * The option whose associated value should to be retrieve. * @return The value associated to the provided {@link Option} or the option * default value, if there is no such option in this schema. */ public <T> T getOption(Option<T> option) { return getOptions().get(option); } SchemaOptions getOptions() { return impl.getOptions(); } /** * Returns the user-friendly name of this schema which may be used for * debugging purposes. The format of the schema name is not defined but * should contain the distinguished name of the subschema sub-entry for opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/schema/SchemaBuilder.java
@@ -52,6 +52,7 @@ import org.forgerock.opendj.ldap.Filter; import org.forgerock.opendj.ldap.LdapException; import org.forgerock.opendj.ldap.LdapPromise; import org.forgerock.opendj.ldap.Option; import org.forgerock.opendj.ldap.ResultCode; import org.forgerock.opendj.ldap.SearchScope; import org.forgerock.opendj.ldap.requests.Requests; @@ -68,8 +69,8 @@ import static org.forgerock.opendj.ldap.LdapException.*; import static org.forgerock.opendj.ldap.schema.Schema.*; import static org.forgerock.opendj.ldap.schema.SchemaConstants.*; import static org.forgerock.opendj.ldap.schema.SchemaOptions.*; import static org.forgerock.opendj.ldap.schema.SchemaUtils.*; import static com.forgerock.opendj.ldap.CoreMessages.*; import static com.forgerock.opendj.util.StaticUtils.*; @@ -146,14 +147,8 @@ private Map<String, List<NameForm>> objectClass2NameForms; private String schemaName; private List<LocalizableMessage> warnings; private boolean allowNonStandardTelephoneNumbers; private boolean allowZeroLengthDirectoryStrings; private boolean allowMalformedNamesAndOptions; private boolean allowMalformedJPEGPhotos; private boolean allowMalformedCertificates; private SchemaOptions options; private String defaultSyntaxOID; private String defaultMatchingRuleOID; /** A schema which should be copied into this builder on any mutation. */ private Schema copyOnWriteSchema; @@ -213,6 +208,10 @@ preLazyInitBuilder(schemaName, null); } private Boolean allowsMalformedNamesAndOptions() { return options.get(ALLOW_MALFORMED_NAMES_AND_OPTIONS); } /** * Adds the provided attribute type definition to this schema builder. * @@ -246,9 +245,7 @@ if (reader.remaining() <= 0) { // This means that the definition was empty or contained only // whitespace. That is illegal. final LocalizableMessage message = ERR_ATTR_SYNTAX_ATTRTYPE_EMPTY_VALUE1.get(definition); throw new LocalizedIllegalArgumentException(message); throw new LocalizedIllegalArgumentException(ERR_ATTR_SYNTAX_ATTRTYPE_EMPTY_VALUE1.get(definition)); } // The next character must be an open parenthesis. If it is not, @@ -265,7 +262,7 @@ reader.skipWhitespaces(); // The next set of characters must be the OID. final String oid = SchemaUtils.readOID(reader, allowMalformedNamesAndOptions); final String oid = readOID(reader, allowsMalformedNamesAndOptions()); List<String> names = Collections.emptyList(); String description = "".intern(); @@ -291,18 +288,18 @@ // the end of the definition. But before we start, set default // values for everything else we might need to know. while (true) { final String tokenName = SchemaUtils.readTokenName(reader); final String tokenName = readTokenName(reader); if (tokenName == null) { // No more tokens. break; } else if ("name".equalsIgnoreCase(tokenName)) { names = SchemaUtils.readNameDescriptors(reader, allowMalformedNamesAndOptions); names = readNameDescriptors(reader, allowsMalformedNamesAndOptions()); } else if ("desc".equalsIgnoreCase(tokenName)) { // This specifies the description for the attribute type. It // is an arbitrary string of characters enclosed in single // quotes. description = SchemaUtils.readQuotedString(reader); description = readQuotedString(reader); } else if ("obsolete".equalsIgnoreCase(tokenName)) { // This indicates whether the attribute type should be // considered obsolete. We do not need to do any more @@ -312,22 +309,19 @@ // This specifies the name or OID of the superior attribute // type from which this attribute type should inherit its // properties. superiorType = SchemaUtils.readOID(reader, allowMalformedNamesAndOptions); superiorType = readOID(reader, allowsMalformedNamesAndOptions()); } else if ("equality".equalsIgnoreCase(tokenName)) { // This specifies the name or OID of the equality matching // rule to use for this attribute type. equalityMatchingRule = SchemaUtils.readOID(reader, allowMalformedNamesAndOptions); equalityMatchingRule = readOID(reader, allowsMalformedNamesAndOptions()); } else if ("ordering".equalsIgnoreCase(tokenName)) { // This specifies the name or OID of the ordering matching // rule to use for this attribute type. orderingMatchingRule = SchemaUtils.readOID(reader, allowMalformedNamesAndOptions); orderingMatchingRule = readOID(reader, allowsMalformedNamesAndOptions()); } else if ("substr".equalsIgnoreCase(tokenName)) { // This specifies the name or OID of the substring matching // rule to use for this attribute type. substringMatchingRule = SchemaUtils.readOID(reader, allowMalformedNamesAndOptions); substringMatchingRule = readOID(reader, allowsMalformedNamesAndOptions()); } else if ("syntax".equalsIgnoreCase(tokenName)) { // This specifies the numeric OID of the syntax for this // matching rule. It may optionally be immediately followed @@ -337,7 +331,7 @@ // implementation will ignore any such length because it // does not impose any practical limit on the length of attribute // values. syntax = SchemaUtils.readOIDLen(reader, allowMalformedNamesAndOptions); syntax = readOIDLen(reader, allowsMalformedNamesAndOptions()); } else if ("single-definition".equalsIgnoreCase(tokenName)) { // This indicates that attributes of this type are allowed // to have at most one definition. We do not need any more @@ -384,9 +378,8 @@ } else if ("dsaoperation".equalsIgnoreCase(usageStr)) { attributeUsage = AttributeUsage.DSA_OPERATION; } else { final LocalizableMessage message = WARN_ATTR_SYNTAX_ATTRTYPE_INVALID_ATTRIBUTE_USAGE1.get(definition, usageStr); throw new LocalizedIllegalArgumentException(message); throw new LocalizedIllegalArgumentException( WARN_ATTR_SYNTAX_ATTRTYPE_INVALID_ATTRIBUTE_USAGE1.get(definition, usageStr)); } } else if (tokenName.matches("^X-[A-Za-z_-]+$")) { // This must be a non-standard property and it must be @@ -399,9 +392,8 @@ } extraProperties.put(tokenName, SchemaUtils.readExtensions(reader)); } else { final LocalizableMessage message = ERR_ATTR_SYNTAX_ATTRTYPE_ILLEGAL_TOKEN1.get(definition, tokenName); throw new LocalizedIllegalArgumentException(message); throw new LocalizedIllegalArgumentException( ERR_ATTR_SYNTAX_ATTRTYPE_ILLEGAL_TOKEN1.get(definition, tokenName)); } } @@ -415,9 +407,8 @@ } if (superiorType == null && syntax == null) { final LocalizableMessage msg = WARN_ATTR_SYNTAX_ATTRTYPE_MISSING_SYNTAX_AND_SUPERIOR.get(definition); throw new LocalizedIllegalArgumentException(msg); throw new LocalizedIllegalArgumentException( WARN_ATTR_SYNTAX_ATTRTYPE_MISSING_SYNTAX_AND_SUPERIOR.get(definition)); } final AttributeType attrType = @@ -545,8 +536,7 @@ if (reader.remaining() <= 0) { // This means that the value was empty or contained only // whitespace. That is illegal. final LocalizableMessage message = ERR_ATTR_SYNTAX_DCR_EMPTY_VALUE1.get(definition); throw new LocalizedIllegalArgumentException(message); throw new LocalizedIllegalArgumentException(ERR_ATTR_SYNTAX_DCR_EMPTY_VALUE1.get(definition)); } // The next character must be an open parenthesis. If it is not, @@ -563,8 +553,7 @@ reader.skipWhitespaces(); // The next set of characters must be the OID. final String structuralClass = SchemaUtils.readOID(reader, allowMalformedNamesAndOptions); final String structuralClass = readOID(reader, allowsMalformedNamesAndOptions()); List<String> names = Collections.emptyList(); String description = "".intern(); @@ -584,34 +573,31 @@ // the end of the value. But before we start, set default values // for everything else we might need to know. while (true) { final String tokenName = SchemaUtils.readTokenName(reader); final String tokenName = readTokenName(reader); if (tokenName == null) { // No more tokens. break; } else if ("name".equalsIgnoreCase(tokenName)) { names = SchemaUtils.readNameDescriptors(reader, allowMalformedNamesAndOptions); names = readNameDescriptors(reader, allowsMalformedNamesAndOptions()); } else if ("desc".equalsIgnoreCase(tokenName)) { // This specifies the description for the attribute type. It // is an arbitrary string of characters enclosed in single // quotes. description = SchemaUtils.readQuotedString(reader); description = readQuotedString(reader); } else if ("obsolete".equalsIgnoreCase(tokenName)) { // This indicates whether the attribute type should be // considered obsolete. We do not need to do any more // parsing for this token. isObsolete = true; } else if ("aux".equalsIgnoreCase(tokenName)) { auxiliaryClasses = SchemaUtils.readOIDs(reader, allowMalformedNamesAndOptions); auxiliaryClasses = readOIDs(reader, allowsMalformedNamesAndOptions()); } else if ("must".equalsIgnoreCase(tokenName)) { requiredAttributes = SchemaUtils.readOIDs(reader, allowMalformedNamesAndOptions); requiredAttributes = readOIDs(reader, allowsMalformedNamesAndOptions()); } else if ("may".equalsIgnoreCase(tokenName)) { optionalAttributes = SchemaUtils.readOIDs(reader, allowMalformedNamesAndOptions); optionalAttributes = readOIDs(reader, allowsMalformedNamesAndOptions()); } else if ("not".equalsIgnoreCase(tokenName)) { prohibitedAttributes = SchemaUtils.readOIDs(reader, allowMalformedNamesAndOptions); prohibitedAttributes = readOIDs(reader, allowsMalformedNamesAndOptions()); } else if (tokenName.matches("^X-[A-Za-z_-]+$")) { // This must be a non-standard property and it must be // followed by either a single definition in single quotes @@ -621,11 +607,10 @@ if (extraProperties.isEmpty()) { extraProperties = new HashMap<String, List<String>>(); } extraProperties.put(tokenName, SchemaUtils.readExtensions(reader)); extraProperties.put(tokenName, readExtensions(reader)); } else { final LocalizableMessage message = ERR_ATTR_SYNTAX_DCR_ILLEGAL_TOKEN1.get(definition, tokenName); throw new LocalizedIllegalArgumentException(message); throw new LocalizedIllegalArgumentException( ERR_ATTR_SYNTAX_DCR_ILLEGAL_TOKEN1.get(definition, tokenName)); } } @@ -774,8 +759,7 @@ if (reader.remaining() <= 0) { // This means that the value was empty or contained only // whitespace. That is illegal. final LocalizableMessage message = ERR_ATTR_SYNTAX_DSR_EMPTY_VALUE1.get(definition); throw new LocalizedIllegalArgumentException(message); throw new LocalizedIllegalArgumentException(ERR_ATTR_SYNTAX_DSR_EMPTY_VALUE1.get(definition)); } // The next character must be an open parenthesis. If it is not, @@ -792,7 +776,7 @@ reader.skipWhitespaces(); // The next set of characters must be the OID. final Integer ruleID = SchemaUtils.readRuleID(reader); final Integer ruleID = readRuleID(reader); List<String> names = Collections.emptyList(); String description = "".intern(); @@ -810,27 +794,27 @@ // the end of the value. But before we start, set default values // for everything else we might need to know. while (true) { final String tokenName = SchemaUtils.readTokenName(reader); final String tokenName = readTokenName(reader); if (tokenName == null) { // No more tokens. break; } else if ("name".equalsIgnoreCase(tokenName)) { names = SchemaUtils.readNameDescriptors(reader, allowMalformedNamesAndOptions); names = readNameDescriptors(reader, allowsMalformedNamesAndOptions()); } else if ("desc".equalsIgnoreCase(tokenName)) { // This specifies the description for the attribute type. It // is an arbitrary string of characters enclosed in single // quotes. description = SchemaUtils.readQuotedString(reader); description = readQuotedString(reader); } else if ("obsolete".equalsIgnoreCase(tokenName)) { // This indicates whether the attribute type should be // considered obsolete. We do not need to do any more // parsing for this token. isObsolete = true; } else if ("form".equalsIgnoreCase(tokenName)) { nameForm = SchemaUtils.readOID(reader, allowMalformedNamesAndOptions); nameForm = readOID(reader, allowsMalformedNamesAndOptions()); } else if ("sup".equalsIgnoreCase(tokenName)) { superiorRules = SchemaUtils.readRuleIDs(reader); superiorRules = readRuleIDs(reader); } else if (tokenName.matches("^X-[A-Za-z_-]+$")) { // This must be a non-standard property and it must be // followed by either a single definition in single quotes @@ -840,17 +824,15 @@ if (extraProperties.isEmpty()) { extraProperties = new HashMap<String, List<String>>(); } extraProperties.put(tokenName, SchemaUtils.readExtensions(reader)); extraProperties.put(tokenName, readExtensions(reader)); } else { final LocalizableMessage message = ERR_ATTR_SYNTAX_DSR_ILLEGAL_TOKEN1.get(definition, tokenName); throw new LocalizedIllegalArgumentException(message); throw new LocalizedIllegalArgumentException( ERR_ATTR_SYNTAX_DSR_ILLEGAL_TOKEN1.get(definition, tokenName)); } } if (nameForm == null) { final LocalizableMessage message = ERR_ATTR_SYNTAX_DSR_NO_NAME_FORM.get(definition); throw new LocalizedIllegalArgumentException(message); throw new LocalizedIllegalArgumentException(ERR_ATTR_SYNTAX_DSR_NO_NAME_FORM.get(definition)); } if (!extraProperties.isEmpty()) { @@ -862,8 +844,7 @@ superiorRules, extraProperties, definition); addDITStructureRule(rule, overwrite); } catch (final DecodeException e) { final LocalizableMessage msg = ERR_ATTR_SYNTAX_DSR_INVALID1.get(definition, e.getMessageObject()); final LocalizableMessage msg = ERR_ATTR_SYNTAX_DSR_INVALID1.get(definition, e.getMessageObject()); throw new LocalizedIllegalArgumentException(msg, e.getCause()); } return this; @@ -946,8 +927,7 @@ if (reader.remaining() <= 0) { // This means that the value was empty or contained only // whitespace. That is illegal. final LocalizableMessage message = ERR_ATTR_SYNTAX_MR_EMPTY_VALUE1.get(definition); throw new LocalizedIllegalArgumentException(message); throw new LocalizedIllegalArgumentException(ERR_ATTR_SYNTAX_MR_EMPTY_VALUE1.get(definition)); } // The next character must be an open parenthesis. If it is not, @@ -964,10 +944,9 @@ reader.skipWhitespaces(); // The next set of characters must be the OID. final MatchingRule.Builder matchingRuleBuilder = new MatchingRule.Builder( SchemaUtils.readOID(reader, allowMalformedNamesAndOptions), this) .definition(definition); final MatchingRule.Builder matchingRuleBuilder = new MatchingRule.Builder( readOID(reader, allowsMalformedNamesAndOptions()), this); matchingRuleBuilder.definition(definition); String syntax = null; // At this point, we should have a pretty specific syntax that @@ -979,25 +958,25 @@ // the end of the value. But before we start, set default values // for everything else we might need to know. while (true) { final String tokenName = SchemaUtils.readTokenName(reader); final String tokenName = readTokenName(reader); if (tokenName == null) { // No more tokens. break; } else if ("name".equalsIgnoreCase(tokenName)) { matchingRuleBuilder.names(SchemaUtils.readNameDescriptors(reader, allowMalformedNamesAndOptions)); matchingRuleBuilder.names(readNameDescriptors(reader, allowsMalformedNamesAndOptions())); } else if ("desc".equalsIgnoreCase(tokenName)) { // This specifies the description for the matching rule. It // is an arbitrary string of characters enclosed in single // quotes. matchingRuleBuilder.description(SchemaUtils.readQuotedString(reader)); matchingRuleBuilder.description(readQuotedString(reader)); } else if ("obsolete".equalsIgnoreCase(tokenName)) { // This indicates whether the matching rule should be // considered obsolete. We do not need to do any more // parsing for this token. matchingRuleBuilder.obsolete(true); } else if ("syntax".equalsIgnoreCase(tokenName)) { syntax = SchemaUtils.readOID(reader, allowMalformedNamesAndOptions); syntax = readOID(reader, allowsMalformedNamesAndOptions()); matchingRuleBuilder.syntaxOID(syntax); } else if (tokenName.matches("^X-[A-Za-z_-]+$")) { // This must be a non-standard property and it must be @@ -1005,20 +984,17 @@ // or an open parenthesis followed by one or more values in // single quotes separated by spaces followed by a close // parenthesis. final List<String> extensions = SchemaUtils.readExtensions(reader); matchingRuleBuilder.extraProperties(tokenName, extensions .toArray(new String[extensions.size()])); final List<String> extensions = readExtensions(reader); matchingRuleBuilder.extraProperties(tokenName, extensions.toArray(new String[extensions.size()])); } else { final LocalizableMessage message = ERR_ATTR_SYNTAX_MR_ILLEGAL_TOKEN1.get(definition, tokenName); throw new LocalizedIllegalArgumentException(message); throw new LocalizedIllegalArgumentException( ERR_ATTR_SYNTAX_MR_ILLEGAL_TOKEN1.get(definition, tokenName)); } } // Make sure that a syntax was specified. if (syntax == null) { final LocalizableMessage message = ERR_ATTR_SYNTAX_MR_NO_SYNTAX.get(definition); throw new LocalizedIllegalArgumentException(message); throw new LocalizedIllegalArgumentException(ERR_ATTR_SYNTAX_MR_NO_SYNTAX.get(definition)); } if (overwrite) { matchingRuleBuilder.addToSchemaOverwrite(); @@ -1066,9 +1042,7 @@ if (reader.remaining() <= 0) { // This means that the value was empty or contained only // whitespace. That is illegal. final LocalizableMessage message = ERR_ATTR_SYNTAX_MRUSE_EMPTY_VALUE1.get(definition); throw new LocalizedIllegalArgumentException(message); throw new LocalizedIllegalArgumentException(ERR_ATTR_SYNTAX_MRUSE_EMPTY_VALUE1.get(definition)); } // The next character must be an open parenthesis. If it is not, @@ -1085,7 +1059,7 @@ reader.skipWhitespaces(); // The next set of characters must be the OID. final String oid = SchemaUtils.readOID(reader, allowMalformedNamesAndOptions); final String oid = readOID(reader, allowsMalformedNamesAndOptions()); List<String> names = Collections.emptyList(); String description = "".intern(); @@ -1102,25 +1076,25 @@ // the end of the value. But before we start, set default values // for everything else we might need to know. while (true) { final String tokenName = SchemaUtils.readTokenName(reader); final String tokenName = readTokenName(reader); if (tokenName == null) { // No more tokens. break; } else if ("name".equalsIgnoreCase(tokenName)) { names = SchemaUtils.readNameDescriptors(reader, allowMalformedNamesAndOptions); names = readNameDescriptors(reader, allowsMalformedNamesAndOptions()); } else if ("desc".equalsIgnoreCase(tokenName)) { // This specifies the description for the attribute type. It // is an arbitrary string of characters enclosed in single // quotes. description = SchemaUtils.readQuotedString(reader); description = readQuotedString(reader); } else if ("obsolete".equalsIgnoreCase(tokenName)) { // This indicates whether the attribute type should be // considered obsolete. We do not need to do any more // parsing for this token. isObsolete = true; } else if ("applies".equalsIgnoreCase(tokenName)) { attributes = SchemaUtils.readOIDs(reader, allowMalformedNamesAndOptions); attributes = readOIDs(reader, allowsMalformedNamesAndOptions()); } else if (tokenName.matches("^X-[A-Za-z_-]+$")) { // This must be a non-standard property and it must be // followed by either a single definition in single quotes @@ -1130,18 +1104,16 @@ if (extraProperties.isEmpty()) { extraProperties = new HashMap<String, List<String>>(); } extraProperties.put(tokenName, SchemaUtils.readExtensions(reader)); extraProperties.put(tokenName, readExtensions(reader)); } else { final LocalizableMessage message = ERR_ATTR_SYNTAX_MRUSE_ILLEGAL_TOKEN1.get(definition, tokenName); throw new LocalizedIllegalArgumentException(message); throw new LocalizedIllegalArgumentException( ERR_ATTR_SYNTAX_MRUSE_ILLEGAL_TOKEN1.get(definition, tokenName)); } } // Make sure that the set of attributes was defined. if (attributes == null || attributes.size() == 0) { final LocalizableMessage message = ERR_ATTR_SYNTAX_MRUSE_NO_ATTR.get(definition); throw new LocalizedIllegalArgumentException(message); throw new LocalizedIllegalArgumentException(ERR_ATTR_SYNTAX_MRUSE_NO_ATTR.get(definition)); } if (!extraProperties.isEmpty()) { @@ -1248,9 +1220,7 @@ if (reader.remaining() <= 0) { // This means that the value was empty or contained only // whitespace. That is illegal. final LocalizableMessage message = ERR_ATTR_SYNTAX_NAME_FORM_EMPTY_VALUE1.get(definition); throw new LocalizedIllegalArgumentException(message); throw new LocalizedIllegalArgumentException(ERR_ATTR_SYNTAX_NAME_FORM_EMPTY_VALUE1.get(definition)); } // The next character must be an open parenthesis. If it is not, @@ -1267,10 +1237,9 @@ reader.skipWhitespaces(); // The next set of characters must be the OID. final NameForm.Builder nameFormBuilder = new NameForm.Builder( SchemaUtils.readOID(reader, allowMalformedNamesAndOptions), this) .definition(definition); final NameForm.Builder nameFormBuilder = new NameForm.Builder( readOID(reader, allowsMalformedNamesAndOptions()), this); nameFormBuilder.definition(definition); // Required properties : String structuralOID = null; @@ -1285,62 +1254,54 @@ // the end of the value. But before we start, set default values // for everything else we might need to know. while (true) { final String tokenName = SchemaUtils.readTokenName(reader); final String tokenName = readTokenName(reader); if (tokenName == null) { // No more tokens. break; } else if ("name".equalsIgnoreCase(tokenName)) { nameFormBuilder.names(SchemaUtils.readNameDescriptors(reader, allowMalformedNamesAndOptions)); nameFormBuilder.names(readNameDescriptors(reader, allowsMalformedNamesAndOptions())); } else if ("desc".equalsIgnoreCase(tokenName)) { // This specifies the description for the attribute type. It // is an arbitrary string of characters enclosed in single // quotes. nameFormBuilder.description(SchemaUtils.readQuotedString(reader)); nameFormBuilder.description(readQuotedString(reader)); } else if ("obsolete".equalsIgnoreCase(tokenName)) { // This indicates whether the attribute type should be // considered obsolete. We do not need to do any more // parsing for this token. nameFormBuilder.obsolete(true); } else if ("oc".equalsIgnoreCase(tokenName)) { structuralOID = SchemaUtils.readOID(reader, allowMalformedNamesAndOptions); structuralOID = readOID(reader, allowsMalformedNamesAndOptions()); nameFormBuilder.structuralObjectClassOID(structuralOID); } else if ("must".equalsIgnoreCase(tokenName)) { requiredAttributes = SchemaUtils.readOIDs(reader, allowMalformedNamesAndOptions); requiredAttributes = readOIDs(reader, allowsMalformedNamesAndOptions()); nameFormBuilder.requiredAttributes(requiredAttributes); } else if ("may".equalsIgnoreCase(tokenName)) { nameFormBuilder.optionalAttributes(SchemaUtils.readOIDs(reader, allowMalformedNamesAndOptions)); nameFormBuilder.optionalAttributes(readOIDs(reader, allowsMalformedNamesAndOptions())); } else if (tokenName.matches("^X-[A-Za-z_-]+$")) { // This must be a non-standard property and it must be // followed by either a single definition in single quotes // or an open parenthesis followed by one or more values in // single quotes separated by spaces followed by a close // parenthesis. final List<String> extensions = SchemaUtils.readExtensions(reader); nameFormBuilder.extraProperties(tokenName, extensions .toArray(new String[extensions.size()])); final List<String> extensions = readExtensions(reader); nameFormBuilder.extraProperties(tokenName, extensions.toArray(new String[extensions.size()])); } else { final LocalizableMessage message = ERR_ATTR_SYNTAX_NAME_FORM_ILLEGAL_TOKEN1.get(definition, tokenName); throw new LocalizedIllegalArgumentException(message); throw new LocalizedIllegalArgumentException( ERR_ATTR_SYNTAX_NAME_FORM_ILLEGAL_TOKEN1.get(definition, tokenName)); } } // Make sure that a structural class was specified. If not, then // it cannot be valid and the name form cannot be build. if (structuralOID == null) { final LocalizableMessage message = ERR_ATTR_SYNTAX_NAME_FORM_NO_STRUCTURAL_CLASS1.get(definition); throw new LocalizedIllegalArgumentException(message); throw new LocalizedIllegalArgumentException( ERR_ATTR_SYNTAX_NAME_FORM_NO_STRUCTURAL_CLASS1.get(definition)); } if (requiredAttributes.isEmpty()) { final LocalizableMessage message = ERR_ATTR_SYNTAX_NAME_FORM_NO_REQUIRED_ATTR.get(definition); throw new LocalizedIllegalArgumentException(message); throw new LocalizedIllegalArgumentException(ERR_ATTR_SYNTAX_NAME_FORM_NO_REQUIRED_ATTR.get(definition)); } if (overwrite) { @@ -1393,74 +1354,6 @@ } /** * Sets the default syntax which will be used when parsing unrecognized * attributes. * <p> * By default the {@link CoreSchema#getOctetStringSyntax() OctetString} * syntax will be used. * * @param syntax * The default syntax which will be used when parsing * unrecognized attributes. * @return A reference to this {@code SchemaBuilder}. */ public SchemaBuilder defaultSyntax(final Syntax syntax) { return defaultSyntax(syntax.getOID()); } /** * Sets the default matching rule which will be used when parsing * unrecognized attributes. * <p> * By default the {@link CoreSchema#getOctetStringMatchingRule() * OctetString} matching rule will be used. * * @param rule * The default matching rule which will be used when parsing * unrecognized attributes. * @return A reference to this {@code SchemaBuilder}. */ public SchemaBuilder defaultMatchingRule(final MatchingRule rule) { return defaultMatchingRule(rule.getOID()); } /** * Sets the default syntax which will be used when parsing unrecognized * attributes. * <p> * By default the {@link CoreSchema#getOctetStringSyntax() OctetString} * syntax will be used. * * @param syntaxOID * The default syntax which will be used when parsing * unrecognized attributes. * @return A reference to this {@code SchemaBuilder}. */ public SchemaBuilder defaultSyntax(final String syntaxOID) { lazyInitBuilder(); this.defaultSyntaxOID = syntaxOID; return this; } /** * Sets the default matching rule which will be used when parsing * unrecognized attributes. * <p> * By default the {@link CoreSchema#getOctetStringMatchingRule() * OctetString} matching rule will be used. * * @param ruleOID * The default matching rule which will be used when parsing * unrecognized attributes. * @return A reference to this {@code SchemaBuilder}. */ public SchemaBuilder defaultMatchingRule(final String ruleOID) { lazyInitBuilder(); this.defaultMatchingRuleOID = ruleOID; return this; } /** * Duplicates the matching rule. * * @param matchingRule @@ -1561,9 +1454,7 @@ if (reader.remaining() <= 0) { // This means that the value was empty or contained only // whitespace. That is illegal. final LocalizableMessage message = ERR_ATTR_SYNTAX_OBJECTCLASS_EMPTY_VALUE1.get(definition); throw new LocalizedIllegalArgumentException(message); throw new LocalizedIllegalArgumentException(ERR_ATTR_SYNTAX_OBJECTCLASS_EMPTY_VALUE1.get(definition)); } // The next character must be an open parenthesis. If it is not, @@ -1580,7 +1471,7 @@ reader.skipWhitespaces(); // The next set of characters must be the OID. final String oid = SchemaUtils.readOID(reader, allowMalformedNamesAndOptions); final String oid = readOID(reader, allowsMalformedNamesAndOptions()); List<String> names = Collections.emptyList(); String description = "".intern(); @@ -1600,25 +1491,25 @@ // the end of the value. But before we start, set default values // for everything else we might need to know. while (true) { final String tokenName = SchemaUtils.readTokenName(reader); final String tokenName = readTokenName(reader); if (tokenName == null) { // No more tokens. break; } else if ("name".equalsIgnoreCase(tokenName)) { names = SchemaUtils.readNameDescriptors(reader, allowMalformedNamesAndOptions); names = readNameDescriptors(reader, allowsMalformedNamesAndOptions()); } else if ("desc".equalsIgnoreCase(tokenName)) { // This specifies the description for the attribute type. It // is an arbitrary string of characters enclosed in single // quotes. description = SchemaUtils.readQuotedString(reader); description = readQuotedString(reader); } else if ("obsolete".equalsIgnoreCase(tokenName)) { // This indicates whether the attribute type should be // considered obsolete. We do not need to do any more // parsing for this token. isObsolete = true; } else if ("sup".equalsIgnoreCase(tokenName)) { superiorClasses = SchemaUtils.readOIDs(reader, allowMalformedNamesAndOptions); superiorClasses = readOIDs(reader, allowsMalformedNamesAndOptions()); } else if ("abstract".equalsIgnoreCase(tokenName)) { // This indicates that entries must not include this // objectclass unless they also include a non-abstract @@ -1634,11 +1525,9 @@ // do not need any more parsing for this token. objectClassType = ObjectClassType.AUXILIARY; } else if ("must".equalsIgnoreCase(tokenName)) { requiredAttributes = SchemaUtils.readOIDs(reader, allowMalformedNamesAndOptions); requiredAttributes = readOIDs(reader, allowsMalformedNamesAndOptions()); } else if ("may".equalsIgnoreCase(tokenName)) { optionalAttributes = SchemaUtils.readOIDs(reader, allowMalformedNamesAndOptions); optionalAttributes = readOIDs(reader, allowsMalformedNamesAndOptions()); } else if (tokenName.matches("^X-[A-Za-z_-]+$")) { // This must be a non-standard property and it must be // followed by either a single definition in single quotes @@ -1648,11 +1537,10 @@ if (extraProperties.isEmpty()) { extraProperties = new HashMap<String, List<String>>(); } extraProperties.put(tokenName, SchemaUtils.readExtensions(reader)); extraProperties.put(tokenName, readExtensions(reader)); } else { final LocalizableMessage message = ERR_ATTR_SYNTAX_OBJECTCLASS_ILLEGAL_TOKEN1.get(definition, tokenName); throw new LocalizedIllegalArgumentException(message); throw new LocalizedIllegalArgumentException( ERR_ATTR_SYNTAX_OBJECTCLASS_ILLEGAL_TOKEN1.get(definition, tokenName)); } } @@ -2124,9 +2012,7 @@ if (reader.remaining() <= 0) { // This means that the value was empty or contained only // whitespace. That is illegal. final LocalizableMessage message = ERR_ATTR_SYNTAX_ATTRSYNTAX_EMPTY_VALUE1.get(definition); throw new LocalizedIllegalArgumentException(message); throw new LocalizedIllegalArgumentException(ERR_ATTR_SYNTAX_ATTRSYNTAX_EMPTY_VALUE1.get(definition)); } // The next character must be an open parenthesis. If it is not, @@ -2143,7 +2029,7 @@ reader.skipWhitespaces(); // The next set of characters must be the OID. final String oid = SchemaUtils.readOID(reader, allowMalformedNamesAndOptions); final String oid = readOID(reader, allowsMalformedNamesAndOptions()); final Syntax.Builder syntaxBuilder = new Syntax.Builder(oid, this).definition(definition); // At this point, we should have a pretty specific syntax that @@ -2155,7 +2041,7 @@ // the end of the value. But before we start, set default values // for everything else we might need to know. while (true) { final String tokenName = SchemaUtils.readTokenName(reader); final String tokenName = readTokenName(reader); if (tokenName == null) { // No more tokens. @@ -2163,19 +2049,18 @@ } else if ("desc".equalsIgnoreCase(tokenName)) { // This specifies the description for the syntax. It is an // arbitrary string of characters enclosed in single quotes. syntaxBuilder.description(SchemaUtils.readQuotedString(reader)); syntaxBuilder.description(readQuotedString(reader)); } else if (tokenName.matches("^X-[A-Za-z_-]+$")) { // This must be a non-standard property and it must be // followed by either a single definition in single quotes // or an open parenthesis followed by one or more values in // single quotes separated by spaces followed by a close // parenthesis. final List<String> extensions = SchemaUtils.readExtensions(reader); final List<String> extensions = readExtensions(reader); syntaxBuilder.extraProperties(tokenName, extensions.toArray(new String[extensions.size()])); } else { final LocalizableMessage message = ERR_ATTR_SYNTAX_ATTRSYNTAX_ILLEGAL_TOKEN1.get(definition, tokenName); throw new LocalizedIllegalArgumentException(message); throw new LocalizedIllegalArgumentException( ERR_ATTR_SYNTAX_ATTRSYNTAX_ILLEGAL_TOKEN1.get(definition, tokenName)); } } @@ -2184,7 +2069,6 @@ if ("x-enum".equalsIgnoreCase(property.getKey())) { final EnumSyntaxImpl enumImpl = new EnumSyntaxImpl(oid, property.getValue()); syntaxBuilder.implementation(enumImpl); syntaxBuilder.addToSchema(overwrite); buildMatchingRule(enumImpl.getOrderingMatchingRule()) @@ -2206,110 +2090,10 @@ return this; } /** * Specifies whether or not the schema should allow certain illegal * characters in OIDs and attribute options. When this compatibility option * is set to {@code true} the following illegal characters will be permitted * in addition to those permitted in section 1.4 of RFC 4512: * * <pre> * USCORE = %x5F ; underscore ("_") * DOT = %x2E ; period (".") * </pre> * * By default this compatibility option is set to {@code true} because these * characters are often used for naming purposes (such as collation rules). * * @param allowMalformedNamesAndOptions * {@code true} if the schema should allow certain illegal * characters in OIDs and attribute options. * @return A reference to this {@code SchemaBuilder}. * @see <a href="http://tools.ietf.org/html/rfc4512">RFC 4512 - Lightweight * Directory Access Protocol (LDAP): Directory Information Models </a> */ public SchemaBuilder allowMalformedNamesAndOptions(final boolean allowMalformedNamesAndOptions) { SchemaOptions getOptions() { lazyInitBuilder(); this.allowMalformedNamesAndOptions = allowMalformedNamesAndOptions; return this; } /** * Specifies whether or not the JPEG Photo syntax should allow values which * do not conform to the JFIF or Exif specifications. * <p> * By default this compatibility option is set to {@code true}. * * @param allowMalformedJPEGPhotos * {@code true} if the JPEG Photo syntax should allow values * which do not conform to the JFIF or Exif specifications. * @return A reference to this {@code SchemaBuilder}. */ public SchemaBuilder allowMalformedJPEGPhotos(final boolean allowMalformedJPEGPhotos) { lazyInitBuilder(); this.allowMalformedJPEGPhotos = allowMalformedJPEGPhotos; return this; } /** * Specifies whether or not the Certificate syntax should allow values which * do not conform to the X.509 specifications. * <p> * By default this compatibility option is set to {@code true}. * * @param allowMalformedCertificates * {@code true} if the Certificate syntax should allow values * which do not conform to the X.509 specifications. * @return A reference to this {@code SchemaBuilder}. */ public SchemaBuilder allowMalformedCertificates(final boolean allowMalformedCertificates) { lazyInitBuilder(); this.allowMalformedCertificates = allowMalformedCertificates; return this; } /** * Specifies whether or not the Telephone Number syntax should allow values * which do not conform to the E.123 international telephone number format. * <p> * By default this compatibility option is set to {@code true}. * * @param allowNonStandardTelephoneNumbers * {@code true} if the Telephone Number syntax should allow * values which do not conform to the E.123 international * telephone number format. * @return A reference to this {@code SchemaBuilder}. */ public SchemaBuilder allowNonStandardTelephoneNumbers( final boolean allowNonStandardTelephoneNumbers) { lazyInitBuilder(); this.allowNonStandardTelephoneNumbers = allowNonStandardTelephoneNumbers; return this; } /** * Specifies whether or not zero-length values will be allowed by the * Directory String syntax. This is technically forbidden by the LDAP * specification, but it was allowed in earlier versions of the server, and * the discussion of the directory string syntax in RFC 2252 does not * explicitly state that they are not allowed. * <p> * By default this compatibility option is set to {@code false}. * * @param allowZeroLengthDirectoryStrings * {@code true} if zero-length values will be allowed by the * Directory String syntax, or {@code false} if not. * @return A reference to this {@code SchemaBuilder}. */ public SchemaBuilder allowZeroLengthDirectoryStrings( final boolean allowZeroLengthDirectoryStrings) { lazyInitBuilder(); this.allowZeroLengthDirectoryStrings = allowZeroLengthDirectoryStrings; return this; return options; } /** @@ -2499,6 +2283,24 @@ } /** * Sets a schema option overriding any previous values for the option. * * @param <T> * The option type. * @param option * Option with which the specified value is to be associated. * @param value * Value to be associated with the specified option. * @return A reference to this schema builder. * @throws UnsupportedOperationException * If the schema builder options are read only. */ public <T> SchemaBuilder setOption(final Option<T> option, T value) { getOptions().set(option, value); return this; } /** * Returns a strict {@code Schema} containing all of the schema elements * contained in this schema builder as well as the same set of schema * compatibility options. @@ -2528,20 +2330,18 @@ localSchemaName = String.format("Schema#%d", NEXT_SCHEMA_ID.getAndIncrement()); } Syntax defaultSyntax = numericOID2Syntaxes.get(defaultSyntaxOID); Syntax defaultSyntax = numericOID2Syntaxes.get(options.get(DEFAULT_SYNTAX_OID)); if (defaultSyntax == null) { defaultSyntax = Schema.getCoreSchema().getDefaultSyntax(); } MatchingRule defaultMatchingRule = numericOID2MatchingRules.get(defaultMatchingRuleOID); MatchingRule defaultMatchingRule = numericOID2MatchingRules.get(options.get(DEFAULT_MATCHING_RULE_OID)); if (defaultMatchingRule == null) { defaultMatchingRule = Schema.getCoreSchema().getDefaultMatchingRule(); } final Schema schema = new Schema.StrictImpl(localSchemaName, allowMalformedNamesAndOptions, allowMalformedJPEGPhotos, allowMalformedCertificates, allowNonStandardTelephoneNumbers, allowZeroLengthDirectoryStrings, new Schema.StrictImpl(localSchemaName, options, defaultSyntax, defaultMatchingRule, numericOID2Syntaxes, numericOID2MatchingRules, numericOID2MatchingRuleUses, numericOID2AttributeTypes, numericOID2ObjectClasses, numericOID2NameForms, @@ -2829,13 +2629,7 @@ private void lazyInitBuilder() { // Lazy initialization. if (numericOID2Syntaxes == null) { allowMalformedNamesAndOptions = true; allowMalformedJPEGPhotos = true; allowMalformedCertificates = true; allowNonStandardTelephoneNumbers = true; allowZeroLengthDirectoryStrings = false; defaultSyntaxOID = SchemaConstants.SYNTAX_OCTET_STRING_OID; defaultMatchingRuleOID = SchemaConstants.EMR_OCTET_STRING_OID; options = defaultSchemaOptions(); numericOID2Syntaxes = new LinkedHashMap<String, Syntax>(); numericOID2MatchingRules = new LinkedHashMap<String, MatchingRule>(); @@ -2862,15 +2656,7 @@ if (copyOnWriteSchema != null) { // Copy the schema. addSchema0(copyOnWriteSchema, true); allowMalformedNamesAndOptions = copyOnWriteSchema.allowMalformedNamesAndOptions(); allowMalformedJPEGPhotos = copyOnWriteSchema.allowMalformedJPEGPhotos(); allowMalformedCertificates = copyOnWriteSchema.allowMalformedCertificates(); allowNonStandardTelephoneNumbers = copyOnWriteSchema.allowNonStandardTelephoneNumbers(); allowZeroLengthDirectoryStrings = copyOnWriteSchema.allowZeroLengthDirectoryStrings(); defaultSyntaxOID = copyOnWriteSchema.getDefaultSyntax().getOID(); defaultMatchingRuleOID = copyOnWriteSchema.getDefaultMatchingRule().getOID(); options = SchemaOptions.copyOf(copyOnWriteSchema.getOptions()); copyOnWriteSchema = null; } } @@ -2879,13 +2665,7 @@ this.schemaName = schemaName; this.copyOnWriteSchema = copyOnWriteSchema; this.allowMalformedNamesAndOptions = true; this.allowMalformedJPEGPhotos = true; this.allowMalformedCertificates = true; this.allowNonStandardTelephoneNumbers = true; this.allowZeroLengthDirectoryStrings = false; this.defaultSyntaxOID = null; this.defaultMatchingRuleOID = null; this.options = null; this.numericOID2Syntaxes = null; this.numericOID2MatchingRules = null; opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/schema/SchemaOptions.java
New file @@ -0,0 +1,214 @@ /* * 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 legal-notices/CDDLv1_0.txt * or http://forgerock.org/license/CDDLv1.0.html. * 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 legal-notices/CDDLv1_0.txt. * 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 * * * Copyright 2014 ForgeRock AS */ package org.forgerock.opendj.ldap.schema; import java.util.IdentityHashMap; import java.util.Map; import org.forgerock.opendj.ldap.Option; import static java.util.Collections.*; import static org.forgerock.opendj.ldap.schema.SchemaConstants.*; /** * Common options for LDAP schemas. * <p> * For example you set schema option as you want when using a schema. * * <pre> * // Retrieves options from builder. * SchemaOptions options = new SchemaBuilder().getOptions(); * // Creates a new option. * Option myIntegerOption = options.set(Option.of(Integer.class, 0)); * // Retrieves option value from SchemaOption * boolean allowMalformedNamesAndOptions = options.get(SchemaOptions.ALLOW_MALFORMED_NAMES_AND_OPTIONS); * </pre> */ public final class SchemaOptions { /** * Specifies whether the schema should allow certain illegal * characters in OIDs and attribute options. When this compatibility option * is set to {@code true} the following illegal characters will be permitted * in addition to those permitted in section 1.4 of RFC 4512: * * <pre> * USCORE = %x5F ; underscore ("_") * DOT = %x2E ; period (".") * </pre> * * By default this compatibility option is set to {@code true} because these * characters are often used for naming purposes (such as collation rules). */ public static final Option<Boolean> ALLOW_MALFORMED_NAMES_AND_OPTIONS = Option.withDefault(true); /** * Specifies whether the JPEG Photo syntax should allow values which * do not conform to the JFIF or Exif specifications. * <p> * By default this compatibility option is set to {@code true}. */ public static final Option<Boolean> ALLOW_MALFORMED_JPEG_PHOTOS = Option.withDefault(true); /** * Specifies whether the Certificate syntax should allow values which * do not conform to the X.509 specifications. * <p> * By default this compatibility option is set to {@code true}. */ public static final Option<Boolean> ALLOW_MALFORMED_CERTIFICATES = Option.withDefault(true); /** * Specifies whether the Telephone Number syntax should allow values * which do not conform to the E.123 international telephone number format. * <p> * By default this compatibility option is set to {@code true}. */ public static final Option<Boolean> ALLOW_NON_STANDARD_TELEPHONE_NUMBERS = Option.withDefault(true); /** * Specifies whether zero-length values will be allowed by the * Directory String syntax. This is technically forbidden by the LDAP * specification, but it was allowed in earlier versions of the server, and * the discussion of the directory string syntax in RFC 2252 does not * explicitly state that they are not allowed. * <p> * By default this compatibility option is set to {@code false}. */ public static final Option<Boolean> ALLOW_ZERO_LENGTH_DIRECTORY_STRINGS = Option.withDefault(false); /** * Specifies the OID of the default syntax which will be used when parsing * unrecognized attributes. * <p> * By default the {@link SchemaConstants#SYNTAX_OCTET_STRING_OID OctetString} * syntax will be used. */ public static final Option<String> DEFAULT_SYNTAX_OID = Option.of(String.class, SYNTAX_OCTET_STRING_OID); /** * Specifies the OID of the default matching rule which will be used when * parsing unrecognized attributes. * <p> * By default the {@link SchemaConstants#EMR_OCTET_STRING_OID OctetString} * matching rule will be used. */ public static final Option<String> DEFAULT_MATCHING_RULE_OID = Option.of(String.class, EMR_OCTET_STRING_OID); /** * Indicates whether country code values are required to strictly * comply with the standard definition for this syntax. * <p> * When set to false, country codes will not be validated and, as a result * any string containing 2 characters will be acceptable. * By default this compatibility option is set to {@code true}. */ public static final Option<Boolean> STRICT_FORMAT_FOR_COUNTRY_STRINGS = Option.withDefault(true); /** * Indicates whether the minimum upper bound value should be stripped from * the Attribute Type Syntax Description. * <p> * By default this compatibility option is set to {@code false}. */ public static final Option<Boolean> STRIP_UPPER_BOUND_FOR_ATTRIBUTE_TYPE = Option.withDefault(false); private final Map<Option<?>, Object> options; /** * Creates a new set of schema options with default settings. * * @return A new {@link SchemaOptions} with default settings. */ static SchemaOptions defaultSchemaOptions() { return new SchemaOptions(new IdentityHashMap<Option<?>, Object>()); } /** * Creates a new schema options object by copying the provided schema * options. The options names and values will all be copied. * * @param schemaOptions * The schema options to be copied. * @return A new schema options object created by copying the provided schema * options. */ static SchemaOptions copyOf(SchemaOptions schemaOptions) { return new SchemaOptions(new IdentityHashMap<Option<?>, Object>(schemaOptions.options)); } /** * Returns an unmodifiable {@link SchemaOptions} copy of this set of options. * * @param schemaOptions * The schema options to be copied. * @return An unmodifiable {@link SchemaOptions} view of this set of options. */ static SchemaOptions unmodifiable(SchemaOptions schemaOptions) { return new SchemaOptions(unmodifiableMap(new IdentityHashMap<Option<?>, Object>(schemaOptions.options))); } private SchemaOptions(Map<Option<?>, Object> optionsMap) { this.options = optionsMap; } /** * Returns the value to which the specified {@link Option} is mapped, or * {@code null} if this options set contains no mapping for the {@link Option}. * * @param <T> * The option type. * @param option * The option whose associated value is to be returned. * @return The value to which the specified option is mapped, or null if * this options set contains no mapping for the option. */ <T> T get(Option<T> option) { return option.getValue(options.get(option)); } /** * Associates the specified option value with the specified option in this * set of options. (optional operation). If this set of options previously * contained a mapping for the option, the old value is replaced by the * specified value. * * @param <T> * The option type. * @param option * Option with which the specified value is to be associated. * @param value * Value to be associated with the specified option. * @return A reference to this set of options. * @throws UnsupportedOperationException * If this set of options is read only. */ <T> SchemaOptions set(Option<T> option, T value) { options.put(option, value); return this; } } opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/schema/SchemaUtils.java
@@ -39,6 +39,8 @@ import java.util.Map; import java.util.Set; import org.forgerock.i18n.LocalizableMessage; import org.forgerock.i18n.slf4j.LocalizedLogger; import org.forgerock.opendj.ldap.ByteSequence; import org.forgerock.opendj.ldap.ByteString; import org.forgerock.opendj.ldap.DecodeException; @@ -743,6 +745,12 @@ return ByteString.valueOf(buffer.toString()); } static void throwDecodeException(LocalizedLogger logger, LocalizableMessage message) throws DecodeException { final DecodeException e = DecodeException.error(message); logger.debug(LocalizableMessage.raw("%s", e)); throw e; } private static void throwIfIA5IllegalCharacter(StringBuilder buffer, ByteSequence value) throws DecodeException { // Replace any consecutive spaces with a single space and watch out // for non-ASCII characters. opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/schema/TelephoneNumberSyntaxImpl.java
@@ -35,6 +35,7 @@ import static org.forgerock.opendj.ldap.schema.SchemaConstants.EMR_TELEPHONE_OID; import static org.forgerock.opendj.ldap.schema.SchemaConstants.SMR_TELEPHONE_OID; import static org.forgerock.opendj.ldap.schema.SchemaConstants.SYNTAX_TELEPHONE_NAME; import static org.forgerock.opendj.ldap.schema.SchemaOptions.*; import org.forgerock.i18n.LocalizableMessage; import org.forgerock.i18n.LocalizableMessageBuilder; @@ -93,7 +94,7 @@ final int length = valueStr.length(); if (!schema.allowNonStandardTelephoneNumbers()) { if (!schema.getOption(ALLOW_NON_STANDARD_TELEPHONE_NUMBERS)) { // If the value does not start with a plus sign, then that's not // acceptable. if (valueStr.charAt(0) != '+') { opendj-sdk/opendj-core/src/test/java/org/forgerock/opendj/ldap/schema/CertificateSyntaxTest.java
@@ -32,7 +32,9 @@ import org.testng.annotations.DataProvider; import org.testng.annotations.Test; import static org.forgerock.opendj.ldap.schema.Schema.*; import static org.forgerock.opendj.ldap.schema.SchemaConstants.SYNTAX_CERTIFICATE_OID; import static org.forgerock.opendj.ldap.schema.SchemaOptions.*; import static org.testng.Assert.*; /** @@ -138,7 +140,7 @@ @Test(dataProvider = "acceptableValues") public void testAllowMalformedCertificates(ByteString value, Boolean result) { // Make sure that the specified class can be instantiated as a task. SchemaBuilder builder = new SchemaBuilder(Schema.getCoreSchema()).allowMalformedCertificates(true); SchemaBuilder builder = new SchemaBuilder(getCoreSchema()).setOption(ALLOW_MALFORMED_CERTIFICATES, true); final Syntax syntax = builder.toSchema().getSyntax(SYNTAX_CERTIFICATE_OID); final LocalizableMessageBuilder reason = new LocalizableMessageBuilder(); @@ -155,7 +157,8 @@ * @return An instance of the attribute syntax that must be tested. */ protected Syntax getRule() { SchemaBuilder builder = new SchemaBuilder(Schema.getCoreSchema()).allowMalformedCertificates(false); SchemaBuilder builder = new SchemaBuilder(getCoreSchema()).setOption(ALLOW_MALFORMED_CERTIFICATES, false); return builder.toSchema().getSyntax(SYNTAX_CERTIFICATE_OID); } } opendj-sdk/opendj-core/src/test/java/org/forgerock/opendj/ldap/schema/SchemaBuilderTestCase.java
@@ -45,7 +45,9 @@ import static org.fest.assertions.Assertions.*; import static org.fest.assertions.Fail.*; import static org.forgerock.opendj.ldap.schema.CoreSchema.*; import static org.forgerock.opendj.ldap.schema.SchemaConstants.*; import static org.forgerock.opendj.ldap.schema.SchemaOptions.*; import static org.forgerock.opendj.ldap.spi.LdapPromises.*; import static org.mockito.Matchers.*; import static org.mockito.Mockito.*; @@ -197,9 +199,8 @@ assertThat(schema.getAttributeTypes().containsAll(baseSchema.getAttributeTypes())); assertThat(schema.getAttributeType("testtype")).isNotNull(); assertThat(schema.getSchemaName()).isEqualTo(baseSchema.getSchemaName()); assertThat(schema.allowMalformedNamesAndOptions()).isEqualTo( baseSchema.allowMalformedNamesAndOptions()); assertThat(schema.getOption(ALLOW_MALFORMED_NAMES_AND_OPTIONS)) .isEqualTo(baseSchema.getOption(ALLOW_MALFORMED_NAMES_AND_OPTIONS)); } /** @@ -2018,11 +2019,11 @@ @Test public void testOverrideDefaultSyntax() { final Schema schema = new SchemaBuilder(Schema.getCoreSchema()).defaultSyntax( CoreSchema.getDirectoryStringSyntax()).toSchema().asNonStrictSchema(); assertThat(schema.getDefaultSyntax()).isEqualTo(CoreSchema.getDirectoryStringSyntax()); assertThat(schema.getAttributeType("dummy").getSyntax()).isEqualTo( CoreSchema.getDirectoryStringSyntax()); new SchemaBuilder(Schema.getCoreSchema()) .setOption(DEFAULT_SYNTAX_OID, getDirectoryStringSyntax().getOID()) .toSchema().asNonStrictSchema(); assertThat(schema.getDefaultSyntax()).isEqualTo(getDirectoryStringSyntax()); assertThat(schema.getAttributeType("dummy").getSyntax()).isEqualTo(getDirectoryStringSyntax()); } @Test @@ -2038,8 +2039,9 @@ @Test public void testOverrideMatchingRule() { final Schema schema = new SchemaBuilder(Schema.getCoreSchema()).defaultMatchingRule( CoreSchema.getCaseIgnoreMatchingRule()).toSchema().asNonStrictSchema(); new SchemaBuilder(Schema.getCoreSchema()) .setOption(DEFAULT_MATCHING_RULE_OID, getCaseIgnoreMatchingRule().getOID()) .toSchema().asNonStrictSchema(); assertThat(schema.getDefaultMatchingRule()).isEqualTo( CoreSchema.getCaseIgnoreMatchingRule()); assertThat(schema.getAttributeType("dummy").getEqualityMatchingRule()).isEqualTo( opendj-sdk/opendj-core/src/test/java/org/forgerock/opendj/ldap/schema/SchemaCompatTest.java
@@ -30,6 +30,8 @@ import org.testng.annotations.DataProvider; import org.testng.annotations.Test; import static org.forgerock.opendj.ldap.schema.SchemaOptions.*; /** * Tests schema compatibility options. */ @@ -73,11 +75,9 @@ */ @Test(dataProvider = "validAttributeDescriptions") public void testValidAttributeDescriptions(String atd, boolean allowIllegalCharacters) { SchemaBuilder builder = new SchemaBuilder(Schema.getCoreSchema()) .allowMalformedNamesAndOptions(allowIllegalCharacters); Schema schema = builder.toSchema().asNonStrictSchema(); AttributeDescription.valueOf(atd, schema); SchemaBuilder builder = new SchemaBuilder(Schema.getCoreSchema()) .setOption(ALLOW_MALFORMED_NAMES_AND_OPTIONS, allowIllegalCharacters); AttributeDescription.valueOf(atd, builder.toSchema().asNonStrictSchema()); } /** @@ -113,14 +113,11 @@ * {@code true} if the attribute description requires the * compatibility option to be set. */ @Test(dataProvider = "invalidAttributeDescriptions", expectedExceptions = LocalizedIllegalArgumentException.class) @Test(dataProvider = "invalidAttributeDescriptions", expectedExceptions = LocalizedIllegalArgumentException.class) public void testInvalidAttributeDescriptions(String atd, boolean allowIllegalCharacters) { SchemaBuilder builder = new SchemaBuilder(Schema.getCoreSchema()) .allowMalformedNamesAndOptions(allowIllegalCharacters); Schema schema = builder.toSchema().asNonStrictSchema(); AttributeDescription.valueOf(atd, schema); SchemaBuilder builder = new SchemaBuilder(Schema.getCoreSchema()); builder.setOption(ALLOW_MALFORMED_NAMES_AND_OPTIONS, allowIllegalCharacters); AttributeDescription.valueOf(atd, builder.toSchema().asNonStrictSchema()); } private static final Syntax ATD_SYNTAX = CoreSchema.getAttributeTypeDescriptionSyntax(); @@ -206,12 +203,10 @@ * {@code true} if the element requires the compatibility option * to be set. */ @Test(dataProvider = "invalidSchemaElements", expectedExceptions = LocalizedIllegalArgumentException.class) public void testInvalidSchemaBuilderElementParsers(String element, Syntax syntax, boolean allowIllegalCharacters) { SchemaBuilder builder = new SchemaBuilder().allowMalformedNamesAndOptions(allowIllegalCharacters); @Test(dataProvider = "invalidSchemaElements", expectedExceptions = LocalizedIllegalArgumentException.class) public void testInvalidSchemaBuilderElementParsers(String element, Syntax syntax, boolean allowIllegalCharacters) { SchemaBuilder builder = new SchemaBuilder(); builder.setOption(ALLOW_MALFORMED_NAMES_AND_OPTIONS, allowIllegalCharacters); if (syntax == ATD_SYNTAX) { builder.addAttributeType(element, false); @@ -301,10 +296,9 @@ * to be set. */ @Test(dataProvider = "validSchemaElements") public void testValidSchemaBuilderElementParsers(String element, Syntax syntax, boolean allowIllegalCharacters) { SchemaBuilder builder = new SchemaBuilder().allowMalformedNamesAndOptions(allowIllegalCharacters); public void testValidSchemaBuilderElementParsers(String element, Syntax syntax, boolean allowIllegalCharacters) { SchemaBuilder builder = new SchemaBuilder(); builder.setOption(ALLOW_MALFORMED_NAMES_AND_OPTIONS, allowIllegalCharacters); if (syntax == ATD_SYNTAX) { builder.addAttributeType(element, false); opendj-sdk/opendj-core/src/test/java/org/forgerock/opendj/ldap/schema/SchemaOptionsTestCase.java
New file @@ -0,0 +1,83 @@ /* * 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 legal-notices/CDDLv1_0.txt * or http://forgerock.org/license/CDDLv1.0.html. * 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 legal-notices/CDDLv1_0.txt. * 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 * * * Copyright 2013-2014 ForgeRock AS. */ package org.forgerock.opendj.ldap.schema; import static org.fest.assertions.Assertions.*; import static org.forgerock.opendj.ldap.schema.SchemaOptions.*; import org.forgerock.opendj.ldap.Option; import org.testng.annotations.DataProvider; import org.testng.annotations.Test; /** * Tests the {@link SchemaOptions} class. */ public class SchemaOptionsTestCase extends AbstractSchemaTestCase { private static final int TEST_OPTION_DEFAULT_VALUE = 42; private static final Option<Integer> TEST_OPTION = Option.of(Integer.class, TEST_OPTION_DEFAULT_VALUE); @DataProvider private Object[][] defaultSchemaOptions() { return new Object[][] { { ALLOW_MALFORMED_CERTIFICATES }, { ALLOW_MALFORMED_JPEG_PHOTOS }, { ALLOW_MALFORMED_NAMES_AND_OPTIONS }, { ALLOW_NON_STANDARD_TELEPHONE_NUMBERS }, { ALLOW_ZERO_LENGTH_DIRECTORY_STRINGS }, { STRICT_FORMAT_FOR_COUNTRY_STRINGS }, { STRIP_UPPER_BOUND_FOR_ATTRIBUTE_TYPE }}; } @Test(dataProvider = "defaultSchemaOptions") public void testDefaultSchemaOptions(Option<?> option) { assertThat(new SchemaBuilder().getOptions().get(option)).isEqualTo(option.getValue(null)); } @Test public void testAddSchemaOption() { assertThat(newSchemaBuilder().getOptions().get(TEST_OPTION)).isEqualTo(TEST_OPTION_DEFAULT_VALUE); } @Test public void testSetSchemaOption() { assertThat(newSchemaBuilder().setOption(TEST_OPTION, 0).getOptions().get(TEST_OPTION)).isEqualTo(0); } @Test public void testSchemaOptionsCopy() { final SchemaOptions copiedOptions = SchemaOptions.copyOf(newSchemaBuilder().getOptions()); assertThat(copiedOptions.get(TEST_OPTION)).isEqualTo(TEST_OPTION_DEFAULT_VALUE); } @Test(expectedExceptions = UnsupportedOperationException.class) public void testAsReadOnlyOptions() { SchemaOptions.unmodifiable(new SchemaBuilder().getOptions()).set(ALLOW_MALFORMED_CERTIFICATES, false); } private SchemaBuilder newSchemaBuilder() { return new SchemaBuilder().setOption(TEST_OPTION, TEST_OPTION_DEFAULT_VALUE); } } opendj-sdk/opendj-core/src/test/java/org/forgerock/opendj/ldap/schema/SyntaxTestCase.java
@@ -27,11 +27,12 @@ package org.forgerock.opendj.ldap.schema; import static org.fest.assertions.Assertions.assertThat; import org.forgerock.opendj.ldap.schema.Syntax.Builder; import org.testng.annotations.Test; import static org.fest.assertions.Assertions.*; import static org.forgerock.opendj.ldap.schema.SchemaOptions.*; /** * This class tests the Syntax class. */ @@ -198,7 +199,7 @@ public final void testBuilderAllowsNoSyntaxCaseWhereDefaultSyntaxIsChanged() { // @formatter:off final Schema schema = new SchemaBuilder(Schema.getCoreSchema()) .defaultSyntax("1.3.6.1.4.1.1466.115.121.1.15") .setOption(DEFAULT_SYNTAX_OID, "1.3.6.1.4.1.1466.115.121.1.15") .buildSyntax("1.9.1.2.3") .description("Security Label") .extraProperties("X-ENUM", "top-secret", "secret", "confidential") opendj-sdk/opendj-core/src/test/java/org/forgerock/opendj/ldif/LDIFTestCase.java
@@ -27,8 +27,6 @@ package org.forgerock.opendj.ldif; import static org.fest.assertions.Assertions.assertThat; import java.io.File; import java.io.IOException; import java.util.ArrayList; @@ -54,13 +52,18 @@ import org.forgerock.opendj.ldap.requests.ModifyRequest; import org.forgerock.opendj.ldap.requests.Requests; import org.forgerock.opendj.ldap.requests.SearchRequest; import org.forgerock.opendj.ldap.schema.CoreSchema; import org.forgerock.opendj.ldap.schema.MatchingRule; import org.forgerock.opendj.ldap.schema.Schema; import org.forgerock.opendj.ldap.schema.SchemaBuilder; import org.forgerock.opendj.ldap.schema.Syntax; import org.testng.annotations.Test; import com.forgerock.opendj.ldap.CoreMessages; import static org.fest.assertions.Assertions.*; import static org.forgerock.opendj.ldap.schema.CoreSchema.*; import static org.forgerock.opendj.ldap.schema.SchemaOptions.*; /** * This class tests the LDIF functionality. */ @@ -550,10 +553,7 @@ */ @Test public final void testSearchForEntryInLDIFUsingIgnoreMatchingRuleSucceedWithLowerCaseFilter() throws IOException { Schema schema = new SchemaBuilder(Schema.getCoreSchema()).defaultMatchingRule( CoreSchema.getCaseIgnoreMatchingRule()).defaultSyntax( CoreSchema.getDirectoryStringSyntax()).toSchema().asNonStrictSchema(); Schema schema = newSchemaBuilder(getCaseIgnoreMatchingRule(), getDirectoryStringSyntax()); // @formatter:off final LDIFEntryReader input = new LDIFEntryReader( @@ -584,10 +584,7 @@ */ @Test(expectedExceptions = NoSuchElementException.class) public final void testSearchForEntryInLDIFUsingExactMatchingRuleFailsWithLowerCaseFilter() throws IOException { Schema schema = new SchemaBuilder(Schema.getCoreSchema()).defaultMatchingRule( CoreSchema.getCaseExactMatchingRule()).defaultSyntax( CoreSchema.getDirectoryStringSyntax()).toSchema().asNonStrictSchema(); Schema schema = newSchemaBuilder(getCaseExactMatchingRule(), getDirectoryStringSyntax()); // @formatter:off final LDIFEntryReader input = new LDIFEntryReader( @@ -613,10 +610,7 @@ */ @Test public final void testSearchForEntryInLDIFUsingExactMatchingRuleSucceedWithRightFilter() throws IOException { Schema schema = new SchemaBuilder(Schema.getCoreSchema()).defaultMatchingRule( CoreSchema.getCaseExactMatchingRule()).defaultSyntax( CoreSchema.getDirectoryStringSyntax()).toSchema().asNonStrictSchema(); Schema schema = newSchemaBuilder(getCaseExactMatchingRule(), getDirectoryStringSyntax()); // @formatter:off final LDIFEntryReader input = new LDIFEntryReader( @@ -640,6 +634,13 @@ input.close(); } private Schema newSchemaBuilder(MatchingRule defaultMatchingRule, Syntax defaultSyntax) { return new SchemaBuilder(Schema.getCoreSchema()) .setOption(DEFAULT_MATCHING_RULE_OID, defaultMatchingRule.getOID()) .setOption(DEFAULT_SYNTAX_OID, defaultSyntax.getOID()) .toSchema().asNonStrictSchema(); } /** * Verifying LDIF collection reader. *