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