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 }