1 20 21 package org.apache.directory.ldapstudio.browser.core.internal.model; 22 23 24 import java.io.IOException ; 25 import java.io.StringWriter ; 26 import java.io.Writer ; 27 import java.text.DateFormat ; 28 import java.text.SimpleDateFormat ; 29 import java.util.Date ; 30 import java.util.LinkedList ; 31 32 import org.apache.directory.ldapstudio.browser.core.BrowserCoreConstants; 33 import org.apache.directory.ldapstudio.browser.core.BrowserCoreMessages; 34 import org.apache.directory.ldapstudio.browser.core.BrowserCorePlugin; 35 import org.apache.directory.ldapstudio.browser.core.jobs.ExtendedProgressMonitor; 36 import org.apache.directory.ldapstudio.browser.core.model.DN; 37 import org.apache.directory.ldapstudio.browser.core.model.IAttribute; 38 import org.apache.directory.ldapstudio.browser.core.model.IConnection; 39 import org.apache.directory.ldapstudio.browser.core.model.IEntry; 40 import org.apache.directory.ldapstudio.browser.core.model.IReferralHandler; 41 import org.apache.directory.ldapstudio.browser.core.model.IValue; 42 import org.apache.directory.ldapstudio.browser.core.model.URL; 43 import org.apache.directory.ldapstudio.browser.core.model.ldif.LdifEnumeration; 44 import org.apache.directory.ldapstudio.browser.core.model.ldif.container.LdifChangeAddRecord; 45 import org.apache.directory.ldapstudio.browser.core.model.ldif.container.LdifChangeDeleteRecord; 46 import org.apache.directory.ldapstudio.browser.core.model.ldif.container.LdifChangeModDnRecord; 47 import org.apache.directory.ldapstudio.browser.core.model.ldif.container.LdifChangeModifyRecord; 48 import org.apache.directory.ldapstudio.browser.core.model.ldif.container.LdifContainer; 49 import org.apache.directory.ldapstudio.browser.core.model.ldif.container.LdifContentRecord; 50 import org.apache.directory.ldapstudio.browser.core.model.ldif.container.LdifModSpec; 51 import org.apache.directory.ldapstudio.browser.core.model.ldif.container.LdifRecord; 52 import org.apache.directory.ldapstudio.browser.core.model.ldif.lines.LdifAttrValLine; 53 import org.apache.directory.ldapstudio.browser.core.model.ldif.lines.LdifChangeTypeLine; 54 import org.apache.directory.ldapstudio.browser.core.model.ldif.lines.LdifCommentLine; 55 import org.apache.directory.ldapstudio.browser.core.model.ldif.lines.LdifDeloldrdnLine; 56 import org.apache.directory.ldapstudio.browser.core.model.ldif.lines.LdifDnLine; 57 import org.apache.directory.ldapstudio.browser.core.model.ldif.lines.LdifModSpecSepLine; 58 import org.apache.directory.ldapstudio.browser.core.model.ldif.lines.LdifNewrdnLine; 59 import org.apache.directory.ldapstudio.browser.core.model.ldif.lines.LdifNewsuperiorLine; 60 import org.apache.directory.ldapstudio.browser.core.model.ldif.lines.LdifSepLine; 61 import org.apache.directory.ldapstudio.browser.core.utils.ModelConverter; 62 63 64 class ConnectionModifyHandler 65 { 66 67 private Connection connection; 68 69 private ModificationLogger modificationLogger; 70 71 private int suspendDepth; 72 73 private LinkedList recordQueue; 74 75 76 ConnectionModifyHandler( Connection connection ) 77 { 78 this.connection = connection; 79 80 this.modificationLogger = new ModificationLogger( connection ); 81 } 82 83 84 void connectionClosed() 85 { 86 this.suspendDepth = 0; 87 this.recordQueue.clear(); 88 this.recordQueue = null; 89 } 90 91 92 void connectionOpened() 93 { 94 this.suspendDepth = 0; 95 this.recordQueue = new LinkedList (); 96 } 97 98 99 void create( IValue[] valuesToCreate, ExtendedProgressMonitor monitor ) 100 { 101 for ( int i = 0; !monitor.isCanceled() && i < valuesToCreate.length; i++ ) 102 { 103 104 LdifChangeModifyRecord cmr = new LdifChangeModifyRecord( LdifDnLine.create( valuesToCreate[i] 105 .getAttribute().getEntry().getDn().toString() ) ); 106 ModelConverter.addControls( cmr, valuesToCreate[i].getAttribute().getEntry() ); 107 cmr.setChangeType( LdifChangeTypeLine.createModify() ); 108 109 LdifModSpec modSpec = LdifModSpec.createAdd( valuesToCreate[i].getAttribute().getDescription() ); 110 if ( valuesToCreate[i].isString() ) 111 { 112 modSpec.addAttrVal( LdifAttrValLine.create( valuesToCreate[i].getAttribute().getDescription(), 113 valuesToCreate[i].getStringValue() ) ); 114 } 115 else 116 { 117 modSpec.addAttrVal( LdifAttrValLine.create( valuesToCreate[i].getAttribute().getDescription(), 118 valuesToCreate[i].getBinaryValue() ) ); 119 } 120 modSpec.finish( LdifModSpecSepLine.create() ); 121 cmr.addModSpec( modSpec ); 122 cmr.finish( LdifSepLine.create() ); 123 124 try 125 { 126 this.applyModificationAndLog( cmr, monitor ); 127 } 128 catch ( ConnectionException e ) 129 { 130 monitor.reportError( e ); 131 } 132 } 133 } 134 135 136 void modify( IValue oldValue, IValue newValue, ExtendedProgressMonitor monitor ) 137 { 138 try 139 { 140 LdifChangeModifyRecord cmr = new LdifChangeModifyRecord( LdifDnLine.create( oldValue.getAttribute() 141 .getEntry().getDn().toString() ) ); 142 ModelConverter.addControls( cmr, oldValue.getAttribute().getEntry() ); 143 cmr.setChangeType( LdifChangeTypeLine.createModify() ); 144 145 if ( oldValue.getAttribute().getValueSize() == 1 ) 146 { 147 LdifModSpec modSpec = LdifModSpec.createReplace( oldValue.getAttribute().getDescription() ); 148 if ( newValue.isString() ) 149 { 150 modSpec.addAttrVal( LdifAttrValLine.create( oldValue.getAttribute().getDescription(), newValue 151 .getStringValue() ) ); 152 } 153 else 154 { 155 modSpec.addAttrVal( LdifAttrValLine.create( oldValue.getAttribute().getDescription(), newValue 156 .getBinaryValue() ) ); 157 } 158 modSpec.finish( LdifModSpecSepLine.create() ); 159 cmr.addModSpec( modSpec ); 160 cmr.finish( LdifSepLine.create() ); 161 } 162 else 163 { 164 LdifModSpec modSpec1 = LdifModSpec.createAdd( oldValue.getAttribute().getDescription() ); 165 if ( newValue.isString() ) 166 { 167 modSpec1.addAttrVal( LdifAttrValLine.create( oldValue.getAttribute().getDescription(), newValue 168 .getStringValue() ) ); 169 } 170 else 171 { 172 modSpec1.addAttrVal( LdifAttrValLine.create( oldValue.getAttribute().getDescription(), newValue 173 .getBinaryValue() ) ); 174 } 175 modSpec1.finish( LdifModSpecSepLine.create() ); 176 cmr.addModSpec( modSpec1 ); 177 178 LdifModSpec modSpec2 = LdifModSpec.createDelete( oldValue.getAttribute().getDescription() ); 179 if ( oldValue.isString() ) 180 { 181 modSpec2.addAttrVal( LdifAttrValLine.create( oldValue.getAttribute().getDescription(), oldValue 182 .getStringValue() ) ); 183 } 184 else 185 { 186 modSpec2.addAttrVal( LdifAttrValLine.create( oldValue.getAttribute().getDescription(), oldValue 187 .getBinaryValue() ) ); 188 } 189 modSpec2.finish( LdifModSpecSepLine.create() ); 190 cmr.addModSpec( modSpec2 ); 191 cmr.finish( LdifSepLine.create() ); 192 } 193 194 this.applyModificationAndLog( cmr, monitor ); 195 196 } 197 catch ( ConnectionException e ) 198 { 199 monitor.reportError( e ); 200 } 201 } 202 203 204 void delete( IValue[] valuesToDelete, ExtendedProgressMonitor monitor ) 205 { 206 try 207 { 208 for ( int i = 0; !monitor.isCanceled() && i < valuesToDelete.length; i++ ) 209 { 210 LdifChangeModifyRecord cmr = new LdifChangeModifyRecord( LdifDnLine.create( valuesToDelete[i] 211 .getAttribute().getEntry().getDn().toString() ) ); 212 ModelConverter.addControls( cmr, valuesToDelete[i].getAttribute().getEntry() ); 213 cmr.setChangeType( LdifChangeTypeLine.createModify() ); 214 215 LdifModSpec modSpec = LdifModSpec.createDelete( valuesToDelete[i].getAttribute().getDescription() ); 216 if ( valuesToDelete[i].isString() ) 217 { 218 modSpec.addAttrVal( LdifAttrValLine.create( valuesToDelete[i].getAttribute().getDescription(), 219 valuesToDelete[i].getStringValue() ) ); 220 } 221 else 222 { 223 modSpec.addAttrVal( LdifAttrValLine.create( valuesToDelete[i].getAttribute().getDescription(), 224 valuesToDelete[i].getBinaryValue() ) ); 225 } 226 modSpec.finish( LdifModSpecSepLine.create() ); 227 cmr.addModSpec( modSpec ); 228 cmr.finish( LdifSepLine.create() ); 229 230 this.applyModificationAndLog( cmr, monitor ); 231 } 232 } 233 catch ( ConnectionException e ) 234 { 235 monitor.reportError( e ); 236 } 237 } 238 239 240 void delete( IAttribute[] attriubtesToDelete, ExtendedProgressMonitor monitor ) 241 { 242 try 243 { 244 for ( int i = 0; !monitor.isCanceled() && i < attriubtesToDelete.length; i++ ) 245 { 246 LdifChangeModifyRecord cmr = new LdifChangeModifyRecord( LdifDnLine.create( attriubtesToDelete[i] 247 .getEntry().getDn().toString() ) ); 248 ModelConverter.addControls( cmr, attriubtesToDelete[i].getEntry() ); 249 cmr.setChangeType( LdifChangeTypeLine.createModify() ); 250 251 LdifModSpec modSpec = LdifModSpec.createDelete( attriubtesToDelete[i].getDescription() ); 252 modSpec.finish( LdifModSpecSepLine.create() ); 253 cmr.addModSpec( modSpec ); 254 cmr.finish( LdifSepLine.create() ); 255 256 this.applyModificationAndLog( cmr, monitor ); 257 } 258 } 259 catch ( ConnectionException e ) 260 { 261 monitor.reportError( e ); 262 } 263 } 264 265 266 void create( IEntry entryToCreate, ExtendedProgressMonitor monitor ) 267 { 268 try 269 { 270 LdifChangeAddRecord car = ModelConverter.entryToLdifChangeAddRecord( entryToCreate ); 271 this.applyModificationAndLog( car, monitor ); 272 273 } 276 catch ( ConnectionException e ) 277 { 278 monitor.reportError( e ); 279 } 280 } 281 282 283 void rename( IEntry entryToRename, DN newDn, boolean deleteOldRdn, ExtendedProgressMonitor monitor ) 284 { 285 try 286 { 287 LdifChangeModDnRecord cmdr = new LdifChangeModDnRecord( LdifDnLine 288 .create( entryToRename.getDn().toString() ) ); 289 ModelConverter.addControls( cmdr, entryToRename ); 290 cmdr.setChangeType( LdifChangeTypeLine.createModDn() ); 291 292 cmdr.setNewrdn( LdifNewrdnLine.create( newDn.getRdn().toString() ) ); 293 cmdr.setDeloldrdn( deleteOldRdn ? LdifDeloldrdnLine.create1() : LdifDeloldrdnLine.create0() ); 294 cmdr.finish( LdifSepLine.create() ); 295 296 this.applyModificationAndLog( cmdr, monitor ); 297 298 uncacheChildren( entryToRename ); 299 300 } 301 catch ( ConnectionException e ) 302 { 303 monitor.reportError( e ); 304 } 305 } 306 307 308 void move( IEntry entryToMove, DN newSuperior, ExtendedProgressMonitor monitor ) 309 { 310 try 311 { 312 LdifChangeModDnRecord cmdr = new LdifChangeModDnRecord( LdifDnLine.create( entryToMove.getDn().toString() ) ); 313 ModelConverter.addControls( cmdr, entryToMove ); 314 cmdr.setChangeType( LdifChangeTypeLine.createModDn() ); 315 316 cmdr.setNewrdn( LdifNewrdnLine.create( entryToMove.getRdn().toString() ) ); 317 cmdr.setDeloldrdn( LdifDeloldrdnLine.create0() ); 318 cmdr.setNewsuperior( LdifNewsuperiorLine.create( newSuperior.toString() ) ); 319 cmdr.finish( LdifSepLine.create() ); 320 321 this.applyModificationAndLog( cmdr, monitor ); 322 323 uncacheChildren( entryToMove ); 324 325 } 326 catch ( ConnectionException e ) 327 { 328 monitor.reportError( e ); 329 } 330 } 331 332 333 private void uncacheChildren( IEntry entry ) 334 { 335 IEntry[] children = entry.getChildren(); 336 if ( entry.getChildren() != null ) 337 { 338 for ( int i = 0; i < children.length; i++ ) 339 { 340 uncacheChildren( children[i] ); 341 } 342 } 343 connection.uncacheEntry( entry ); 344 } 345 346 347 void delete( IEntry entry, ExtendedProgressMonitor monitor ) 348 { 349 try 350 { 351 LdifChangeDeleteRecord cdr = new LdifChangeDeleteRecord( LdifDnLine.create( entry.getDn().toString() ) ); 352 ModelConverter.addControls( cdr, entry ); 353 cdr.setChangeType( LdifChangeTypeLine.createDelete() ); 354 cdr.finish( LdifSepLine.create() ); 355 356 this.applyModificationAndLog( cdr, monitor ); 357 358 connection.uncacheEntry( entry ); 359 360 } 361 catch ( ConnectionException e ) 362 { 363 monitor.reportError( e ); 364 } 365 } 366 367 368 void importLdif( LdifEnumeration enumeration, Writer logWriter, boolean continueOnError, 369 ExtendedProgressMonitor monitor ) 370 { 371 int importedCount = 0; 372 int errorCount = 0; 373 try 374 { 375 while ( !monitor.isCanceled() && enumeration.hasNext( monitor ) ) 376 { 377 LdifContainer container = enumeration.next( monitor ); 378 379 if ( container instanceof LdifRecord ) 380 { 381 382 LdifRecord record = ( LdifRecord ) container; 383 try 384 { 385 this.applyModificationAndLog( record, monitor ); 386 387 DN dn = new DN( record.getDnLine().getValueAsString() ); 389 IEntry entry = connection.getEntryFromCache( dn ); 390 DN parentDn = dn.getParentDn(); 391 IEntry parentEntry = parentDn != null ? connection.getEntryFromCache( dn.getParentDn() ) : null; 392 393 if ( record instanceof LdifChangeDeleteRecord ) 394 { 395 if ( entry != null ) 396 { 397 entry.setAttributesInitialized( false ); 398 connection.uncacheEntry( entry ); 399 } 400 if ( parentEntry != null ) 401 { 402 parentEntry.setChildrenInitialized( false ); 403 } 404 } 405 else if ( record instanceof LdifChangeModDnRecord ) 406 { 407 if ( entry != null ) 408 { 409 entry.setAttributesInitialized( false ); 410 connection.uncacheEntry( entry ); 411 } 412 if ( parentEntry != null ) 413 { 414 parentEntry.setChildrenInitialized( false ); 415 } 416 LdifChangeModDnRecord modDnRecord = ( LdifChangeModDnRecord ) record; 417 if ( modDnRecord.getNewsuperiorLine() != null ) 418 { 419 DN newSuperiorDn = new DN( modDnRecord.getNewsuperiorLine().getValueAsString() ); 420 IEntry newSuperiorEntry = connection.getEntryFromCache( newSuperiorDn ); 421 if ( newSuperiorEntry != null ) 422 { 423 newSuperiorEntry.setChildrenInitialized( false ); 424 } 425 } 426 } 427 else if ( record instanceof LdifChangeAddRecord || record instanceof LdifContentRecord ) 428 { 429 if ( parentEntry != null ) 430 { 431 parentEntry.setChildrenInitialized( false ); 432 } 433 } 434 else 435 { 436 if ( entry != null ) 437 { 438 entry.setAttributesInitialized( false ); 439 } 440 } 441 442 logModification( logWriter, record, monitor ); 443 444 importedCount++; 445 } 446 catch ( Exception e ) 447 { 448 449 logModificationError( logWriter, record, e, monitor ); 450 451 errorCount++; 452 453 if ( !continueOnError ) 454 { 455 monitor.reportError( e ); 456 return; 457 } 458 } 459 460 monitor.reportProgress( BrowserCoreMessages.bind( 461 BrowserCoreMessages.ldif__imported_n_entries_m_errors, new String [] 462 { "" + importedCount, "" + errorCount } ) ); } 464 else 465 { 466 logWriter.write( container.toRawString() ); 467 } 468 } 469 470 if ( errorCount > 0 ) 471 { 472 monitor.reportError( BrowserCoreMessages.bind( BrowserCoreMessages.ldif__n_errors_see_logfile, 473 new String [] 474 { "" + errorCount } ) ); } 476 } 477 catch ( Exception e ) 478 { 479 monitor.reportError( e ); 480 } 481 } 482 483 484 boolean isSuspended() 485 { 486 return this.suspendDepth > 0; 487 } 488 489 490 void suspend() 491 { 492 this.suspendDepth++; 493 } 494 495 496 void resume( ExtendedProgressMonitor monitor ) 497 { 498 try 499 { 500 this.suspendDepth--; 501 this.commit( monitor ); 502 } 503 catch ( Exception e ) 504 { 505 monitor.reportError( e ); 506 } 507 } 508 509 510 void reset() 511 { 512 this.recordQueue.clear(); 513 this.suspendDepth = 0; 514 } 515 516 517 private void commit( ExtendedProgressMonitor monitor ) throws ConnectionException 518 { 519 if ( this.suspendDepth == 0 && !recordQueue.isEmpty() ) 520 { 521 522 final LdifRecord[] records = ( LdifRecord[] ) this.recordQueue.toArray( new LdifRecord[this.recordQueue 523 .size()] ); 524 this.reset(); 525 526 for ( int i = 0; i < records.length; i++ ) 527 { 528 try 529 { 530 int referralsHandlingMethod = connection.getReferralsHandlingMethod(); 531 connection.connectionProvider.applyModification( records[i], referralsHandlingMethod, monitor ); 534 535 StringWriter writer = new StringWriter (); 536 this.logModification( writer, records[i], monitor ); 537 this.modificationLogger.log( writer.toString() ); 538 539 } 540 catch ( ConnectionException ce ) 541 { 542 543 if ( ce instanceof ReferralException ) 544 { 545 546 if ( connection.getReferralsHandlingMethod() == IConnection.HANDLE_REFERRALS_FOLLOW ) 547 { 548 549 IReferralHandler referralHandler = BrowserCorePlugin.getDefault().getReferralHandler(); 551 if ( referralHandler == null ) 552 { 553 throw new ConnectionException( BrowserCoreMessages.model__no_referral_handler ); 554 } 555 556 ReferralException re = ( ReferralException ) ce; 558 for ( int r = 0; r < re.getReferrals().length; r++ ) 559 { 560 561 String referral = re.getReferrals()[r]; 563 URL referralUrl = new URL( referral ); 564 565 IConnection referralConnection = referralHandler.getReferralConnection( referralUrl ); 567 if ( referralConnection == null ) 568 { 569 continue; 572 } 573 574 if ( !referralConnection.isOpened() ) 576 { 577 referralConnection.open( monitor ); 578 } 579 580 ( ( Connection ) referralConnection ).modifyHandler.applyModificationAndLog( 581 records[i], monitor ); 582 583 } 584 } 585 586 } 587 else 588 { 589 590 StringWriter writer = new StringWriter (); 591 this.logModificationError( writer, records[i], ce, monitor ); 592 this.modificationLogger.log( writer.toString() ); 593 594 throw ce; 595 } 596 } 597 } 598 } 599 } 600 601 602 ModificationLogger getModificationLogger() 603 { 604 return modificationLogger; 605 } 606 607 608 private void logModificationError( Writer logWriter, LdifRecord record, Exception e, ExtendedProgressMonitor monitor ) 609 { 610 try 611 { 612 DateFormat df = new SimpleDateFormat ( BrowserCoreConstants.DATEFORMAT ); 613 614 String errorComment = "#!ERROR " + e.getMessage(); errorComment = errorComment.replaceAll( "\r", " " ); errorComment = errorComment.replaceAll( "\n", " " ); LdifCommentLine errorCommentLine = LdifCommentLine.create( errorComment ); 618 619 logWriter.write( LdifCommentLine.create( "#!RESULT ERROR" ).toFormattedString() ); logWriter.write( LdifCommentLine.create( 621 "#!CONNECTION ldap://" + connection.getHost() + ":" + connection.getPort() ).toFormattedString() ); logWriter.write( LdifCommentLine.create( "#!DATE " + df.format( new Date () ) ).toFormattedString() ); logWriter.write( errorCommentLine.toFormattedString() ); 624 logWriter.write( record.toFormattedString() ); 625 } 626 catch ( IOException ioe ) 627 { 628 monitor.reportError( BrowserCoreMessages.model__error_logging_modification, ioe ); 629 } 630 } 631 632 633 private void logModification( Writer logWriter, LdifRecord record, ExtendedProgressMonitor monitor ) 634 { 635 try 636 { 637 DateFormat df = new SimpleDateFormat ( BrowserCoreConstants.DATEFORMAT ); 638 logWriter.write( LdifCommentLine.create( "#!RESULT OK" ).toFormattedString() ); logWriter.write( LdifCommentLine.create( 640 "#!CONNECTION ldap://" + connection.getHost() + ":" + connection.getPort() ).toFormattedString() ); logWriter.write( LdifCommentLine.create( "#!DATE " + df.format( new Date () ) ).toFormattedString() ); logWriter.write( record.toFormattedString() ); 643 } 644 catch ( IOException ioe ) 645 { 646 monitor.reportError( BrowserCoreMessages.model__error_logging_modification, ioe ); 647 } 648 } 649 650 651 private void applyModificationAndLog( LdifRecord record, ExtendedProgressMonitor monitor ) 652 throws ConnectionException 653 { 654 this.recordQueue.add( record ); 655 this.commit( monitor ); 656 } 657 658 } 659 | Popular Tags |