View Javadoc

1   /*
2    *  Licensed to the Apache Software Foundation (ASF) under one
3    *  or more contributor license agreements.  See the NOTICE file
4    *  distributed with this work for additional information
5    *  regarding copyright ownership.  The ASF licenses this file
6    *  to you under the Apache License, Version 2.0 (the
7    *  "License"); you may not use this file except in compliance
8    *  with the License.  You may obtain a copy of the License at
9    *  
10   *    http://www.apache.org/licenses/LICENSE-2.0
11   *  
12   *  Unless required by applicable law or agreed to in writing,
13   *  software distributed under the License is distributed on an
14   *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15   *  KIND, either express or implied.  See the License for the
16   *  specific language governing permissions and limitations
17   *  under the License. 
18   *  
19   */
20  package org.apache.directory.server.core.entry;
21  
22  import java.io.ByteArrayInputStream;
23  import java.io.ByteArrayOutputStream;
24  import java.io.IOException;
25  import java.io.ObjectInputStream;
26  import java.io.ObjectOutputStream;
27  
28  import org.apache.directory.server.schema.registries.Registries;
29  import org.slf4j.Logger;
30  import org.slf4j.LoggerFactory;
31  
32  import jdbm.helper.Serializer;
33  
34  
35  /**
36   * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
37   * @version $Rev$, $Date$
38   */
39  public class ServerEntrySerializer implements Serializer
40  {
41      private static final long serialVersionUID = 1L;
42  
43      /** the logger for this class */
44      private static final Logger LOG = LoggerFactory.getLogger( ServerEntrySerializer.class );
45  
46      /**
47       * Speedup for logs
48       */
49      private static final boolean IS_DEBUG = LOG.isDebugEnabled();
50  
51      /** The registries reference */
52      private transient Registries registries;
53  
54  
55      /**
56       * Creates a new instance of ServerEntrySerializer.
57       *
58       * @param registries The reference to the global registries
59       */
60      public ServerEntrySerializer( Registries registries )
61      {
62          this.registries = registries;
63      }
64  
65  
66      /**
67       * <p>
68       * 
69       * This is the place where we serialize entries, and all theirs
70       * elements. the reason why we don't call the underlying methods
71       * (<code>ServerAttribute.write(), Value.write()</code>) is that we need
72       * access to the registries to read back the values.
73       * <p>
74       * The structure used to store the entry is the following :
75       * <li><b>[DN length]</b> : can be -1 if we don't have a DN, 0 if the 
76       * DN is empty, otherwise contains the DN's length.<p> 
77       * <b>NOTE :</b>This should be unnecessary, as the DN should always exists
78       * <p>
79       * </li>
80       * <li>
81       * <b>DN</b> : The entry's DN. Can be empty (rootDSE)<p>
82       * </li>
83       * <li>
84       * <b>[nb attributes]</b> The number of attributes
85       * </li>
86       * <br>
87       * For each attribute :
88       * <li>
89       * <b>[upId]</b> The attribute user provided ID (it can't be null)
90       * </li>
91       * <li>
92       * <b>[nb values]</b> The number of values
93       * </li>
94       * <br>
95       * For each value :
96       * <li>
97       *  <b>[is valid]</b> if the value is valid
98       * </li>
99       * <li>
100      *  <b>[HR flag]</b> if the value is a String
101      * </li>
102      * <li>
103      *  <b>[Streamed flag]</b> if the value is streamed
104      * </li>
105      * <li>
106      *  <b>[UP value]</b> the user provided value
107      * </li>
108      * <li>
109      *  <b>[Norm value]</b> (will be null if normValue == upValue)
110      * </li>
111      */
112     public byte[] serialize( Object object ) throws IOException
113     {
114         DefaultServerEntry entry = ( DefaultServerEntry ) object;
115         
116         ByteArrayOutputStream baos = new ByteArrayOutputStream();
117         ObjectOutputStream out = new ObjectOutputStream( baos );
118 
119         entry.serialize( out );
120 
121         // Note : we don't store the ObjectClassAttribute. I has already
122         // been stored as an attribute.
123 
124         out.flush();
125 
126         if ( IS_DEBUG )
127         {
128             LOG.debug( ">------------------------------------------------" );
129             LOG.debug( "Serialize " + entry );
130         }
131 
132         return baos.toByteArray();
133     }
134 
135     
136     /**
137      *  Deserialize a ServerEntry.
138      *  
139      *  @param bytes the byte array containing the serialized entry
140      *  @return An instance of a ServerEntry object 
141      *  @throws IOException if we can't deserialize the ServerEntry
142      */
143     public Object deserialize( byte[] bytes ) throws IOException
144     {
145         ObjectInputStream in = new ObjectInputStream( new ByteArrayInputStream( bytes ) );
146 
147         DefaultServerEntry serverEntry = new DefaultServerEntry( registries );
148         
149         try
150         {
151             serverEntry.deserialize( in );
152             
153             return serverEntry;
154         }
155         catch ( ClassNotFoundException cnfe )
156         {
157             LOG.error( "Cannot deserialize the entry :" + cnfe.getMessage() );
158             return null;
159         }
160     }
161 }