001/* 002 * CDDL HEADER START 003 * 004 * The contents of this file are subject to the terms of the 005 * Common Development and Distribution License, Version 1.0 only 006 * (the "License"). You may not use this file except in compliance 007 * with the License. 008 * 009 * You can obtain a copy of the license at legal-notices/CDDLv1_0.txt 010 * or http://forgerock.org/license/CDDLv1.0.html. 011 * See the License for the specific language governing permissions 012 * and limitations under the License. 013 * 014 * When distributing Covered Code, include this CDDL HEADER in each 015 * file and include the License file at legal-notices/CDDLv1_0.txt. 016 * If applicable, add the following below this CDDL HEADER, with the 017 * fields enclosed by brackets "[]" replaced with your own identifying 018 * information: 019 * Portions Copyright [yyyy] [name of copyright owner] 020 * 021 * CDDL HEADER END 022 * 023 * 024 * Copyright 2014 ForgeRock AS 025 */ 026package org.forgerock.opendj.ldap.schema; 027 028import java.util.IdentityHashMap; 029import java.util.Map; 030 031import org.forgerock.opendj.ldap.Option; 032 033import static java.util.Collections.*; 034 035import static org.forgerock.opendj.ldap.schema.SchemaConstants.*; 036 037/** 038 * Common options for LDAP schemas. 039 * <p> 040 * For example you set schema option as you want when using a schema. 041 * 042 * <pre> 043 * // Retrieves options from builder. 044 * SchemaOptions options = new SchemaBuilder().getOptions(); 045 * // Creates a new option. 046 * Option myIntegerOption = options.set(Option.of(Integer.class, 0)); 047 * // Retrieves option value from SchemaOption 048 * boolean allowMalformedNamesAndOptions = options.get(SchemaOptions.ALLOW_MALFORMED_NAMES_AND_OPTIONS); 049 * </pre> 050 */ 051public final class SchemaOptions { 052 /** 053 * Specifies whether the schema should allow certain illegal 054 * characters in OIDs and attribute options. When this compatibility option 055 * is set to {@code true} the following illegal characters will be permitted 056 * in addition to those permitted in section 1.4 of RFC 4512: 057 * 058 * <pre> 059 * USCORE = %x5F ; underscore ("_") 060 * DOT = %x2E ; period (".") 061 * </pre> 062 * 063 * By default this compatibility option is set to {@code true} because these 064 * characters are often used for naming purposes (such as collation rules). 065 */ 066 public static final Option<Boolean> ALLOW_MALFORMED_NAMES_AND_OPTIONS = Option.withDefault(true); 067 068 /** 069 * Specifies whether the JPEG Photo syntax should allow values which 070 * do not conform to the JFIF or Exif specifications. 071 * <p> 072 * By default this compatibility option is set to {@code true}. 073 */ 074 public static final Option<Boolean> ALLOW_MALFORMED_JPEG_PHOTOS = Option.withDefault(true); 075 076 /** 077 * Specifies whether the Certificate syntax should allow values which 078 * do not conform to the X.509 specifications. 079 * <p> 080 * By default this compatibility option is set to {@code true}. 081 */ 082 public static final Option<Boolean> ALLOW_MALFORMED_CERTIFICATES = Option.withDefault(true); 083 084 /** 085 * Specifies whether the Telephone Number syntax should allow values 086 * which do not conform to the E.123 international telephone number format. 087 * <p> 088 * By default this compatibility option is set to {@code true}. 089 */ 090 public static final Option<Boolean> ALLOW_NON_STANDARD_TELEPHONE_NUMBERS = Option.withDefault(true); 091 092 /** 093 * Specifies whether zero-length values will be allowed by the 094 * Directory String syntax. This is technically forbidden by the LDAP 095 * specification, but it was allowed in earlier versions of the server, and 096 * the discussion of the directory string syntax in RFC 2252 does not 097 * explicitly state that they are not allowed. 098 * <p> 099 * By default this compatibility option is set to {@code false}. 100 */ 101 public static final Option<Boolean> ALLOW_ZERO_LENGTH_DIRECTORY_STRINGS = Option.withDefault(false); 102 103 /** 104 * Specifies the OID of the default syntax which will be used when parsing 105 * unrecognized attributes. 106 * <p> 107 * By default the {@link SchemaConstants#SYNTAX_OCTET_STRING_OID OctetString} 108 * syntax will be used. 109 */ 110 public static final Option<String> DEFAULT_SYNTAX_OID = Option.of(String.class, SYNTAX_OCTET_STRING_OID); 111 112 /** 113 * Specifies the OID of the default matching rule which will be used when 114 * parsing unrecognized attributes. 115 * <p> 116 * By default the {@link SchemaConstants#EMR_OCTET_STRING_OID OctetString} 117 * matching rule will be used. 118 */ 119 public static final Option<String> DEFAULT_MATCHING_RULE_OID = Option.of(String.class, EMR_OCTET_STRING_OID); 120 121 /** 122 * Indicates whether country code values are required to strictly 123 * comply with the standard definition for this syntax. 124 * <p> 125 * When set to false, country codes will not be validated and, as a result 126 * any string containing 2 characters will be acceptable. 127 * By default this compatibility option is set to {@code true}. 128 */ 129 public static final Option<Boolean> STRICT_FORMAT_FOR_COUNTRY_STRINGS = Option.withDefault(true); 130 131 /** 132 * Indicates whether the minimum upper bound value should be stripped from 133 * the Attribute Type Syntax Description. 134 * <p> 135 * By default this compatibility option is set to {@code false}. 136 */ 137 public static final Option<Boolean> STRIP_UPPER_BOUND_FOR_ATTRIBUTE_TYPE = Option.withDefault(false); 138 139 private final Map<Option<?>, Object> options; 140 141 /** 142 * Creates a new set of schema options with default settings. 143 * 144 * @return A new {@link SchemaOptions} with default settings. 145 */ 146 static SchemaOptions defaultSchemaOptions() { 147 return new SchemaOptions(new IdentityHashMap<Option<?>, Object>()); 148 } 149 150 /** 151 * Creates a new schema options object by copying the provided schema 152 * options. The options names and values will all be copied. 153 * 154 * @param schemaOptions 155 * The schema options to be copied. 156 * @return A new schema options object created by copying the provided schema 157 * options. 158 */ 159 static SchemaOptions copyOf(SchemaOptions schemaOptions) { 160 return new SchemaOptions(new IdentityHashMap<Option<?>, Object>(schemaOptions.options)); 161 } 162 163 /** 164 * Returns an unmodifiable {@link SchemaOptions} copy of this set of options. 165 * 166 * @param schemaOptions 167 * The schema options to be copied. 168 * @return An unmodifiable {@link SchemaOptions} view of this set of options. 169 */ 170 static SchemaOptions unmodifiable(SchemaOptions schemaOptions) { 171 return new SchemaOptions(unmodifiableMap(new IdentityHashMap<Option<?>, Object>(schemaOptions.options))); 172 } 173 174 private SchemaOptions(Map<Option<?>, Object> optionsMap) { 175 this.options = optionsMap; 176 } 177 178 /** 179 * Returns the value to which the specified {@link Option} is mapped, or 180 * {@code null} if this options set contains no mapping for the {@link Option}. 181 * 182 * @param <T> 183 * The option type. 184 * @param option 185 * The option whose associated value is to be returned. 186 * @return The value to which the specified option is mapped, or null if 187 * this options set contains no mapping for the option. 188 */ 189 <T> T get(Option<T> option) { 190 return option.getValue(options.get(option)); 191 } 192 193 /** 194 * Associates the specified option value with the specified option in this 195 * set of options. (optional operation). If this set of options previously 196 * contained a mapping for the option, the old value is replaced by the 197 * specified value. 198 * 199 * @param <T> 200 * The option type. 201 * @param option 202 * Option with which the specified value is to be associated. 203 * @param value 204 * Value to be associated with the specified option. 205 * @return A reference to this set of options. 206 * @throws UnsupportedOperationException 207 * If this set of options is read only. 208 */ 209 <T> SchemaOptions set(Option<T> option, T value) { 210 options.put(option, value); 211 return this; 212 } 213 214}