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 }