1 /* InitialContext.java -- Initial naming context.
2 Copyright (C) 2000, 2002, 2003, 2004, 2006 Free Software Foundation, Inc.
4 This file is part of GNU Classpath.
6 GNU Classpath is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2, or (at your option)
11 GNU Classpath is distributed in the hope that it will be useful, but
12 WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with GNU Classpath; see the file COPYING. If not, write to the
18 Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
21 Linking this library statically or dynamically with other modules is
22 making a combined work based on this library. Thus, the terms and
23 conditions of the GNU General Public License cover the whole
26 As a special exception, the copyright holders of this library give you
27 permission to link this library with independent modules to produce an
28 executable, regardless of the license terms of these independent
29 modules, and to copy and distribute the resulting executable under
30 terms of your choice, provided that you also meet, for each linked
31 independent module, the terms and conditions of the license of that
32 module. An independent module is a module which is not derived from
33 or based on this library. If you modify this library, you may extend
34 this exception to your version of the library, but you are not
35 obligated to do so. If you do not wish to do so, delete this
36 exception statement from your version. */
41 import java.applet.Applet;
42 import java.io.IOException;
43 import java.io.InputStream;
45 import java.util.Enumeration;
46 import java.util.HashSet;
47 import java.util.Hashtable;
48 import java.util.Properties;
50 import javax.naming.spi.NamingManager;
53 * The starting context for performing naming operations. All naming operations
54 * are performed in the scope of some context. The initial context is the
55 * starting point for the name resolution.
57 public class InitialContext implements Context
60 * Contains the default initial context. This value is returned by
61 * {@link NamingManager#getInitialContext}. It is set by this method
62 * when calling it first time. The subsequent calls return the value of
65 protected Context defaultInitCtx;
68 * Indicates if the initial context was obtained by calling
69 * {@link NamingManager#getInitialContext}.
71 protected boolean gotDefault = false;
74 * The environment, associated with this initial context.
76 protected Hashtable<Object,Object> myProps;
79 * The list of the properties, to that the second alternative value must
80 * be appended after the colon to the first possible value. Used in
81 * {@link #merge(Hashtable, Hashtable)}
83 static final HashSet colon_list;
86 colon_list = new HashSet();
87 colon_list.add(Context.OBJECT_FACTORIES);
88 colon_list.add(Context.URL_PKG_PREFIXES);
89 colon_list.add(Context.STATE_FACTORIES);
93 * The properties that are searched in the agreed places in the
94 * {@link #init(Hashtable)} method.
96 static final String[] use_properties =
99 Context.INITIAL_CONTEXT_FACTORY,
100 Context.OBJECT_FACTORIES,
101 Context.PROVIDER_URL,
102 Context.STATE_FACTORIES,
103 Context.URL_PKG_PREFIXES,
108 * Creates the new initial context with the given properties.
110 * @param environment the properties, used by the initial context being
112 * @throws NamingException
114 public InitialContext(Hashtable<?,?> environment) throws NamingException
120 * Creates the initial context with the possibility to delay its
123 * @param lazy specified if the initialization should not be performed by this
124 * constructor (true). If the valueis false, it works the same way as
125 * the parameterless constructor.
126 * @throws NamingException
128 protected InitialContext(boolean lazy) throws NamingException
135 * Creates teh new initial context with no properties. Same as
136 * InitialContext(null).
138 * @throws NamingException
140 public InitialContext() throws NamingException
147 * Initialises the context, using the properties, specified in the passed
150 * The missing properties are additionally obtained (in order) from the
151 * following locations:
153 * <li>If the passed parameter contains the key Context.APPLET, its value
154 * must be the instance of the {@link Applet}. Then the properties are
155 * requested via {@link Applet#getParameter(String)}.</li>
156 * <li>The value of the system property is used.</li>
157 * <li>The resource "jndi.properties" is requested from the context class
158 * loader of the current thread</li>
159 * <li>The property file "jndi.properties" is read from the location,
160 * specified by the system property "gnu.classpath.home.url".
164 * @param environment the table of the properties, may be null. The method
165 * modifies the table and stores the reference to it. The caller must
166 * not later reuse this structure for other purposes.
169 protected void init(Hashtable<?, ?> environment) throws NamingException
171 // If is documented that the caller should not modify the environment.
172 if (environment != null)
173 myProps = (Hashtable<Object, Object>) environment;
175 myProps = new Hashtable<Object, Object>();
177 Applet napplet = (Applet) myProps.get(Context.APPLET);
179 Properties pApplet = null;
181 pApplet = new Properties();
182 Properties pSystem = new Properties();
185 for (int i = use_properties.length - 1; i >= 0; i--)
187 String key = use_properties[i];
190 value = napplet.getParameter(key);
192 pApplet.put(key, value);
195 value = System.getProperty(key);
197 pSystem.put(key, value);
200 merge(myProps, pSystem);
202 merge(myProps, pApplet);
206 Enumeration ep = Thread.currentThread().
207 getContextClassLoader().getResources("jndi.properties");
208 while (ep.hasMoreElements())
210 URL url = (URL) ep.nextElement();
211 Properties p = new Properties();
215 InputStream is = url.openStream();
219 catch (IOException e)
227 catch (IOException e)
232 String home = System.getProperty("gnu.classpath.home.url");
235 String url = home + "/jndi.properties";
236 Properties p = new Properties();
240 InputStream is = new URL(url).openStream();
244 catch (IOException e)
254 * Merge the content of the two tables. If the second table contains the key
255 * that is missing in the first table, this key - value pair is copied to the
256 * first table. If both first and second tables contain the same key AND the
257 * {@link #colon_list} set also contains this key, the value from the second
258 * table is appended to the value from the first table after semicolon, and
259 * the resulted value replaces the value in the first table.
261 * @param primary the first table to merge. The merged result is also stored
263 * @param additional the second table, from where additional values are taken
265 static void merge (Hashtable primary, Hashtable additional)
267 Enumeration en = additional.keys();
269 while (en.hasMoreElements())
271 String key2 = (String) en.nextElement();
272 Object value1 = primary.get(key2);
274 primary.put(key2, additional.get(key2));
275 else if (colon_list.contains(key2))
277 String value2 = (String) additional.get(key2);
278 primary.put(key2, (String) value1 + ":" + value2);
284 * Get the default initial context. If {@link #gotDefault} == false, this
285 * method obtains the initial context from the naming manager and sets
286 * gotDefault to true. Otherwise the cached value ({@link #defaultInitCtx} is
289 * @return the default initial context
290 * @throws NamingException
292 protected Context getDefaultInitCtx() throws NamingException
296 defaultInitCtx = NamingManager.getInitialContext(myProps);
299 return defaultInitCtx;
303 * Obtains the context for resolving the given name. If the first component of
304 * the name is the URL string, this method tries to find the corressponding
305 * URL naming context. If it is not an URL string, or the URL context is not
306 * found, the default initial context is returned.
308 * @param name the name, for that it is required to obtain the context.
309 * @return the context for resolving the name.
310 * @throws NamingException
312 protected Context getURLOrDefaultInitCtx(Name name) throws NamingException
315 return getURLOrDefaultInitCtx(name.get(0));
317 return getDefaultInitCtx();
321 * Obtains the context for resolving the given name. If the first component of
322 * the name is the URL string, this method tries to find the corressponding
323 * URL naming context. If it is not an URL string, or the URL context is not
324 * found, the default initial context is returned.
326 * @param name the name, for that it is required to obtain the context.
327 * @return the context for resolving the name.
328 * @throws NamingException
330 protected Context getURLOrDefaultInitCtx(String name) throws NamingException
332 String scheme = null;
334 if (NamingManager.hasInitialContextFactoryBuilder())
335 return getDefaultInitCtx();
336 int colon = name.indexOf(':');
337 int slash = name.indexOf('/');
338 if (colon > 0 && (slash == - 1 || colon < slash))
339 scheme = name.substring(0, colon);
342 Context context = NamingManager.getURLContext(scheme, myProps);
347 return getDefaultInitCtx();
351 public void bind (Name name, Object obj) throws NamingException
353 getURLOrDefaultInitCtx (name).bind (name, obj);
357 public void bind (String name, Object obj) throws NamingException
359 getURLOrDefaultInitCtx (name).bind (name, obj);
363 public Object lookup (Name name) throws NamingException
367 return getURLOrDefaultInitCtx (name).lookup (name);
369 catch (CannotProceedException cpe)
371 Context ctx = NamingManager.getContinuationContext (cpe);
372 return ctx.lookup (cpe.getRemainingName());
377 public Object lookup (String name) throws NamingException
381 return getURLOrDefaultInitCtx (name).lookup (name);
383 catch (CannotProceedException cpe)
385 Context ctx = NamingManager.getContinuationContext (cpe);
386 return ctx.lookup (cpe.getRemainingName());
391 public void rebind (Name name, Object obj) throws NamingException
393 getURLOrDefaultInitCtx (name).rebind (name, obj);
397 public void rebind (String name, Object obj) throws NamingException
399 getURLOrDefaultInitCtx (name).rebind (name, obj);
403 public void unbind (Name name) throws NamingException
405 getURLOrDefaultInitCtx (name).unbind (name);
409 public void unbind (String name) throws NamingException
411 getURLOrDefaultInitCtx (name).unbind (name);
415 public void rename (Name oldName, Name newName) throws NamingException
417 getURLOrDefaultInitCtx (oldName).rename (oldName, newName);
421 public void rename (String oldName, String newName) throws NamingException
423 getURLOrDefaultInitCtx (oldName).rename (oldName, newName);
427 public NamingEnumeration<NameClassPair> list (Name name) throws NamingException
429 return getURLOrDefaultInitCtx (name).list (name);
433 public NamingEnumeration<NameClassPair> list (String name) throws NamingException
435 return getURLOrDefaultInitCtx (name).list (name);
439 public NamingEnumeration<Binding> listBindings (Name name) throws NamingException
441 return getURLOrDefaultInitCtx (name).listBindings (name);
445 public NamingEnumeration<Binding> listBindings (String name) throws NamingException
447 return getURLOrDefaultInitCtx (name).listBindings (name);
451 public void destroySubcontext (Name name) throws NamingException
453 getURLOrDefaultInitCtx (name).destroySubcontext (name);
457 public void destroySubcontext (String name) throws NamingException
459 getURLOrDefaultInitCtx (name).destroySubcontext (name);
463 public Context createSubcontext (Name name) throws NamingException
465 return getURLOrDefaultInitCtx (name).createSubcontext (name);
469 public Context createSubcontext (String name) throws NamingException
471 return getURLOrDefaultInitCtx (name).createSubcontext (name);
475 public Object lookupLink (Name name) throws NamingException
477 return getURLOrDefaultInitCtx (name).lookupLink (name);
481 public Object lookupLink (String name) throws NamingException
483 return getURLOrDefaultInitCtx (name).lookupLink (name);
487 public NameParser getNameParser (Name name) throws NamingException
489 return getURLOrDefaultInitCtx (name).getNameParser (name);
493 public NameParser getNameParser (String name) throws NamingException
495 return getURLOrDefaultInitCtx (name).getNameParser (name);
499 public Name composeName (Name name, Name prefix) throws NamingException
501 return getURLOrDefaultInitCtx (name).composeName (name, prefix);
505 public String composeName (String name,
506 String prefix) throws NamingException
508 return getURLOrDefaultInitCtx (name).composeName (name, prefix);
512 public Object addToEnvironment (String propName,
513 Object propVal) throws NamingException
515 return myProps.put (propName, propVal);
519 public Object removeFromEnvironment (String propName) throws NamingException
521 return myProps.remove (propName);
525 public Hashtable<?,?> getEnvironment () throws NamingException
531 public void close () throws NamingException
534 defaultInitCtx = null;
538 * This operation is not supported for the initial naming context.
540 * @throws OperationNotSupportedException always, unless the method is
541 * overridden in the derived class.
543 public String getNameInNamespace () throws NamingException
545 throw new OperationNotSupportedException ();