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
26package com.sun.jndi.toolkit.ctx;
27
28import java.util.Hashtable;
29
30import javax.naming.*;
31import javax.naming.directory.*;
32import 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
46public abstract class PartialCompositeDirContext
47        extends AtomicContext implements DirContext {
48
49    protected PartialCompositeDirContext() {
50        _contextType = _PARTIAL;
51    }
52
53// ------ Abstract methods whose implementation come from subclasses
54
55     /* Equivalent to DirContext methods */
56     protected abstract Attributes p_getAttributes(Name name, String[] attrIds,
57                                                     Continuation cont)
58         throws NamingException;
59
60     protected abstract void p_modifyAttributes(Name name, int mod_op,
61                                                Attributes attrs,
62                                                Continuation cont)
63         throws NamingException;
64
65     protected abstract void p_modifyAttributes(Name name,
66                                                ModificationItem[] mods,
67                                                Continuation cont)
68         throws NamingException;
69
70     protected abstract void p_bind(Name name, Object obj,
71                                    Attributes attrs,
72                                    Continuation cont)
73         throws NamingException;
74
75     protected abstract void p_rebind(Name name, Object obj,
76                                      Attributes attrs,
77                                      Continuation cont)
78         throws NamingException;
79
80     protected abstract DirContext p_createSubcontext(Name name,
81                                                     Attributes attrs,
82                                                     Continuation cont)
83         throws NamingException;
84
85     protected abstract NamingEnumeration<SearchResult> p_search(
86                            Name name,
87                            Attributes matchingAttributes,
88                            String[] attributesToReturn,
89                            Continuation cont)
90         throws NamingException;
91
92     protected abstract NamingEnumeration<SearchResult> p_search(
93                            Name name,
94                            String filter,
95                            SearchControls cons,
96                            Continuation cont)
97         throws NamingException;
98
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
107     protected abstract DirContext p_getSchema(Name name, Continuation cont)
108         throws NamingException;
109
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
117    public Attributes getAttributes(String name)
118            throws NamingException {
119        return getAttributes(name, null);
120    }
121
122    public Attributes getAttributes(Name name)
123            throws NamingException {
124        return getAttributes(name, null);
125    }
126
127    public Attributes getAttributes(String name, String[] attrIds)
128            throws NamingException {
129        return getAttributes(new CompositeName(name), attrIds);
130    }
131
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
154    public void modifyAttributes(String name, int mod_op, Attributes attrs)
155            throws NamingException {
156        modifyAttributes(new CompositeName(name), mod_op, attrs);
157    }
158
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
179    public void modifyAttributes(String name, ModificationItem[] mods)
180            throws NamingException {
181        modifyAttributes(new CompositeName(name), mods);
182    }
183
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
204    public void bind(String name, Object obj, Attributes attrs)
205            throws NamingException {
206        bind(new CompositeName(name), obj, attrs);
207    }
208
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
229    public void rebind(String name, Object obj, Attributes attrs)
230            throws NamingException {
231        rebind(new CompositeName(name), obj, attrs);
232    }
233
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
254    public DirContext createSubcontext(String name, Attributes attrs)
255            throws NamingException {
256        return createSubcontext(new CompositeName(name), attrs);
257    }
258
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>
282        search(String name, Attributes matchingAttributes)
283        throws NamingException
284    {
285        return search(name, matchingAttributes, null);
286    }
287
288    public NamingEnumeration<SearchResult>
289        search(Name name, Attributes matchingAttributes)
290        throws NamingException
291    {
292        return search(name, matchingAttributes, null);
293    }
294
295    public NamingEnumeration<SearchResult>
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>
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>
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>
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>
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>
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
410    public DirContext getSchema(String name) throws NamingException {
411        return getSchema(new CompositeName(name));
412    }
413
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
435    public DirContext getSchemaClassDefinition(String name)
436            throws NamingException {
437        return getSchemaClassDefinition(new CompositeName(name));
438    }
439
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     */
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
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
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
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
514    protected NamingEnumeration<NameClassPair> a_list(
515        Continuation cont) throws NamingException {
516            OperationNotSupportedException e = new
517                OperationNotSupportedException();
518            throw cont.fillInException(e);
519        }
520
521    protected NamingEnumeration<Binding> a_listBindings(
522        Continuation cont) throws NamingException {
523            OperationNotSupportedException e = new
524                OperationNotSupportedException();
525            throw cont.fillInException(e);
526        }
527
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
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
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
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
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
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
570    protected NameParser a_getNameParser(Continuation cont)
571        throws NamingException {
572            OperationNotSupportedException e = new
573                OperationNotSupportedException();
574            throw cont.fillInException(e);
575        }
576}
577