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.ldap.replication;
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.entry.DefaultEntry;
033import org.apache.directory.api.ldap.model.entry.Entry;
034import org.apache.directory.api.ldap.model.message.controls.ChangeType;
035import org.apache.directory.api.ldap.model.name.Dn;
036import org.apache.directory.api.ldap.model.schema.SchemaManager;
037
038
039/**
040 * A ReplicaEventMessage serializer/deserializer.
041 * 
042 * A modification is serialized following this format : <br>
043 * <ul>
044 * <li>byte : EventType</li>
045 * <li>byte[] : the serialized DN</li>
046 * <li>byte[] : the serialized entry</li>
047 * </ul>
048 * 
049 * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
050 */
051public class ReplicaEventMessageSerializer implements Serializer
052{
053    /** The serialVersionUID */
054    private static final long serialVersionUID = 1L;
055
056    /** The schemaManager */
057    private transient SchemaManager schemaManager;
058
059
060    /**
061     * Creates a new instance of ReplicaEventMessageSerializer.
062     *
063     * @param schemaManager The reference to the global schemaManager
064     */
065    public ReplicaEventMessageSerializer( SchemaManager schemaManager )
066    {
067        this.schemaManager = schemaManager;
068    }
069
070
071    /**
072     * {@inheritDoc}
073     */
074    public byte[] serialize( Object object ) throws IOException
075    {
076        ReplicaEventMessage replicaEventMessage = ( ReplicaEventMessage ) object;
077
078        Entry entry = replicaEventMessage.getEntry();
079        ChangeType changeType = replicaEventMessage.getChangeType();
080
081        try ( ByteArrayOutputStream baos = new ByteArrayOutputStream();
082            ObjectOutput out = new ObjectOutputStream( baos ) )
083        {
084
085            // The change type first
086            out.writeByte( changeType.getValue() );
087
088            // The entry DN
089            entry.getDn().writeExternal( out );
090
091            // The entry
092            entry.writeExternal( out );
093
094            out.flush();
095
096            return baos.toByteArray();
097        }
098    }
099
100
101    /**
102     *  Deserialize a ReplicaEventMessage.
103     *  
104     *  @param bytes the byte array containing the serialized ReplicaEventMessage
105     *  @return An instance of a ReplicaEventMessage object 
106     *  @throws IOException if we can't deserialize the ReplicaEventMessage
107     */
108    public Object deserialize( byte[] bytes ) throws IOException
109    {
110        ObjectInputStream in = new ObjectInputStream( new ByteArrayInputStream( bytes ) );
111
112        ReplicaEventMessage replicaEventMessage = null;
113
114        try
115        {
116            // The changeType
117            byte type = in.readByte();
118            ChangeType changeType = ChangeType.getChangeType( type );
119
120            // The Entry's DN
121            Dn entryDn = new Dn( schemaManager );
122            entryDn.readExternal( in );
123
124            // The Entry
125            Entry entry = new DefaultEntry( schemaManager );
126            entry.readExternal( in );
127            entry.setDn( entryDn );
128
129            // And create a ReplicaEventMessage
130            replicaEventMessage = new ReplicaEventMessage( changeType, entry );
131        }
132        catch ( ClassNotFoundException cnfe )
133        {
134            // there is nothing we can do here...
135        }
136
137        return replicaEventMessage;
138    }
139}