001: /**
002: * EasyBeans
003: * Copyright (C) 2006 Bull S.A.S.
004: * Contact: easybeans@ow2.org
005: *
006: * This library is free software; you can redistribute it and/or
007: * modify it under the terms of the GNU Lesser General Public
008: * License as published by the Free Software Foundation; either
009: * version 2.1 of the License, or any later version.
010: *
011: * This library is distributed in the hope that it will be useful,
012: * but WITHOUT ANY WARRANTY; without even the implied warranty of
013: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
014: * Lesser General Public License for more details.
015: *
016: * You should have received a copy of the GNU Lesser General Public
017: * License along with this library; if not, write to the Free Software
018: * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
019: * USA
020: *
021: * --------------------------------------------------------------------------
022: * $Id: JavaURLContext.java 1970 2007-10-16 11:49:25Z benoitf $
023: * --------------------------------------------------------------------------
024: */package org.ow2.easybeans.naming.pkg.java;
025:
026: import java.util.Hashtable;
027:
028: import javax.naming.Binding;
029: import javax.naming.Context;
030: import javax.naming.Name;
031: import javax.naming.NameClassPair;
032: import javax.naming.NameNotFoundException;
033: import javax.naming.NameParser;
034: import javax.naming.NamingEnumeration;
035: import javax.naming.NamingException;
036:
037: import org.ow2.easybeans.naming.NamingManager;
038: import org.ow2.util.log.Log;
039: import org.ow2.util.log.LogFactory;
040:
041: /**
042: * Context implementation for the "java:" namespace. <br>
043: * @author Florent Benoit
044: */
045: public class JavaURLContext implements Context {
046:
047: /**
048: * java: prefix.
049: */
050: private static final String JAVA_PREFIX = "java:";
051:
052: /**
053: * Reference on the naming manager.
054: */
055: private static NamingManager namingManager = null;
056:
057: /**
058: * Logger.
059: */
060: private static Log logger = LogFactory.getLog(JavaURLContext.class);
061:
062: /**
063: * Constructor.
064: * @throws NamingException if naming manager is not found.
065: */
066: public JavaURLContext() throws NamingException {
067: if (namingManager == null) {
068: namingManager = NamingManager.getInstance();
069: }
070: }
071:
072: /**
073: * Get name without the url prefix.
074: * @param name the absolute name.
075: * @return the relative name (without prefix).
076: * @throws NamingException if the naming failed.
077: */
078: private String getRelativeName(final String name)
079: throws NamingException {
080: String newName = name;
081: // We suppose that all names must be prefixed as this
082: if (!name.startsWith(JAVA_PREFIX)) {
083: logger.error("relative name! {0}" + name);
084: throw new NameNotFoundException("Invalid name:" + name);
085: }
086: if (name.endsWith("/")) {
087: newName = name.substring(JAVA_PREFIX.length() + 1);
088: } else {
089: newName = name.substring(JAVA_PREFIX.length());
090: }
091:
092: return newName;
093: }
094:
095: /**
096: * Get name without the url prefix.
097: * @param name the absolute name.
098: * @return the relative name (without prefix).
099: * @throws NamingException if the naming failed.
100: */
101: private Name getRelativeName(final Name name)
102: throws NamingException {
103: if (name.get(0).equals(JAVA_PREFIX)) {
104: return (name.getSuffix(1));
105: }
106: throw new NameNotFoundException("Invalid name:" + name);
107: }
108:
109: /**
110: * Retrieves the named object.
111: * @param name the name of the object to look up
112: * @return the object bound to name
113: * @throws NamingException if a naming exception is encountered
114: */
115: public Object lookup(final Name name) throws NamingException {
116: return findContext().lookup(getRelativeName(name));
117: }
118:
119: /**
120: * Retrieves the named object.
121: * @param name the name of the object to look up
122: * @return the object bound to name
123: * @throws NamingException if a naming exception is encountered
124: */
125: public Object lookup(final String name) throws NamingException {
126: return findContext().lookup(getRelativeName(name));
127: }
128:
129: /**
130: * Binds a name to an object.
131: * @param name the name to bind; may not be empty
132: * @param obj the object to bind; possibly null
133: * @throws NamingException if a naming exception is encountered
134: */
135: public void bind(final Name name, final Object obj)
136: throws NamingException {
137: findContext().bind(getRelativeName(name), obj);
138: }
139:
140: /**
141: * Binds a name to an object. All intermediate contexts and the target
142: * context (that named by all but terminal atomic component of the name)
143: * must already exist.
144: * @param name the name to bind; may not be empty
145: * @param obj the object to bind; possibly null
146: * @throws NamingException if a naming exception is encountered
147: */
148: public void bind(final String name, final Object obj)
149: throws NamingException {
150: findContext().bind(getRelativeName(name), obj);
151: }
152:
153: /**
154: * Binds a name to an object, overwriting any existing binding. All
155: * intermediate contexts and the target context (that named by all but
156: * terminal atomic component of the name) must already exist. If the object
157: * is a DirContext, any existing attributes associated with the name are
158: * replaced with those of the object. Otherwise, any existing attributes
159: * associated with the name remain unchanged.
160: * @param name the name to bind; may not be empty
161: * @param obj the object to bind; possibly null
162: * @throws NamingException if a naming exception is encountered
163: */
164: public void rebind(final Name name, final Object obj)
165: throws NamingException {
166: findContext().rebind(getRelativeName(name), obj);
167: }
168:
169: /**
170: * Binds a name to an object, overwriting any existing binding. See
171: * {@link #rebind(Name, Object)}for details.
172: * @param name the name to bind; may not be empty
173: * @param obj the object to bind; possibly null
174: * @throws NamingException if a naming exception is encountered
175: */
176: public void rebind(final String name, final Object obj)
177: throws NamingException {
178: findContext().rebind(getRelativeName(name), obj);
179: }
180:
181: /**
182: * Unbinds the named object. Removes the terminal atomic name in name from
183: * the target context--that named by all but the terminal atomic part of
184: * name. This method is idempotent. It succeeds even if the terminal atomic
185: * name is not bound in the target context, but throws NameNotFoundException
186: * if any of the intermediate contexts do not exist. Any attributes
187: * associated with the name are removed. Intermediate contexts are not
188: * changed.
189: * @param name the name to unbind; may not be empty
190: * @throws NamingException if a naming exception is encountered
191: * @see #unbind(String)
192: */
193: public void unbind(final Name name) throws NamingException {
194: findContext().unbind(getRelativeName(name));
195: }
196:
197: /**
198: * Unbinds the named object. See {@link #unbind(Name)}for details.
199: * @param name the name to unbind; may not be empty
200: * @throws NamingException if a naming exception is encountered
201: */
202: public void unbind(final String name) throws NamingException {
203: findContext().unbind(getRelativeName(name));
204: }
205:
206: /**
207: * Binds a new name to the object bound to an old name, and unbinds the old
208: * name. This operation is not supported (read only env.)
209: * @param oldName the name of the existing binding; may not be empty
210: * @param newName the name of the new binding; may not be empty
211: * @throws NamingException if a naming exception is encountered
212: */
213: public void rename(final Name oldName, final Name newName)
214: throws NamingException {
215: findContext().rename(getRelativeName(oldName),
216: getRelativeName(newName));
217: }
218:
219: /**
220: * Binds a new name to the object bound to an old name, and unbinds the old
221: * name. Not supported.
222: * @param oldName the name of the existing binding; may not be empty
223: * @param newName the name of the new binding; may not be empty
224: * @throws NamingException if a naming exception is encountered
225: */
226: public void rename(final String oldName, final String newName)
227: throws NamingException {
228: findContext().rename(getRelativeName(oldName),
229: getRelativeName(newName));
230: }
231:
232: /**
233: * Enumerates the names bound in the named context, along with the class
234: * names of objects bound to them. The contents of any subcontexts are not
235: * included. If a binding is added to or removed from this context, its
236: * effect on an enumeration previously returned is undefined.
237: * @param name the name of the context to list
238: * @return an enumeration of the names and class names of the bindings in
239: * this context. Each element of the enumeration is of type
240: * NameClassPair.
241: * @throws NamingException if a naming exception is encountered
242: */
243: public NamingEnumeration<NameClassPair> list(final Name name)
244: throws NamingException {
245: return findContext().list(getRelativeName(name));
246: }
247:
248: /**
249: * Enumerates the names bound in the named context, along with the class
250: * names of objects bound to them. See {@link #list(Name)}for details.
251: * @param name the name of the context to list
252: * @return an enumeration of the names and class names of the bindings in
253: * this context. Each element of the enumeration is of type
254: * NameClassPair.
255: * @throws NamingException if a naming exception is encountered
256: */
257: public NamingEnumeration<NameClassPair> list(final String name)
258: throws NamingException {
259: return findContext().list(getRelativeName(name));
260: }
261:
262: /**
263: * Enumerates the names bound in the named context, along with the objects
264: * bound to them. The contents of any subcontexts are not included. If a
265: * binding is added to or removed from this context, its effect on an
266: * enumeration previously returned is undefined.
267: * @param name the name of the context to list
268: * @return an enumeration of the bindings in this context. Each element of
269: * the enumeration is of type Binding.
270: * @throws NamingException if a naming exception is encountered
271: */
272: public NamingEnumeration<Binding> listBindings(final Name name)
273: throws NamingException {
274: return findContext().listBindings(getRelativeName(name));
275: }
276:
277: /**
278: * Enumerates the names bound in the named context, along with the objects
279: * bound to them. See {@link #listBindings(Name)}for details.
280: * @param name the name of the context to list
281: * @return an enumeration of the bindings in this context. Each element of
282: * the enumeration is of type Binding.
283: * @throws NamingException if a naming exception is encountered
284: */
285: public NamingEnumeration<Binding> listBindings(final String name)
286: throws NamingException {
287: return findContext().listBindings(getRelativeName(name));
288: }
289:
290: /**
291: * Destroys the named context and removes it from the namespace. Any
292: * attributes associated with the name are also removed. Intermediate
293: * contexts are not destroyed. This method is idempotent. It succeeds even
294: * if the terminal atomic name is not bound in the target context, but
295: * throws NameNotFoundException if any of the intermediate contexts do not
296: * exist. In a federated naming system, a context from one naming system may
297: * be bound to a name in another. One can subsequently look up and perform
298: * operations on the foreign context using a composite name. However, an
299: * attempt destroy the context using this composite name will fail with
300: * NotContextException, because the foreign context is not a "subcontext" of
301: * the context in which it is bound. Instead, use unbind() to remove the
302: * binding of the foreign context. Destroying the foreign context requires
303: * that the destroySubcontext() be performed on a context from the foreign
304: * context's "native" naming system.
305: * @param name the name of the context to be destroyed; may not be empty
306: * @throws NamingException if a naming exception is encountered
307: */
308: public void destroySubcontext(final Name name)
309: throws NamingException {
310: findContext().destroySubcontext(getRelativeName(name));
311: }
312:
313: /**
314: * Destroys the named context and removes it from the namespace. See
315: * {@link #destroySubcontext(Name)}for details.
316: * @param name the name of the context to be destroyed; may not be empty
317: * @throws NamingException if a naming exception is encountered
318: */
319: public void destroySubcontext(final String name)
320: throws NamingException {
321: findContext().destroySubcontext(getRelativeName(name));
322: }
323:
324: /**
325: * Creates and binds a new context. Creates a new context with the given
326: * name and binds it in the target context (that named by all but terminal
327: * atomic component of the name). All intermediate contexts and the target
328: * context must already exist.
329: * @param name the name of the context to create; may not be empty
330: * @return the newly created context
331: * @throws NamingException if a naming exception is encountered
332: */
333: public Context createSubcontext(final Name name)
334: throws NamingException {
335: return findContext().createSubcontext(getRelativeName(name));
336: }
337:
338: /**
339: * Creates and binds a new context. See {@link #createSubcontext(Name)}for
340: * details.
341: * @param name the name of the context to create; may not be empty
342: * @return the newly created context
343: * @throws NamingException if a naming exception is encountered
344: */
345: public Context createSubcontext(final String name)
346: throws NamingException {
347: return findContext().createSubcontext(getRelativeName(name));
348: }
349:
350: /**
351: * Retrieves the named object, following links except for the terminal
352: * atomic component of the name. If the object bound to name is not a link,
353: * returns the object itself.
354: * @param name the name of the object to look up
355: * @return the object bound to name, not following the terminal link (if
356: * any).
357: * @throws NamingException if a naming exception is encountered
358: */
359: public Object lookupLink(final Name name) throws NamingException {
360: return findContext().lookupLink(getRelativeName(name));
361: }
362:
363: /**
364: * Retrieves the named object, following links except for the terminal
365: * atomic component of the name. See {@link #lookupLink(Name)}for details.
366: * @param name the name of the object to look up
367: * @return the object bound to name, not following the terminal link (if
368: * any)
369: * @throws NamingException if a naming exception is encountered
370: */
371: public Object lookupLink(final String name) throws NamingException {
372: return findContext().lookupLink(getRelativeName(name));
373: }
374:
375: /**
376: * Retrieves the parser associated with the named context. In a federation
377: * of namespaces, different naming systems will parse names differently.
378: * This method allows an application to get a parser for parsing names into
379: * their atomic components using the naming convention of a particular
380: * naming system. Within any single naming system, NameParser objects
381: * returned by this method must be equal (using the equals() test).
382: * @param name the name of the context from which to get the parser
383: * @return a name parser that can parse compound names into their atomic
384: * components
385: * @throws NamingException if a naming exception is encountered
386: */
387: public NameParser getNameParser(final Name name)
388: throws NamingException {
389: return findContext().getNameParser(getRelativeName(name));
390: }
391:
392: /**
393: * Retrieves the parser associated with the named context. See
394: * {@link #getNameParser(Name)}for details.
395: * @param name the name of the context from which to get the parser
396: * @return a name parser that can parse compound names into their atomic
397: * components
398: * @throws NamingException if a naming exception is encountered
399: */
400: public NameParser getNameParser(final String name)
401: throws NamingException {
402: return findContext().getNameParser(getRelativeName(name));
403: }
404:
405: /**
406: * Composes the name of this context with a name relative to this context.
407: * @param name a name relative to this context
408: * @param prefix the name of this context relative to one of its ancestors
409: * @return the composition of prefix and name
410: * @throws NamingException if a naming exception is encountered
411: */
412: public Name composeName(final Name name, final Name prefix)
413: throws NamingException {
414: Name newPrefix = (Name) name.clone();
415: return newPrefix.addAll(name);
416: }
417:
418: /**
419: * Composes the name of this context with a name relative to this context.
420: * @param name a name relative to this context
421: * @param prefix the name of this context relative to one of its ancestors
422: * @return the composition of prefix and name
423: * @throws NamingException if a naming exception is encountered
424: */
425: public String composeName(final String name, final String prefix)
426: throws NamingException {
427: return prefix + "/" + name;
428: }
429:
430: /**
431: * Adds a new environment property to the environment of this context. If
432: * the property already exists, its value is overwritten. See class
433: * description for more details on environment properties.
434: * @param propName the name of the environment property to add; may not be
435: * null
436: * @param propVal the value of the property to add; may not be null
437: * @return the previous value of the property, or null if the property was
438: * not in the environment before
439: * @throws NamingException if a naming exception is encountered
440: */
441: public Object addToEnvironment(final String propName,
442: final Object propVal) throws NamingException {
443: return findContext().addToEnvironment(propName, propVal);
444: }
445:
446: /**
447: * Removes an environment property from the environment of this context. See
448: * class description for more details on environment properties.
449: * @param propName the name of the environment property to remove; may not
450: * be null
451: * @return the previous value of the property, or null if the property was
452: * not in the environment
453: * @throws NamingException if a naming exception is encountered
454: */
455: public Object removeFromEnvironment(final String propName)
456: throws NamingException {
457: return findContext().removeFromEnvironment(propName);
458: }
459:
460: /**
461: * Retrieves the environment in effect for this context. See class
462: * description for more details on environment properties. The caller should
463: * not make any changes to the object returned: their effect on the context
464: * is undefined. The environment of this context may be changed using
465: * addToEnvironment() and removeFromEnvironment().
466: * @return the environment of this context; never null
467: * @throws NamingException if a naming exception is encountered
468: */
469: public Hashtable<?, ?> getEnvironment() throws NamingException {
470: return findContext().getEnvironment();
471: }
472:
473: /**
474: * Closes this context. This method releases this context's resources
475: * immediately, instead of waiting for them to be released automatically by
476: * the garbage collector. This method is idempotent: invoking it on a
477: * context that has already been closed has no effect. Invoking any other
478: * method on a closed context is not allowed, and results in undefined
479: * behaviour.
480: * @throws NamingException if a naming exception is encountered
481: */
482: public void close() throws NamingException {
483: findContext().close();
484: }
485:
486: /**
487: * Retrieves the full name of this context within its own namespace.
488: * @return this context's name in its own namespace; never null
489: * @throws NamingException if a naming exception is encountered
490: */
491: public String getNameInNamespace() throws NamingException {
492: return JAVA_PREFIX;
493: }
494:
495: /**
496: * @return the Context associated with the current thread.
497: * @throws NamingException if no context is found.
498: */
499: public Context findContext() throws NamingException {
500: return namingManager.getComponentContext();
501: }
502:
503: }
|