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.changelog;
021
022
023 import java.io.Externalizable;
024 import java.io.IOException;
025 import java.io.ObjectInput;
026 import java.io.ObjectOutput;
027 import java.util.ArrayList;
028 import java.util.List;
029
030 import org.apache.directory.server.core.LdapPrincipal;
031 import org.apache.directory.shared.ldap.entry.EntryAttribute;
032 import org.apache.directory.shared.ldap.ldif.LdifEntry;
033
034
035 /**
036 * A loggable directory change event.
037 *
038 * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
039 * @version $Rev$, $Date$
040 */
041 public class ChangeLogEvent implements Externalizable
042 {
043 private static final long serialVersionUID = 1L;
044 private String zuluTime;
045 private long revision;
046 private LdifEntry forwardLdif;
047
048 /** The revert changes. Can contain more than one single change */
049 private List<LdifEntry> reverseLdifs;
050 private LdapPrincipal committer;
051
052
053 /**
054 * Creates a new instance of ChangeLogEvent, used during the deserialization
055 * process
056 */
057 public ChangeLogEvent()
058 {
059 }
060
061
062 /**
063 * Creates a new instance of ChangeLogEvent.
064 *
065 * @param revision the revision number for the change
066 * @param zuluTime the timestamp for when the change occurred in generalizedTime format
067 */
068 public ChangeLogEvent( long revision, String zuluTime, LdapPrincipal committer, LdifEntry forwardLdif,
069 LdifEntry reverseLdif )
070 {
071 this.zuluTime = zuluTime;
072 this.revision = revision;
073 this.forwardLdif = forwardLdif;
074 this.reverseLdifs = new ArrayList<LdifEntry>(1);
075 reverseLdifs.add( reverseLdif );
076 this.committer = committer;
077 }
078
079
080 /**
081 * Creates a new instance of ChangeLogEvent.
082 *
083 * @param revision the revision number for the change
084 * @param zuluTime the timestamp for when the change occurred in generalizedTime format
085 * @param committer the user who did the modification
086 * @param forwardLdif the original operation
087 * @param reverseLdifs the reverted operations
088 */
089 public ChangeLogEvent( long revision, String zuluTime, LdapPrincipal committer, LdifEntry forwardLdif,
090 List<LdifEntry> reverseLdifs )
091 {
092 this.zuluTime = zuluTime;
093 this.revision = revision;
094 this.forwardLdif = forwardLdif;
095 this.reverseLdifs = reverseLdifs;
096 this.committer = committer;
097 }
098
099
100 /**
101 * @return the forwardLdif
102 */
103 public LdifEntry getForwardLdif()
104 {
105 return forwardLdif;
106 }
107
108
109 /**
110 * @return the reverseLdif
111 */
112 public List<LdifEntry> getReverseLdifs()
113 {
114 return reverseLdifs;
115 }
116
117
118 /**
119 * @return the committer
120 */
121 public LdapPrincipal getCommitterPrincipal()
122 {
123 return committer;
124 }
125
126
127 /**
128 * Gets the revision of this event.
129 *
130 * @return the revision
131 */
132 public long getRevision()
133 {
134 return revision;
135 }
136
137
138 /**
139 * Gets the generalizedTime when this event occured.
140 *
141 * @return the zuluTime when this event occured
142 */
143 public String getZuluTime()
144 {
145 return zuluTime;
146 }
147
148
149 public EntryAttribute get( String attributeName )
150 {
151 return forwardLdif.get( attributeName );
152 }
153
154
155 /**
156 * @see Externalizable#readExternal(ObjectInput)
157 *
158 * @param in The stream from which the ChangeOlgEvent is read
159 * @throws IOException If the stream can't be read
160 * @throws ClassNotFoundException If the ChangeLogEvent can't be created
161 */
162 public void readExternal( ObjectInput in ) throws IOException , ClassNotFoundException
163 {
164 // Read the committer
165 committer = (LdapPrincipal)in.readObject();
166
167 // Read the revision
168 revision = in.readLong();
169
170 // Read the time
171 boolean hasZuluTime = in.readBoolean();
172
173 if ( hasZuluTime )
174 {
175 zuluTime = in.readUTF();
176 }
177
178 // Read the forward LDIF
179 boolean hasForwardLdif = in.readBoolean();
180
181 if ( hasForwardLdif )
182 {
183 forwardLdif = (LdifEntry)in.readObject();
184 }
185
186 // Read the reverse LDIF number
187 int nbReverseLdif = in.readInt();
188
189 if ( nbReverseLdif > 0 )
190 {
191 // Read each reverse ldif
192 reverseLdifs = new ArrayList<LdifEntry>(nbReverseLdif);
193
194 for ( int i = 0; i < nbReverseLdif; i++ )
195 {
196 reverseLdifs.add( (LdifEntry)in.readObject() );
197 }
198 }
199 }
200
201
202 /**
203 * @see Externalizable#readExternal(ObjectInput)<p>
204 *
205 *@param out The stream in which the ChangeLogEvent will be serialized.
206 *
207 *@throws IOException If the serialization fail
208 */
209 public void writeExternal( ObjectOutput out ) throws IOException
210 {
211 // Write the committer
212 out.writeObject( committer );
213
214 // write the revision
215 out.writeLong( revision );
216
217 // write the time
218
219 if ( zuluTime != null )
220 {
221 out.writeBoolean( true );
222 out.writeUTF( zuluTime );
223 }
224 else
225 {
226 out.writeBoolean( false );
227 }
228
229 // write the forward LDIF
230 if ( forwardLdif != null )
231 {
232 out.writeBoolean( true );
233 out.writeObject( forwardLdif );
234 }
235 else
236 {
237 out.writeBoolean( false );
238 }
239
240 // write the reverse LDIF
241 if ( reverseLdifs != null )
242 {
243 out.writeInt( reverseLdifs.size() );
244
245 // write each reverse
246 for ( LdifEntry reverseLdif:reverseLdifs )
247 {
248 out.writeObject( reverseLdif );
249 }
250 }
251 else
252 {
253 out.writeBoolean( false );
254 }
255
256 // and flush the result
257 out.flush();
258 }
259
260
261 @Override
262 public String toString()
263 {
264 StringBuilder sb = new StringBuilder();
265 sb.append( "ChangeLogEvent { " );
266
267 sb.append( "principal=" )
268 .append( getCommitterPrincipal() )
269 .append( ", " );
270
271 sb.append( "zuluTime=" )
272 .append( getZuluTime() )
273 .append( ", " );
274
275 sb.append( "revision=" )
276 .append( getRevision() )
277 .append( ", " );
278
279 sb.append( "\nforwardLdif=" )
280 .append( getForwardLdif() )
281 .append( ", " );
282
283 if ( reverseLdifs != null )
284 {
285 sb.append( "\nreverseLdif number=" ).append( reverseLdifs.size() );
286 int i = 0;
287
288 for ( LdifEntry reverseLdif:reverseLdifs )
289 {
290 sb.append( "\nReverse[" ).append( i++ ).append( "] :\n" );
291 sb.append( reverseLdif );
292 }
293 }
294
295 sb.append( " }" );
296
297 return sb.toString();
298 }
299 }