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