001 /* 002 * Licensed to the Apache Software Foundation (ASF) under one 003 * or more contributor license agreements. See the NOTICE file 004 * distributed with this work for additional information 005 * regarding copyright ownership. The ASF licenses this file 006 * to you under the Apache License, Version 2.0 (the 007 * "License"); you may not use this file except in compliance 008 * with the License. You may obtain a copy of the License at 009 * 010 * http://www.apache.org/licenses/LICENSE-2.0 011 * 012 * Unless required by applicable law or agreed to in writing, 013 * software distributed under the License is distributed on an 014 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 015 * KIND, either express or implied. See the License for the 016 * specific language governing permissions and limitations 017 * under the License. 018 * 019 */ 020 package org.apache.directory.server.core.partition.impl.btree.jdbm; 021 022 import java.io.ByteArrayInputStream; 023 import java.io.ByteArrayOutputStream; 024 import java.io.IOException; 025 import java.io.ObjectInputStream; 026 import java.io.ObjectOutputStream; 027 028 import jdbm.helper.Serializer; 029 030 import org.apache.directory.server.i18n.I18n; 031 import org.apache.directory.shared.ldap.entry.DefaultServerEntry; 032 import org.apache.directory.shared.ldap.schema.SchemaManager; 033 import org.slf4j.Logger; 034 import org.slf4j.LoggerFactory; 035 036 037 /** 038 * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a> 039 * @version $Rev$, $Date$ 040 */ 041 public class ServerEntrySerializer implements Serializer 042 { 043 private static final long serialVersionUID = 1L; 044 045 /** the logger for this class */ 046 private static final Logger LOG = LoggerFactory.getLogger( ServerEntrySerializer.class ); 047 048 /** 049 * Speedup for logs 050 */ 051 private static final boolean IS_DEBUG = LOG.isDebugEnabled(); 052 053 /** The schemaManager reference */ 054 private transient SchemaManager schemaManager; 055 056 057 /** 058 * Creates a new instance of ServerEntrySerializer. 059 * 060 * @param schemaManager The reference to the global schemaManager 061 */ 062 public ServerEntrySerializer( SchemaManager schemaManager ) 063 { 064 this.schemaManager = schemaManager; 065 } 066 067 068 /** 069 * <p> 070 * 071 * This is the place where we serialize entries, and all theirs 072 * elements. the reason why we don't call the underlying methods 073 * (<code>ServerAttribute.write(), Value.write()</code>) is that we need 074 * access to the registries to read back the values. 075 * <p> 076 * The structure used to store the entry is the following : 077 * <li><b>[DN length]</b> : can be -1 if we don't have a DN, 0 if the 078 * DN is empty, otherwise contains the DN's length.<p> 079 * <b>NOTE :</b>This should be unnecessary, as the DN should always exists 080 * <p> 081 * </li> 082 * <li> 083 * <b>DN</b> : The entry's DN. Can be empty (rootDSE)<p> 084 * </li> 085 * <li> 086 * <b>[nb attributes]</b> The number of attributes 087 * </li> 088 * <br> 089 * For each attribute : 090 * <li> 091 * <b>[upId]</b> The attribute user provided ID (it can't be null) 092 * </li> 093 * <li> 094 * <b>[nb values]</b> The number of values 095 * </li> 096 * <br> 097 * For each value : 098 * <li> 099 * <b>[is valid]</b> if the value is valid 100 * </li> 101 * <li> 102 * <b>[HR flag]</b> if the value is a String 103 * </li> 104 * <li> 105 * <b>[Streamed flag]</b> if the value is streamed 106 * </li> 107 * <li> 108 * <b>[UP value]</b> the user provided value 109 * </li> 110 * <li> 111 * <b>[Norm value]</b> (will be null if normValue == upValue) 112 * </li> 113 */ 114 public byte[] serialize( Object object ) throws IOException 115 { 116 DefaultServerEntry entry = ( DefaultServerEntry ) object; 117 118 ByteArrayOutputStream baos = new ByteArrayOutputStream(); 119 ObjectOutputStream out = new ObjectOutputStream( baos ); 120 121 entry.serialize( out ); 122 123 // Note : we don't store the ObjectClassAttribute. I has already 124 // been stored as an attribute. 125 126 out.flush(); 127 128 if ( IS_DEBUG ) 129 { 130 LOG.debug( ">------------------------------------------------" ); 131 LOG.debug( "Serialize " + entry ); 132 } 133 134 return baos.toByteArray(); 135 } 136 137 138 /** 139 * Deserialize a ServerEntry. 140 * 141 * @param bytes the byte array containing the serialized entry 142 * @return An instance of a ServerEntry object 143 * @throws IOException if we can't deserialize the ServerEntry 144 */ 145 public Object deserialize( byte[] bytes ) throws IOException 146 { 147 ObjectInputStream in = new ObjectInputStream( new ByteArrayInputStream( bytes ) ); 148 149 DefaultServerEntry serverEntry = new DefaultServerEntry( schemaManager ); 150 151 try 152 { 153 serverEntry.deserialize( in ); 154 155 return serverEntry; 156 } 157 catch ( ClassNotFoundException cnfe ) 158 { 159 LOG.error( I18n.err( I18n.ERR_134, cnfe.getLocalizedMessage() ) ); 160 return null; 161 } 162 } 163 }