View Javadoc

1   /*
2    * @(#)InitialEventContext.java Feb 1, 2003
3    * 
4    * Copyright (c) 2003 Delft University of Technology Jaffalaan 5, 2628 BX Delft,
5    * the Netherlands All rights reserved.
6    * 
7    * This software is proprietary information of Delft University of Technology
8    * The code is published under the General Public License
9    */
10  package nl.tudelft.simulation.naming;
11  
12  import java.util.Hashtable;
13  
14  import javax.naming.Context;
15  import javax.naming.Name;
16  import javax.naming.NameParser;
17  import javax.naming.NamingEnumeration;
18  import javax.naming.NamingException;
19  import javax.naming.NoInitialContextException;
20  import javax.naming.event.EventContext;
21  import javax.naming.event.NamingListener;
22  import javax.naming.spi.NamingManager;
23  
24  import com.sun.naming.internal.ResourceManager;
25  
26  /***
27   * This class is the starting context for performing naming operations.
28   * <p>
29   * (c) copyright 2003 <a href="http://www.simulation.tudelft.nl">Delft
30   * University of Technology </a>, the Netherlands. <br>
31   * See for project information <a href="http://www.simulation.tudelft.nl">
32   * www.simulation.tudelft.nl </a> <br>
33   * License of use: <a href="http://www.gnu.org/copyleft/gpl.html">General Public
34   * License (GPL) </a>, no warranty <br>
35   * 
36   * @author <a href="http://www.simulation.tudelft.nl/people/jacobs.html">Peter
37   *         Jacobs </a>
38   * @version 1.2 2004-03-24
39   * @since 1.3
40   */
41  public class InitialEventContext implements EventContext
42  {
43  	/*** the properties of the initialEventContext */
44  	protected Hashtable myProps = null;
45  
46  	/***
47  	 * Field holding the result of calling NamingManager.getInitialContext(). It
48  	 * is set by getDefaultInitCtx() the first time getDefaultInitCtx() is
49  	 * called. Subsequent invocations of getDefaultInitCtx() return the value of
50  	 * defaultInitCtx.
51  	 */
52  	protected EventContext defaultInitCtx = null;
53  
54  	/***
55  	 * Field indicating whether the initial context has been obtained by calling
56  	 * NamingManager.getInitialContext(). If true, its result is in
57  	 * <code>defaultInitCtx</code>.
58  	 */
59  	protected boolean gotDefault = false;
60  
61  	/***
62  	 * Constructs an initial context with the option of not initializing it.
63  	 * This may be used by a constructor in a subclass when the value of the
64  	 * environment parameter is not yet known at the time the
65  	 * <tt>InitialContext</tt> constructor is called. The subclass's
66  	 * constructor will call this constructor, compute the value of the
67  	 * environment, and then call <tt>init()</tt> before returning.
68  	 * 
69  	 * @param lazy true means do not initialize the initial context; false is
70  	 *        equivalent to calling <tt>new InitialContext()</tt>
71  	 * @throws NamingException if a naming exception is encountered
72  	 * 
73  	 * @see #init(Hashtable)
74  	 * @since 1.3
75  	 */
76  	protected InitialEventContext(final boolean lazy) throws NamingException
77  	{
78  		if (!lazy)
79  		{
80  			init(null);
81  		}
82  	}
83  
84  	/***
85  	 * Constructs an initial context. No environment properties are supplied.
86  	 * Equivalent to <tt>new InitialContext(null)</tt>.
87  	 * 
88  	 * @throws NamingException if a naming exception is encountered
89  	 */
90  	public InitialEventContext() throws NamingException
91  	{
92  		init(null);
93  	}
94  
95  	/***
96  	 * Constructs an initial context using the supplied environment. Environment
97  	 * properties are discussed in the class description.
98  	 * 
99  	 * <p>
100 	 * This constructor will not modify <tt>environment</tt> or save a
101 	 * reference to it, but may save a clone.
102 	 * 
103 	 * @param environment environment used to create the initial context. Null
104 	 *        indicates an empty environment.
105 	 * 
106 	 * @throws NamingException if a naming exception is encountered
107 	 */
108 	public InitialEventContext(final Hashtable environment)
109 			throws NamingException
110 	{
111 		if (environment != null)
112 		{
113 			this.init((Hashtable) environment.clone());
114 		} else
115 		{
116 			this.init(environment);
117 		}
118 	}
119 
120 	/***
121 	 * Initializes the initial context using the supplied environment.
122 	 * Environment properties are discussed in the class description.
123 	 * 
124 	 * <p>
125 	 * This method will modify <tt>environment</tt> and save a reference to
126 	 * it. The caller may no longer modify it.
127 	 * 
128 	 * @param environment environment used to create the initial context. Null
129 	 *        indicates an empty environment.
130 	 * 
131 	 * @throws NamingException if a naming exception is encountered
132 	 * 
133 	 * @since 1.3
134 	 */
135 	protected void init(final Hashtable environment) throws NamingException
136 	{
137 		this.myProps = ResourceManager.getInitialEnvironment(environment);
138 
139 		if (this.myProps.get(Context.INITIAL_CONTEXT_FACTORY) != null)
140 		{
141 			// user has specified initial context factory; try to get it
142 			getDefaultInitCtx();
143 		}
144 	}
145 
146 	/***
147 	 * returns the URL Scheme
148 	 * 
149 	 * @param str the string
150 	 * @return URL
151 	 */
152 	private static String getURLScheme(final String str)
153 	{
154 		int colonPosn = str.indexOf(':');
155 		int slashPosn = str.indexOf('/');
156 		if (colonPosn > 0 && (slashPosn == -1 || colonPosn < slashPosn))
157 		{
158 			return str.substring(0, colonPosn);
159 		}
160 		return null;
161 	}
162 
163 	/***
164 	 * Retrieves the initial context by calling
165 	 * NamingManager.getInitialContext() and cache it in defaultInitCtx. Set
166 	 * <code>gotDefault</code> so that we know we've tried this before.
167 	 * 
168 	 * @return The non-null cached initial context.
169 	 * @throws NamingException If a naming exception was encountered.
170 	 */
171 	protected EventContext getDefaultInitCtx() throws NamingException
172 	{
173 		if (!this.gotDefault)
174 		{
175 			this.defaultInitCtx = (EventContext) NamingManager
176 					.getInitialContext(this.myProps);
177 			this.gotDefault = true;
178 		}
179 		if (this.defaultInitCtx == null)
180 		{
181 			throw new NoInitialContextException();
182 		}
183 		return this.defaultInitCtx;
184 	}
185 
186 	/***
187 	 * Retrieves a context for resolving the string name <code>name</code>.
188 	 * If <code>name</code> name is a URL string, then attempt to find a URL
189 	 * context for it. If none is found, or if <code>name</code> is not a URL
190 	 * string, then return <code>getDefaultInitCtx()</code>.
191 	 * <p>
192 	 * See getURLOrDefaultInitCtx(Name) for description of how a subclass should
193 	 * use this method.
194 	 * 
195 	 * @param name The non-null name for which to get the context.
196 	 * @return A URL context for <code>name</code> or the cached initial
197 	 *         context. The result cannot be null.
198 	 * @throws NamingException on exception
199 	 */
200 	protected Context getURLOrDefaultInitCtx(final String name)
201 			throws NamingException
202 	{
203 		if (NamingManager.hasInitialContextFactoryBuilder())
204 		{
205 			return getDefaultInitCtx();
206 		}
207 		String scheme = getURLScheme(name);
208 		if (scheme != null)
209 		{
210 			Context ctx = NamingManager.getURLContext(scheme, this.myProps);
211 			if (ctx != null)
212 			{
213 				return ctx;
214 			}
215 		}
216 		return getDefaultInitCtx();
217 	}
218 
219 	/***
220 	 * @param name The non-null name for which to get the context.
221 	 * @return A URL context for <code>name</code>
222 	 * @throws NamingException In a naming exception is encountered.
223 	 *  
224 	 */
225 	protected Context getURLOrDefaultInitCtx(final Name name)
226 			throws NamingException
227 	{
228 		if (NamingManager.hasInitialContextFactoryBuilder())
229 		{
230 			return getDefaultInitCtx();
231 		}
232 		if (name.size() > 0)
233 		{
234 			String first = name.get(0);
235 			String scheme = getURLScheme(first);
236 			if (scheme != null)
237 			{
238 				Context ctx = NamingManager.getURLContext(scheme, this.myProps);
239 				if (ctx != null)
240 				{
241 					return ctx;
242 				}
243 			}
244 		}
245 		return getDefaultInitCtx();
246 	}
247 
248 	/***
249 	 * @see javax.naming.Context#lookup(java.lang.String)
250 	 */
251 	public Object lookup(final String name) throws NamingException
252 	{
253 		return getURLOrDefaultInitCtx(name).lookup(name);
254 	}
255 
256 	/***
257 	 * @see javax.naming.Context#lookup(javax.naming.Name)
258 	 */
259 	public Object lookup(final Name name) throws NamingException
260 	{
261 		return getURLOrDefaultInitCtx(name).lookup(name);
262 	}
263 
264 	/***
265 	 * @see javax.naming.Context#bind(java.lang.String, java.lang.Object)
266 	 */
267 	public void bind(final String name, final Object obj)
268 			throws NamingException
269 	{
270 		getURLOrDefaultInitCtx(name).bind(name, obj);
271 	}
272 
273 	/***
274 	 * @see javax.naming.Context#bind(javax.naming.Name, java.lang.Object)
275 	 */
276 	public void bind(final Name name, final Object obj) throws NamingException
277 	{
278 		getURLOrDefaultInitCtx(name).bind(name, obj);
279 	}
280 
281 	/***
282 	 * @see javax.naming.Context#rebind(java.lang.String, java.lang.Object)
283 	 */
284 	public void rebind(final String name, final Object obj)
285 			throws NamingException
286 	{
287 		getURLOrDefaultInitCtx(name).rebind(name, obj);
288 	}
289 
290 	/***
291 	 * @see javax.naming.Context#rebind(javax.naming.Name, java.lang.Object)
292 	 */
293 	public void rebind(final Name name, final Object obj)
294 			throws NamingException
295 	{
296 		getURLOrDefaultInitCtx(name).rebind(name, obj);
297 	}
298 
299 	/***
300 	 * @see javax.naming.Context#unbind(java.lang.String)
301 	 */
302 	public void unbind(final String name) throws NamingException
303 	{
304 		getURLOrDefaultInitCtx(name).unbind(name);
305 	}
306 
307 	/***
308 	 * @see javax.naming.Context#unbind(javax.naming.Name)
309 	 */
310 	public void unbind(final Name name) throws NamingException
311 	{
312 		getURLOrDefaultInitCtx(name).unbind(name);
313 	}
314 
315 	/***
316 	 * @see javax.naming.Context#rename(java.lang.String, java.lang.String)
317 	 */
318 	public void rename(final String oldName, final String newName)
319 			throws NamingException
320 	{
321 		getURLOrDefaultInitCtx(oldName).rename(oldName, newName);
322 	}
323 
324 	/***
325 	 * @see javax.naming.Context#rename(javax.naming.Name, javax.naming.Name)
326 	 */
327 	public void rename(final Name oldName, final Name newName)
328 			throws NamingException
329 	{
330 		getURLOrDefaultInitCtx(oldName).rename(oldName, newName);
331 	}
332 
333 	/***
334 	 * @see javax.naming.Context#list(java.lang.String)
335 	 */
336 	public NamingEnumeration list(final String name) throws NamingException
337 	{
338 		return (getURLOrDefaultInitCtx(name).list(name));
339 	}
340 
341 	/***
342 	 * @see javax.naming.Context#list(javax.naming.Name)
343 	 */
344 	public NamingEnumeration list(final Name name) throws NamingException
345 	{
346 		return (getURLOrDefaultInitCtx(name).list(name));
347 	}
348 
349 	/***
350 	 * @see javax.naming.Context#listBindings(java.lang.String)
351 	 */
352 	public NamingEnumeration listBindings(final String name)
353 			throws NamingException
354 	{
355 		return getURLOrDefaultInitCtx(name).listBindings(name);
356 	}
357 
358 	/***
359 	 * @see javax.naming.Context#listBindings(javax.naming.Name)
360 	 */
361 	public NamingEnumeration listBindings(final Name name)
362 			throws NamingException
363 	{
364 		return getURLOrDefaultInitCtx(name).listBindings(name);
365 	}
366 
367 	/***
368 	 * @see javax.naming.Context#destroySubcontext(java.lang.String)
369 	 */
370 	public void destroySubcontext(final String name) throws NamingException
371 	{
372 		getURLOrDefaultInitCtx(name).destroySubcontext(name);
373 	}
374 
375 	/***
376 	 * @see javax.naming.Context#destroySubcontext(javax.naming.Name)
377 	 */
378 	public void destroySubcontext(final Name name) throws NamingException
379 	{
380 		getURLOrDefaultInitCtx(name).destroySubcontext(name);
381 	}
382 
383 	/***
384 	 * @see javax.naming.Context#createSubcontext(java.lang.String)
385 	 */
386 	public Context createSubcontext(final String name) throws NamingException
387 	{
388 		return getURLOrDefaultInitCtx(name).createSubcontext(name);
389 	}
390 
391 	/***
392 	 * @see javax.naming.Context#createSubcontext(javax.naming.Name)
393 	 */
394 	public Context createSubcontext(final Name name) throws NamingException
395 	{
396 		return getURLOrDefaultInitCtx(name).createSubcontext(name);
397 	}
398 
399 	/***
400 	 * @see javax.naming.Context#lookupLink(java.lang.String)
401 	 */
402 	public Object lookupLink(final String name) throws NamingException
403 	{
404 		return getURLOrDefaultInitCtx(name).lookupLink(name);
405 	}
406 
407 	/***
408 	 * @see javax.naming.Context#lookupLink(javax.naming.Name)
409 	 */
410 	public Object lookupLink(final Name name) throws NamingException
411 	{
412 		return getURLOrDefaultInitCtx(name).lookupLink(name);
413 	}
414 
415 	/***
416 	 * @see javax.naming.Context#getNameParser(java.lang.String)
417 	 */
418 	public NameParser getNameParser(final String name) throws NamingException
419 	{
420 		return getURLOrDefaultInitCtx(name).getNameParser(name);
421 	}
422 
423 	/***
424 	 * @see javax.naming.Context#getNameParser(javax.naming.Name)
425 	 */
426 	public NameParser getNameParser(final Name name) throws NamingException
427 	{
428 		return getURLOrDefaultInitCtx(name).getNameParser(name);
429 	}
430 
431 	/***
432 	 * Composes the name of this context with a name relative to this context.
433 	 * Since an initial context may never be named relative to any context other
434 	 * than itself, the value of the <tt>prefix</tt> parameter must be an
435 	 * empty name (<tt>""</tt>).
436 	 * 
437 	 * @param name the name
438 	 * @param prefix the prefix
439 	 * @return String
440 	 * @throws NamingException on exception
441 	 */
442 	public String composeName(final String name, final String prefix)
443 			throws NamingException
444 	{
445 		throw new NamingException("composeName " + name + ", " + prefix
446 				+ " is not supported.");
447 	}
448 
449 	/***
450 	 * Composes the name of this context with a name relative to this context.
451 	 * Since an initial context may never be named relative to any context other
452 	 * than itself, the value of the <tt>prefix</tt> parameter must be an
453 	 * empty name.
454 	 * 
455 	 * @param name the name
456 	 * @param prefix the prefix
457 	 * @return Name
458 	 * @throws NamingException on exception
459 	 */
460 	public Name composeName(final Name name, final Name prefix)
461 			throws NamingException
462 	{
463 		throw new NamingException("composeName " + name + ", " + prefix
464 				+ " is not supported.");
465 	}
466 
467 	/***
468 	 * @see javax.naming.Context #addToEnvironment(java.lang.String,
469 	 *      java.lang.Object)
470 	 */
471 	public Object addToEnvironment(final String propName, final Object propVal)
472 			throws NamingException
473 	{
474 		this.myProps.put(propName, propVal);
475 		return getDefaultInitCtx().addToEnvironment(propName, propVal);
476 	}
477 
478 	/***
479 	 * @see javax.naming.Context#removeFromEnvironment(java.lang.String)
480 	 */
481 	public Object removeFromEnvironment(final String propName)
482 			throws NamingException
483 	{
484 		this.myProps.remove(propName);
485 		return getDefaultInitCtx().removeFromEnvironment(propName);
486 	}
487 
488 	/***
489 	 * @see javax.naming.Context#getEnvironment()
490 	 */
491 	public Hashtable getEnvironment() throws NamingException
492 	{
493 		return getDefaultInitCtx().getEnvironment();
494 	}
495 
496 	/***
497 	 * @see javax.naming.Context#close()
498 	 */
499 	public void close() throws NamingException
500 	{
501 		this.myProps = null;
502 		if (this.defaultInitCtx != null)
503 		{
504 			this.defaultInitCtx.close();
505 			this.defaultInitCtx = null;
506 		}
507 		this.gotDefault = false;
508 	}
509 
510 	/***
511 	 * @see javax.naming.Context#getNameInNamespace()
512 	 */
513 	public String getNameInNamespace() throws NamingException
514 	{
515 		return getDefaultInitCtx().getNameInNamespace();
516 	}
517 
518 	/***
519 	 * @see javax.naming.event.EventContext
520 	 *      #addNamingListener(javax.naming.Name, int, NamingListener)
521 	 */
522 	public void addNamingListener(final Name target, final int scope,
523 			final NamingListener l) throws NamingException
524 	{
525 		this.getDefaultInitCtx().addNamingListener(target, scope, l);
526 	}
527 
528 	/***
529 	 * @see javax.naming.event.EventContext #addNamingListener(java.lang.String,
530 	 *      int, NamingListener)
531 	 */
532 	public void addNamingListener(final String target, final int scope,
533 			final NamingListener l) throws NamingException
534 	{
535 		this.getDefaultInitCtx().addNamingListener(target, scope, l);
536 	}
537 
538 	/***
539 	 * @see javax.naming.event.EventContext
540 	 *      #removeNamingListener(javax.naming.event.NamingListener)
541 	 */
542 	public void removeNamingListener(final NamingListener l)
543 			throws NamingException
544 	{
545 		this.getDefaultInitCtx().removeNamingListener(l);
546 	}
547 
548 	/***
549 	 * @see javax.naming.event.EventContext#targetMustExist()
550 	 */
551 	public boolean targetMustExist() throws NamingException
552 	{
553 		return this.getDefaultInitCtx().targetMustExist();
554 	}
555 }