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 }