1 /*
2  * Copyright (c) 1999, 2011, Oracle and/or its affiliates. All rights reserved.
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  *
5  * This code is free software; you can redistribute it and/or modify it
6  * under the terms of the GNU General Public License version 2 only, as
7  * published by the Free Software Foundation.  Oracle designates this
8  * particular file as subject to the "Classpath" exception as provided
9  * by Oracle in the LICENSE file that accompanied this code.
10  *
11  * This code is distributed in the hope that it will be useful, but WITHOUT
12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
14  * version 2 for more details (a copy is included in the LICENSE file that
15  * accompanied this code).
16  *
17  * You should have received a copy of the GNU General Public License version
18  * 2 along with this work; if not, write to the Free Software Foundation,
19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20  *
21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22  * or visit www.oracle.com if you need additional information or have any
23  * questions.
24  */
25 
26 package com.sun.jndi.toolkit.ctx;
27 
28 import java.util.Hashtable;
29 
30 import javax.naming.*;
31 import javax.naming.directory.*;
32 import javax.naming.spi.DirectoryManager;
33 
34 /*
35  * Inherit from AtomicContext so that subclasses of PartialCompositeDirContext
36  * can get the ns methods defined in subclasses of PartialCompositeContext.
37  *
38  * Direct subclasses of DirContext should provide implementations for
39  * the p_ abstract DirContext methods and override the p_ Context methods
40  * (not abstract anymore because they are overridden by ComponentContext
41  * (the superclass of AtomicContext)).
42  *
43  * @author Rosanna Lee
44  */
45 
46 public abstract class PartialCompositeDirContext
47         extends AtomicContext implements DirContext {
48 
PartialCompositeDirContext()49     protected PartialCompositeDirContext() {
50         _contextType = _PARTIAL;
51     }
52 
53 // ------ Abstract methods whose implementation come from subclasses
54 
55      /* Equivalent to DirContext methods */
p_getAttributes(Name name, String[] attrIds, Continuation cont)56      protected abstract Attributes p_getAttributes(Name name, String[] attrIds,
57                                                      Continuation cont)
58          throws NamingException;
59 
p_modifyAttributes(Name name, int mod_op, Attributes attrs, Continuation cont)60      protected abstract void p_modifyAttributes(Name name, int mod_op,
61                                                 Attributes attrs,
62                                                 Continuation cont)
63          throws NamingException;
64 
p_modifyAttributes(Name name, ModificationItem[] mods, Continuation cont)65      protected abstract void p_modifyAttributes(Name name,
66                                                 ModificationItem[] mods,
67                                                 Continuation cont)
68          throws NamingException;
69 
p_bind(Name name, Object obj, Attributes attrs, Continuation cont)70      protected abstract void p_bind(Name name, Object obj,
71                                     Attributes attrs,
72                                     Continuation cont)
73          throws NamingException;
74 
p_rebind(Name name, Object obj, Attributes attrs, Continuation cont)75      protected abstract void p_rebind(Name name, Object obj,
76                                       Attributes attrs,
77                                       Continuation cont)
78          throws NamingException;
79 
p_createSubcontext(Name name, Attributes attrs, Continuation cont)80      protected abstract DirContext p_createSubcontext(Name name,
81                                                      Attributes attrs,
82                                                      Continuation cont)
83          throws NamingException;
84 
p_search( Name name, Attributes matchingAttributes, String[] attributesToReturn, Continuation cont)85      protected abstract NamingEnumeration<SearchResult> p_search(
86                             Name name,
87                             Attributes matchingAttributes,
88                             String[] attributesToReturn,
89                             Continuation cont)
90          throws NamingException;
91 
p_search( Name name, String filter, SearchControls cons, Continuation cont)92      protected abstract NamingEnumeration<SearchResult> p_search(
93                             Name name,
94                             String filter,
95                             SearchControls cons,
96                             Continuation cont)
97          throws NamingException;
98 
p_search( Name name, String filterExpr, Object[] filterArgs, SearchControls cons, Continuation cont)99      protected abstract NamingEnumeration<SearchResult> p_search(
100                             Name name,
101                             String filterExpr,
102                             Object[] filterArgs,
103                             SearchControls cons,
104                             Continuation cont)
105          throws NamingException;
106 
p_getSchema(Name name, Continuation cont)107      protected abstract DirContext p_getSchema(Name name, Continuation cont)
108          throws NamingException;
109 
p_getSchemaClassDefinition(Name name, Continuation cont)110      protected abstract DirContext p_getSchemaClassDefinition(Name name,
111                                                              Continuation cont)
112          throws NamingException;
113 
114 // ------ implementation for DirContext methods using
115 // ------ corresponding p_ methods
116 
getAttributes(String name)117     public Attributes getAttributes(String name)
118             throws NamingException {
119         return getAttributes(name, null);
120     }
121 
getAttributes(Name name)122     public Attributes getAttributes(Name name)
123             throws NamingException {
124         return getAttributes(name, null);
125     }
126 
getAttributes(String name, String[] attrIds)127     public Attributes getAttributes(String name, String[] attrIds)
128             throws NamingException {
129         return getAttributes(new CompositeName(name), attrIds);
130     }
131 
getAttributes(Name name, String[] attrIds)132     public Attributes getAttributes(Name name, String[] attrIds)
133             throws NamingException {
134         PartialCompositeDirContext ctx = this;
135         Hashtable<?,?> env = p_getEnvironment();
136         Continuation cont = new Continuation(name, env);
137         Attributes answer;
138         Name nm = name;
139 
140         try {
141             answer = ctx.p_getAttributes(nm, attrIds, cont);
142             while (cont.isContinue()) {
143                 nm = cont.getRemainingName();
144                 ctx = getPCDirContext(cont);
145                 answer = ctx.p_getAttributes(nm, attrIds, cont);
146             }
147         } catch (CannotProceedException e) {
148             DirContext cctx = DirectoryManager.getContinuationDirContext(e);
149             answer = cctx.getAttributes(e.getRemainingName(), attrIds);
150         }
151         return answer;
152     }
153 
modifyAttributes(String name, int mod_op, Attributes attrs)154     public void modifyAttributes(String name, int mod_op, Attributes attrs)
155             throws NamingException {
156         modifyAttributes(new CompositeName(name), mod_op, attrs);
157     }
158 
modifyAttributes(Name name, int mod_op, Attributes attrs)159     public void modifyAttributes(Name name, int mod_op, Attributes attrs)
160             throws NamingException {
161         PartialCompositeDirContext ctx = this;
162         Hashtable<?,?> env = p_getEnvironment();
163         Continuation cont = new Continuation(name, env);
164         Name nm = name;
165 
166         try {
167             ctx.p_modifyAttributes(nm, mod_op, attrs, cont);
168             while (cont.isContinue()) {
169                 nm = cont.getRemainingName();
170                 ctx = getPCDirContext(cont);
171                 ctx.p_modifyAttributes(nm, mod_op, attrs, cont);
172             }
173         } catch (CannotProceedException e) {
174             DirContext cctx = DirectoryManager.getContinuationDirContext(e);
175             cctx.modifyAttributes(e.getRemainingName(), mod_op, attrs);
176         }
177     }
178 
modifyAttributes(String name, ModificationItem[] mods)179     public void modifyAttributes(String name, ModificationItem[] mods)
180             throws NamingException {
181         modifyAttributes(new CompositeName(name), mods);
182     }
183 
modifyAttributes(Name name, ModificationItem[] mods)184     public void modifyAttributes(Name name, ModificationItem[] mods)
185             throws NamingException {
186         PartialCompositeDirContext ctx = this;
187         Hashtable<?,?> env = p_getEnvironment();
188         Continuation cont = new Continuation(name, env);
189         Name nm = name;
190 
191         try {
192             ctx.p_modifyAttributes(nm, mods, cont);
193             while (cont.isContinue()) {
194                 nm = cont.getRemainingName();
195                 ctx = getPCDirContext(cont);
196                 ctx.p_modifyAttributes(nm, mods, cont);
197             }
198         } catch (CannotProceedException e) {
199             DirContext cctx = DirectoryManager.getContinuationDirContext(e);
200             cctx.modifyAttributes(e.getRemainingName(), mods);
201         }
202     }
203 
bind(String name, Object obj, Attributes attrs)204     public void bind(String name, Object obj, Attributes attrs)
205             throws NamingException {
206         bind(new CompositeName(name), obj, attrs);
207     }
208 
bind(Name name, Object obj, Attributes attrs)209     public void bind(Name name, Object obj, Attributes attrs)
210             throws NamingException {
211         PartialCompositeDirContext ctx = this;
212         Hashtable<?,?> env = p_getEnvironment();
213         Continuation cont = new Continuation(name, env);
214         Name nm = name;
215 
216         try {
217             ctx.p_bind(nm, obj, attrs, cont);
218             while (cont.isContinue()) {
219                 nm = cont.getRemainingName();
220                 ctx = getPCDirContext(cont);
221                 ctx.p_bind(nm, obj, attrs, cont);
222             }
223         } catch (CannotProceedException e) {
224             DirContext cctx = DirectoryManager.getContinuationDirContext(e);
225             cctx.bind(e.getRemainingName(), obj, attrs);
226         }
227     }
228 
rebind(String name, Object obj, Attributes attrs)229     public void rebind(String name, Object obj, Attributes attrs)
230             throws NamingException {
231         rebind(new CompositeName(name), obj, attrs);
232     }
233 
rebind(Name name, Object obj, Attributes attrs)234     public void rebind(Name name, Object obj, Attributes attrs)
235             throws NamingException {
236         PartialCompositeDirContext ctx = this;
237         Hashtable<?,?> env = p_getEnvironment();
238         Continuation cont = new Continuation(name, env);
239         Name nm = name;
240 
241         try {
242             ctx.p_rebind(nm, obj, attrs, cont);
243             while (cont.isContinue()) {
244                 nm = cont.getRemainingName();
245                 ctx = getPCDirContext(cont);
246                 ctx.p_rebind(nm, obj, attrs, cont);
247             }
248         } catch (CannotProceedException e) {
249             DirContext cctx = DirectoryManager.getContinuationDirContext(e);
250             cctx.rebind(e.getRemainingName(), obj, attrs);
251         }
252     }
253 
createSubcontext(String name, Attributes attrs)254     public DirContext createSubcontext(String name, Attributes attrs)
255             throws NamingException {
256         return createSubcontext(new CompositeName(name), attrs);
257     }
258 
createSubcontext(Name name, Attributes attrs)259     public DirContext createSubcontext(Name name, Attributes attrs)
260             throws NamingException {
261         PartialCompositeDirContext ctx = this;
262         Hashtable<?,?> env = p_getEnvironment();
263         Continuation cont = new Continuation(name, env);
264         DirContext answer;
265         Name nm = name;
266 
267         try {
268             answer = ctx.p_createSubcontext(nm, attrs, cont);
269             while (cont.isContinue()) {
270                 nm = cont.getRemainingName();
271                 ctx = getPCDirContext(cont);
272                 answer = ctx.p_createSubcontext(nm, attrs, cont);
273             }
274         } catch (CannotProceedException e) {
275             DirContext cctx = DirectoryManager.getContinuationDirContext(e);
276             answer = cctx.createSubcontext(e.getRemainingName(), attrs);
277         }
278         return answer;
279     }
280 
281     public NamingEnumeration<SearchResult>
search(String name, Attributes matchingAttributes)282         search(String name, Attributes matchingAttributes)
283         throws NamingException
284     {
285         return search(name, matchingAttributes, null);
286     }
287 
288     public NamingEnumeration<SearchResult>
search(Name name, Attributes matchingAttributes)289         search(Name name, Attributes matchingAttributes)
290         throws NamingException
291     {
292         return search(name, matchingAttributes, null);
293     }
294 
295     public NamingEnumeration<SearchResult>
search(String name, Attributes matchingAttributes, String[] attributesToReturn)296         search(String name,
297                Attributes matchingAttributes,
298                String[] attributesToReturn)
299         throws NamingException
300     {
301         return search(new CompositeName(name),
302                       matchingAttributes, attributesToReturn);
303     }
304 
305     public NamingEnumeration<SearchResult>
search(Name name, Attributes matchingAttributes, String[] attributesToReturn)306         search(Name name,
307                Attributes matchingAttributes,
308                String[] attributesToReturn)
309         throws NamingException
310     {
311 
312         PartialCompositeDirContext ctx = this;
313         Hashtable<?,?> env = p_getEnvironment();
314         Continuation cont = new Continuation(name, env);
315         NamingEnumeration<SearchResult> answer;
316         Name nm = name;
317 
318         try {
319             answer = ctx.p_search(nm, matchingAttributes,
320                                   attributesToReturn, cont);
321             while (cont.isContinue()) {
322                 nm = cont.getRemainingName();
323                 ctx = getPCDirContext(cont);
324                 answer = ctx.p_search(nm, matchingAttributes,
325                                       attributesToReturn, cont);
326             }
327         } catch (CannotProceedException e) {
328             DirContext cctx = DirectoryManager.getContinuationDirContext(e);
329             answer = cctx.search(e.getRemainingName(), matchingAttributes,
330                                  attributesToReturn);
331         }
332         return answer;
333     }
334 
335     public NamingEnumeration<SearchResult>
search(String name, String filter, SearchControls cons)336         search(String name,
337                String filter,
338                SearchControls cons)
339         throws NamingException
340     {
341         return search(new CompositeName(name), filter, cons);
342     }
343 
344     public NamingEnumeration<SearchResult>
search(Name name, String filter, SearchControls cons)345         search(Name name,
346                String filter,
347                SearchControls cons)
348         throws NamingException
349     {
350 
351         PartialCompositeDirContext ctx = this;
352         Hashtable<?,?> env = p_getEnvironment();
353         Continuation cont = new Continuation(name, env);
354         NamingEnumeration<SearchResult> answer;
355         Name nm = name;
356 
357         try {
358             answer = ctx.p_search(nm, filter, cons, cont);
359             while (cont.isContinue()) {
360                 nm = cont.getRemainingName();
361                 ctx = getPCDirContext(cont);
362                 answer = ctx.p_search(nm, filter, cons, cont);
363             }
364         } catch (CannotProceedException e) {
365             DirContext cctx = DirectoryManager.getContinuationDirContext(e);
366             answer = cctx.search(e.getRemainingName(), filter, cons);
367         }
368         return answer;
369     }
370 
371     public NamingEnumeration<SearchResult>
search(String name, String filterExpr, Object[] filterArgs, SearchControls cons)372         search(String name,
373                String filterExpr,
374                Object[] filterArgs,
375                SearchControls cons)
376         throws NamingException
377     {
378         return search(new CompositeName(name), filterExpr, filterArgs, cons);
379     }
380 
381     public NamingEnumeration<SearchResult>
search(Name name, String filterExpr, Object[] filterArgs, SearchControls cons)382         search(Name name,
383                String filterExpr,
384                Object[] filterArgs,
385                SearchControls cons)
386         throws NamingException
387     {
388 
389         PartialCompositeDirContext ctx = this;
390         Hashtable<?,?> env = p_getEnvironment();
391         Continuation cont = new Continuation(name, env);
392         NamingEnumeration<SearchResult> answer;
393         Name nm = name;
394 
395         try {
396             answer = ctx.p_search(nm, filterExpr, filterArgs, cons, cont);
397             while (cont.isContinue()) {
398                 nm = cont.getRemainingName();
399                 ctx = getPCDirContext(cont);
400                 answer = ctx.p_search(nm, filterExpr, filterArgs, cons, cont);
401             }
402         } catch (CannotProceedException e) {
403             DirContext cctx = DirectoryManager.getContinuationDirContext(e);
404             answer = cctx.search(e.getRemainingName(), filterExpr, filterArgs,
405                                  cons);
406         }
407         return answer;
408     }
409 
getSchema(String name)410     public DirContext getSchema(String name) throws NamingException {
411         return getSchema(new CompositeName(name));
412     }
413 
getSchema(Name name)414     public DirContext getSchema(Name name) throws NamingException {
415         PartialCompositeDirContext ctx = this;
416         Hashtable<?,?> env = p_getEnvironment();
417         Continuation cont = new Continuation(name, env);
418         DirContext answer;
419         Name nm = name;
420 
421         try {
422             answer = ctx.p_getSchema(nm, cont);
423             while (cont.isContinue()) {
424                 nm = cont.getRemainingName();
425                 ctx = getPCDirContext(cont);
426                 answer = ctx.p_getSchema(nm, cont);
427             }
428         } catch (CannotProceedException e) {
429             DirContext cctx = DirectoryManager.getContinuationDirContext(e);
430             answer = cctx.getSchema(e.getRemainingName());
431         }
432         return answer;
433     }
434 
getSchemaClassDefinition(String name)435     public DirContext getSchemaClassDefinition(String name)
436             throws NamingException {
437         return getSchemaClassDefinition(new CompositeName(name));
438     }
439 
getSchemaClassDefinition(Name name)440     public DirContext getSchemaClassDefinition(Name name)
441             throws NamingException {
442         PartialCompositeDirContext ctx = this;
443         Hashtable<?,?> env = p_getEnvironment();
444         Continuation cont = new Continuation(name, env);
445         DirContext answer;
446         Name nm = name;
447 
448         try {
449             answer = ctx.p_getSchemaClassDefinition(nm, cont);
450             while (cont.isContinue()) {
451                 nm = cont.getRemainingName();
452                 ctx = getPCDirContext(cont);
453                 answer = ctx.p_getSchemaClassDefinition(nm, cont);
454             }
455         } catch (CannotProceedException e) {
456             DirContext cctx = DirectoryManager.getContinuationDirContext(e);
457             answer = cctx.getSchemaClassDefinition(e.getRemainingName());
458         }
459         return answer;
460     }
461 
462 // ------ internal method used by PartialCompositeDirContext
463 
464     /**
465      * Retrieves a PartialCompositeDirContext for the resolved object in
466      * cont.  Throws CannotProceedException if not successful.
467      */
getPCDirContext(Continuation cont)468     protected static PartialCompositeDirContext getPCDirContext(Continuation cont)
469             throws NamingException {
470 
471         PartialCompositeContext pctx =
472             PartialCompositeContext.getPCContext(cont);
473 
474         if (!(pctx instanceof PartialCompositeDirContext)) {
475             throw cont.fillInException(
476                     new NotContextException(
477                             "Resolved object is not a DirContext."));
478         }
479 
480         return (PartialCompositeDirContext)pctx;
481     }
482 
483 
484 //------ Compensation for inheriting from AtomicContext
485 
486     /*
487      * Dummy implementations defined here so that direct subclasses
488      * of PartialCompositeDirContext or ComponentDirContext do not
489      * have to provide dummy implementations for these.
490      * Override these for subclasses of AtomicDirContext.
491      */
492 
c_parseComponent(String inputName, Continuation cont)493     protected StringHeadTail c_parseComponent(String inputName,
494         Continuation cont) throws NamingException {
495             OperationNotSupportedException e = new
496                 OperationNotSupportedException();
497             throw cont.fillInException(e);
498         }
499 
a_lookup(String name, Continuation cont)500     protected Object a_lookup(String name, Continuation cont)
501         throws NamingException {
502             OperationNotSupportedException e = new
503                 OperationNotSupportedException();
504             throw cont.fillInException(e);
505         }
506 
a_lookupLink(String name, Continuation cont)507     protected Object a_lookupLink(String name, Continuation cont)
508         throws NamingException {
509             OperationNotSupportedException e = new
510                 OperationNotSupportedException();
511             throw cont.fillInException(e);
512         }
513 
a_list( Continuation cont)514     protected NamingEnumeration<NameClassPair> a_list(
515         Continuation cont) throws NamingException {
516             OperationNotSupportedException e = new
517                 OperationNotSupportedException();
518             throw cont.fillInException(e);
519         }
520 
a_listBindings( Continuation cont)521     protected NamingEnumeration<Binding> a_listBindings(
522         Continuation cont) throws NamingException {
523             OperationNotSupportedException e = new
524                 OperationNotSupportedException();
525             throw cont.fillInException(e);
526         }
527 
a_bind(String name, Object obj, Continuation cont)528     protected void a_bind(String name, Object obj, Continuation cont)
529         throws NamingException {
530             OperationNotSupportedException e = new
531                 OperationNotSupportedException();
532             throw cont.fillInException(e);
533         }
534 
a_rebind(String name, Object obj, Continuation cont)535     protected void a_rebind(String name, Object obj, Continuation cont)
536         throws NamingException {
537             OperationNotSupportedException e = new
538                 OperationNotSupportedException();
539             throw cont.fillInException(e);
540         }
541 
a_unbind(String name, Continuation cont)542     protected void a_unbind(String name, Continuation cont)
543         throws NamingException {
544             OperationNotSupportedException e = new
545                 OperationNotSupportedException();
546             throw cont.fillInException(e);
547         }
548 
a_destroySubcontext(String name, Continuation cont)549     protected void a_destroySubcontext(String name, Continuation cont)
550         throws NamingException {
551             OperationNotSupportedException e = new
552                 OperationNotSupportedException();
553             throw cont.fillInException(e);
554         }
555 
a_createSubcontext(String name, Continuation cont)556     protected Context a_createSubcontext(String name, Continuation cont)
557         throws NamingException {
558             OperationNotSupportedException e = new
559                 OperationNotSupportedException();
560             throw cont.fillInException(e);
561         }
562 
a_rename(String oldname, Name newname, Continuation cont)563     protected void a_rename(String oldname, Name newname,
564         Continuation cont) throws NamingException {
565             OperationNotSupportedException e = new
566                 OperationNotSupportedException();
567             throw cont.fillInException(e);
568         }
569 
a_getNameParser(Continuation cont)570     protected NameParser a_getNameParser(Continuation cont)
571         throws NamingException {
572             OperationNotSupportedException e = new
573                 OperationNotSupportedException();
574             throw cont.fillInException(e);
575         }
576 }
577