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 javax.naming.spi;
27
28import java.util.Hashtable;
29
30import javax.naming.Name;
31import javax.naming.NamingEnumeration;
32import javax.naming.CompositeName;
33import javax.naming.NamingException;
34import javax.naming.CannotProceedException;
35import javax.naming.OperationNotSupportedException;
36import javax.naming.Context;
37
38import javax.naming.directory.DirContext;
39import javax.naming.directory.Attributes;
40import javax.naming.directory.SearchControls;
41import javax.naming.directory.SearchResult;
42import javax.naming.directory.ModificationItem;
43
44/**
45  * This class is the continuation context for invoking DirContext methods.
46  *
47  * @author Rosanna Lee
48  * @author Scott Seligman
49  * @since 1.3
50  */
51
52class ContinuationDirContext extends ContinuationContext implements DirContext {
53
54    ContinuationDirContext(CannotProceedException cpe, Hashtable<?,?> env) {
55        super(cpe, env);
56    }
57
58    protected DirContextNamePair getTargetContext(Name name)
59            throws NamingException {
60
61        if (cpe.getResolvedObj() == null)
62            throw (NamingException)cpe.fillInStackTrace();
63
64        Context ctx = NamingManager.getContext(cpe.getResolvedObj(),
65                                               cpe.getAltName(),
66                                               cpe.getAltNameCtx(),
67                                               env);
68        if (ctx == null)
69            throw (NamingException)cpe.fillInStackTrace();
70
71        if (ctx instanceof DirContext)
72            return new DirContextNamePair((DirContext)ctx, name);
73
74        if (ctx instanceof Resolver) {
75            Resolver res = (Resolver)ctx;
76            ResolveResult rr = res.resolveToClass(name, DirContext.class);
77
78            // Reached a DirContext; return result.
79            DirContext dctx = (DirContext)rr.getResolvedObj();
80            return (new DirContextNamePair(dctx, rr.getRemainingName()));
81        }
82
83        // Resolve all the way using lookup().  This may allow the operation
84        // to succeed if it doesn't require the penultimate context.
85        Object ultimate = ctx.lookup(name);
86        if (ultimate instanceof DirContext) {
87            return (new DirContextNamePair((DirContext)ultimate,
88                                          new CompositeName()));
89        }
90
91        throw (NamingException)cpe.fillInStackTrace();
92    }
93
94    protected DirContextStringPair getTargetContext(String name)
95            throws NamingException {
96
97        if (cpe.getResolvedObj() == null)
98            throw (NamingException)cpe.fillInStackTrace();
99
100        Context ctx = NamingManager.getContext(cpe.getResolvedObj(),
101                                               cpe.getAltName(),
102                                               cpe.getAltNameCtx(),
103                                               env);
104
105        if (ctx instanceof DirContext)
106            return new DirContextStringPair((DirContext)ctx, name);
107
108        if (ctx instanceof Resolver) {
109            Resolver res = (Resolver)ctx;
110            ResolveResult rr = res.resolveToClass(name, DirContext.class);
111
112            // Reached a DirContext; return result.
113            DirContext dctx = (DirContext)rr.getResolvedObj();
114            Name tmp = rr.getRemainingName();
115            String remains = (tmp != null) ? tmp.toString() : "";
116            return (new DirContextStringPair(dctx, remains));
117        }
118
119        // Resolve all the way using lookup().  This may allow the operation
120        // to succeed if it doesn't require the penultimate context.
121        Object ultimate = ctx.lookup(name);
122        if (ultimate instanceof DirContext) {
123            return (new DirContextStringPair((DirContext)ultimate, ""));
124        }
125
126        throw (NamingException)cpe.fillInStackTrace();
127    }
128
129    public Attributes getAttributes(String name) throws NamingException {
130        DirContextStringPair res = getTargetContext(name);
131        return res.getDirContext().getAttributes(res.getString());
132    }
133
134    public Attributes getAttributes(String name, String[] attrIds)
135        throws NamingException {
136            DirContextStringPair res = getTargetContext(name);
137            return res.getDirContext().getAttributes(res.getString(), attrIds);
138        }
139
140    public Attributes getAttributes(Name name) throws NamingException {
141        DirContextNamePair res = getTargetContext(name);
142        return res.getDirContext().getAttributes(res.getName());
143    }
144
145    public Attributes getAttributes(Name name, String[] attrIds)
146        throws NamingException {
147            DirContextNamePair res = getTargetContext(name);
148            return res.getDirContext().getAttributes(res.getName(), attrIds);
149        }
150
151    public void modifyAttributes(Name name, int mod_op, Attributes attrs)
152        throws NamingException  {
153            DirContextNamePair res = getTargetContext(name);
154            res.getDirContext().modifyAttributes(res.getName(), mod_op, attrs);
155        }
156    public void modifyAttributes(String name, int mod_op, Attributes attrs)
157        throws NamingException  {
158            DirContextStringPair res = getTargetContext(name);
159            res.getDirContext().modifyAttributes(res.getString(), mod_op, attrs);
160        }
161
162    public void modifyAttributes(Name name, ModificationItem[] mods)
163        throws NamingException  {
164            DirContextNamePair res = getTargetContext(name);
165            res.getDirContext().modifyAttributes(res.getName(), mods);
166        }
167    public void modifyAttributes(String name, ModificationItem[] mods)
168        throws NamingException  {
169            DirContextStringPair res = getTargetContext(name);
170            res.getDirContext().modifyAttributes(res.getString(), mods);
171        }
172
173    public void bind(Name name, Object obj, Attributes attrs)
174        throws NamingException  {
175            DirContextNamePair res = getTargetContext(name);
176            res.getDirContext().bind(res.getName(), obj, attrs);
177        }
178    public void bind(String name, Object obj, Attributes attrs)
179        throws NamingException  {
180            DirContextStringPair res = getTargetContext(name);
181            res.getDirContext().bind(res.getString(), obj, attrs);
182        }
183
184    public void rebind(Name name, Object obj, Attributes attrs)
185                throws NamingException {
186            DirContextNamePair res = getTargetContext(name);
187            res.getDirContext().rebind(res.getName(), obj, attrs);
188        }
189    public void rebind(String name, Object obj, Attributes attrs)
190                throws NamingException {
191            DirContextStringPair res = getTargetContext(name);
192            res.getDirContext().rebind(res.getString(), obj, attrs);
193        }
194
195    public DirContext createSubcontext(Name name, Attributes attrs)
196                throws NamingException  {
197            DirContextNamePair res = getTargetContext(name);
198            return res.getDirContext().createSubcontext(res.getName(), attrs);
199        }
200
201    public DirContext createSubcontext(String name, Attributes attrs)
202                throws NamingException  {
203            DirContextStringPair res = getTargetContext(name);
204            return
205                res.getDirContext().createSubcontext(res.getString(), attrs);
206        }
207
208    public NamingEnumeration<SearchResult> search(Name name,
209                                    Attributes matchingAttributes,
210                                    String[] attributesToReturn)
211        throws NamingException  {
212            DirContextNamePair res = getTargetContext(name);
213            return res.getDirContext().search(res.getName(), matchingAttributes,
214                                             attributesToReturn);
215        }
216
217    public NamingEnumeration<SearchResult> search(String name,
218                                    Attributes matchingAttributes,
219                                    String[] attributesToReturn)
220        throws NamingException  {
221            DirContextStringPair res = getTargetContext(name);
222            return res.getDirContext().search(res.getString(),
223                                             matchingAttributes,
224                                             attributesToReturn);
225        }
226
227    public NamingEnumeration<SearchResult> search(Name name,
228                                    Attributes matchingAttributes)
229        throws NamingException  {
230            DirContextNamePair res = getTargetContext(name);
231            return res.getDirContext().search(res.getName(), matchingAttributes);
232        }
233    public NamingEnumeration<SearchResult> search(String name,
234                                    Attributes matchingAttributes)
235        throws NamingException  {
236            DirContextStringPair res = getTargetContext(name);
237            return res.getDirContext().search(res.getString(),
238                                             matchingAttributes);
239        }
240
241    public NamingEnumeration<SearchResult> search(Name name,
242                                    String filter,
243                                    SearchControls cons)
244        throws NamingException {
245            DirContextNamePair res = getTargetContext(name);
246            return res.getDirContext().search(res.getName(), filter, cons);
247        }
248
249    public NamingEnumeration<SearchResult> search(String name,
250                                    String filter,
251                                    SearchControls cons)
252        throws NamingException {
253            DirContextStringPair res = getTargetContext(name);
254            return res.getDirContext().search(res.getString(), filter, cons);
255        }
256
257    public NamingEnumeration<SearchResult> search(Name name,
258                                    String filterExpr,
259                                    Object[] args,
260                                    SearchControls cons)
261        throws NamingException {
262            DirContextNamePair res = getTargetContext(name);
263            return res.getDirContext().search(res.getName(), filterExpr, args,
264                                             cons);
265        }
266
267    public NamingEnumeration<SearchResult> search(String name,
268                                    String filterExpr,
269                                    Object[] args,
270                                    SearchControls cons)
271        throws NamingException {
272            DirContextStringPair res = getTargetContext(name);
273            return res.getDirContext().search(res.getString(), filterExpr, args,
274                                             cons);
275        }
276
277    public DirContext getSchema(String name) throws NamingException {
278        DirContextStringPair res = getTargetContext(name);
279        return res.getDirContext().getSchema(res.getString());
280    }
281
282    public DirContext getSchema(Name name) throws NamingException  {
283        DirContextNamePair res = getTargetContext(name);
284        return res.getDirContext().getSchema(res.getName());
285    }
286
287    public DirContext getSchemaClassDefinition(String name)
288            throws NamingException  {
289        DirContextStringPair res = getTargetContext(name);
290        return res.getDirContext().getSchemaClassDefinition(res.getString());
291    }
292
293    public DirContext getSchemaClassDefinition(Name name)
294            throws NamingException  {
295        DirContextNamePair res = getTargetContext(name);
296        return res.getDirContext().getSchemaClassDefinition(res.getName());
297    }
298}
299
300class DirContextNamePair {
301        DirContext ctx;
302        Name name;
303
304        DirContextNamePair(DirContext ctx, Name name) {
305            this.ctx = ctx;
306            this.name = name;
307        }
308
309        DirContext getDirContext() {
310            return ctx;
311        }
312
313        Name getName() {
314            return name;
315        }
316}
317
318class DirContextStringPair {
319        DirContext ctx;
320        String str;
321
322        DirContextStringPair(DirContext ctx, String str) {
323            this.ctx = ctx;
324            this.str = str;
325        }
326
327        DirContext getDirContext() {
328            return ctx;
329        }
330
331        String getString() {
332            return str;
333        }
334}
335