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 */ 020package org.apache.directory.server.core.partition.impl.btree.jdbm; 021 022 023import java.io.ByteArrayInputStream; 024import java.io.ByteArrayOutputStream; 025import java.io.IOException; 026import java.io.ObjectInputStream; 027import java.io.ObjectOutput; 028import java.io.ObjectOutputStream; 029 030import jdbm.helper.Serializer; 031 032import org.apache.directory.api.ldap.model.name.Rdn; 033import org.apache.directory.api.ldap.model.schema.SchemaManager; 034import org.apache.directory.server.i18n.I18n; 035import org.apache.directory.server.xdbm.ParentIdAndRdn; 036import org.slf4j.Logger; 037import org.slf4j.LoggerFactory; 038 039 040/** 041 * Serialize and deserialize a ParentidAndRdn. 042 * <br><br> 043 * <b>This class must *not* be used outside of the server.</b> 044 * 045 * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a> 046 */ 047public class ParentIdAndRdnSerializer implements Serializer 048{ 049 /** The serialVersionUID */ 050 private static final long serialVersionUID = 1L; 051 052 /** the logger for this class */ 053 private static final Logger LOG = LoggerFactory.getLogger( ParentIdAndRdnSerializer.class ); 054 055 /** 056 * Speedup for logs 057 */ 058 private static final boolean IS_DEBUG = LOG.isDebugEnabled(); 059 060 /** The schemaManager reference */ 061 private transient SchemaManager schemaManager; 062 063 064 /** 065 * Creates a new instance of ParentIdAndRdnSerializer. 066 * 067 * @param schemaManager The reference to the global schemaManager 068 */ 069 public ParentIdAndRdnSerializer( SchemaManager schemaManager ) 070 { 071 this.schemaManager = schemaManager; 072 } 073 074 075 /** 076 * This is the place where we serialize ParentIdAndRdn 077 * 078 * @param object The element to serialize 079 * @return the byte] containing the serialized element 080 * @throws IOException If the serialization failed 081 */ 082 public byte[] serialize( Object object ) throws IOException 083 { 084 ParentIdAndRdn parentIdAndRdn = ( ParentIdAndRdn ) object; 085 086 try ( ByteArrayOutputStream baos = new ByteArrayOutputStream(); 087 ObjectOutput out = new ObjectOutputStream( baos ) ) 088 { 089 090 // First, the Dn 091 Rdn[] rdns = parentIdAndRdn.getRdns(); 092 093 // Write the Rdn of the Dn 094 if ( ( rdns == null ) || ( rdns.length == 0 ) ) 095 { 096 out.writeByte( 0 ); 097 } 098 else 099 { 100 out.writeByte( rdns.length ); 101 102 for ( Rdn rdn : rdns ) 103 { 104 rdn.writeExternal( out ); 105 } 106 } 107 108 // Then the parentId. 109 out.writeUTF( parentIdAndRdn.getParentId() ); 110 111 // The number of children 112 out.writeInt( parentIdAndRdn.getNbChildren() ); 113 114 // The number of descendants 115 out.writeInt( parentIdAndRdn.getNbDescendants() ); 116 117 out.flush(); 118 119 if ( IS_DEBUG ) 120 { 121 LOG.debug( ">------------------------------------------------" ); 122 LOG.debug( "Serialize {}", parentIdAndRdn ); 123 } 124 125 return baos.toByteArray(); 126 } 127 } 128 129 130 /** 131 * Deserialize a ParentIdAndRdn. 132 * 133 * @param bytes the byte array containing the serialized ParentIdAndRdn 134 * @return An instance of a ParentIdAndRdn object 135 * @throws IOException if we can't deserialize the ParentIdAndRdn 136 */ 137 public Object deserialize( byte[] bytes ) throws IOException 138 { 139 ObjectInputStream in = new ObjectInputStream( new ByteArrayInputStream( bytes ) ); 140 141 try 142 { 143 ParentIdAndRdn parentIdAndRdn = new ParentIdAndRdn(); 144 145 // Read the number of rdns, if any 146 byte nbRdns = in.readByte(); 147 148 if ( nbRdns == 0 ) 149 { 150 parentIdAndRdn.setRdns( new Rdn[0] ); 151 } 152 else 153 { 154 Rdn[] rdns = new Rdn[nbRdns]; 155 156 for ( int i = 0; i < nbRdns; i++ ) 157 { 158 Rdn rdn = new Rdn( schemaManager ); 159 rdn.readExternal( in ); 160 rdns[i] = rdn; 161 } 162 163 parentIdAndRdn.setRdns( rdns ); 164 } 165 166 // Read the parent ID 167 String uuid = in.readUTF(); 168 169 parentIdAndRdn.setParentId( uuid ); 170 171 // Read the nulber of children and descendants 172 int nbChildren = in.readInt(); 173 int nbDescendants = in.readInt(); 174 175 parentIdAndRdn.setNbChildren( nbChildren ); 176 parentIdAndRdn.setNbDescendants( nbDescendants ); 177 178 return parentIdAndRdn; 179 } 180 catch ( ClassNotFoundException cnfe ) 181 { 182 LOG.error( I18n.err( I18n.ERR_134, cnfe.getLocalizedMessage() ) ); 183 throw new IOException( cnfe.getLocalizedMessage() ); 184 } 185 } 186}