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 2009 Sun Microsystems, Inc. 025 * Portions Copyright 2013-2015 ForgeRock AS. 026 */ 027package org.opends.server.types; 028 029import org.forgerock.opendj.ldap.ByteStringBuilder; 030import org.forgerock.opendj.ldap.ByteSequenceReader; 031 032import org.forgerock.i18n.LocalizableMessage; 033import org.opends.server.api.CompressedSchema; 034import org.opends.server.core.DirectoryServer; 035 036import static org.opends.messages.CoreMessages.*; 037 038/** 039 * This class defines a data structure that contains configuration 040 * information about how an entry should be encoded. 041 */ 042@org.opends.server.types.PublicAPI( 043 stability=org.opends.server.types.StabilityLevel.VOLATILE, 044 mayInstantiate=true, 045 mayExtend=false, 046 mayInvoke=true) 047public final class EntryEncodeConfig 048{ 049 /** 050 * The encode mask value that can be used to indicate that the 051 * encoded entry should not contain a DN. 052 */ 053 private static final byte ENCODE_FLAG_EXCLUDE_DN = 0x01; 054 055 056 057 /** 058 * The encode mask value that can be used that the encoded 059 * representation should compress the set of object classes. 060 */ 061 private static final byte ENCODE_FLAG_COMPRESS_OCS = 0x02; 062 063 064 065 /** 066 * The encode mask value that can be used that the encoded 067 * representation should compress the set of attribute descriptions 068 * to conserve space and improve performance. 069 */ 070 private static final byte ENCODE_FLAG_COMPRESS_ADS = 0x04; 071 072 073 074 /** 075 * A reference to an entry encode configuration with all the default 076 * settings. 077 */ 078 public static final EntryEncodeConfig 079 DEFAULT_CONFIG = new EntryEncodeConfig(); 080 081 082 083 /** Indicates whether to compress the attribute descriptions. */ 084 private final boolean compressAttrDescriptions; 085 086 /** Indicates whether to compress the object class sets. */ 087 private final boolean compressObjectClassSets; 088 089 /** Indicates whether to exclude the DN. */ 090 private final boolean excludeDN; 091 092 /** The encoded representation of this encode configuration. */ 093 private final byte encodedRepresentation; 094 095 /** The compressed schema handler for this encode configuration. */ 096 private final CompressedSchema compressedSchema; 097 098 099 100 /** 101 * Creates a new encoded entry configuration with the default 102 * settings. 103 */ 104 public EntryEncodeConfig() 105 { 106 excludeDN = false; 107 compressAttrDescriptions = false; 108 compressObjectClassSets = false; 109 110 compressedSchema = DirectoryServer.getDefaultCompressedSchema(); 111 112 encodedRepresentation = 0x00; 113 } 114 115 116 117 /** 118 * Creates a new encoded entry configuration with the specified 119 * settings. 120 * 121 * @param excludeDN Indicates whether to exclude 122 * the DN from the encoded entry. 123 * @param compressAttrDescriptions Indicates whether to compress 124 * attribute descriptions. 125 * @param compressObjectClassSets Indicates whether to compress 126 * object class sets. 127 */ 128 public EntryEncodeConfig(boolean excludeDN, 129 boolean compressAttrDescriptions, 130 boolean compressObjectClassSets) 131 { 132 this.excludeDN = excludeDN; 133 this.compressAttrDescriptions = compressAttrDescriptions; 134 this.compressObjectClassSets = compressObjectClassSets; 135 136 compressedSchema = DirectoryServer.getDefaultCompressedSchema(); 137 138 byte flagByte = 0x00; 139 if (excludeDN) 140 { 141 flagByte |= ENCODE_FLAG_EXCLUDE_DN; 142 } 143 144 if (compressAttrDescriptions) 145 { 146 flagByte |= ENCODE_FLAG_COMPRESS_ADS; 147 } 148 149 if (compressObjectClassSets) 150 { 151 flagByte |= ENCODE_FLAG_COMPRESS_OCS; 152 } 153 154 encodedRepresentation = flagByte; 155 } 156 157 158 159 /** 160 * Creates a new encoded entry configuration with the specified 161 * settings. 162 * 163 * @param excludeDN Indicates whether to exclude 164 * the DN from the encoded entry. 165 * @param compressAttrDescriptions Indicates whether to compress 166 * attribute descriptions. 167 * @param compressObjectClassSets Indicates whether to compress 168 * object class sets. 169 * @param compressedSchema The compressed schema manager 170 * for this encode config. 171 */ 172 public EntryEncodeConfig(boolean excludeDN, 173 boolean compressAttrDescriptions, 174 boolean compressObjectClassSets, 175 CompressedSchema compressedSchema) 176 { 177 this.excludeDN = excludeDN; 178 this.compressAttrDescriptions = compressAttrDescriptions; 179 this.compressObjectClassSets = compressObjectClassSets; 180 this.compressedSchema = compressedSchema; 181 182 byte flagByte = 0x00; 183 if (excludeDN) 184 { 185 flagByte |= ENCODE_FLAG_EXCLUDE_DN; 186 } 187 188 if (compressAttrDescriptions) 189 { 190 flagByte |= ENCODE_FLAG_COMPRESS_ADS; 191 } 192 193 if (compressObjectClassSets) 194 { 195 flagByte |= ENCODE_FLAG_COMPRESS_OCS; 196 } 197 198 encodedRepresentation = flagByte; 199 } 200 201 202 203 /** 204 * Indicates whether the encoded entry should exclude the DN. 205 * 206 * @return {@code true} if the encoded entry should exclude the DN, 207 * or {@code false} if not. 208 */ 209 public boolean excludeDN() 210 { 211 return excludeDN; 212 } 213 214 215 216 /** 217 * Indicates whether the encoded entry should use compressed 218 * attribute descriptions. 219 * 220 * @return {@code true} if the encoded entry should use compressed 221 * attribute descriptions, or {@code false} if not. 222 */ 223 public boolean compressAttributeDescriptions() 224 { 225 return compressAttrDescriptions; 226 } 227 228 229 230 /** 231 * Indicates whether the encoded entry should use compressed object 232 * class sets. 233 * 234 * @return {@code true} if the encoded entry should use compressed 235 * object class sets, or {@code false} if not. 236 */ 237 public boolean compressObjectClassSets() 238 { 239 return compressObjectClassSets; 240 } 241 242 243 244 /** 245 * Retrieves the compressed schema manager that may be used to 246 * generate compact schema encodings with this entry encode 247 * configuration. 248 * 249 * @return The compressed schema manager that may be used to 250 * generate compact schema encodings with this entry encode 251 * configuration. 252 */ 253 public CompressedSchema getCompressedSchema() 254 { 255 return compressedSchema; 256 } 257 258 259 260 /** 261 * Encodes this entry encode configuration into a byte array 262 * suitable for inclusion in the encoded entry. 263 * 264 * @param buffer The buffer to encode this configuration to. 265 */ 266 public void encode(ByteStringBuilder buffer) 267 { 268 buffer.appendBERLength(1); 269 buffer.append(encodedRepresentation); 270 } 271 272 273 /** 274 * Decodes the entry encode configuration from current position and 275 * length of the given byte array. 276 * 277 * @param buffer The byte array containing the encoded 278 * entry. 279 * @param length The number of bytes contained in the 280 * encode configuration. 281 * @param compressedSchema The compressed schema manager to use 282 * when decoding. 283 * 284 * @return The decoded configuration. 285 * 286 * @throws DirectoryException If the configuration cannot be 287 * properly decoded. 288 */ 289 public static EntryEncodeConfig 290 decode(ByteSequenceReader buffer, int length, 291 CompressedSchema compressedSchema) 292 throws DirectoryException 293 { 294 if (length != 1) 295 { 296 LocalizableMessage message = ERR_ENTRYENCODECFG_INVALID_LENGTH.get(); 297 throw new DirectoryException( 298 DirectoryServer.getServerErrorResultCode(), 299 message); 300 } 301 302 byte b = buffer.get(); 303 boolean excludeDN = is(b, ENCODE_FLAG_EXCLUDE_DN); 304 boolean compressAttrDescriptions = is(b, ENCODE_FLAG_COMPRESS_ADS); 305 boolean compressObjectClassSets = is(b, ENCODE_FLAG_COMPRESS_OCS); 306 return new EntryEncodeConfig(excludeDN, compressAttrDescriptions, 307 compressObjectClassSets, 308 compressedSchema); 309 } 310 311 private static boolean is(byte b, byte flag) 312 { 313 return (b & flag) == flag; 314 } 315 316 /** 317 * Retrieves a string representation of this entry encode 318 * configuration. 319 * 320 * @return A string representation of this entry encode 321 * configuration. 322 */ 323 public String toString() 324 { 325 StringBuilder buffer = new StringBuilder(); 326 toString(buffer); 327 return buffer.toString(); 328 } 329 330 331 332 /** 333 * Appends a string representation of this entry encode 334 * configuration to the provided buffer. 335 * 336 * @param buffer The buffer to which the information should be 337 * appended. 338 */ 339 public void toString(StringBuilder buffer) 340 { 341 buffer.append("EntryEncodeConfig(excludeDN="); 342 buffer.append(excludeDN); 343 buffer.append(", compressAttrDescriptions="); 344 buffer.append(compressAttrDescriptions); 345 buffer.append(", compressObjectClassSets="); 346 buffer.append(compressObjectClassSets); 347 buffer.append(")"); 348 } 349} 350