001: /*
002: *
003: * JOnAS: Java(TM) Open Application Server
004: * Copyright (C) 1999 Bull S.A.
005: * Contact: jonas-team@objectweb.org
006: *
007: * This library is free software; you can redistribute it and/or
008: * modify it under the terms of the GNU Lesser General Public
009: * License as published by the Free Software Foundation; either
010: * version 2.1 of the License, or any later version.
011: *
012: * This library is distributed in the hope that it will be useful,
013: * but WITHOUT ANY WARRANTY; without even the implied warranty of
014: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
015: * Lesser General Public License for more details.
016: *
017: * You should have received a copy of the GNU Lesser General Public
018: * License along with this library; if not, write to the Free Software
019: * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
020: * USA
021: *
022: * --------------------------------------------------------------------------
023: * $Id: javaURLContext.java 3493 2003-10-09 13:53:09Z durieuxp $
024: * --------------------------------------------------------------------------
025: */
026:
027: package org.objectweb.jonas.naming.java;
028:
029: import java.util.Hashtable;
030:
031: import javax.naming.Context;
032: import javax.naming.Name;
033: import javax.naming.NameNotFoundException;
034: import javax.naming.NameParser;
035: import javax.naming.NamingEnumeration;
036: import javax.naming.NamingException;
037:
038: import org.objectweb.jonas.common.Log;
039: import org.objectweb.jonas.naming.EJBNameParser;
040: import org.objectweb.jonas.naming.NamingManager;
041:
042: import org.objectweb.util.monolog.api.Logger;
043: import org.objectweb.util.monolog.api.BasicLevel;
044:
045: /**
046: * Context implementation for the "java:" namespace.
047: * Package must be named .../java (See Initial Context)
048: * Most operations consist of retrieving the actual CompNamingContext
049: * and sending it the operation for processing.
050: *
051: * @author Philippe Durieux
052: * Contributor(s):
053: * Philippe Coq Monolog
054: */
055: public class javaURLContext implements Context {
056:
057: /**
058: * Logger used by JOnAS
059: */
060: private static Logger logger = Log
061: .getLogger(Log.JONAS_NAMING_PREFIX);
062:
063: /**
064: * Url prefix, ie : java:
065: */
066: private static final String URL_PREFIX = "java:";
067:
068: /**
069: * Environment
070: */
071: private Hashtable myEnv = null;
072:
073: /**
074: * Name Parser
075: */
076: private static NameParser myParser = new EJBNameParser();
077:
078: /**
079: * Naming manager.
080: * Manage component contexts.
081: */
082: private static NamingManager naming;
083:
084: /*
085: * Get unique instance
086: */
087: static {
088: try {
089: naming = NamingManager.getInstance();
090: } catch (Exception e) {
091: logger.log(BasicLevel.ERROR,
092: "cannot get instance of NamingManager");
093: }
094: }
095:
096: /**
097: * Constructor
098: * @param env the environment
099: * @throws NamingException if it can be built.
100: */
101: public javaURLContext(Hashtable env) throws NamingException {
102: myEnv = (Hashtable) env.clone();
103: }
104:
105: /**
106: * Get name without the url prefix.
107: * @param name the absolute name.
108: * @return the relative name (without prefix).
109: * @throws NamingException if the naming failed.
110: */
111: private String getRelativeName(String name) throws NamingException {
112:
113: // We suppose that all names must be prefixed as this
114: if (!name.startsWith(URL_PREFIX)) {
115: logger.log(BasicLevel.ERROR, "relative name! :" + name);
116: throw new NameNotFoundException("Invalid name:" + name);
117: }
118: if (name.endsWith("/")) {
119: name = name.substring(URL_PREFIX.length() + 1);
120: } else {
121: name = name.substring(URL_PREFIX.length());
122: }
123:
124: return name;
125: }
126:
127: /**
128: * Get name without the url prefix.
129: * @param name the absolute name.
130: * @return the relative name (without prefix).
131: * @throws NamingException if the naming failed.
132: */
133: private Name getRelativeName(Name name) throws NamingException {
134: if (name.get(0).equals(URL_PREFIX)) {
135: return (name.getSuffix(1));
136: } else {
137: logger.log(BasicLevel.ERROR, "relative name! :" + name);
138: throw new NameNotFoundException("Invalid name:" + name);
139: }
140: }
141:
142: /**
143: * Return the context
144: * - of the web components
145: * - of the ejb components
146: * - of the catalina server
147: * - else error
148: * @return the right context which is hierarchical.
149: */
150: private Context findContext() throws NamingException {
151: return naming.getComponentContext();
152: }
153:
154: // ------------------------------------------------------------------
155: // Context implementation
156: // ------------------------------------------------------------------
157:
158: /**
159: * Retrieves the named object.
160: *
161: * @param name the name of the object to look up
162: * @return the object bound to name
163: * @throws NamingException if a naming exception is encountered
164: */
165: public Object lookup(Name name) throws NamingException {
166: return findContext().lookup(getRelativeName(name));
167: }
168:
169: /**
170: * Retrieves the named object.
171: *
172: * @param name the name of the object to look up
173: * @return the object bound to name
174: * @throws NamingException if a naming exception is encountered
175: */
176: public Object lookup(String name) throws NamingException {
177: return findContext().lookup(getRelativeName(name));
178: }
179:
180: /**
181: * Binds a name to an object.
182: *
183: * @param name the name to bind; may not be empty
184: * @param obj the object to bind; possibly null
185: * @throws NameAlreadyBoundException if name is already bound
186: * @throws javax.naming.directory.InvalidAttributesException
187: * if object did not supply all mandatory attributes
188: * @throws NamingException if a naming exception is encountered
189: *
190: * @see #bind(String, Object)
191: * @see #rebind(Name, Object)
192: * @see javax.naming.directory.DirContext#bind(Name, Object,
193: * javax.naming.directory.Attributes)
194: */
195: public void bind(Name name, Object obj) throws NamingException {
196: findContext().bind(getRelativeName(name), obj);
197: }
198:
199: /**
200: * Binds a name to an object.
201: * All intermediate contexts and the target context (that named by all
202: * but terminal atomic component of the name) must already exist.
203: *
204: * @param name
205: * the name to bind; may not be empty
206: * @param obj
207: * the object to bind; possibly null
208: * @throws NameAlreadyBoundException if name is already bound
209: * @throws javax.naming.directory.InvalidAttributesException
210: * if object did not supply all mandatory attributes
211: * @throws NamingException if a naming exception is encountered
212: */
213: public void bind(String name, Object obj) throws NamingException {
214: findContext().bind(getRelativeName(name), obj);
215: }
216:
217: /**
218: * Binds a name to an object, overwriting any existing binding.
219: * All intermediate contexts and the target context (that named by all
220: * but terminal atomic component of the name) must already exist.
221: *
222: * If the object is a DirContext, any existing attributes
223: * associated with the name are replaced with those of the object.
224: * Otherwise, any existing attributes associated with the name remain
225: * unchanged.
226: *
227: * @param name
228: * the name to bind; may not be empty
229: * @param obj
230: * the object to bind; possibly null
231: * @throws javax.naming.directory.InvalidAttributesException
232: * if object did not supply all mandatory attributes
233: * @throws NamingException if a naming exception is encountered
234: *
235: */
236: public void rebind(Name name, Object obj) throws NamingException {
237: findContext().rebind(getRelativeName(name), obj);
238: }
239:
240: /**
241: * Binds a name to an object, overwriting any existing binding.
242: * See {@link #rebind(Name, Object)} for details.
243: *
244: * @param name
245: * the name to bind; may not be empty
246: * @param obj
247: * the object to bind; possibly null
248: * @throws javax.naming.directory.InvalidAttributesException
249: * if object did not supply all mandatory attributes
250: * @throws NamingException if a naming exception is encountered
251: */
252: public void rebind(String name, Object obj) throws NamingException {
253: findContext().rebind(getRelativeName(name), obj);
254: }
255:
256: /**
257: * Unbinds the named object.
258: * Removes the terminal atomic name in name
259: * from the target context--that named by all but the terminal
260: * atomic part of name.
261: *
262: * This method is idempotent.
263: * It succeeds even if the terminal atomic name
264: * is not bound in the target context, but throws
265: * NameNotFoundException
266: * if any of the intermediate contexts do not exist.
267: *
268: * Any attributes associated with the name are removed.
269: * Intermediate contexts are not changed.
270: *
271: * @param name
272: * the name to unbind; may not be empty
273: * @throws NameNotFoundException if an intermediate context does not exist
274: * @throws NamingException if a naming exception is encountered
275: * @see #unbind(String)
276: */
277: public void unbind(Name name) throws NamingException {
278: findContext().unbind(getRelativeName(name));
279: }
280:
281: /**
282: * Unbinds the named object.
283: * See {@link #unbind(Name)} for details.
284: *
285: * @param name
286: * the name to unbind; may not be empty
287: * @throws NameNotFoundException if an intermediate context does not exist
288: * @throws NamingException if a naming exception is encountered
289: */
290: public void unbind(String name) throws NamingException {
291: findContext().unbind(getRelativeName(name));
292: }
293:
294: /**
295: * Binds a new name to the object bound to an old name, and unbinds
296: * the old name. This operation is not supported (read only env.)
297: *
298: * @param oldName
299: * the name of the existing binding; may not be empty
300: * @param newName
301: * the name of the new binding; may not be empty
302: * @throws NamingException if a naming exception is encountered
303: */
304: public void rename(Name oldName, Name newName)
305: throws NamingException {
306: findContext().rename(getRelativeName(oldName),
307: getRelativeName(newName));
308: }
309:
310: /**
311: * Binds a new name to the object bound to an old name, and unbinds
312: * the old name. Not supported.
313: *
314: * @param oldName
315: * the name of the existing binding; may not be empty
316: * @param newName
317: * the name of the new binding; may not be empty
318: * @throws NamingException if a naming exception is encountered
319: */
320: public void rename(String oldName, String newName)
321: throws NamingException {
322: findContext().rename(getRelativeName(oldName),
323: getRelativeName(newName));
324: }
325:
326: /**
327: * Enumerates the names bound in the named context, along with the
328: * class names of objects bound to them.
329: * The contents of any subcontexts are not included.
330: *
331: * If a binding is added to or removed from this context,
332: * its effect on an enumeration previously returned is undefined.
333: *
334: * @param name
335: * the name of the context to list
336: * @return an enumeration of the names and class names of the
337: * bindings in this context. Each element of the
338: * enumeration is of type NameClassPair.
339: * @throws NamingException if a naming exception is encountered
340: *
341: * @see #list(String)
342: * @see #listBindings(Name)
343: * @see NameClassPair
344: */
345: public NamingEnumeration list(Name name) throws NamingException {
346: return findContext().list(getRelativeName(name));
347: }
348:
349: /**
350: * Enumerates the names bound in the named context, along with the
351: * class names of objects bound to them.
352: * See {@link #list(Name)} for details.
353: *
354: * @param name
355: * the name of the context to list
356: * @return an enumeration of the names and class names of the
357: * bindings in this context. Each element of the
358: * enumeration is of type NameClassPair.
359: * @throws NamingException if a naming exception is encountered
360: */
361: public NamingEnumeration list(String name) throws NamingException {
362: return findContext().list(getRelativeName(name));
363: }
364:
365: /**
366: * Enumerates the names bound in the named context, along with the
367: * objects bound to them.
368: * The contents of any subcontexts are not included.
369: *
370: * If a binding is added to or removed from this context,
371: * its effect on an enumeration previously returned is undefined.
372: *
373: * @param name
374: * the name of the context to list
375: * @return an enumeration of the bindings in this context.
376: * Each element of the enumeration is of type
377: * Binding.
378: * @throws NamingException if a naming exception is encountered
379: *
380: * @see #listBindings(String)
381: * @see #list(Name)
382: * @see Binding
383: */
384: public NamingEnumeration listBindings(Name name)
385: throws NamingException {
386: return findContext().listBindings(getRelativeName(name));
387: }
388:
389: /**
390: * Enumerates the names bound in the named context, along with the
391: * objects bound to them.
392: * See {@link #listBindings(Name)} for details.
393: *
394: * @param name
395: * the name of the context to list
396: * @return an enumeration of the bindings in this context.
397: * Each element of the enumeration is of type
398: * Binding.
399: * @throws NamingException if a naming exception is encountered
400: */
401: public NamingEnumeration listBindings(String name)
402: throws NamingException {
403: return findContext().listBindings(getRelativeName(name));
404: }
405:
406: /**
407: * Destroys the named context and removes it from the namespace.
408: * Any attributes associated with the name are also removed.
409: * Intermediate contexts are not destroyed.
410: *
411: * This method is idempotent.
412: * It succeeds even if the terminal atomic name
413: * is not bound in the target context, but throws
414: * NameNotFoundException
415: * if any of the intermediate contexts do not exist.
416: *
417: * In a federated naming system, a context from one naming system
418: * may be bound to a name in another. One can subsequently
419: * look up and perform operations on the foreign context using a
420: * composite name. However, an attempt destroy the context using
421: * this composite name will fail with
422: * NotContextException, because the foreign context is not
423: * a "subcontext" of the context in which it is bound.
424: * Instead, use unbind() to remove the
425: * binding of the foreign context. Destroying the foreign context
426: * requires that the destroySubcontext() be performed
427: * on a context from the foreign context's "native" naming system.
428: *
429: * @param name
430: * the name of the context to be destroyed; may not be empty
431: * @throws NameNotFoundException if an intermediate context does not exist
432: * @throws NotContextException if the name is bound but does not name a
433: * context, or does not name a context of the appropriate type
434: * @throws ContextNotEmptyException if the named context is not empty
435: * @throws NamingException if a naming exception is encountered
436: *
437: * @see #destroySubcontext(String)
438: */
439: public void destroySubcontext(Name name) throws NamingException {
440: findContext().destroySubcontext(getRelativeName(name));
441: }
442:
443: /**
444: * Destroys the named context and removes it from the namespace.
445: * See {@link #destroySubcontext(Name)} for details.
446: *
447: * @param name
448: * the name of the context to be destroyed; may not be empty
449: * @throws NameNotFoundException if an intermediate context does not exist
450: * @throws NotContextException if the name is bound but does not name a
451: * context, or does not name a context of the appropriate type
452: * @throws ContextNotEmptyException if the named context is not empty
453: * @throws NamingException if a naming exception is encountered
454: */
455: public void destroySubcontext(String name) throws NamingException {
456: findContext().destroySubcontext(getRelativeName(name));
457: }
458:
459: /**
460: * Creates and binds a new context.
461: * Creates a new context with the given name and binds it in
462: * the target context (that named by all but terminal atomic
463: * component of the name). All intermediate contexts and the
464: * target context must already exist.
465: *
466: * @param name
467: * the name of the context to create; may not be empty
468: * @return the newly created context
469: *
470: * @throws NameAlreadyBoundException if name is already bound
471: * @throws javax.naming.directory.InvalidAttributesException
472: * if creation of the subcontext requires specification of
473: * mandatory attributes
474: * @throws NamingException if a naming exception is encountered
475: *
476: * @see #createSubcontext(String)
477: * @see javax.naming.directory.DirContext#createSubcontext
478: */
479: public Context createSubcontext(Name name) throws NamingException {
480: return findContext().createSubcontext(getRelativeName(name));
481: }
482:
483: /**
484: * Creates and binds a new context.
485: * See {@link #createSubcontext(Name)} for details.
486: *
487: * @param name
488: * the name of the context to create; may not be empty
489: * @return the newly created context
490: *
491: * @throws NameAlreadyBoundException if name is already bound
492: * @throws javax.naming.directory.InvalidAttributesException
493: * if creation of the subcontext requires specification of
494: * mandatory attributes
495: * @throws NamingException if a naming exception is encountered
496: */
497: public Context createSubcontext(String name) throws NamingException {
498: return findContext().createSubcontext(getRelativeName(name));
499: }
500:
501: /**
502: * Retrieves the named object, following links except
503: * for the terminal atomic component of the name.
504: * If the object bound to name is not a link,
505: * returns the object itself.
506: *
507: * @param name
508: * the name of the object to look up
509: * @return the object bound to name, not following the
510: * terminal link (if any).
511: * @throws NamingException if a naming exception is encountered
512: *
513: * @see #lookupLink(String)
514: */
515: public Object lookupLink(Name name) throws NamingException {
516: return findContext().lookupLink(getRelativeName(name));
517: }
518:
519: /**
520: * Retrieves the named object, following links except
521: * for the terminal atomic component of the name.
522: * See {@link #lookupLink(Name)} for details.
523: *
524: * @param name
525: * the name of the object to look up
526: * @return the object bound to name, not following the
527: * terminal link (if any)
528: * @throws NamingException if a naming exception is encountered
529: */
530: public Object lookupLink(String name) throws NamingException {
531: return findContext().lookupLink(getRelativeName(name));
532: }
533:
534: /**
535: * Retrieves the parser associated with the named context.
536: * In a federation of namespaces, different naming systems will
537: * parse names differently. This method allows an application
538: * to get a parser for parsing names into their atomic components
539: * using the naming convention of a particular naming system.
540: * Within any single naming system, NameParser objects
541: * returned by this method must be equal (using the equals()
542: * test).
543: *
544: * @param name
545: * the name of the context from which to get the parser
546: * @return a name parser that can parse compound names into their atomic
547: * components
548: * @throws NamingException if a naming exception is encountered
549: *
550: * @see #getNameParser(String)
551: * @see CompoundName
552: */
553: public NameParser getNameParser(Name name) throws NamingException {
554: return findContext().getNameParser(getRelativeName(name));
555: }
556:
557: /**
558: * Retrieves the parser associated with the named context.
559: * See {@link #getNameParser(Name)} for details.
560: *
561: * @param name
562: * the name of the context from which to get the parser
563: * @return a name parser that can parse compound names into their atomic
564: * components
565: * @throws NamingException if a naming exception is encountered
566: */
567: public NameParser getNameParser(String name) throws NamingException {
568: return findContext().getNameParser(getRelativeName(name));
569: }
570:
571: /**
572: * Composes the name of this context with a name relative to
573: * this context.
574: *
575: * @param name
576: * a name relative to this context
577: * @param prefix
578: * the name of this context relative to one of its ancestors
579: * @return the composition of prefix and name
580: * @throws NamingException if a naming exception is encountered
581: *
582: * @see #composeName(String, String)
583: */
584: public Name composeName(Name name, Name prefix)
585: throws NamingException {
586: prefix = (Name) name.clone();
587: return prefix.addAll(name);
588: }
589:
590: /**
591: * Composes the name of this context with a name relative to
592: * this context.
593: *
594: * @param name
595: * a name relative to this context
596: * @param prefix
597: * the name of this context relative to one of its ancestors
598: * @return the composition of prefix and name
599: * @throws NamingException if a naming exception is encountered
600: */
601: public String composeName(String name, String prefix)
602: throws NamingException {
603: return prefix + "/" + name;
604: }
605:
606: /**
607: * Adds a new environment property to the environment of this
608: * context. If the property already exists, its value is overwritten.
609: * See class description for more details on environment properties.
610: *
611: * @param propName
612: * the name of the environment property to add; may not be null
613: * @param propVal
614: * the value of the property to add; may not be null
615: * @return the previous value of the property, or null if the property was
616: * not in the environment before
617: * @throws NamingException if a naming exception is encountered
618: *
619: * @see #getEnvironment()
620: * @see #removeFromEnvironment(String)
621: */
622: public Object addToEnvironment(String propName, Object propVal)
623: throws NamingException {
624: return findContext().addToEnvironment(propName, propVal);
625: }
626:
627: /**
628: * Removes an environment property from the environment of this
629: * context. See class description for more details on environment
630: * properties.
631: *
632: * @param propName
633: * the name of the environment property to remove; may not be null
634: * @return the previous value of the property, or null if the property was
635: * not in the environment
636: * @throws NamingException if a naming exception is encountered
637: *
638: * @see #getEnvironment()
639: * @see #addToEnvironment(String, Object)
640: */
641: public Object removeFromEnvironment(String propName)
642: throws NamingException {
643: return findContext().removeFromEnvironment(propName);
644: }
645:
646: /**
647: * Retrieves the environment in effect for this context.
648: * See class description for more details on environment properties.
649: *
650: * The caller should not make any changes to the object returned:
651: * their effect on the context is undefined.
652: * The environment of this context may be changed using
653: * addToEnvironment() and removeFromEnvironment().
654: *
655: * @return the environment of this context; never null
656: * @throws NamingException if a naming exception is encountered
657: *
658: * @see #addToEnvironment(String, Object)
659: * @see #removeFromEnvironment(String)
660: */
661: public Hashtable getEnvironment() throws NamingException {
662: return findContext().getEnvironment();
663: }
664:
665: /**
666: * Closes this context.
667: * This method releases this context's resources immediately, instead of
668: * waiting for them to be released automatically by the garbage collector.
669: *
670: * This method is idempotent: invoking it on a context that has
671: * already been closed has no effect. Invoking any other method
672: * on a closed context is not allowed, and results in undefined behaviour.
673: *
674: * @throws NamingException if a naming exception is encountered
675: */
676: public void close() throws NamingException {
677: findContext().close();
678: }
679:
680: /**
681: * Retrieves the full name of this context within its own namespace.
682: *
683: *
684: * @return this context's name in its own namespace; never null
685: * @throws OperationNotSupportedException if the naming system does
686: * not have the notion of a full name
687: * @throws NamingException if a naming exception is encountered
688: */
689: public String getNameInNamespace() throws NamingException {
690: return URL_PREFIX;
691: }
692: }
|