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.shared.ldap.entry; 021 022 import java.io.IOException; 023 import java.io.ObjectInput; 024 import java.io.ObjectOutput; 025 026 import org.apache.directory.shared.i18n.I18n; 027 import org.apache.directory.shared.ldap.entry.client.ClientModification; 028 import org.apache.directory.shared.ldap.exception.LdapException; 029 import org.apache.directory.shared.ldap.schema.AttributeType; 030 import org.apache.directory.shared.ldap.schema.SchemaManager; 031 import org.slf4j.Logger; 032 import org.slf4j.LoggerFactory; 033 034 /** 035 * An internal implementation for a ModificationItem. The name has been 036 * chosen so that it does not conflict with @see ModificationItem 037 * 038 * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a> 039 * @version $Rev$, $Date$ 040 */ 041 public class ServerModification implements Modification 042 { 043 public static final long serialVersionUID = 1L; 044 045 /** logger for reporting errors that might not be handled properly upstream */ 046 private static final Logger LOG = LoggerFactory.getLogger( ServerModification.class ); 047 048 /** The modification operation */ 049 private ModificationOperation operation; 050 051 /** The attribute which contains the modification */ 052 private EntryAttribute attribute; 053 054 055 //------------------------------------------------------------------------- 056 // Constructors 057 //------------------------------------------------------------------------- 058 /** 059 * Create a new instance of a ServerModification. 060 */ 061 public ServerModification() 062 { 063 } 064 065 066 /** 067 * Create a new instance of a ServerModification. 068 * 069 * @param operation the Modification operation (one of add, replace or remove) 070 * @param attribute the modified attribute 071 */ 072 public ServerModification( ModificationOperation operation, EntryAttribute attribute ) 073 { 074 this.operation = operation; 075 this.attribute = attribute; 076 } 077 078 079 public ServerModification( SchemaManager schemaManager, Modification modification ) 080 { 081 operation = modification.getOperation(); 082 083 EntryAttribute modAttribute = modification.getAttribute(); 084 085 try 086 { 087 AttributeType at = null; 088 089 if ( modAttribute instanceof DefaultServerAttribute ) 090 { 091 at = ((EntryAttribute)modAttribute).getAttributeType(); 092 } 093 else 094 { 095 at = schemaManager.lookupAttributeTypeRegistry( modAttribute.getId() ); 096 } 097 098 attribute = new DefaultServerAttribute( at, modAttribute ); 099 } 100 catch ( LdapException ne ) 101 { 102 // The attributeType is incorrect. Log, but do nothing otherwise. 103 LOG.error( I18n.err( I18n.ERR_04472, modAttribute.getId() ) ); 104 } 105 } 106 107 108 //------------------------------------------------------------------------- 109 // API 110 //------------------------------------------------------------------------- 111 /** 112 * @return the operation 113 */ 114 public ModificationOperation getOperation() 115 { 116 return operation; 117 } 118 119 120 /** 121 * Store the modification operation 122 * 123 * @param operation The DirContext value to assign 124 */ 125 public void setOperation( int operation ) 126 { 127 this.operation = ModificationOperation.getOperation( operation ); 128 } 129 130 131 /** 132 * Store the modification operation 133 * 134 * @param operation The DirContext value to assign 135 */ 136 public void setOperation( ModificationOperation operation ) 137 { 138 this.operation = operation; 139 } 140 141 142 /** 143 * @return the attribute containing the modifications 144 */ 145 public EntryAttribute getAttribute() 146 { 147 return attribute; 148 } 149 150 151 /** 152 * Set the attribute's modification 153 * 154 * @param attribute The modified attribute 155 */ 156 public void setAttribute( EntryAttribute attribute ) 157 { 158 this.attribute = (EntryAttribute)attribute; 159 } 160 161 162 /** 163 * Convert the current ServerModification to a ClientModification instance 164 * 165 * @return a new ClientModification instance 166 */ 167 public Modification toClientModification() 168 { 169 ModificationOperation newOperation = operation; 170 EntryAttribute newAttribute = attribute.toClientAttribute(); 171 Modification newModification = new ClientModification( newOperation, newAttribute ); 172 173 return newModification; 174 } 175 176 //------------------------------------------------------------------------- 177 // Overloaded Object class methods 178 //------------------------------------------------------------------------- 179 /** 180 * Compute the modification @see Object#hashCode 181 * @return the instance's hash code 182 */ 183 public int hashCode() 184 { 185 int h = 37; 186 187 h += h*17 + operation.getValue(); 188 h += h*17 + attribute.hashCode(); 189 190 return h; 191 } 192 193 194 /** 195 * @see Object#equals(Object) 196 */ 197 public boolean equals( Object that ) 198 { 199 // Shortcut 200 if ( this == that ) 201 { 202 return true; 203 } 204 205 if ( ! ( that instanceof ServerModification ) ) 206 { 207 return false; 208 } 209 210 ServerModification modification = (ServerModification)that; 211 212 if ( operation != modification.getOperation() ) 213 { 214 return false; 215 } 216 217 if ( attribute == null ) 218 { 219 return modification.getAttribute() == null; 220 } 221 222 return attribute.equals( modification.getAttribute() ); 223 } 224 225 226 /** 227 * Create a clone instance 228 */ 229 public ServerModification clone() 230 { 231 try 232 { 233 ServerModification clone = (ServerModification)super.clone(); 234 235 clone.attribute = (EntryAttribute)this.attribute.clone(); 236 return clone; 237 } 238 catch ( CloneNotSupportedException cnse ) 239 { 240 return null; 241 } 242 } 243 244 245 /** 246 * @see java.io.Externalizable#writeExternal(ObjectOutput) 247 * 248 * We can't use this method for a ServerModification. 249 */ 250 public void writeExternal( ObjectOutput out ) throws IOException 251 { 252 throw new IllegalStateException( I18n.err( I18n.ERR_04469 ) ); 253 } 254 255 256 /** 257 * @see java.io.Externalizable#readExternal(ObjectInput) 258 * 259 * We can't use this method for a ServerModification. 260 */ 261 public void readExternal( ObjectInput in ) throws IOException 262 { 263 throw new IllegalStateException( I18n.err( I18n.ERR_04469 ) ); 264 } 265 266 267 /** 268 * Deserialize a ServerModification 269 * 270 * @param in The buffer containing the serialized value 271 * @param atRegistry The AttributeType registry 272 * @throws IOException If we weren't able to deserialize the data 273 * @throws ClassNotFoundException if we weren't able to construct a Modification instance 274 * @throws LdapException If we didn't found the AttributeType in the registries 275 */ 276 public void deserialize( ObjectInput in, SchemaManager schemaManager ) throws IOException, ClassNotFoundException, LdapException 277 { 278 // Read the operation 279 int op = in.readInt(); 280 281 operation = ModificationOperation.getOperation( op ); 282 283 // Read the attribute OID 284 String oid = in.readUTF(); 285 286 // Lookup for tha associated AttributeType 287 AttributeType attributeType = schemaManager.lookupAttributeTypeRegistry( oid ); 288 289 attribute = new DefaultServerAttribute( attributeType ); 290 291 // Read the attribute 292 ((DefaultServerAttribute)attribute).deserialize( in ); 293 } 294 295 296 /** 297 * Serialize a ServerModification. 298 */ 299 public void serialize( ObjectOutput out ) throws IOException 300 { 301 if ( attribute == null ) 302 { 303 throw new IOException( I18n.err( I18n.ERR_04471 ) ); 304 } 305 306 // Write the operation 307 out.writeInt( operation.getValue() ); 308 309 AttributeType at = ((DefaultServerAttribute)attribute).getAttributeType(); 310 311 // Write the attribute's oid 312 out.writeUTF( at.getOid() ); 313 314 // Write the attribute 315 ((DefaultServerAttribute)attribute).serialize( out ); 316 } 317 318 319 /** 320 * @see Object#toString() 321 */ 322 public String toString() 323 { 324 StringBuilder sb = new StringBuilder(); 325 326 sb.append( "Modification: " ). 327 append( operation ). 328 append( "\n" ). 329 append( ", attribute : " ). 330 append( attribute ); 331 332 return sb.toString(); 333 } 334 }