1 20 21 package org.apache.directory.ldapstudio.browser.core.internal.model; 22 23 24 import java.net.ConnectException ; 25 import java.net.NoRouteToHostException ; 26 import java.net.SocketException ; 27 import java.net.UnknownHostException ; 28 import java.util.ArrayList ; 29 30 import javax.naming.Context ; 31 import javax.naming.NamingEnumeration ; 32 import javax.naming.NamingException ; 33 import javax.naming.ReferralException ; 34 import javax.naming.directory.Attribute ; 35 import javax.naming.directory.Attributes ; 36 import javax.naming.directory.BasicAttribute ; 37 import javax.naming.directory.BasicAttributes ; 38 import javax.naming.directory.DirContext ; 39 import javax.naming.directory.ModificationItem ; 40 import javax.naming.directory.SearchControls ; 41 import javax.naming.directory.SearchResult ; 42 import javax.naming.ldap.Control ; 43 44 import org.apache.directory.ldapstudio.browser.core.BrowserCoreConstants; 45 import org.apache.directory.ldapstudio.browser.core.BrowserCoreMessages; 46 import org.apache.directory.ldapstudio.browser.core.jobs.ExtendedProgressMonitor; 47 import org.apache.directory.ldapstudio.browser.core.model.ConnectionParameter; 48 import org.apache.directory.ldapstudio.browser.core.model.DN; 49 import org.apache.directory.ldapstudio.browser.core.model.IConnection; 50 import org.apache.directory.ldapstudio.browser.core.model.IConnectionProvider; 51 import org.apache.directory.ldapstudio.browser.core.model.ICredentials; 52 import org.apache.directory.ldapstudio.browser.core.model.ISearch; 53 import org.apache.directory.ldapstudio.browser.core.model.NameException; 54 import org.apache.directory.ldapstudio.browser.core.model.SearchParameter; 55 import org.apache.directory.ldapstudio.browser.core.model.ldif.LdifEnumeration; 56 import org.apache.directory.ldapstudio.browser.core.model.ldif.container.LdifChangeAddRecord; 57 import org.apache.directory.ldapstudio.browser.core.model.ldif.container.LdifChangeDeleteRecord; 58 import org.apache.directory.ldapstudio.browser.core.model.ldif.container.LdifChangeModDnRecord; 59 import org.apache.directory.ldapstudio.browser.core.model.ldif.container.LdifChangeModifyRecord; 60 import org.apache.directory.ldapstudio.browser.core.model.ldif.container.LdifChangeRecord; 61 import org.apache.directory.ldapstudio.browser.core.model.ldif.container.LdifContainer; 62 import org.apache.directory.ldapstudio.browser.core.model.ldif.container.LdifContentRecord; 63 import org.apache.directory.ldapstudio.browser.core.model.ldif.container.LdifModSpec; 64 import org.apache.directory.ldapstudio.browser.core.model.ldif.container.LdifRecord; 65 import org.apache.directory.ldapstudio.browser.core.model.ldif.lines.LdifAttrValLine; 66 import org.apache.directory.ldapstudio.browser.core.model.ldif.lines.LdifControlLine; 67 import org.apache.directory.ldapstudio.browser.core.model.ldif.lines.LdifModSpecTypeLine; 68 import org.apache.directory.ldapstudio.browser.core.model.ldif.lines.LdifSepLine; 69 70 71 public class JNDIConnectionProvider implements IConnectionProvider 72 { 73 74 private JNDIConnectionContext context; 75 76 77 public JNDIConnectionProvider() 78 { 79 } 80 81 82 public void connect( ConnectionParameter parameter, ExtendedProgressMonitor monitor ) throws ConnectionException 83 { 84 try 85 { 86 this.context = new JNDIConnectionContext(); 87 this.context.connect( parameter.getHost(), parameter.getPort(), 88 parameter.getEncryptionMethod() == IConnection.ENCYRPTION_LDAPS, 89 parameter.getEncryptionMethod() == IConnection.ENCYRPTION_STARTTLS, null, monitor ); 90 } 91 catch ( NamingException ne ) 92 { 93 this.context = null; 94 throw createConnectionException( null, ne ); 95 } 96 } 97 98 99 public void bind( ConnectionParameter parameter, ICredentials credentials, ExtendedProgressMonitor monitor ) 100 throws ConnectionException 101 { 102 try 103 { 104 if ( parameter.getAuthMethod() == IConnection.AUTH_SIMPLE ) 105 { 106 String bindPrincipal = credentials.getBindPrincipal(); 107 String bindPassword = credentials.getBindPassword(); 108 this.context.bindSimple( bindPrincipal, bindPassword, monitor ); 109 } 110 else if ( parameter.getAuthMethod() == IConnection.AUTH_ANONYMOUS ) 111 { 112 this.context.bindAnonymous( monitor ); 113 } 114 115 } 116 catch ( NamingException ne ) 117 { 118 this.context = null; 119 throw createConnectionException( null, ne ); 120 } 121 } 122 123 124 public void close() throws ConnectionException 125 { 126 if ( this.context != null ) 127 { 128 try 129 { 130 this.context.close(); 131 this.context = null; 132 } 133 catch ( NamingException e ) 134 { 135 } 136 } 137 } 138 139 140 public LdifEnumeration search( SearchParameter parameter, ExtendedProgressMonitor monitor ) 141 throws ConnectionException 142 { 143 SearchControls controls = new SearchControls (); 144 switch ( parameter.getScope() ) 145 { 146 case ISearch.SCOPE_OBJECT: 147 controls.setSearchScope( SearchControls.OBJECT_SCOPE ); 148 break; 149 case ISearch.SCOPE_ONELEVEL: 150 controls.setSearchScope( SearchControls.ONELEVEL_SCOPE ); 151 break; 152 case ISearch.SCOPE_SUBTREE: 153 controls.setSearchScope( SearchControls.SUBTREE_SCOPE ); 154 break; 155 default: 156 controls.setSearchScope( SearchControls.ONELEVEL_SCOPE ); 157 } 158 controls.setReturningAttributes( parameter.getReturningAttributes() ); 159 controls.setCountLimit( parameter.getCountLimit() ); 160 controls.setTimeLimit( parameter.getTimeLimit() ); 161 String filter = parameter.getFilter(); 162 String derefAliasMethod = getDerefAliasMethod( parameter ); 163 String handleReferralsMethod = getReferralsHandlingMethod( parameter.getReferralsHandlingMethod() ); 164 165 Control [] ldapControls = null; 166 if ( parameter.getControls() != null ) 167 { 168 org.apache.directory.ldapstudio.browser.core.model.Control[] ctls = parameter.getControls(); 169 ldapControls = new Control [ctls.length]; 170 for ( int i = 0; i < ctls.length; i++ ) 171 { 172 ldapControls[i] = new JNDIControl( ctls[i].getOid(), ctls[i].isCritical(), ctls[i].getControlValue() ); 173 } 174 } 179 180 try 181 { 182 NamingEnumeration list = this.context.search( parameter.getSearchBase().toString(), filter, controls, 183 derefAliasMethod, handleReferralsMethod, ldapControls, monitor ); 184 return new LdifEnumerationImpl( list, parameter ); 185 } 186 catch ( NamingException e ) 187 { 188 throw createConnectionException( parameter, e ); 189 } 190 191 } 192 193 194 public void applyModification( LdifRecord record, int referralsHandlingMethod, ExtendedProgressMonitor monitor ) 195 throws ConnectionException 196 { 197 198 if ( !record.isValid() ) 199 { 200 throw new ConnectionException( BrowserCoreMessages.model__invalid_record ); 201 } 202 203 String dn = record.getDnLine().getValueAsString(); 204 205 if ( record instanceof LdifContentRecord ) 206 { 207 LdifContentRecord attrValRecord = ( LdifContentRecord ) record; 208 LdifAttrValLine[] attrVals = attrValRecord.getAttrVals(); 209 Attributes jndiAttributes = new BasicAttributes (); 210 for ( int ii = 0; ii < attrVals.length; ii++ ) 211 { 212 String attributeName = attrVals[ii].getUnfoldedAttributeDescription(); 213 Object realValue = attrVals[ii].getValueAsObject(); 216 217 if ( jndiAttributes.get( attributeName ) != null ) 218 { 219 jndiAttributes.get( attributeName ).add( realValue ); 220 } 221 else 222 { 223 jndiAttributes.put( attributeName, realValue ); 224 } 225 } 226 227 try 228 { 229 this.context.createSubcontext( dn, jndiAttributes, getControls( attrValRecord ), monitor ); 230 } 231 catch ( NamingException ne ) 232 { 233 throw createConnectionException( null, ne ); 234 } 235 } 236 else if ( record instanceof LdifChangeAddRecord ) 237 { 238 LdifChangeAddRecord changeAddRecord = ( LdifChangeAddRecord ) record; 239 LdifAttrValLine[] attrVals = changeAddRecord.getAttrVals(); 240 Attributes jndiAttributes = new BasicAttributes (); 241 for ( int ii = 0; ii < attrVals.length; ii++ ) 242 { 243 String attributeName = attrVals[ii].getUnfoldedAttributeDescription(); 244 Object realValue = attrVals[ii].getValueAsObject(); 245 246 if ( jndiAttributes.get( attributeName ) != null ) 247 { 248 jndiAttributes.get( attributeName ).add( realValue ); 249 } 250 else 251 { 252 jndiAttributes.put( attributeName, realValue ); 253 } 254 } 255 256 try 257 { 258 this.context.createSubcontext( dn, jndiAttributes, getControls( changeAddRecord ), monitor ); 259 } 260 catch ( NamingException ne ) 261 { 262 throw createConnectionException( null, ne ); 263 } 264 } 265 else if ( record instanceof LdifChangeDeleteRecord ) 266 { 267 LdifChangeDeleteRecord changeDeleteRecord = ( LdifChangeDeleteRecord ) record; 268 try 269 { 270 this.context.destroySubcontext( dn, getControls( changeDeleteRecord ), monitor ); 271 } 272 catch ( NamingException ne ) 273 { 274 throw createConnectionException( null, ne ); 275 } 276 } 277 else if ( record instanceof LdifChangeModifyRecord ) 278 { 279 LdifChangeModifyRecord modifyRecord = ( LdifChangeModifyRecord ) record; 280 LdifModSpec[] modSpecs = modifyRecord.getModSpecs(); 281 ModificationItem [] mis = new ModificationItem [modSpecs.length]; 282 for ( int ii = 0; ii < modSpecs.length; ii++ ) 283 { 284 LdifModSpecTypeLine modSpecType = modSpecs[ii].getModSpecType(); 285 LdifAttrValLine[] attrVals = modSpecs[ii].getAttrVals(); 286 287 Attribute attribute = new BasicAttribute ( modSpecType.getUnfoldedAttributeDescription() ); 288 for ( int x = 0; x < attrVals.length; x++ ) 289 { 290 attribute.add( attrVals[x].getValueAsObject() ); 291 } 292 293 if ( modSpecType.isAdd() ) 294 { 295 mis[ii] = new ModificationItem ( DirContext.ADD_ATTRIBUTE, attribute ); 296 } 297 else if ( modSpecType.isDelete() ) 298 { 299 mis[ii] = new ModificationItem ( DirContext.REMOVE_ATTRIBUTE, attribute ); 300 } 301 else if ( modSpecType.isReplace() ) 302 { 303 mis[ii] = new ModificationItem ( DirContext.REPLACE_ATTRIBUTE, attribute ); 304 } 305 } 306 307 try 308 { 309 this.context.modifyAttributes( dn, mis, getControls( modifyRecord ), monitor ); 310 } 311 catch ( NamingException ne ) 312 { 313 throw createConnectionException( null, ne ); 314 } 315 } 316 else if ( record instanceof LdifChangeModDnRecord ) 317 { 318 LdifChangeModDnRecord modDnRecord = ( LdifChangeModDnRecord ) record; 319 if ( modDnRecord.getNewrdnLine() != null && modDnRecord.getDeloldrdnLine() != null ) 320 { 321 String newRdn = modDnRecord.getNewrdnLine().getValueAsString(); 322 boolean deleteOldRdn = modDnRecord.getDeloldrdnLine().isDeleteOldRdn(); 323 324 try 325 { 326 DN newDn; 327 if ( modDnRecord.getNewsuperiorLine() != null ) 328 newDn = new DN( newRdn, modDnRecord.getNewsuperiorLine().getValueAsString() ); 329 else 330 { 331 DN dnObject = new DN( dn ); 332 newDn = new DN( newRdn.toString(), dnObject.getParentDn().toString() ); 333 } 334 335 try 336 { 337 this.context.rename( dn.toString(), newDn.toString(), deleteOldRdn, getControls( modDnRecord ), 338 monitor ); 339 } 340 catch ( NamingException ne ) 341 { 342 throw createConnectionException( null, ne ); 343 } 344 } 345 catch ( NameException ne ) 346 { 347 throw new ConnectionException( ne ); 348 } 349 } 350 } 351 } 352 353 354 private Control [] getControls( LdifRecord record ) 355 { 356 Control [] controls = null; 357 if ( record instanceof LdifChangeRecord ) 358 { 359 LdifChangeRecord changeRecord = ( LdifChangeRecord ) record; 360 LdifControlLine[] controlLines = changeRecord.getControls(); 361 controls = new Control [controlLines.length]; 362 for ( int i = 0; i < controlLines.length; i++ ) 363 { 364 LdifControlLine line = controlLines[i]; 365 controls[i] = new JNDIControl( line.getUnfoldedOid(), line.isCritical(), null ); 367 } 368 } 369 return controls; 370 } 371 372 class LdifEnumerationImpl implements LdifEnumeration 373 { 374 375 private NamingEnumeration enumeration; 376 377 private SearchParameter parameter; 378 379 380 public LdifEnumerationImpl( NamingEnumeration enumeration, SearchParameter parameter ) 381 { 382 this.enumeration = enumeration; 383 this.parameter = parameter; 384 } 385 386 387 public boolean hasNext( ExtendedProgressMonitor monitor ) throws ConnectionException 388 { 389 try 390 { 391 return enumeration != null && enumeration.hasMore(); 392 } 393 catch ( NamingException e ) 394 { 395 throw createConnectionException( parameter, e ); 396 } 397 } 398 399 400 public LdifContainer next( ExtendedProgressMonitor monitor ) throws ConnectionException 401 { 402 403 try 404 { 405 SearchResult sr = ( SearchResult ) enumeration.next(); 406 407 DN dn = JNDIUtils.getDn( sr, parameter.getSearchBase().toString(), context ); 408 LdifContentRecord record = LdifContentRecord.create( dn.toString() ); 409 410 NamingEnumeration attributeEnumeration = sr.getAttributes().getAll(); 411 while ( attributeEnumeration.hasMore() ) 412 { 413 Attribute attribute = ( Attribute ) attributeEnumeration.next(); 414 String attributeName = attribute.getID(); 415 NamingEnumeration valueEnumeration = attribute.getAll(); 416 while ( valueEnumeration.hasMore() ) 417 { 418 Object o = valueEnumeration.next(); 419 if ( o instanceof String ) 420 { 421 record.addAttrVal( LdifAttrValLine.create( attributeName, ( String ) o ) ); 422 } 423 if ( o instanceof byte[] ) 424 { 425 record.addAttrVal( LdifAttrValLine.create( attributeName, ( byte[] ) o ) ); 426 } 427 } 428 } 429 430 record.finish( LdifSepLine.create() ); 431 432 return record; 433 434 } 435 catch ( NamingException e ) 436 { 437 throw createConnectionException( parameter, e ); 438 } 439 catch ( NameException e ) 440 { 441 throw new ConnectionException( e ); 442 } 443 catch ( NoSuchFieldException e ) 444 { 445 throw new ConnectionException( e ); 446 } 447 } 448 449 } 450 451 452 private ConnectionException createConnectionException( SearchParameter searchParameter, Throwable e ) 453 { 454 455 ConnectionException connectionException = null; 456 ConnectionException lastException = null; 457 458 do 459 { 460 461 String message = e.getMessage() != null ? e.getMessage() : e.getClass().getName(); 462 int ldapStatusCode = -1; 463 String [] referrals = null; 464 465 if ( message != null && message.startsWith( "[LDAP: error code " ) ) { int begin = "[LDAP: error code ".length(); int end = begin + 2; 471 try 472 { 473 ldapStatusCode = Integer.parseInt( message.substring( begin, end ).trim() ); 474 } 475 catch ( NumberFormatException nfe ) 476 { 477 } 478 } 479 480 if ( e instanceof ConnectException ) 490 { 491 message = e.getMessage() + " (" + e.getMessage() + ")"; } 493 if ( e instanceof NoRouteToHostException ) 494 { 495 message += e.getMessage() + " (" + e.getMessage() + ")"; } 497 if ( e instanceof UnknownHostException ) 498 { 499 message = BrowserCoreMessages.model__unknown_host + e.getMessage(); 500 } 501 if ( e instanceof SocketException ) 502 { 503 message = e.getMessage() + " (" + e.getMessage() + ")";; } 505 if ( e instanceof ReferralException ) 506 { 507 508 message = "Referrals: "; ReferralException re; 510 ArrayList referralsList = new ArrayList (); 511 512 re = ( ReferralException ) e; 513 message += BrowserCoreConstants.LINE_SEPARATOR + re.getReferralInfo(); 514 referralsList.add( re.getReferralInfo() ); 515 516 while ( re.skipReferral() ) 517 { 518 try 519 { 520 Context ctx = re.getReferralContext(); 521 ctx.list( "" ); } 523 catch ( NamingException e1 ) 524 { 525 if ( e1 instanceof ReferralException ) 526 { 527 re = ( ReferralException ) e1; 528 message += BrowserCoreConstants.LINE_SEPARATOR + re.getReferralInfo(); 529 referralsList.add( re.getReferralInfo() ); 530 } 531 else 532 { 533 break; 534 } 535 } 536 } 537 538 referrals = ( String [] ) referralsList.toArray( new String [referralsList.size()] ); 539 } 540 541 ConnectionException ce; 542 if ( referrals != null ) 543 { 544 ce = new org.apache.directory.ldapstudio.browser.core.internal.model.ReferralException( 545 searchParameter, referrals, ldapStatusCode, message, e ); 546 } 547 else 548 { 549 ce = new ConnectionException( ldapStatusCode, message, e ); 550 } 551 if ( lastException != null ) 552 { 553 lastException.initCause( ce ); 554 } 555 lastException = ce; 556 if ( connectionException == null ) 557 { 558 connectionException = lastException; 559 } 560 561 e = e.getCause(); 563 } 564 while ( e != null ); 565 566 return connectionException; 567 568 } 569 570 571 private String getDerefAliasMethod( SearchParameter parameter ) 572 { 573 String m = "always"; 575 switch ( parameter.getAliasesDereferencingMethod() ) 576 { 577 case IConnection.DEREFERENCE_ALIASES_NEVER: 578 m = "never"; break; 580 case IConnection.DEREFERENCE_ALIASES_ALWAYS: 581 m = "always"; break; 583 case IConnection.DEREFERENCE_ALIASES_FINDING: 584 m = "finding"; break; 586 case IConnection.DEREFERENCE_ALIASES_SEARCH: 587 m = "searching"; break; 589 } 590 591 return m; 592 } 593 594 595 private String getReferralsHandlingMethod( int referralHandlingMethod ) 596 { 597 String m = "follow"; 599 switch ( referralHandlingMethod ) 600 { 601 case IConnection.HANDLE_REFERRALS_IGNORE: 602 m = "ignore"; break; 604 case IConnection.HANDLE_REFERRALS_FOLLOW: 605 m = "throw"; break; 608 } 609 610 return m; 611 } 612 613 } 614 | Popular Tags |