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.api.changelog;
021
022
023import java.io.IOException;
024import java.io.ObjectInput;
025import java.io.ObjectOutput;
026import java.util.ArrayList;
027import java.util.List;
028
029import org.apache.directory.api.ldap.model.ldif.LdifEntry;
030import org.apache.directory.api.ldap.model.schema.SchemaManager;
031import org.apache.directory.server.core.api.LdapPrincipal;
032import org.apache.directory.server.core.api.LdapPrincipalSerializer;
033import org.slf4j.Logger;
034import org.slf4j.LoggerFactory;
035
036
037/**
038 * A helper class which serialize and deserialize a ChangeLogEvent.
039 *
040 * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
041 */
042public final class ChangeLogEventSerializer
043{
044    /** The LoggerFactory used by this class */
045    protected static final Logger LOG = LoggerFactory.getLogger( ChangeLogEventSerializer.class );
046
047
048    /**
049     * Private constructor.
050     */
051    private ChangeLogEventSerializer()
052    {
053    }
054
055
056    /**
057     * Serializes a ChangeLogEvent instance.
058     * 
059     * @param event The ChangeLogEvent instance to serialize
060     * @param out The stream into which we will write the serialized instance
061     * @throws IOException If the stream can't be written
062     */
063    public static void serialize( ChangeLogEvent event, ObjectOutput out ) throws IOException
064    {
065        // The date the change has been created, "yyyyMMddHHmmss'Z'" 
066        out.writeUTF( event.getZuluTime() );
067
068        // The committer's Principal
069        LdapPrincipalSerializer.serialize( event.getCommitterPrincipal(), out );
070
071        // The revision
072        out.writeLong( event.getRevision() );
073
074        // The forward LDIF
075        event.getForwardLdif().writeExternal( out );
076
077        // The reverse LDIFs number
078        int nbReverses = event.getReverseLdifs().size();
079        out.writeInt( nbReverses );
080
081        for ( LdifEntry reverseLdif : event.getReverseLdifs() )
082        {
083            reverseLdif.writeExternal( out );
084        }
085
086        out.flush();
087    }
088
089
090    /**
091     * Deserializes a ChangeLogEvent instance.
092     * 
093     * @param schemaManager The SchemaManager (can be null)
094     * @param in The input stream from which the ChengaLogEvent is read
095     * @return a deserialized ChangeLogEvent
096     * @throws IOException If we had an issue processing the stream
097     */
098    public static ChangeLogEvent deserialize( SchemaManager schemaManager, ObjectInput in )
099        throws IOException
100    {
101        // The date the change has been created, "yyyyMMddHHmmss'Z'" 
102        String zuluTime = in.readUTF();
103
104        // The committer's Principal
105        LdapPrincipal committerPrincipal = LdapPrincipalSerializer.deserialize( schemaManager, in );
106
107        // The revision
108        long revision = in.readLong();
109
110        // The forward LDIF
111        LdifEntry forwardEntry = new LdifEntry();
112
113        try
114        {
115            forwardEntry.readExternal( in );
116        }
117        catch ( ClassNotFoundException cnfe )
118        {
119            IOException ioe = new IOException( cnfe.getMessage() );
120            ioe.initCause( cnfe );
121            throw ioe;
122        }
123
124        // The reverse LDIFs number
125        int nbReverses = in.readInt();
126
127        List<LdifEntry> reverses = new ArrayList<>( nbReverses );
128
129        for ( int i = 0; i < nbReverses; i++ )
130        {
131            LdifEntry reverseEntry = new LdifEntry();
132
133            try
134            {
135                reverseEntry.readExternal( in );
136            }
137            catch ( ClassNotFoundException cnfe )
138            {
139                IOException ioe = new IOException( cnfe.getMessage() );
140                ioe.initCause( cnfe );
141                throw ioe;
142            }
143
144            reverses.add( reverseEntry );
145        }
146
147        return new ChangeLogEvent( revision, zuluTime, committerPrincipal, forwardEntry, reverses );
148    }
149}