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.message; 021 022 023import java.util.ArrayList; 024import java.util.Collection; 025import java.util.Collections; 026import java.util.Iterator; 027import java.util.List; 028 029import org.apache.directory.api.ldap.model.entry.Attribute; 030import org.apache.directory.api.ldap.model.entry.DefaultAttribute; 031import org.apache.directory.api.ldap.model.entry.DefaultModification; 032import org.apache.directory.api.ldap.model.entry.Modification; 033import org.apache.directory.api.ldap.model.entry.ModificationOperation; 034import org.apache.directory.api.ldap.model.name.Dn; 035import org.apache.directory.api.util.StringConstants; 036 037 038/** 039 * Lockable ModifyRequest implementation. 040 * 041 * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a> 042 */ 043public class ModifyRequestImpl extends AbstractAbandonableRequest implements ModifyRequest 044{ 045 static final long serialVersionUID = -505803669028990304L; 046 047 /** Dn of the entry to modify or PDU's <b>object</b> field */ 048 private Dn name; 049 050 /** Sequence of modifications or PDU's <b>modification</b> sequence field */ 051 private List<Modification> mods = new ArrayList<>(); 052 053 /** The associated response */ 054 private ModifyResponse response; 055 056 057 // ----------------------------------------------------------------------- 058 // Constructors 059 // ----------------------------------------------------------------------- 060 /** 061 * Creates a ModifyRequest implementing object used to modify the 062 * attributes of an entry. 063 */ 064 public ModifyRequestImpl() 065 { 066 super( -1, MessageTypeEnum.MODIFY_REQUEST ); 067 } 068 069 070 // ------------------------------------------------------------------------ 071 // ModifyRequest Interface Method Implementations 072 // ------------------------------------------------------------------------ 073 /** 074 * {@inheritDoc} 075 */ 076 @Override 077 public Collection<Modification> getModifications() 078 { 079 return Collections.unmodifiableCollection( mods ); 080 } 081 082 083 /** 084 * {@inheritDoc} 085 */ 086 @Override 087 public Dn getName() 088 { 089 return name; 090 } 091 092 093 /** 094 * {@inheritDoc} 095 */ 096 @Override 097 public ModifyRequest setName( Dn name ) 098 { 099 this.name = name; 100 101 return this; 102 } 103 104 105 /** 106 * {@inheritDoc} 107 */ 108 @Override 109 public ModifyRequest addModification( Modification mod ) 110 { 111 mods.add( mod ); 112 113 return this; 114 } 115 116 117 private void addModification( ModificationOperation modOp, String attributeName, byte[]... attributeValue ) 118 { 119 Attribute attr = new DefaultAttribute( attributeName, attributeValue ); 120 addModification( attr, modOp ); 121 } 122 123 124 private void addModification( ModificationOperation modOp, String attributeName, String... attributeValue ) 125 { 126 Attribute attr = new DefaultAttribute( attributeName, attributeValue ); 127 addModification( attr, modOp ); 128 } 129 130 131 /** 132 * {@inheritDoc} 133 */ 134 @Override 135 public ModifyRequest addModification( Attribute attr, ModificationOperation modOp ) 136 { 137 mods.add( new DefaultModification( modOp, attr ) ); 138 139 return this; 140 } 141 142 143 /** 144 *{@inheritDoc} 145 */ 146 @Override 147 public ModifyRequest add( String attributeName, String... attributeValue ) 148 { 149 addModification( ModificationOperation.ADD_ATTRIBUTE, attributeName, attributeValue ); 150 151 return this; 152 } 153 154 155 /** 156 * @see #add(String, String...) 157 */ 158 public ModifyRequest add( String attributeName, byte[]... attributeValue ) 159 { 160 addModification( ModificationOperation.ADD_ATTRIBUTE, attributeName, attributeValue ); 161 162 return this; 163 } 164 165 166 /** 167 *{@inheritDoc} 168 */ 169 @Override 170 public ModifyRequest add( Attribute attr ) 171 { 172 addModification( attr, ModificationOperation.ADD_ATTRIBUTE ); 173 174 return this; 175 } 176 177 178 /** 179 * @see #replace(String, String...) 180 */ 181 @Override 182 public ModifyRequest replace( String attributeName ) 183 { 184 addModification( ModificationOperation.REPLACE_ATTRIBUTE, attributeName, StringConstants.EMPTY_STRINGS ); 185 186 return this; 187 } 188 189 190 /** 191 *{@inheritDoc} 192 */ 193 @Override 194 public ModifyRequest replace( String attributeName, String... attributeValue ) 195 { 196 addModification( ModificationOperation.REPLACE_ATTRIBUTE, attributeName, attributeValue ); 197 198 return this; 199 } 200 201 202 /** 203 * @see #replace(String, String...) 204 */ 205 public ModifyRequest replace( String attributeName, byte[]... attributeValue ) 206 { 207 addModification( ModificationOperation.REPLACE_ATTRIBUTE, attributeName, attributeValue ); 208 209 return this; 210 } 211 212 213 /** 214 *{@inheritDoc} 215 */ 216 @Override 217 public ModifyRequest replace( Attribute attr ) 218 { 219 addModification( attr, ModificationOperation.REPLACE_ATTRIBUTE ); 220 221 return this; 222 } 223 224 225 /** 226 * {@inheritDoc} 227 */ 228 @Override 229 public ModifyRequest removeModification( Modification mod ) 230 { 231 mods.remove( mod ); 232 233 return this; 234 } 235 236 237 /** 238 * {@inheritDoc} 239 */ 240 @Override 241 public ModifyRequest remove( String attributeName, String... attributeValue ) 242 { 243 addModification( ModificationOperation.REMOVE_ATTRIBUTE, attributeName, attributeValue ); 244 245 return this; 246 } 247 248 249 /** 250 * {@inheritDoc} 251 */ 252 public ModifyRequest remove( String attributeName, byte[]... attributeValue ) 253 { 254 addModification( ModificationOperation.REMOVE_ATTRIBUTE, attributeName, attributeValue ); 255 256 return this; 257 } 258 259 260 /** 261 * {@inheritDoc} 262 */ 263 @Override 264 public ModifyRequest remove( Attribute attr ) 265 { 266 addModification( attr, ModificationOperation.REMOVE_ATTRIBUTE ); 267 268 return this; 269 } 270 271 272 /** 273 * {@inheritDoc} 274 */ 275 @Override 276 public ModifyRequest remove( String attributerName ) 277 { 278 addModification( new DefaultModification( ModificationOperation.REMOVE_ATTRIBUTE, attributerName ) ); 279 280 return this; 281 } 282 283 284 /** 285 * {@inheritDoc} 286 */ 287 @Override 288 public ModifyRequest setMessageId( int messageId ) 289 { 290 super.setMessageId( messageId ); 291 292 return this; 293 } 294 295 296 /** 297 * {@inheritDoc} 298 */ 299 @Override 300 public ModifyRequest addControl( Control control ) 301 { 302 return ( ModifyRequest ) super.addControl( control ); 303 } 304 305 306 /** 307 * {@inheritDoc} 308 */ 309 @Override 310 public ModifyRequest addAllControls( Control[] controls ) 311 { 312 return ( ModifyRequest ) super.addAllControls( controls ); 313 } 314 315 316 /** 317 * {@inheritDoc} 318 */ 319 @Override 320 public ModifyRequest removeControl( Control control ) 321 { 322 return ( ModifyRequest ) super.removeControl( control ); 323 } 324 325 326 // ------------------------------------------------------------------------ 327 // SingleReplyRequest Interface Method Implementations 328 // ------------------------------------------------------------------------ 329 330 /** 331 * Gets the protocol response message type for this request which produces 332 * at least one response. 333 * 334 * @return the message type of the response. 335 */ 336 @Override 337 public MessageTypeEnum getResponseType() 338 { 339 return MessageTypeEnum.MODIFY_RESPONSE; 340 } 341 342 343 /** 344 * The result containing response for this request. 345 * 346 * @return the result containing response for this request 347 */ 348 @Override 349 public ModifyResponse getResultResponse() 350 { 351 if ( response == null ) 352 { 353 response = new ModifyResponseImpl( getMessageId() ); 354 } 355 356 return response; 357 } 358 359 360 /** 361 * {@inheritDoc} 362 */ 363 @Override 364 public int hashCode() 365 { 366 int hash = 37; 367 if ( name != null ) 368 { 369 hash = hash * 17 + name.hashCode(); 370 } 371 hash = hash * 17 + mods.size(); 372 for ( int i = 0; i < mods.size(); i++ ) 373 { 374 hash = hash * 17 + ( ( DefaultModification ) mods.get( i ) ).hashCode(); 375 } 376 hash = hash * 17 + super.hashCode(); 377 378 return hash; 379 } 380 381 382 /** 383 * Checks to see if ModifyRequest stub equals another by factoring in checks 384 * for the name and modification items of the request. 385 * 386 * @param obj 387 * the object to compare this ModifyRequest to 388 * @return true if obj equals this ModifyRequest, false otherwise 389 */ 390 @Override 391 public boolean equals( Object obj ) 392 { 393 if ( obj == this ) 394 { 395 return true; 396 } 397 398 if ( !super.equals( obj ) ) 399 { 400 return false; 401 } 402 403 ModifyRequest req = ( ModifyRequest ) obj; 404 405 if ( name != null && req.getName() == null ) 406 { 407 return false; 408 } 409 410 if ( name == null && req.getName() != null ) 411 { 412 return false; 413 } 414 415 if ( name != null && req.getName() != null && !name.equals( req.getName() ) ) 416 { 417 return false; 418 } 419 420 if ( req.getModifications().size() != mods.size() ) 421 { 422 return false; 423 } 424 425 Iterator<Modification> list = req.getModifications().iterator(); 426 427 for ( int i = 0; i < mods.size(); i++ ) 428 { 429 Modification item = list.next(); 430 431 if ( item == null ) 432 { 433 if ( mods.get( i ) != null ) 434 { 435 return false; 436 } 437 } 438 else 439 440 if ( !item.equals( mods.get( i ) ) ) 441 { 442 return false; 443 } 444 } 445 446 return true; 447 } 448 449 450 /** 451 * Get a String representation of a ModifyRequest 452 * 453 * @return A ModifyRequest String 454 */ 455 @Override 456 public String toString() 457 { 458 StringBuilder sb = new StringBuilder(); 459 460 sb.append( " Modify Request\n" ); 461 sb.append( " Object : '" ).append( name ).append( "'\n" ); 462 463 if ( mods != null ) 464 { 465 466 for ( int i = 0; i < mods.size(); i++ ) 467 { 468 469 DefaultModification modification = ( DefaultModification ) mods.get( i ); 470 471 sb.append( " Modification[" ).append( i ).append( "]\n" ); 472 sb.append( " Operation : " ); 473 474 switch ( modification.getOperation() ) 475 { 476 case ADD_ATTRIBUTE: 477 sb.append( " add\n" ); 478 break; 479 480 case REPLACE_ATTRIBUTE: 481 sb.append( " replace\n" ); 482 break; 483 484 case REMOVE_ATTRIBUTE: 485 sb.append( " delete\n" ); 486 break; 487 488 default: 489 throw new IllegalArgumentException( "Unexpected ModificationOperation " 490 + modification.getOperation() ); 491 } 492 493 sb.append( " Modification\n" ); 494 sb.append( modification.getAttribute() ); 495 } 496 } 497 498 // The controls 499 sb.append( super.toString() ); 500 501 return super.toString( sb.toString() ); 502 } 503}