author | sspitsyn |
Wed, 07 Sep 2016 03:35:45 +0000 | |
changeset 40963 | c7c990c4ec68 |
parent 32029 | a5538163e144 |
permissions | -rw-r--r-- |
2 | 1 |
/* |
10324
e28265130e4f
7072353: JNDI libraries do not build with javac -Xlint:all -Werror
jjg
parents:
5506
diff
changeset
|
2 |
* Copyright (c) 1999, 2011, Oracle and/or its affiliates. All rights reserved. |
2 | 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 |
|
5506 | 7 |
* published by the Free Software Foundation. Oracle designates this |
2 | 8 |
* particular file as subject to the "Classpath" exception as provided |
5506 | 9 |
* by Oracle in the LICENSE file that accompanied this code. |
2 | 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 |
* |
|
5506 | 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. |
|
2 | 24 |
*/ |
25 |
||
26 |
package javax.naming.spi; |
|
27 |
||
28 |
import java.util.Hashtable; |
|
29 |
||
30 |
import javax.naming.Context; |
|
31 |
import javax.naming.Name; |
|
32 |
import javax.naming.Reference; |
|
33 |
import javax.naming.Referenceable; |
|
34 |
import javax.naming.NamingException; |
|
35 |
import javax.naming.CannotProceedException; |
|
36 |
import javax.naming.directory.DirContext; |
|
37 |
import javax.naming.directory.Attributes; |
|
38 |
||
39 |
import com.sun.naming.internal.ResourceManager; |
|
40 |
import com.sun.naming.internal.FactoryEnumeration; |
|
41 |
||
42 |
||
43 |
/** |
|
32029
a5538163e144
8132877: docs: replace <tt> tags (obsolete in html5) for javax.naming
avstepan
parents:
25859
diff
changeset
|
44 |
* This class contains methods for supporting {@code DirContext} |
2 | 45 |
* implementations. |
46 |
*<p> |
|
32029
a5538163e144
8132877: docs: replace <tt> tags (obsolete in html5) for javax.naming
avstepan
parents:
25859
diff
changeset
|
47 |
* This class is an extension of {@code NamingManager}. It contains methods |
2 | 48 |
* for use by service providers for accessing object factories and |
49 |
* state factories, and for getting continuation contexts for |
|
50 |
* supporting federation. |
|
51 |
*<p> |
|
32029
a5538163e144
8132877: docs: replace <tt> tags (obsolete in html5) for javax.naming
avstepan
parents:
25859
diff
changeset
|
52 |
* {@code DirectoryManager} is safe for concurrent access by multiple threads. |
2 | 53 |
*<p> |
54 |
* Except as otherwise noted, |
|
32029
a5538163e144
8132877: docs: replace <tt> tags (obsolete in html5) for javax.naming
avstepan
parents:
25859
diff
changeset
|
55 |
* a {@code Name}, {@code Attributes}, or environment parameter |
2 | 56 |
* passed to any method is owned by the caller. |
57 |
* The implementation will not modify the object or keep a reference |
|
58 |
* to it, although it may keep a reference to a clone or copy. |
|
59 |
* |
|
60 |
* @author Rosanna Lee |
|
61 |
* @author Scott Seligman |
|
62 |
* |
|
63 |
* @see DirObjectFactory |
|
64 |
* @see DirStateFactory |
|
65 |
* @since 1.3 |
|
66 |
*/ |
|
67 |
||
68 |
public class DirectoryManager extends NamingManager { |
|
69 |
||
70 |
/* |
|
71 |
* Disallow anyone from creating one of these. |
|
72 |
*/ |
|
73 |
DirectoryManager() {} |
|
74 |
||
75 |
/** |
|
32029
a5538163e144
8132877: docs: replace <tt> tags (obsolete in html5) for javax.naming
avstepan
parents:
25859
diff
changeset
|
76 |
* Creates a context in which to continue a {@code DirContext} operation. |
a5538163e144
8132877: docs: replace <tt> tags (obsolete in html5) for javax.naming
avstepan
parents:
25859
diff
changeset
|
77 |
* Operates just like {@code NamingManager.getContinuationContext()}, |
a5538163e144
8132877: docs: replace <tt> tags (obsolete in html5) for javax.naming
avstepan
parents:
25859
diff
changeset
|
78 |
* only the continuation context returned is a {@code DirContext}. |
2 | 79 |
* |
80 |
* @param cpe |
|
81 |
* The non-null exception that triggered this continuation. |
|
32029
a5538163e144
8132877: docs: replace <tt> tags (obsolete in html5) for javax.naming
avstepan
parents:
25859
diff
changeset
|
82 |
* @return A non-null {@code DirContext} object for continuing the operation. |
2 | 83 |
* @exception NamingException If a naming exception occurred. |
84 |
* |
|
85 |
* @see NamingManager#getContinuationContext(CannotProceedException) |
|
86 |
*/ |
|
10324
e28265130e4f
7072353: JNDI libraries do not build with javac -Xlint:all -Werror
jjg
parents:
5506
diff
changeset
|
87 |
@SuppressWarnings("unchecked") |
2 | 88 |
public static DirContext getContinuationDirContext( |
89 |
CannotProceedException cpe) throws NamingException { |
|
90 |
||
10324
e28265130e4f
7072353: JNDI libraries do not build with javac -Xlint:all -Werror
jjg
parents:
5506
diff
changeset
|
91 |
Hashtable<Object,Object> env = (Hashtable<Object,Object>)cpe.getEnvironment(); |
2 | 92 |
if (env == null) { |
10324
e28265130e4f
7072353: JNDI libraries do not build with javac -Xlint:all -Werror
jjg
parents:
5506
diff
changeset
|
93 |
env = new Hashtable<>(7); |
2 | 94 |
} else { |
95 |
// Make a (shallow) copy of the environment. |
|
10324
e28265130e4f
7072353: JNDI libraries do not build with javac -Xlint:all -Werror
jjg
parents:
5506
diff
changeset
|
96 |
env = (Hashtable<Object,Object>) env.clone(); |
2 | 97 |
} |
98 |
env.put(CPE, cpe); |
|
99 |
||
100 |
return (new ContinuationDirContext(cpe, env)); |
|
101 |
} |
|
102 |
||
103 |
/** |
|
104 |
* Creates an instance of an object for the specified object, |
|
105 |
* attributes, and environment. |
|
106 |
* <p> |
|
32029
a5538163e144
8132877: docs: replace <tt> tags (obsolete in html5) for javax.naming
avstepan
parents:
25859
diff
changeset
|
107 |
* This method is the same as {@code NamingManager.getObjectInstance} |
2 | 108 |
* except for the following differences: |
109 |
*<ul> |
|
110 |
*<li> |
|
32029
a5538163e144
8132877: docs: replace <tt> tags (obsolete in html5) for javax.naming
avstepan
parents:
25859
diff
changeset
|
111 |
* It accepts an {@code Attributes} parameter that contains attributes |
a5538163e144
8132877: docs: replace <tt> tags (obsolete in html5) for javax.naming
avstepan
parents:
25859
diff
changeset
|
112 |
* associated with the object. The {@code DirObjectFactory} might use these |
2 | 113 |
* attributes to save having to look them up from the directory. |
114 |
*<li> |
|
115 |
* The object factories tried must implement either |
|
32029
a5538163e144
8132877: docs: replace <tt> tags (obsolete in html5) for javax.naming
avstepan
parents:
25859
diff
changeset
|
116 |
* {@code ObjectFactory} or {@code DirObjectFactory}. |
a5538163e144
8132877: docs: replace <tt> tags (obsolete in html5) for javax.naming
avstepan
parents:
25859
diff
changeset
|
117 |
* If it implements {@code DirObjectFactory}, |
a5538163e144
8132877: docs: replace <tt> tags (obsolete in html5) for javax.naming
avstepan
parents:
25859
diff
changeset
|
118 |
* {@code DirObjectFactory.getObjectInstance()} is used, otherwise, |
a5538163e144
8132877: docs: replace <tt> tags (obsolete in html5) for javax.naming
avstepan
parents:
25859
diff
changeset
|
119 |
* {@code ObjectFactory.getObjectInstance()} is used. |
2 | 120 |
*</ul> |
32029
a5538163e144
8132877: docs: replace <tt> tags (obsolete in html5) for javax.naming
avstepan
parents:
25859
diff
changeset
|
121 |
* Service providers that implement the {@code DirContext} interface |
a5538163e144
8132877: docs: replace <tt> tags (obsolete in html5) for javax.naming
avstepan
parents:
25859
diff
changeset
|
122 |
* should use this method, not {@code NamingManager.getObjectInstance()}. |
2 | 123 |
* |
124 |
* @param refInfo The possibly null object for which to create an object. |
|
32029
a5538163e144
8132877: docs: replace <tt> tags (obsolete in html5) for javax.naming
avstepan
parents:
25859
diff
changeset
|
125 |
* @param name The name of this object relative to {@code nameCtx}. |
2 | 126 |
* Specifying a name is optional; if it is |
32029
a5538163e144
8132877: docs: replace <tt> tags (obsolete in html5) for javax.naming
avstepan
parents:
25859
diff
changeset
|
127 |
* omitted, {@code name} should be null. |
a5538163e144
8132877: docs: replace <tt> tags (obsolete in html5) for javax.naming
avstepan
parents:
25859
diff
changeset
|
128 |
* @param nameCtx The context relative to which the {@code name} |
a5538163e144
8132877: docs: replace <tt> tags (obsolete in html5) for javax.naming
avstepan
parents:
25859
diff
changeset
|
129 |
* parameter is specified. If null, {@code name} is |
2 | 130 |
* relative to the default initial context. |
131 |
* @param environment The possibly null environment to |
|
132 |
* be used in the creation of the object factory and the object. |
|
133 |
* @param attrs The possibly null attributes associated with refInfo. |
|
134 |
* This might not be the complete set of attributes for refInfo; |
|
135 |
* you might be able to read more attributes from the directory. |
|
32029
a5538163e144
8132877: docs: replace <tt> tags (obsolete in html5) for javax.naming
avstepan
parents:
25859
diff
changeset
|
136 |
* @return An object created using {@code refInfo} and {@code attrs}; or |
a5538163e144
8132877: docs: replace <tt> tags (obsolete in html5) for javax.naming
avstepan
parents:
25859
diff
changeset
|
137 |
* {@code refInfo} if an object cannot be created by |
2 | 138 |
* a factory. |
139 |
* @exception NamingException If a naming exception was encountered |
|
140 |
* while attempting to get a URL context, or if one of the |
|
141 |
* factories accessed throws a NamingException. |
|
142 |
* @exception Exception If one of the factories accessed throws an |
|
143 |
* exception, or if an error was encountered while loading |
|
144 |
* and instantiating the factory and object classes. |
|
145 |
* A factory should only throw an exception if it does not want |
|
146 |
* other factories to be used in an attempt to create an object. |
|
32029
a5538163e144
8132877: docs: replace <tt> tags (obsolete in html5) for javax.naming
avstepan
parents:
25859
diff
changeset
|
147 |
* See {@code DirObjectFactory.getObjectInstance()}. |
2 | 148 |
* @see NamingManager#getURLContext |
149 |
* @see DirObjectFactory |
|
150 |
* @see DirObjectFactory#getObjectInstance |
|
151 |
* @since 1.3 |
|
152 |
*/ |
|
153 |
public static Object |
|
154 |
getObjectInstance(Object refInfo, Name name, Context nameCtx, |
|
155 |
Hashtable<?,?> environment, Attributes attrs) |
|
156 |
throws Exception { |
|
157 |
||
158 |
ObjectFactory factory; |
|
159 |
||
160 |
ObjectFactoryBuilder builder = getObjectFactoryBuilder(); |
|
161 |
if (builder != null) { |
|
162 |
// builder must return non-null factory |
|
163 |
factory = builder.createObjectFactory(refInfo, environment); |
|
164 |
if (factory instanceof DirObjectFactory) { |
|
165 |
return ((DirObjectFactory)factory).getObjectInstance( |
|
166 |
refInfo, name, nameCtx, environment, attrs); |
|
167 |
} else { |
|
168 |
return factory.getObjectInstance(refInfo, name, nameCtx, |
|
169 |
environment); |
|
170 |
} |
|
171 |
} |
|
172 |
||
173 |
// use reference if possible |
|
174 |
Reference ref = null; |
|
175 |
if (refInfo instanceof Reference) { |
|
176 |
ref = (Reference) refInfo; |
|
177 |
} else if (refInfo instanceof Referenceable) { |
|
178 |
ref = ((Referenceable)(refInfo)).getReference(); |
|
179 |
} |
|
180 |
||
181 |
Object answer; |
|
182 |
||
183 |
if (ref != null) { |
|
184 |
String f = ref.getFactoryClassName(); |
|
185 |
if (f != null) { |
|
186 |
// if reference identifies a factory, use exclusively |
|
187 |
||
188 |
factory = getObjectFactoryFromReference(ref, f); |
|
189 |
if (factory instanceof DirObjectFactory) { |
|
190 |
return ((DirObjectFactory)factory).getObjectInstance( |
|
191 |
ref, name, nameCtx, environment, attrs); |
|
192 |
} else if (factory != null) { |
|
193 |
return factory.getObjectInstance(ref, name, nameCtx, |
|
194 |
environment); |
|
195 |
} |
|
196 |
// No factory found, so return original refInfo. |
|
197 |
// Will reach this point if factory class is not in |
|
198 |
// class path and reference does not contain a URL for it |
|
199 |
return refInfo; |
|
200 |
||
201 |
} else { |
|
202 |
// if reference has no factory, check for addresses |
|
203 |
// containing URLs |
|
204 |
// ignore name & attrs params; not used in URL factory |
|
205 |
||
206 |
answer = processURLAddrs(ref, name, nameCtx, environment); |
|
207 |
if (answer != null) { |
|
208 |
return answer; |
|
209 |
} |
|
210 |
} |
|
211 |
} |
|
212 |
||
213 |
// try using any specified factories |
|
214 |
answer = createObjectFromFactories(refInfo, name, nameCtx, |
|
215 |
environment, attrs); |
|
216 |
return (answer != null) ? answer : refInfo; |
|
217 |
} |
|
218 |
||
219 |
private static Object createObjectFromFactories(Object obj, Name name, |
|
10324
e28265130e4f
7072353: JNDI libraries do not build with javac -Xlint:all -Werror
jjg
parents:
5506
diff
changeset
|
220 |
Context nameCtx, Hashtable<?,?> environment, Attributes attrs) |
2 | 221 |
throws Exception { |
222 |
||
223 |
FactoryEnumeration factories = ResourceManager.getFactories( |
|
224 |
Context.OBJECT_FACTORIES, environment, nameCtx); |
|
225 |
||
226 |
if (factories == null) |
|
227 |
return null; |
|
228 |
||
229 |
ObjectFactory factory; |
|
230 |
Object answer = null; |
|
231 |
// Try each factory until one succeeds |
|
232 |
while (answer == null && factories.hasMore()) { |
|
233 |
factory = (ObjectFactory)factories.next(); |
|
234 |
if (factory instanceof DirObjectFactory) { |
|
235 |
answer = ((DirObjectFactory)factory). |
|
236 |
getObjectInstance(obj, name, nameCtx, environment, attrs); |
|
237 |
} else { |
|
238 |
answer = |
|
239 |
factory.getObjectInstance(obj, name, nameCtx, environment); |
|
240 |
} |
|
241 |
} |
|
242 |
return answer; |
|
243 |
} |
|
244 |
||
245 |
/** |
|
246 |
* Retrieves the state of an object for binding when given the original |
|
247 |
* object and its attributes. |
|
248 |
* <p> |
|
32029
a5538163e144
8132877: docs: replace <tt> tags (obsolete in html5) for javax.naming
avstepan
parents:
25859
diff
changeset
|
249 |
* This method is like {@code NamingManager.getStateToBind} except |
2 | 250 |
* for the following differences: |
251 |
*<ul> |
|
32029
a5538163e144
8132877: docs: replace <tt> tags (obsolete in html5) for javax.naming
avstepan
parents:
25859
diff
changeset
|
252 |
*<li>It accepts an {@code Attributes} parameter containing attributes |
a5538163e144
8132877: docs: replace <tt> tags (obsolete in html5) for javax.naming
avstepan
parents:
25859
diff
changeset
|
253 |
* that were passed to the {@code DirContext.bind()} method. |
a5538163e144
8132877: docs: replace <tt> tags (obsolete in html5) for javax.naming
avstepan
parents:
25859
diff
changeset
|
254 |
*<li>It returns a non-null {@code DirStateFactory.Result} instance |
2 | 255 |
* containing the object to be bound, and the attributes to |
256 |
* accompany the binding. Either the object or the attributes may be null. |
|
257 |
*<li> |
|
258 |
* The state factories tried must each implement either |
|
32029
a5538163e144
8132877: docs: replace <tt> tags (obsolete in html5) for javax.naming
avstepan
parents:
25859
diff
changeset
|
259 |
* {@code StateFactory} or {@code DirStateFactory}. |
a5538163e144
8132877: docs: replace <tt> tags (obsolete in html5) for javax.naming
avstepan
parents:
25859
diff
changeset
|
260 |
* If it implements {@code DirStateFactory}, then |
a5538163e144
8132877: docs: replace <tt> tags (obsolete in html5) for javax.naming
avstepan
parents:
25859
diff
changeset
|
261 |
* {@code DirStateFactory.getStateToBind()} is called; otherwise, |
a5538163e144
8132877: docs: replace <tt> tags (obsolete in html5) for javax.naming
avstepan
parents:
25859
diff
changeset
|
262 |
* {@code StateFactory.getStateToBind()} is called. |
2 | 263 |
*</ul> |
264 |
* |
|
32029
a5538163e144
8132877: docs: replace <tt> tags (obsolete in html5) for javax.naming
avstepan
parents:
25859
diff
changeset
|
265 |
* Service providers that implement the {@code DirContext} interface |
a5538163e144
8132877: docs: replace <tt> tags (obsolete in html5) for javax.naming
avstepan
parents:
25859
diff
changeset
|
266 |
* should use this method, not {@code NamingManager.getStateToBind()}. |
2 | 267 |
*<p> |
268 |
* See NamingManager.getStateToBind() for a description of how |
|
269 |
* the list of state factories to be tried is determined. |
|
270 |
*<p> |
|
271 |
* The object returned by this method is owned by the caller. |
|
272 |
* The implementation will not subsequently modify it. |
|
32029
a5538163e144
8132877: docs: replace <tt> tags (obsolete in html5) for javax.naming
avstepan
parents:
25859
diff
changeset
|
273 |
* It will contain either a new {@code Attributes} object that is |
2 | 274 |
* likewise owned by the caller, or a reference to the original |
32029
a5538163e144
8132877: docs: replace <tt> tags (obsolete in html5) for javax.naming
avstepan
parents:
25859
diff
changeset
|
275 |
* {@code attrs} parameter. |
2 | 276 |
* |
277 |
* @param obj The non-null object for which to get state to bind. |
|
32029
a5538163e144
8132877: docs: replace <tt> tags (obsolete in html5) for javax.naming
avstepan
parents:
25859
diff
changeset
|
278 |
* @param name The name of this object relative to {@code nameCtx}, |
2 | 279 |
* or null if no name is specified. |
32029
a5538163e144
8132877: docs: replace <tt> tags (obsolete in html5) for javax.naming
avstepan
parents:
25859
diff
changeset
|
280 |
* @param nameCtx The context relative to which the {@code name} |
a5538163e144
8132877: docs: replace <tt> tags (obsolete in html5) for javax.naming
avstepan
parents:
25859
diff
changeset
|
281 |
* parameter is specified, or null if {@code name} is |
2 | 282 |
* relative to the default initial context. |
283 |
* @param environment The possibly null environment to |
|
284 |
* be used in the creation of the state factory and |
|
285 |
* the object's state. |
|
286 |
* @param attrs The possibly null Attributes that is to be bound with the |
|
287 |
* object. |
|
288 |
* @return A non-null DirStateFactory.Result containing |
|
289 |
* the object and attributes to be bound. |
|
290 |
* If no state factory returns a non-null answer, the result will contain |
|
32029
a5538163e144
8132877: docs: replace <tt> tags (obsolete in html5) for javax.naming
avstepan
parents:
25859
diff
changeset
|
291 |
* the object ({@code obj}) itself with the original attributes. |
2 | 292 |
* @exception NamingException If a naming exception was encountered |
293 |
* while using the factories. |
|
294 |
* A factory should only throw an exception if it does not want |
|
295 |
* other factories to be used in an attempt to create an object. |
|
32029
a5538163e144
8132877: docs: replace <tt> tags (obsolete in html5) for javax.naming
avstepan
parents:
25859
diff
changeset
|
296 |
* See {@code DirStateFactory.getStateToBind()}. |
2 | 297 |
* @see DirStateFactory |
298 |
* @see DirStateFactory#getStateToBind |
|
299 |
* @see NamingManager#getStateToBind |
|
300 |
* @since 1.3 |
|
301 |
*/ |
|
302 |
public static DirStateFactory.Result |
|
303 |
getStateToBind(Object obj, Name name, Context nameCtx, |
|
304 |
Hashtable<?,?> environment, Attributes attrs) |
|
305 |
throws NamingException { |
|
306 |
||
307 |
// Get list of state factories |
|
308 |
FactoryEnumeration factories = ResourceManager.getFactories( |
|
309 |
Context.STATE_FACTORIES, environment, nameCtx); |
|
310 |
||
311 |
if (factories == null) { |
|
312 |
// no factories to try; just return originals |
|
313 |
return new DirStateFactory.Result(obj, attrs); |
|
314 |
} |
|
315 |
||
316 |
// Try each factory until one succeeds |
|
317 |
StateFactory factory; |
|
318 |
Object objanswer; |
|
319 |
DirStateFactory.Result answer = null; |
|
320 |
while (answer == null && factories.hasMore()) { |
|
321 |
factory = (StateFactory)factories.next(); |
|
322 |
if (factory instanceof DirStateFactory) { |
|
323 |
answer = ((DirStateFactory)factory). |
|
324 |
getStateToBind(obj, name, nameCtx, environment, attrs); |
|
325 |
} else { |
|
326 |
objanswer = |
|
327 |
factory.getStateToBind(obj, name, nameCtx, environment); |
|
328 |
if (objanswer != null) { |
|
329 |
answer = new DirStateFactory.Result(objanswer, attrs); |
|
330 |
} |
|
331 |
} |
|
332 |
} |
|
333 |
||
334 |
return (answer != null) ? answer : |
|
335 |
new DirStateFactory.Result(obj, attrs); // nothing new |
|
336 |
} |
|
337 |
} |