KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > ldap > server > jndi > ServerDirContext


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

17 package org.apache.ldap.server.jndi;
18
19
20 import org.apache.ldap.common.filter.*;
21 import org.apache.ldap.common.name.LdapName;
22 import org.apache.ldap.common.util.NamespaceTools;
23 import org.apache.ldap.server.PartitionNexus;
24 import org.apache.ldap.server.authn.LdapPrincipal;
25
26 import javax.naming.*;
27 import javax.naming.directory.*;
28 import javax.naming.ldap.Control JavaDoc;
29 import javax.naming.spi.DirStateFactory JavaDoc;
30 import javax.naming.spi.DirectoryManager JavaDoc;
31 import java.io.IOException JavaDoc;
32 import java.io.Serializable JavaDoc;
33 import java.text.ParseException JavaDoc;
34 import java.util.Hashtable JavaDoc;
35
36
37 /**
38  * The DirContext implementation for the Server Side JNDI LDAP provider.
39  *
40  * @author <a HREF="mailto:dev@directory.apache.org">Apache Directory Project</a>
41  * @version $Rev: 169198 $
42  */

43 public abstract class ServerDirContext extends ServerContext implements DirContext
44 {
45     
46     
47     // ------------------------------------------------------------------------
48
// Constructors
49
// ------------------------------------------------------------------------
50

51     /**
52      * Creates a new ServerDirContext by reading the PROVIDER_URL to resolve the
53      * distinguished name for this context.
54      *
55      * @param nexusProxy the proxy to the backend nexus
56      * @param env the environment used for this context
57      * @throws NamingException if something goes wrong
58      */

59     public ServerDirContext( PartitionNexus nexusProxy, Hashtable JavaDoc env ) throws NamingException
60     {
61         super( nexusProxy, env );
62     }
63
64
65     /**
66      * Creates a new ServerDirContext with a distinguished name which is used to
67      * set the PROVIDER_URL to the distinguished name for this context.
68      *
69      * @param principal the principal which is propagated
70      * @param nexusProxy the intercepting proxy to the nexus
71      * @param env the environment properties used by this context
72      * @param dn the distinguished name of this context
73      */

74     protected ServerDirContext( LdapPrincipal principal, PartitionNexus nexusProxy, Hashtable JavaDoc env, Name dn )
75     {
76         super( principal, nexusProxy, env, dn );
77     }
78
79
80     // ------------------------------------------------------------------------
81
// DirContext Implementations
82
// ------------------------------------------------------------------------
83

84
85     /**
86      * @see javax.naming.directory.DirContext#getAttributes(java.lang.String)
87      */

88     public Attributes getAttributes( String JavaDoc name ) throws NamingException
89     {
90         return getAttributes( new LdapName( name ) );
91     }
92     
93
94     /**
95      * @see javax.naming.directory.DirContext#getAttributes(javax.naming.Name)
96      */

97     public Attributes getAttributes( Name name ) throws NamingException
98     {
99         return getNexusProxy().lookup( buildTarget( name ) );
100     }
101
102
103     /**
104      * @see javax.naming.directory.DirContext#getAttributes(java.lang.String,
105      * java.lang.String[])
106      */

107     public Attributes getAttributes( String JavaDoc name, String JavaDoc[] attrIds ) throws NamingException
108     {
109         return getAttributes( new LdapName( name ), attrIds );
110     }
111
112
113     /**
114      * @see javax.naming.directory.DirContext#getAttributes(javax.naming.Name,
115      * java.lang.String[])
116      */

117     public Attributes getAttributes( Name name, String JavaDoc[] attrIds ) throws NamingException
118     {
119         return getNexusProxy().lookup( buildTarget( name ), attrIds );
120     }
121     
122
123     /**
124      * @see javax.naming.directory.DirContext#modifyAttributes(java.lang.String,
125      * int, javax.naming.directory.Attributes)
126      */

127     public void modifyAttributes( String JavaDoc name, int modOp, Attributes attrs ) throws NamingException
128     {
129         modifyAttributes( new LdapName( name ), modOp, attrs );
130     }
131
132
133     /**
134      * @see javax.naming.directory.DirContext#modifyAttributes(
135      * javax.naming.Name,int, javax.naming.directory.Attributes)
136      */

137     public void modifyAttributes( Name name, int modOp, Attributes attrs ) throws NamingException
138     {
139         getNexusProxy().modify( buildTarget( name ), modOp, attrs );
140     }
141
142
143     /**
144      * @see javax.naming.directory.DirContext#modifyAttributes(java.lang.String,
145      * javax.naming.directory.ModificationItem[])
146      */

147     public void modifyAttributes( String JavaDoc name, ModificationItem[] mods ) throws NamingException
148     {
149         modifyAttributes( new LdapName( name ), mods );
150     }
151
152
153     /**
154      * @see javax.naming.directory.DirContext#modifyAttributes(
155      * javax.naming.Name, javax.naming.directory.ModificationItem[])
156      */

157     public void modifyAttributes( Name name, ModificationItem[] mods ) throws NamingException
158     {
159         getNexusProxy().modify( buildTarget( name ), mods );
160     }
161     
162
163     /**
164      * @see javax.naming.directory.DirContext#bind(java.lang.String,
165      * java.lang.Object, javax.naming.directory.Attributes)
166      */

167     public void bind( String JavaDoc name, Object JavaDoc obj, Attributes attrs ) throws NamingException
168     {
169         bind( new LdapName( name ), obj, attrs );
170     }
171
172
173     /**
174      * @see javax.naming.directory.DirContext#bind(javax.naming.Name,
175      * java.lang.Object, javax.naming.directory.Attributes)
176      */

177     public void bind( Name name, Object JavaDoc obj, Attributes attrs ) throws NamingException
178     {
179         if ( null == obj && null == attrs )
180         {
181             throw new NamingException( "Both obj and attrs args are null. "
182                 + "At least one of these parameters must not be null." );
183         }
184
185         // A null attrs defaults this to the Context.bind() operation
186
if ( null == attrs )
187         {
188             super.bind( name, obj );
189
190             return;
191         }
192
193         // No object binding so we just add the attributes
194
if ( null == obj )
195         {
196             Attributes clone = ( Attributes ) attrs.clone();
197
198             Name target = buildTarget( name );
199
200             getNexusProxy().add( target.toString(), target, clone );
201
202             return;
203         }
204
205         // First, use state factories to do a transformation
206
DirStateFactory.Result JavaDoc res = DirectoryManager.getStateToBind( obj, name, this, getEnvironment(), attrs );
207
208         Attributes outAttrs = res.getAttributes();
209
210         if ( outAttrs != attrs )
211         {
212             Name target = buildTarget( name );
213
214             Attributes attributes = ( Attributes ) attrs.clone();
215
216             if ( outAttrs != null && outAttrs.size() > 0 )
217             {
218                 NamingEnumeration list = outAttrs.getAll();
219
220                 while ( list.hasMore() )
221                 {
222                     attributes.put( ( Attribute ) list.next() );
223                 }
224             }
225
226             getNexusProxy().add( target.toString(), target, attributes );
227
228             return;
229         }
230
231         // Check for Referenceable
232
if ( obj instanceof Referenceable )
233         {
234             obj = ( ( Referenceable ) obj ).getReference();
235
236             throw new NamingException( "Do not know how to store Referenceables yet!" );
237         }
238
239         // Store different formats
240
if ( obj instanceof Reference )
241         {
242             // Store as ref and add outAttrs
243

244             throw new NamingException( "Do not know how to store References yet!" );
245         }
246         else if ( obj instanceof Serializable JavaDoc )
247         {
248             // Serialize and add outAttrs
249

250             Attributes attributes = ( Attributes ) attrs.clone();
251
252             if ( outAttrs != null && outAttrs.size() > 0 )
253             {
254                 NamingEnumeration list = outAttrs.getAll();
255
256                 while ( list.hasMore() )
257                 {
258                     attributes.put( ( Attribute ) list.next() );
259                 }
260             }
261
262             Name target = buildTarget( name );
263
264             // Serialize object into entry attributes and add it.
265

266             JavaLdapSupport.serialize( attributes, obj );
267
268             getNexusProxy().add( target.toString(), target, attributes );
269         }
270         else if ( obj instanceof DirContext )
271         {
272             // Grab attributes and merge with outAttrs
273

274             Attributes attributes = ( ( DirContext ) obj ).getAttributes( "" );
275
276             if ( outAttrs != null && outAttrs.size() > 0 )
277             {
278                 NamingEnumeration list = outAttrs.getAll();
279
280                 while ( list.hasMore() )
281                 {
282                     attributes.put( ( Attribute ) list.next() );
283                 }
284             }
285
286             Name target = buildTarget( name );
287
288             getNexusProxy().add( target.toString(), target, attributes );
289         }
290         else
291         {
292             throw new NamingException( "Can't find a way to bind: " + obj );
293         }
294     }
295
296
297     /**
298      * @see javax.naming.directory.DirContext#rebind(java.lang.String,
299      * java.lang.Object, javax.naming.directory.Attributes)
300      */

301     public void rebind( String JavaDoc name, Object JavaDoc obj, Attributes attrs ) throws NamingException
302     {
303         rebind( new LdapName( name ), obj, attrs );
304     }
305
306
307     /**
308      * @see javax.naming.directory.DirContext#rebind(javax.naming.Name,
309      * java.lang.Object, javax.naming.directory.Attributes)
310      */

311     public void rebind( Name name, Object JavaDoc obj, Attributes attrs ) throws NamingException
312     {
313         Name target = buildTarget( name );
314
315         if ( getNexusProxy().hasEntry( target ) )
316         {
317             getNexusProxy().delete( target );
318         }
319
320         bind( name, obj, attrs );
321     }
322
323
324     /**
325      * @see javax.naming.directory.DirContext#createSubcontext(java.lang.String,
326      * javax.naming.directory.Attributes)
327      */

328     public DirContext createSubcontext( String JavaDoc name, Attributes attrs ) throws NamingException
329     {
330         return createSubcontext( new LdapName( name ), attrs );
331     }
332
333
334     /**
335      * @see javax.naming.directory.DirContext#createSubcontext(
336      * javax.naming.Name, javax.naming.directory.Attributes)
337      */

338     public DirContext createSubcontext( Name name, Attributes attrs ) throws NamingException
339     {
340         if ( null == attrs )
341         {
342             return ( DirContext ) super.createSubcontext( name );
343         }
344
345         LdapName target = buildTarget( name );
346
347         String JavaDoc rdn = name.get( name.size() - 1 );
348
349         String JavaDoc rdnAttribute = NamespaceTools.getRdnAttribute( rdn );
350
351         String JavaDoc rdnValue = NamespaceTools.getRdnValue( rdn );
352
353         // Clone the attributes and add the Rdn attributes
354
Attributes attributes = ( Attributes ) attrs.clone();
355
356         boolean doRdnPut = attributes.get( rdnAttribute ) == null;
357
358         doRdnPut = doRdnPut || attributes.get( rdnAttribute ).size() == 0;
359
360         doRdnPut = doRdnPut || ! attributes.get( rdnAttribute ).contains( rdnValue );
361
362         if ( doRdnPut )
363         {
364             attributes.put( rdnAttribute, rdnValue );
365         }
366
367         // Add the new context to the server which as a side effect adds
368
getNexusProxy().add( target.toString(), target, attributes );
369
370         // Initialize the new context
371
ServerLdapContext ctx = new ServerLdapContext( getPrincipal(), getNexusProxy(), getEnvironment(), target );
372
373         Control JavaDoc [] controls = ( ( ServerLdapContext ) this ).getRequestControls();
374
375         if ( controls != null )
376         {
377             controls = ( Control JavaDoc[] ) controls.clone();
378         }
379         else
380         {
381             controls = new Control JavaDoc[0];
382         }
383
384         ctx.setRequestControls( controls );
385
386         return ctx;
387     }
388
389
390     /**
391      * Presently unsupported operation!
392      */

393     public DirContext getSchema( Name name ) throws NamingException
394     {
395         throw new UnsupportedOperationException JavaDoc();
396     }
397
398
399     /**
400      * Presently unsupported operation!
401      */

402     public DirContext getSchema( String JavaDoc name ) throws NamingException
403     {
404         throw new UnsupportedOperationException JavaDoc();
405     }
406
407
408     /**
409      * Presently unsupported operation!
410      */

411     public DirContext getSchemaClassDefinition( Name name ) throws NamingException
412     {
413         throw new UnsupportedOperationException JavaDoc();
414     }
415
416
417     /**
418      * Presently unsupported operation!
419      */

420     public DirContext getSchemaClassDefinition( String JavaDoc name ) throws NamingException
421     {
422         throw new UnsupportedOperationException JavaDoc();
423     }
424
425
426     // ------------------------------------------------------------------------
427
// Search Operation Implementations
428
// ------------------------------------------------------------------------
429

430
431     /**
432      * @see javax.naming.directory.DirContext#search(java.lang.String,
433      * javax.naming.directory.Attributes)
434      */

435     public NamingEnumeration search( String JavaDoc name, Attributes matchingAttributes )
436             throws NamingException
437     {
438         return search( new LdapName( name ), matchingAttributes, null );
439     }
440
441
442     /**
443      * @see javax.naming.directory.DirContext#search(javax.naming.Name,
444      * javax.naming.directory.Attributes)
445      */

446     public NamingEnumeration search( Name name, Attributes matchingAttributes )
447             throws NamingException
448     {
449         return search( name, matchingAttributes, null );
450     }
451
452
453     /**
454      * @see javax.naming.directory.DirContext#search(java.lang.String,
455      * javax.naming.directory.Attributes, java.lang.String[])
456      */

457     public NamingEnumeration search( String JavaDoc name, Attributes matchingAttributes, String JavaDoc[] attributesToReturn ) throws NamingException
458     {
459         return search( new LdapName( name ), matchingAttributes, attributesToReturn );
460     }
461
462
463     /**
464      * @see javax.naming.directory.DirContext#search(javax.naming.Name,
465      * javax.naming.directory.Attributes, java.lang.String[])
466      */

467     public NamingEnumeration search( Name name, Attributes matchingAttributes, String JavaDoc[] attributesToReturn ) throws NamingException
468     {
469         SearchControls ctls = new SearchControls();
470
471         LdapName target = buildTarget( name );
472
473         // If we need to return specific attributes add em to the SearchControls
474
if ( null != attributesToReturn )
475         {
476             ctls.setReturningAttributes( attributesToReturn );
477         }
478
479         // If matchingAttributes is null/empty use a match for everything filter
480
if ( null == matchingAttributes || matchingAttributes.size() <= 0 )
481         {
482             PresenceNode filter = new PresenceNode( "objectClass" );
483
484             return getNexusProxy().search( target , getEnvironment(), filter, ctls );
485         }
486
487         /*
488          * Go through the set of attributes using each attribute value pair as
489          * an attribute value assertion within one big AND filter expression.
490          */

491         Attribute attr = null;
492
493         SimpleNode node = null;
494
495         BranchNode filter = new BranchNode( BranchNode.AND );
496
497         NamingEnumeration list = matchingAttributes.getAll();
498
499         // Loop through each attribute value pair
500
while ( list.hasMore() )
501         {
502             attr = ( Attribute ) list.next();
503             
504             /*
505              * According to JNDI if an attribute in the matchingAttributes
506              * list does not have any values then we match for just the presence
507              * of the attribute in the entry
508              */

509             if ( attr.size() == 0 )
510             {
511                 filter.addNode( new PresenceNode( attr.getID() ) );
512
513                 continue;
514             }
515             
516             /*
517              * With 1 or more value we build a set of simple nodes and add them
518              * to the AND node - each attribute value pair is a simple AVA node.
519              */

520             for ( int ii = 0; ii < attr.size(); ii++ )
521             {
522                 Object JavaDoc val = attr.get( ii );
523                 
524                 // Add simpel AVA node if its value is a String
525
if ( val instanceof String JavaDoc )
526                 {
527                     node = new SimpleNode( attr.getID(), ( String JavaDoc ) val, SimpleNode.EQUALITY );
528
529                     filter.addNode( node );
530                 }
531             }
532         }
533
534         return getNexusProxy().search( target , getEnvironment(), filter, ctls );
535     }
536
537
538     /**
539      * @see javax.naming.directory.DirContext#search(java.lang.String,
540      * java.lang.String, javax.naming.directory.SearchControls)
541      */

542     public NamingEnumeration search( String JavaDoc name, String JavaDoc filter, SearchControls cons )
543             throws NamingException
544     {
545         return search( new LdapName( name ), filter, cons );
546     }
547
548
549     /**
550      * @see javax.naming.directory.DirContext#search(javax.naming.Name,
551      * java.lang.String, javax.naming.directory.SearchControls)
552      */

553     public NamingEnumeration search( Name name, String JavaDoc filter, SearchControls cons )
554             throws NamingException
555     {
556         ExprNode filterNode = null;
557
558         LdapName target = buildTarget( name );
559
560         if ( filter == null && getEnvironment().containsKey( "__filter__" ) )
561         {
562             filterNode = ( ExprNode ) getEnvironment().get( "__filter__" );
563         }
564         else
565         {
566             try
567             {
568                 FilterParser parser = new FilterParserImpl();
569
570                 filterNode = parser.parse( filter );
571             }
572             catch ( ParseException JavaDoc pe )
573             {
574                 InvalidSearchFilterException isfe =
575                     new InvalidSearchFilterException (
576                     "Encountered parse exception while parsing the filter: '"
577                     + filter + "'" );
578
579                 isfe.setRootCause( pe );
580
581                 throw isfe;
582             }
583             catch ( IOException JavaDoc ioe )
584             {
585                 NamingException ne = new NamingException(
586                     "Parser failed with IO exception on filter: '"
587                     + filter + "'" );
588                 ne.setRootCause( ioe );
589                 throw ne;
590             }
591         }
592
593         return getNexusProxy().search( target , getEnvironment(), filterNode, cons );
594     }
595
596
597     /**
598      * @see javax.naming.directory.DirContext#search(java.lang.String,
599      * java.lang.String, java.lang.Object[],
600      * javax.naming.directory.SearchControls)
601      */

602     public NamingEnumeration search( String JavaDoc name, String JavaDoc filterExpr,
603         Object JavaDoc[] filterArgs, SearchControls cons ) throws NamingException
604     {
605         return search( new LdapName( name ), filterExpr, filterArgs, cons );
606     }
607
608
609     /**
610      * @see javax.naming.directory.DirContext#search(javax.naming.Name,
611      * java.lang.String, java.lang.Object[],
612      * javax.naming.directory.SearchControls)
613      */

614     public NamingEnumeration search( Name name, String JavaDoc filterExpr, Object JavaDoc[] filterArgs, SearchControls cons ) throws NamingException
615     {
616         int start;
617
618         StringBuffer JavaDoc buf = new StringBuffer JavaDoc( filterExpr );
619         
620         // Scan until we hit the end of the string buffer
621
for ( int ii = 0; ii < buf.length(); ii++ )
622         {
623             // Advance until we hit the start of a variable
624
while ( '{' != buf.charAt( ii ) )
625             {
626                 ii++;
627             }
628             
629             // Record start of variable at '{'
630
start = ii;
631             
632             // Advance to the end of a variable at '}'
633
while ( '}' != buf.charAt( ii ) )
634             {
635                 ii++;
636             }
637             
638             /*
639              * Replace the '{ i }' with the string representation of the value
640              * held in the filterArgs array at index index.
641              */

642             buf.replace( start, ii + 1, filterArgs[ii].toString() );
643         }
644         
645         return search( name, buf.toString(), cons );
646     }
647 }
648
Popular Tags