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 */
25package com.sun.jndi.toolkit.url;
26
27import javax.naming.*;
28import javax.naming.directory.*;
29import javax.naming.spi.ResolveResult;
30import javax.naming.spi.DirectoryManager;
31
32import java.util.Hashtable;
33
34/**
35 * This abstract class is a generic URL DirContext that accepts as the
36 * name argument either a string URL or a Name whose first component
37 * is a URL. It resolves the URL to a target context and then continues
38 * the operation using the remaining name in the target context as if
39 * the first component names a junction.
40 *
41 * A subclass must define getRootURLContext()
42 * to process the URL into head/tail pieces. If it wants to control how
43 * URL strings are parsed and compared for the rename() operation, then
44 * it should override getNonRootURLSuffixes() and urlEquals().
45 *
46 * @author Scott Seligman
47 * @author Rosanna Lee
48 */
49
50abstract public class GenericURLDirContext extends GenericURLContext
51implements DirContext {
52
53    protected GenericURLDirContext(Hashtable<?,?> env) {
54        super(env);
55    }
56
57    /**
58     * Gets the context in which to continue the operation. This method
59     * is called when this context is asked to process a multicomponent
60     * Name in which the first component is a URL.
61     * Treat the first component like a junction: resolve it and then use
62     * DirectoryManager.getContinuationDirContext() to get the target context in
63     * which to operate on the remainder of the name (n.getSuffix(1)).
64     * Do this in case intermediate contexts are not DirContext.
65     */
66    protected DirContext getContinuationDirContext(Name n) throws NamingException {
67        Object obj = lookup(n.get(0));
68        CannotProceedException cpe = new CannotProceedException();
69        cpe.setResolvedObj(obj);
70        cpe.setEnvironment(myEnv);
71        return DirectoryManager.getContinuationDirContext(cpe);
72    }
73
74
75    public Attributes getAttributes(String name) throws NamingException {
76        ResolveResult res = getRootURLContext(name, myEnv);
77        DirContext ctx = (DirContext)res.getResolvedObj();
78        try {
79            return ctx.getAttributes(res.getRemainingName());
80        } finally {
81            ctx.close();
82        }
83    }
84
85    public Attributes getAttributes(Name name) throws NamingException  {
86        if (name.size() == 1) {
87            return getAttributes(name.get(0));
88        } else {
89            DirContext ctx = getContinuationDirContext(name);
90            try {
91                return ctx.getAttributes(name.getSuffix(1));
92            } finally {
93                ctx.close();
94            }
95        }
96    }
97
98    public Attributes getAttributes(String name, String[] attrIds)
99        throws NamingException {
100            ResolveResult res = getRootURLContext(name, myEnv);
101            DirContext ctx = (DirContext)res.getResolvedObj();
102            try {
103                return ctx.getAttributes(res.getRemainingName(), attrIds);
104            } finally {
105                ctx.close();
106            }
107    }
108
109    public Attributes getAttributes(Name name, String[] attrIds)
110        throws NamingException {
111            if (name.size() == 1) {
112                return getAttributes(name.get(0), attrIds);
113            } else {
114                DirContext ctx = getContinuationDirContext(name);
115                try {
116                    return ctx.getAttributes(name.getSuffix(1), attrIds);
117                } finally {
118                    ctx.close();
119                }
120            }
121    }
122
123    public void modifyAttributes(String name, int mod_op, Attributes attrs)
124        throws NamingException {
125            ResolveResult res = getRootURLContext(name, myEnv);
126            DirContext ctx = (DirContext)res.getResolvedObj();
127            try {
128                ctx.modifyAttributes(res.getRemainingName(), mod_op, attrs);
129            } finally {
130                ctx.close();
131            }
132    }
133
134    public void modifyAttributes(Name name, int mod_op, Attributes attrs)
135        throws NamingException {
136            if (name.size() == 1) {
137                modifyAttributes(name.get(0), mod_op, attrs);
138            } else {
139                DirContext ctx = getContinuationDirContext(name);
140                try {
141                    ctx.modifyAttributes(name.getSuffix(1), mod_op, attrs);
142                } finally {
143                    ctx.close();
144                }
145            }
146    }
147
148    public void modifyAttributes(String name, ModificationItem[] mods)
149        throws NamingException {
150            ResolveResult res = getRootURLContext(name, myEnv);
151            DirContext ctx = (DirContext)res.getResolvedObj();
152            try {
153                ctx.modifyAttributes(res.getRemainingName(), mods);
154            } finally {
155                ctx.close();
156            }
157    }
158
159    public void modifyAttributes(Name name, ModificationItem[] mods)
160        throws NamingException  {
161            if (name.size() == 1) {
162                modifyAttributes(name.get(0), mods);
163            } else {
164                DirContext ctx = getContinuationDirContext(name);
165                try {
166                    ctx.modifyAttributes(name.getSuffix(1), mods);
167                } finally {
168                    ctx.close();
169                }
170            }
171    }
172
173    public void bind(String name, Object obj, Attributes attrs)
174        throws NamingException {
175            ResolveResult res = getRootURLContext(name, myEnv);
176            DirContext ctx = (DirContext)res.getResolvedObj();
177            try {
178                ctx.bind(res.getRemainingName(), obj, attrs);
179            } finally {
180                ctx.close();
181            }
182    }
183
184    public void bind(Name name, Object obj, Attributes attrs)
185        throws NamingException {
186            if (name.size() == 1) {
187                bind(name.get(0), obj, attrs);
188            } else {
189                DirContext ctx = getContinuationDirContext(name);
190                try {
191                    ctx.bind(name.getSuffix(1), obj, attrs);
192                } finally {
193                    ctx.close();
194                }
195            }
196    }
197
198    public void rebind(String name, Object obj, Attributes attrs)
199        throws NamingException {
200            ResolveResult res = getRootURLContext(name, myEnv);
201            DirContext ctx = (DirContext)res.getResolvedObj();
202            try {
203                ctx.rebind(res.getRemainingName(), obj, attrs);
204            } finally {
205                ctx.close();
206            }
207    }
208
209    public void rebind(Name name, Object obj, Attributes attrs)
210        throws NamingException {
211            if (name.size() == 1) {
212                rebind(name.get(0), obj, attrs);
213            } else {
214                DirContext ctx = getContinuationDirContext(name);
215                try {
216                    ctx.rebind(name.getSuffix(1), obj, attrs);
217                } finally {
218                    ctx.close();
219                }
220            }
221    }
222
223    public DirContext createSubcontext(String name, Attributes attrs)
224        throws NamingException {
225            ResolveResult res = getRootURLContext(name, myEnv);
226            DirContext ctx = (DirContext)res.getResolvedObj();
227            try {
228                return ctx.createSubcontext(res.getRemainingName(), attrs);
229            } finally {
230                ctx.close();
231            }
232    }
233
234    public DirContext createSubcontext(Name name, Attributes attrs)
235        throws NamingException {
236            if (name.size() == 1) {
237                return createSubcontext(name.get(0), attrs);
238            } else {
239                DirContext ctx = getContinuationDirContext(name);
240                try {
241                    return ctx.createSubcontext(name.getSuffix(1), attrs);
242                } finally {
243                    ctx.close();
244                }
245            }
246    }
247
248    public DirContext getSchema(String name) throws NamingException {
249        ResolveResult res = getRootURLContext(name, myEnv);
250        DirContext ctx = (DirContext)res.getResolvedObj();
251        return ctx.getSchema(res.getRemainingName());
252    }
253
254    public DirContext getSchema(Name name) throws NamingException {
255        if (name.size() == 1) {
256            return getSchema(name.get(0));
257        } else {
258            DirContext ctx = getContinuationDirContext(name);
259            try {
260                return ctx.getSchema(name.getSuffix(1));
261            } finally {
262                ctx.close();
263            }
264        }
265    }
266
267    public DirContext getSchemaClassDefinition(String name)
268        throws NamingException {
269            ResolveResult res = getRootURLContext(name, myEnv);
270            DirContext ctx = (DirContext)res.getResolvedObj();
271            try {
272                return ctx.getSchemaClassDefinition(res.getRemainingName());
273            } finally {
274                ctx.close();
275            }
276    }
277
278    public DirContext getSchemaClassDefinition(Name name)
279        throws NamingException {
280            if (name.size() == 1) {
281                return getSchemaClassDefinition(name.get(0));
282            } else {
283                DirContext ctx = getContinuationDirContext(name);
284                try {
285                    return ctx.getSchemaClassDefinition(name.getSuffix(1));
286                } finally {
287                    ctx.close();
288                }
289            }
290    }
291
292    public NamingEnumeration<SearchResult> search(String name,
293        Attributes matchingAttributes)
294        throws NamingException {
295            ResolveResult res = getRootURLContext(name, myEnv);
296            DirContext ctx = (DirContext)res.getResolvedObj();
297            try {
298                return ctx.search(res.getRemainingName(), matchingAttributes);
299            } finally {
300                ctx.close();
301            }
302    }
303
304    public NamingEnumeration<SearchResult> search(Name name,
305        Attributes matchingAttributes)
306        throws NamingException {
307            if (name.size() == 1) {
308                return search(name.get(0), matchingAttributes);
309            } else {
310                DirContext ctx = getContinuationDirContext(name);
311                try {
312                    return ctx.search(name.getSuffix(1), matchingAttributes);
313                } finally {
314                    ctx.close();
315                }
316            }
317    }
318
319    public NamingEnumeration<SearchResult> search(String name,
320        Attributes matchingAttributes,
321        String[] attributesToReturn)
322        throws NamingException {
323            ResolveResult res = getRootURLContext(name, myEnv);
324            DirContext ctx = (DirContext)res.getResolvedObj();
325            try {
326                return ctx.search(res.getRemainingName(),
327                    matchingAttributes, attributesToReturn);
328            } finally {
329                ctx.close();
330            }
331    }
332
333    public NamingEnumeration<SearchResult> search(Name name,
334        Attributes matchingAttributes,
335        String[] attributesToReturn)
336        throws NamingException {
337            if (name.size() == 1) {
338                return search(name.get(0), matchingAttributes,
339                    attributesToReturn);
340            } else {
341                DirContext ctx = getContinuationDirContext(name);
342                try {
343                    return ctx.search(name.getSuffix(1),
344                        matchingAttributes, attributesToReturn);
345                } finally {
346                    ctx.close();
347                }
348            }
349    }
350
351    public NamingEnumeration<SearchResult> search(String name,
352        String filter,
353        SearchControls cons)
354        throws NamingException {
355            ResolveResult res = getRootURLContext(name, myEnv);
356            DirContext ctx = (DirContext)res.getResolvedObj();
357            try {
358                return ctx.search(res.getRemainingName(), filter, cons);
359            } finally {
360                ctx.close();
361            }
362    }
363
364    public NamingEnumeration<SearchResult> search(Name name,
365        String filter,
366        SearchControls cons)
367        throws NamingException {
368            if (name.size() == 1) {
369                return search(name.get(0), filter, cons);
370            } else {
371                DirContext ctx = getContinuationDirContext(name);
372                try {
373                    return ctx.search(name.getSuffix(1), filter, cons);
374                } finally {
375                    ctx.close();
376                }
377            }
378    }
379
380    public NamingEnumeration<SearchResult> search(String name,
381        String filterExpr,
382        Object[] filterArgs,
383        SearchControls cons)
384        throws NamingException {
385            ResolveResult res = getRootURLContext(name, myEnv);
386            DirContext ctx = (DirContext)res.getResolvedObj();
387            try {
388                return
389                    ctx.search(res.getRemainingName(), filterExpr, filterArgs, cons);
390            } finally {
391                ctx.close();
392            }
393    }
394
395    public NamingEnumeration<SearchResult> search(Name name,
396        String filterExpr,
397        Object[] filterArgs,
398        SearchControls cons)
399        throws NamingException {
400            if (name.size() == 1) {
401                return search(name.get(0), filterExpr, filterArgs, cons);
402            } else {
403                DirContext ctx = getContinuationDirContext(name);
404                try {
405                return ctx.search(name.getSuffix(1), filterExpr, filterArgs, cons);
406                } finally {
407                    ctx.close();
408                }
409            }
410    }
411}
412