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.shared.ldap.model.entry; 021 022import java.io.IOException; 023import java.io.ObjectInput; 024import java.io.ObjectOutput; 025 026import org.apache.directory.shared.i18n.I18n; 027import org.apache.directory.shared.ldap.model.exception.LdapException; 028import org.apache.directory.shared.ldap.model.exception.LdapInvalidAttributeValueException; 029import org.apache.directory.shared.ldap.model.schema.AttributeType; 030import org.apache.directory.shared.ldap.model.schema.SchemaManager; 031import org.slf4j.Logger; 032import 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 */ 040public class DefaultModification implements Modification 041{ 042 /** The modification operation */ 043 private ModificationOperation operation; 044 045 /** The attribute which contains the modification */ 046 private Attribute attribute; 047 048 /** The AtributeType */ 049 private AttributeType attributeType; 050 051 /** logger for reporting errors that might not be handled properly upstream */ 052 protected static final Logger LOG = LoggerFactory.getLogger( Modification.class ); 053 054 055 /** 056 * Creates a new instance of DefaultModification. 057 */ 058 public DefaultModification() 059 { 060 } 061 062 063 /** 064 * Creates a new instance of DefaultModification. 065 * 066 * @param operation The modification operation 067 * @param attribute The associated attribute 068 */ 069 public DefaultModification( ModificationOperation operation, Attribute attribute ) 070 { 071 this.operation = operation; 072 this.attribute = attribute; 073 } 074 075 076 /** 077 * Creates a new instance of DefaultModification. 078 * 079 * @param operation The modification operation 080 * @param attributeId The associated attribute ID 081 * @param values the associated values 082 */ 083 public DefaultModification( ModificationOperation operation, String attributeId, String... values ) 084 { 085 this.operation = operation; 086 this.attribute = new DefaultAttribute( attributeId, values ); 087 } 088 089 090 /** 091 * Creates a new instance of DefaultModification. 092 * 093 * @param operation The modification operation 094 * @param attributeId The associated attribute ID 095 * @param values the associated values 096 */ 097 public DefaultModification( ModificationOperation operation, String attributeId, byte[]... values ) 098 { 099 this.operation = operation; 100 this.attribute = new DefaultAttribute( attributeId, values ); 101 } 102 103 104 /** 105 * Creates a new instance of DefaultModification. 106 * 107 * @param operation The modification operation 108 * @param attributeId The associated attribute ID 109 * @param values the associated values 110 */ 111 public DefaultModification( ModificationOperation operation, String attributeId, Value<?>... values ) 112 { 113 this.operation = operation; 114 this.attribute = new DefaultAttribute( attributeId, values ); 115 } 116 117 118 /** 119 * Creates a new instance of DefaultModification with no value 120 * 121 * @param operation The modification operation 122 * @param attributeId The associated attribute ID 123 */ 124 public DefaultModification( ModificationOperation operation, String attributeId ) 125 { 126 this.operation = operation; 127 this.attribute = new DefaultAttribute( attributeId ); 128 } 129 130 131 /** 132 * Creates a new instance of DefaultModification. 133 * 134 * @param operation The modification operation 135 * @param attributeType The associated attributeType 136 * @param values the associated values 137 */ 138 public DefaultModification( ModificationOperation operation, AttributeType attributeType, String... values ) 139 throws LdapInvalidAttributeValueException 140 { 141 this.operation = operation; 142 this.attribute = new DefaultAttribute( attributeType, values ); 143 } 144 145 146 /** 147 * Creates a new instance of DefaultModification. 148 * 149 * @param operation The modification operation 150 * @param attributeType The associated attributeType 151 * @param values the associated values 152 */ 153 public DefaultModification( ModificationOperation operation, AttributeType attributeType, byte[]... values ) 154 throws LdapInvalidAttributeValueException 155 { 156 this.operation = operation; 157 this.attribute = new DefaultAttribute( attributeType, values ); 158 } 159 160 161 /** 162 * Creates a new instance of DefaultModification. 163 * 164 * @param operation The modification operation 165 * @param attributeType The associated attributeType 166 * @param values the associated values 167 */ 168 public DefaultModification( ModificationOperation operation, AttributeType attributeType, Value<?>... values ) 169 throws LdapInvalidAttributeValueException 170 { 171 this.operation = operation; 172 this.attribute = new DefaultAttribute( attributeType, values ); 173 } 174 175 176 /** 177 * Creates a new instance of DefaultModification with no value. 178 * 179 * @param operation The modification operation 180 * @param attributeType The associated attributeType 181 */ 182 public DefaultModification( ModificationOperation operation, AttributeType attributeType ) 183 throws LdapInvalidAttributeValueException 184 { 185 this.operation = operation; 186 this.attribute = new DefaultAttribute( attributeType ); 187 } 188 189 190 /** 191 * Creates a new instance of DefaultModification. 192 * 193 * @param schemaManager The schema manager 194 * @param modification The modification 195 */ 196 public DefaultModification( SchemaManager schemaManager, Modification modification ) 197 { 198 operation = modification.getOperation(); 199 200 Attribute modAttribute = modification.getAttribute(); 201 202 try 203 { 204 AttributeType at = modAttribute.getAttributeType(); 205 206 if ( at == null ) 207 { 208 at = schemaManager.lookupAttributeTypeRegistry( modAttribute.getId() ); 209 } 210 211 attribute = new DefaultAttribute( at, modAttribute ); 212 } 213 catch ( LdapException ne ) 214 { 215 // The attributeType is incorrect. Log, but do nothing otherwise. 216 LOG.error( I18n.err( I18n.ERR_04472, modAttribute.getId() ) ); 217 } 218 } 219 220 221 /** 222 * {@inheritDoc} 223 */ 224 public ModificationOperation getOperation() 225 { 226 return operation; 227 } 228 229 230 /** 231 * {@inheritDoc} 232 */ 233 public void setOperation( int operation ) 234 { 235 this.operation = ModificationOperation.getOperation( operation ); 236 } 237 238 239 /** 240 * {@inheritDoc} 241 */ 242 public void setOperation( ModificationOperation operation ) 243 { 244 this.operation = operation; 245 } 246 247 248 /** 249 * {@inheritDoc} 250 */ 251 public Attribute getAttribute() 252 { 253 return attribute; 254 } 255 256 257 /** 258 * {@inheritDoc} 259 */ 260 public void setAttribute( Attribute attribute ) 261 { 262 this.attribute = attribute; 263 } 264 265 266 /** 267 * {@inheritDoc} 268 */ 269 public void apply( AttributeType attributeType ) throws LdapInvalidAttributeValueException 270 { 271 this.attributeType = attributeType; 272 273 if ( attribute != null ) 274 { 275 attribute.apply( attributeType ); 276 } 277 } 278 279 280 /** 281 * {@inheritDoc} 282 */ 283 public AttributeType getAttributeType() 284 { 285 return attributeType; 286 } 287 288 289 /** 290 * @see Object#equals(Object) 291 * @return <code>true</code> if both values are equal 292 */ 293 public boolean equals( Object that ) 294 { 295 // Basic equals checks 296 if ( this == that ) 297 { 298 return true; 299 } 300 301 if ( ! (that instanceof Modification ) ) 302 { 303 return false; 304 } 305 306 Modification otherModification = (Modification)that; 307 308 // Check the operation 309 if ( operation != otherModification.getOperation() ) 310 { 311 return false; 312 } 313 314 // Check the attribute 315 if ( attribute == null ) 316 { 317 return otherModification.getAttribute() == null; 318 } 319 320 return attribute.equals( otherModification.getAttribute() ); 321 } 322 323 324 /** 325 * Compute the modification @see Object#hashCode 326 * @return the instance's hash code 327 */ 328 public int hashCode() 329 { 330 int h = 37; 331 332 h += h*17 + operation.getValue(); 333 h += h*17 + attribute.hashCode(); 334 335 return h; 336 } 337 338 339 /** 340 * @see java.io.Externalizable#readExternal(ObjectInput) 341 */ 342 public void readExternal( ObjectInput in ) throws IOException, ClassNotFoundException 343 { 344 // The operation 345 operation = ModificationOperation.getOperation( in.readInt() ); 346 347 // The EntryAttribute if we have some 348 boolean hasAttribute = in.readBoolean(); 349 350 if ( hasAttribute ) 351 { 352 attribute = new DefaultAttribute(); 353 attribute.readExternal( in ); 354 } 355 } 356 357 358 /** 359 * @see java.io.Externalizable#writeExternal(ObjectOutput) 360 */ 361 public void writeExternal( ObjectOutput out ) throws IOException 362 { 363 // The operation 364 out.writeInt( operation.getValue() ); 365 366 // The EntryAttribute if not null 367 if ( attribute != null ) 368 { 369 out.writeBoolean( true ); 370 attribute.writeExternal( out ); 371 } 372 else 373 { 374 out.writeBoolean( false ); 375 } 376 377 out.flush(); 378 } 379 380 381 /** 382 * {@inheritDoc} 383 */ 384 public DefaultModification clone() 385 { 386 try 387 { 388 DefaultModification clone = (DefaultModification)super.clone(); 389 390 clone.attribute = this.attribute.clone(); 391 return clone; 392 } 393 catch ( CloneNotSupportedException cnse ) 394 { 395 return null; 396 } 397 } 398 399 400 /** 401 * @see Object#toString() 402 */ 403 public String toString() 404 { 405 StringBuilder sb = new StringBuilder(); 406 407 sb.append( "Modification: " ). 408 append( operation ). 409 append( "\n" ). 410 append( ", attribute : " ). 411 append( attribute ); 412 413 return sb.toString(); 414 } 415}