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