KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > directory > ldapstudio > browser > core > internal > model > JNDIConnectionContext


1 /*
2  * Licensed to the Apache Software Foundation (ASF) under one
3  * or more contributor license agreements. See the NOTICE file
4  * distributed with this work for additional information
5  * regarding copyright ownership. The ASF licenses this file
6  * to you under the Apache License, Version 2.0 (the
7  * "License"); you may not use this file except in compliance
8  * with the License. You may obtain a copy of the License at
9  *
10  * http://www.apache.org/licenses/LICENSE-2.0
11  *
12  * Unless required by applicable law or agreed to in writing,
13  * software distributed under the License is distributed on an
14  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15  * KIND, either express or implied. See the License for the
16  * specific language governing permissions and limitations
17  * under the License.
18  *
19  */

20
21 package org.apache.directory.ldapstudio.browser.core.internal.model;
22
23
24 import java.util.Hashtable JavaDoc;
25
26 import javax.naming.CommunicationException JavaDoc;
27 import javax.naming.Context JavaDoc;
28 import javax.naming.InsufficientResourcesException JavaDoc;
29 import javax.naming.NamingEnumeration JavaDoc;
30 import javax.naming.NamingException JavaDoc;
31 import javax.naming.ServiceUnavailableException JavaDoc;
32 import javax.naming.directory.Attributes JavaDoc;
33 import javax.naming.directory.ModificationItem JavaDoc;
34 import javax.naming.directory.SearchControls JavaDoc;
35 import javax.naming.ldap.Control JavaDoc;
36 import javax.naming.ldap.InitialLdapContext JavaDoc;
37 import javax.naming.ldap.LdapContext JavaDoc;
38 import javax.naming.ldap.StartTlsRequest JavaDoc;
39 import javax.naming.ldap.StartTlsResponse JavaDoc;
40 import javax.net.ssl.HostnameVerifier;
41 import javax.net.ssl.SSLSession;
42
43 import org.apache.directory.ldapstudio.browser.core.BrowserCoreMessages;
44 import org.apache.directory.ldapstudio.browser.core.jobs.ExtendedProgressMonitor;
45
46
47 public class JNDIConnectionContext
48 {
49
50     private Control JavaDoc[] connCtls;
51
52     private boolean useStartTLS;
53
54     private String JavaDoc authMethod;
55
56     private String JavaDoc principal;
57
58     private String JavaDoc credentials;
59
60     private Hashtable JavaDoc<String JavaDoc, String JavaDoc> environment;
61
62     private InitialLdapContext JavaDoc context;
63
64     private boolean isConnected;
65
66     private Thread JavaDoc jobThread;
67
68
69     public JNDIConnectionContext() throws NamingException JavaDoc
70     {
71     }
72
73
74     public void connect( String JavaDoc host, int port, boolean useLdaps, boolean useStartTLS, Control JavaDoc[] connCtls,
75         ExtendedProgressMonitor monitor ) throws NamingException JavaDoc
76     {
77
78         this.environment = new Hashtable JavaDoc<String JavaDoc, String JavaDoc>();
79         this.environment.put( Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.ldap.LdapCtxFactory" ); //$NON-NLS-1$
80
this.environment.put( "java.naming.ldap.version", "3" ); //$NON-NLS-1$ //$NON-NLS-2$
81

82         // timeouts
83
if ( !useLdaps )
84         {
85             this.environment.put( "com.sun.jndi.ldap.connect.timeout", "10000" ); //$NON-NLS-1$ //$NON-NLS-2$
86
}
87         this.environment.put( "com.sun.jndi.dns.timeout.initial", "2000" ); //$NON-NLS-1$ //$NON-NLS-2$
88
this.environment.put( "com.sun.jndi.dns.timeout.retries", "3" ); //$NON-NLS-1$ //$NON-NLS-2$
89

90         // ldaps://
91
if ( useLdaps )
92         {
93             environment.put( Context.PROVIDER_URL, "ldaps://" + host + ":" + port ); //$NON-NLS-1$ //$NON-NLS-2$
94
environment.put( Context.SECURITY_PROTOCOL, "ssl" ); //$NON-NLS-1$
95
environment.put( "java.naming.ldap.factory.socket", DummySSLSocketFactory.class.getName() ); //$NON-NLS-1$
96
}
97         else
98         {
99             environment.put( Context.PROVIDER_URL, "ldap://" + host + ":" + port ); //$NON-NLS-1$ //$NON-NLS-2$
100
}
101
102         this.useStartTLS = useStartTLS;
103
104         this.connCtls = connCtls;
105
106         this.context = null;
107         this.isConnected = false;
108         this.jobThread = null;
109
110         try
111         {
112             this.doConnect( monitor );
113         }
114         catch ( NamingException JavaDoc ne )
115         {
116             this.close();
117             throw ne;
118         }
119     }
120
121
122     public void bindAnonymous( ExtendedProgressMonitor monitor ) throws NamingException JavaDoc
123     {
124         this.authMethod = "none"; //$NON-NLS-1$
125
this.principal = ""; //$NON-NLS-1$
126
this.credentials = ""; //$NON-NLS-1$
127

128         try
129         {
130             this.doBind( monitor );
131         }
132         catch ( NamingException JavaDoc ne )
133         {
134             this.close();
135             throw ne;
136         }
137     }
138
139
140     public void bindSimple( String JavaDoc user, String JavaDoc password, ExtendedProgressMonitor monitor ) throws NamingException JavaDoc
141     {
142         this.authMethod = "simple"; //$NON-NLS-1$
143
this.principal = user;
144         this.credentials = password;
145
146         try
147         {
148             this.doBind( monitor );
149         }
150         catch ( NamingException JavaDoc ne )
151         {
152             this.close();
153             throw ne;
154         }
155     }
156
157
158     public void close() throws NamingException JavaDoc
159     {
160         if ( this.jobThread != null )
161         {
162             Thread JavaDoc t = this.jobThread;
163             this.jobThread = null;
164             t.interrupt();
165         }
166         if ( this.context != null )
167         {
168             this.context.close();
169             this.context = null;
170         }
171         this.isConnected = false;
172         System.gc();
173     }
174     
175     
176     public NamingEnumeration JavaDoc search( final String JavaDoc searchBase, final String JavaDoc filter, final SearchControls JavaDoc controls,
177         final String JavaDoc derefAliasMethod, final String JavaDoc handleReferralsMethod, final Control JavaDoc[] ldapControls,
178         final ExtendedProgressMonitor monitor ) throws NamingException JavaDoc
179     {
180         // start
181
InnerRunnable runnable = new InnerRunnable()
182         {
183             private NamingEnumeration JavaDoc namingEnumeration = null;
184
185             private NamingException JavaDoc namingException = null;
186
187
188             public void run()
189             {
190
191                 try
192                 {
193
194                     // Control[] ldapControls = null;
195
// try {
196
// //Control subEntryControl = new
197
// JNDISubentriesControl();
198
// Control subEntryControl = new
199
// JNDIControl("1.3.6.1.4.1.4203.1.10.1", false, new
200
// byte[]{0x01, 0x01, ( byte ) 0xFF});
201
// ldapControls = new Control[]{subEntryControl};
202
// }
203
// catch(Exception e) {
204
// e.printStackTrace();
205
// }
206

207                     LdapContext JavaDoc searchCtx = context.newInstance( ldapControls );
208                     try
209                     {
210                         searchCtx.addToEnvironment( "java.naming.ldap.derefAliases", derefAliasMethod ); //$NON-NLS-1$
211
searchCtx.addToEnvironment( Context.REFERRAL, handleReferralsMethod );
212
213                     }
214                     catch ( NamingException JavaDoc e )
215                     {
216                         this.namingException = e;
217                     }
218
219                     try
220                     {
221                         this.namingEnumeration = searchCtx.search( searchBase, filter, controls );
222                     }
223                     catch ( NamingException JavaDoc ne )
224                     {
225                         this.namingException = ne;
226                     }
227
228                 }
229                 catch ( NamingException JavaDoc e )
230                 {
231                     this.namingException = e;
232                 }
233
234             }
235
236
237             public NamingException JavaDoc getException()
238             {
239                 return this.namingException;
240             }
241
242
243             public Object JavaDoc getResult()
244             {
245                 return this.namingEnumeration;
246             }
247
248
249             public void reset()
250             {
251                 this.namingEnumeration = null;
252                 this.namingException = null;
253             }
254
255         };
256         this.checkConnectionAndRunAndMonitor( runnable, monitor );
257
258         if ( runnable.getException() != null )
259         {
260             throw runnable.getException();
261         }
262         else if ( runnable.getResult() != null && runnable.getResult() instanceof NamingEnumeration JavaDoc )
263         {
264             return ( NamingEnumeration JavaDoc ) runnable.getResult();
265         }
266         else
267         {
268             return null;
269         }
270     }
271
272
273     void modifyAttributes( final String JavaDoc dn, final ModificationItem JavaDoc[] modificationItems, final Control JavaDoc[] controls,
274         final ExtendedProgressMonitor monitor ) throws NamingException JavaDoc
275     {
276
277         InnerRunnable runnable = new InnerRunnable()
278         {
279             private NamingException JavaDoc namingException = null;
280
281
282             public void run()
283             {
284                 try
285                 {
286                     LdapContext JavaDoc modCtx = context.newInstance( controls );
287                     modCtx.addToEnvironment( Context.REFERRAL, "throw" ); //$NON-NLS-1$
288

289                     modCtx.modifyAttributes( dn, modificationItems );
290                 }
291                 catch ( NamingException JavaDoc ne )
292                 {
293                     this.namingException = ne;
294                 }
295             }
296
297
298             public NamingException JavaDoc getException()
299             {
300                 return this.namingException;
301             }
302
303
304             public Object JavaDoc getResult()
305             {
306                 return null;
307             }
308
309
310             public void reset()
311             {
312                 this.namingException = null;
313             }
314         };
315         this.checkConnectionAndRunAndMonitor( runnable, monitor );
316
317         if ( runnable.getException() != null )
318         {
319             throw runnable.getException();
320         }
321     }
322
323
324     void rename( final String JavaDoc oldDn, final String JavaDoc newDn, final boolean deleteOldRdn, final Control JavaDoc[] controls,
325         final ExtendedProgressMonitor monitor ) throws NamingException JavaDoc
326     {
327
328         InnerRunnable runnable = new InnerRunnable()
329         {
330             private NamingException JavaDoc namingException = null;
331
332
333             public void run()
334             {
335                 try
336                 {
337                     LdapContext JavaDoc modCtx = context.newInstance( controls );
338                     modCtx.addToEnvironment( Context.REFERRAL, "throw" ); //$NON-NLS-1$
339

340                     modCtx.rename( oldDn, newDn );
341
342                 }
343                 catch ( NamingException JavaDoc ne )
344                 {
345                     this.namingException = ne;
346                 }
347             }
348
349
350             public NamingException JavaDoc getException()
351             {
352                 return this.namingException;
353             }
354
355
356             public Object JavaDoc getResult()
357             {
358                 return null;
359             }
360
361
362             public void reset()
363             {
364                 this.namingException = null;
365             }
366         };
367         this.checkConnectionAndRunAndMonitor( runnable, monitor );
368
369         if ( runnable.getException() != null )
370         {
371             throw runnable.getException();
372         }
373     }
374
375
376     void createSubcontext( final String JavaDoc dn, final Attributes JavaDoc attributes, final Control JavaDoc[] controls,
377         final ExtendedProgressMonitor monitor ) throws NamingException JavaDoc
378     {
379
380         InnerRunnable runnable = new InnerRunnable()
381         {
382             private NamingException JavaDoc namingException = null;
383
384
385             public void run()
386             {
387                 try
388                 {
389                     LdapContext JavaDoc modCtx = context.newInstance( controls );
390                     modCtx.addToEnvironment( Context.REFERRAL, "throw" ); //$NON-NLS-1$
391

392                     modCtx.createSubcontext( dn, attributes );
393                 }
394                 catch ( NamingException JavaDoc ne )
395                 {
396                     this.namingException = ne;
397                 }
398             }
399
400
401             public NamingException JavaDoc getException()
402             {
403                 return this.namingException;
404             }
405
406
407             public Object JavaDoc getResult()
408             {
409                 return null;
410             }
411
412
413             public void reset()
414             {
415                 this.namingException = null;
416             }
417         };
418         this.checkConnectionAndRunAndMonitor( runnable, monitor );
419
420         if ( runnable.getException() != null )
421         {
422             throw runnable.getException();
423         }
424     }
425
426
427     void destroySubcontext( final String JavaDoc dn, final Control JavaDoc[] controls, final ExtendedProgressMonitor monitor )
428         throws NamingException JavaDoc
429     {
430
431         InnerRunnable runnable = new InnerRunnable()
432         {
433             private NamingException JavaDoc namingException = null;
434
435
436             public void run()
437             {
438                 try
439                 {
440                     LdapContext JavaDoc modCtx = context.newInstance( controls );
441                     modCtx.addToEnvironment( Context.REFERRAL, "throw" ); //$NON-NLS-1$
442

443                     modCtx.destroySubcontext( dn );
444                 }
445                 catch ( NamingException JavaDoc ne )
446                 {
447                     this.namingException = ne;
448                 }
449             }
450
451
452             public NamingException JavaDoc getException()
453             {
454                 return this.namingException;
455             }
456
457
458             public Object JavaDoc getResult()
459             {
460                 return null;
461             }
462
463
464             public void reset()
465             {
466                 this.namingException = null;
467             }
468         };
469         this.checkConnectionAndRunAndMonitor( runnable, monitor );
470
471         if ( runnable.getException() != null )
472         {
473             throw runnable.getException();
474         }
475     }
476
477
478     private void doConnect( final ExtendedProgressMonitor monitor ) throws NamingException JavaDoc
479     {
480
481         this.context = null;
482         this.isConnected = true;
483
484         InnerRunnable runnable = new InnerRunnable()
485         {
486             private NamingException JavaDoc namingException = null;
487
488
489             public void run()
490             {
491                 try
492                 {
493                     context = new InitialLdapContext JavaDoc( environment, connCtls );
494
495                     if ( useStartTLS )
496                     {
497                         try
498                         {
499                             StartTlsResponse JavaDoc tls = ( StartTlsResponse JavaDoc ) context
500                                 .extendedOperation( new StartTlsRequest JavaDoc() );
501                             tls.setHostnameVerifier( new HostnameVerifier()
502                             {
503                                 public boolean verify( String JavaDoc arg0, SSLSession arg1 )
504                                 {
505                                     return true;
506                                 }
507                             } );
508                             tls.negotiate( new DummySSLSocketFactory() );
509
510                         }
511                         catch ( Exception JavaDoc e )
512                         {
513                             this.namingException = new NamingException JavaDoc( e.getMessage() != null ? e.getMessage()
514                                 : "Error while establishing TLS session" ); //$NON-NLS-1$
515
this.namingException.setRootCause( e );
516                             context.close();
517                         }
518                     }
519
520                 }
521                 catch ( NamingException JavaDoc ne )
522                 {
523                     this.namingException = ne;
524                 }
525             }
526
527
528             public NamingException JavaDoc getException()
529             {
530                 return this.namingException;
531             }
532
533
534             public Object JavaDoc getResult()
535             {
536                 return null;
537             }
538
539
540             public void reset()
541             {
542                 this.namingException = null;
543             }
544         };
545         this.runAndMonitor( runnable, monitor );
546
547         if ( runnable.getException() != null )
548         {
549             throw runnable.getException();
550         }
551         else if ( this.context != null )
552         {
553             // all OK
554
}
555         else
556         {
557             throw new NamingException JavaDoc( "???" ); //$NON-NLS-1$
558
}
559     }
560
561
562     private void doBind( final ExtendedProgressMonitor monitor ) throws NamingException JavaDoc
563     {
564
565         if ( this.context != null && this.isConnected )
566         {
567
568             InnerRunnable runnable = new InnerRunnable()
569             {
570                 private NamingException JavaDoc namingException = null;
571
572
573                 public void run()
574                 {
575                     try
576                     {
577                         context.removeFromEnvironment( Context.SECURITY_AUTHENTICATION );
578                         context.removeFromEnvironment( Context.SECURITY_PRINCIPAL );
579                         context.removeFromEnvironment( Context.SECURITY_CREDENTIALS );
580
581                         context.addToEnvironment( Context.SECURITY_PRINCIPAL, principal );
582                         context.addToEnvironment( Context.SECURITY_CREDENTIALS, credentials );
583                         context.addToEnvironment( Context.SECURITY_AUTHENTICATION, authMethod );
584
585                         context.reconnect( context.getConnectControls() );
586                     }
587                     catch ( NamingException JavaDoc ne )
588                     {
589                         this.namingException = ne;
590                     }
591                 }
592
593
594                 public NamingException JavaDoc getException()
595                 {
596                     return this.namingException;
597                 }
598
599
600                 public Object JavaDoc getResult()
601                 {
602                     return null;
603                 }
604
605
606                 public void reset()
607                 {
608                     this.namingException = null;
609                 }
610             };
611             this.runAndMonitor( runnable, monitor );
612
613             if ( runnable.getException() != null )
614             {
615                 throw runnable.getException();
616             }
617             else if ( this.context != null )
618             {
619                 // all OK
620
}
621             else
622             {
623                 throw new NamingException JavaDoc( "???" ); //$NON-NLS-1$
624
}
625
626         }
627         else
628         {
629             throw new NamingException JavaDoc( BrowserCoreMessages.model__no_connection );
630         }
631     }
632
633
634     private void checkConnectionAndRunAndMonitor( final InnerRunnable runnable, final ExtendedProgressMonitor monitor )
635         throws NamingException JavaDoc
636     {
637
638         // System.out.println("Context: " + this.context);
639

640         // check connection
641
if ( !this.isConnected || this.context == null )
642         {
643             this.doConnect( monitor );
644             this.doBind( monitor );
645         }
646         if ( this.context == null )
647         {
648             throw new NamingException JavaDoc( BrowserCoreMessages.model__no_connection );
649         }
650
651         // loop for reconnection
652
for ( int i = 0; i <= 1; i++ )
653         {
654
655             this.runAndMonitor( runnable, monitor );
656
657             // check reconnection
658
if ( i == 0
659                 && runnable.getException() != null
660                 && ( ( runnable.getException() instanceof CommunicationException JavaDoc )
661                     || ( runnable.getException() instanceof ServiceUnavailableException JavaDoc ) || ( runnable.getException() instanceof InsufficientResourcesException JavaDoc ) ) )
662             {
663
664                 this.doConnect( monitor );
665                 this.doBind( monitor );
666                 runnable.reset();
667             }
668             else
669             {
670                 break;
671             }
672         }
673     }
674
675
676     private void runAndMonitor( final InnerRunnable runnable, final ExtendedProgressMonitor monitor )
677         throws CancelException
678     {
679
680         if ( !monitor.isCanceled() )
681         {
682
683             // monitor
684
ExtendedProgressMonitor.CancelListener listener = new ExtendedProgressMonitor.CancelListener()
685             {
686                 public void cancelRequested( ExtendedProgressMonitor.CancelEvent event )
687                 {
688                     if ( monitor.isCanceled() )
689                     {
690                         if ( jobThread.isAlive() )
691                         {
692                             jobThread.interrupt();
693                         }
694                         if ( context != null )
695                         {
696                             try
697                             {
698                                 context.close();
699                             }
700                             catch ( NamingException JavaDoc ne )
701                             {
702                             }
703                             isConnected = false;
704                             context = null;
705                             System.gc();
706                         }
707                         isConnected = false;
708                     }
709                 }
710             };
711             monitor.addCancelListener( listener );
712             this.jobThread = Thread.currentThread();
713
714             // run
715
try
716             {
717
718                 // try {
719
// Thread.sleep(5000);
720
// } catch (InterruptedException e) {
721
// System.out.println(System.currentTimeMillis() + ": sleep
722
// interrupted!");
723
// }
724
// System.out.println(System.currentTimeMillis() + ": " +
725
// runnable);
726

727                 runnable.run();
728             }
729             finally
730             {
731                 monitor.removeCancelListener( listener );
732                 this.jobThread = null;
733             }
734
735             if ( monitor.isCanceled() )
736             {
737                 throw new CancelException();
738             }
739
740         }
741     }
742
743     interface InnerRunnable extends Runnable JavaDoc
744     {
745         public NamingException JavaDoc getException();
746
747
748         public Object JavaDoc getResult();
749
750
751         public void reset();
752     }
753
754 }
755
Popular Tags