001: /*
002: * CoadunationLib: The coaduntion implementation library.
003: * Copyright (C) 2006 Rift IT Contracting
004: *
005: * This library is free software; you can redistribute it and/or
006: * modify it under the terms of the GNU Lesser General Public
007: * License as published by the Free Software Foundation; either
008: * version 2.1 of the License, or (at your option) any later version.
009: *
010: * This library is distributed in the hope that it will be useful,
011: * but WITHOUT ANY WARRANTY; without even the implied warranty of
012: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
013: * Lesser General Public License for more details.
014: *
015: * You should have received a copy of the GNU Lesser General Public
016: * License along with this library; if not, write to the Free Software
017: * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
018: *
019: * URLContext.java
020: *
021: * This is the master context responsible for managing both the URL in memory
022: * contexts and the Cos contexts.
023: */
024:
025: // package path
026: package com.rift.coad.lib.naming.cos;
027:
028: // imports
029: import java.util.Hashtable;
030: import java.util.HashMap;
031: import java.util.Map;
032: import javax.naming.Context;
033: import javax.naming.CompositeName;
034: import javax.naming.Name;
035: import javax.naming.NameParser;
036: import javax.naming.NamingEnumeration;
037: import javax.naming.NamingException;
038: import javax.naming.NameAlreadyBoundException;
039: import javax.naming.NameNotFoundException;
040: import javax.naming.Reference;
041: import javax.naming.OperationNotSupportedException;
042: import javax.naming.spi.ObjectFactory;
043:
044: // logging import
045: import org.apache.log4j.Logger;
046:
047: // coadunation imports
048: import com.rift.coad.lib.naming.*;
049: import com.rift.coad.lib.thread.CoadunationThreadGroup;
050:
051: /**
052: * This is the master context responsible for managing both the URL in memory
053: * contexts and the Cos contexts.
054: *
055: * @author Brett Chaldecott
056: */
057: public class MasterContext implements Context {
058:
059: // the class log variable
060: protected Logger log = Logger.getLogger(MasterContext.class
061: .getName());
062:
063: // class private member variables
064: private Hashtable env = null;
065: private OrbManager orbManager = null;
066: private CosContext cosContext = null;
067: private MemoryContext masterMemoryContext = null;
068: private Map classLoaderMemoryContexts = new HashMap();
069:
070: /**
071: * Creates a new instance of MasterContext
072: *
073: * @param env The environment of the cos context.
074: *
075: * @param env The global has table for this environment.
076: * @param threadGroup The thread group for this object.
077: * @param orbManager The reference to the orb manager.
078: * @param instanceId The id of the coadunation server
079: */
080: public MasterContext(Hashtable env,
081: CoadunationThreadGroup threadGroup, OrbManager orbManager,
082: String instanceId)
083: throws com.rift.coad.lib.naming.NamingException {
084: try {
085: this .env = (Hashtable) env.clone();
086: this .orbManager = orbManager;
087: this .cosContext = new CosContext(env, threadGroup,
088: orbManager, instanceId);
089: this .masterMemoryContext = new MemoryContext(env,
090: new NamingParser().parse(""));
091: } catch (javax.naming.NamingException ex) {
092: log.error(
093: "Failed to instanciate the Master Context because : "
094: + ex.getMessage(), ex);
095: throw new com.rift.coad.lib.naming.NamingException(
096: "Failed to "
097: + "instanciate the Master Context because : "
098: + ex.getMessage(), ex);
099: }
100: }
101:
102: /**
103: * Adds a new environment property to the environment of this context.
104: *
105: * @return The previous value of the property or null.
106: * @param propName The property to replace or add.
107: * @param propValue The new property value.
108: */
109: public Object addToEnvironment(String propName, Object propVal)
110: throws NamingException {
111: synchronized (env) {
112: Object origValue = null;
113: if (env.containsKey(propName)) {
114: origValue = env.get(propName);
115: }
116: env.put(propName, propVal);
117: return origValue;
118: }
119: }
120:
121: /**
122: * Binds a name to an object.
123: *
124: * @param name The name of the object to bind.
125: * @param obj The object to bind.
126: * @exception NamingException
127: */
128: public void bind(Name name, Object obj) throws NamingException {
129: Context context = getContext(name);
130: context.bind(name, obj);
131: }
132:
133: /**
134: * Binds a name to an object.
135: *
136: * @param name The name to bind.
137: * @param obj The object value to bind to the name.
138: * @exception NamingException
139: */
140: public void bind(String name, Object obj) throws NamingException {
141: Context context = getContext(name);
142: context.bind(name, obj);
143: }
144:
145: /**
146: * Closes this context.
147: */
148: public void close() throws NamingException {
149:
150: }
151:
152: /**
153: * Composes the name of this context with a name relative to this context.
154: *
155: * @return The compisit name.
156: * @param name The name to add to the prefix.
157: * @param prefix The prefix of the current context.
158: * @exception NamingException
159: */
160: public Name composeName(Name name, Name prefix)
161: throws NamingException {
162: Name newName = (Name) prefix.clone();
163: newName.addAll(name);
164: return newName;
165: }
166:
167: /**
168: * Composes the name of this context with a name relative to this context.
169: *
170: * @return The string version of the composed name.
171: * @param name The name to add to the preffix.
172: * @param prefix The prefix for this context.
173: */
174: public String composeName(String name, String prefix)
175: throws NamingException {
176: return composeName(new NamingParser().parse(name),
177: new NamingParser().parse(prefix)).toString();
178: }
179:
180: /**
181: * Creates and binds a new context to this context.
182: *
183: * @return The newly created context.
184: * @param name The name of the new sub context.
185: * @exception NamingException
186: */
187: public Context createSubcontext(Name name) throws NamingException {
188: Context context = getContext(name);
189: return context.createSubcontext(name);
190: }
191:
192: /**
193: * Creates and binds a new context.
194: *
195: * @return The newly create sub context.
196: * @exception name The name of the new sub context.
197: * @exception NamingException
198: */
199: public Context createSubcontext(String name) throws NamingException {
200: Context context = getContext(name);
201: return context.createSubcontext(name);
202: }
203:
204: /**
205: * Destroys the named context and removes it from the namespace.
206: *
207: * @param name The name of the sub context to remove.
208: * @exception NamingException
209: */
210: public void destroySubcontext(Name name) throws NamingException {
211: Context context = getContext(name);
212: context.destroySubcontext(name);
213: }
214:
215: /**
216: * Destroys the named context and removes it from the namespace.
217: *
218: * @param name The name of the context to destroy.
219: */
220: public void destroySubcontext(String name) throws NamingException {
221: Context context = getContext(name);
222: context.destroySubcontext(name);
223: }
224:
225: /**
226: * Retrieves the environment in effect for this context.
227: *
228: * @return The reference to the hash table.
229: * @exception NamingException
230: */
231: public Hashtable getEnvironment() throws NamingException {
232: return env;
233: }
234:
235: /**
236: * Retrieves the full name of this context within its own namespace.
237: */
238: public String getNameInNamespace() throws NamingException {
239: return new NamingParser().parse("").toString();
240: }
241:
242: /**
243: * Retrieves the parser associated with the named context.
244: *
245: * @return The reference to the name parser.
246: * @param name The name to return the parser for.
247: * @exception NamingException
248: */
249: public NameParser getNameParser(Name name) throws NamingException {
250: Context context = getContext(name);
251: return context.getNameParser(name);
252: }
253:
254: /**
255: * Retrieves the parser associated with the named context.
256: */
257: public NameParser getNameParser(String name) throws NamingException {
258: Context context = getContext(name);
259: return context.getNameParser(name);
260: }
261:
262: /**
263: * Enumerates the names bound in the named context, along with the class
264: * names of objects bound to them.
265: */
266: public NamingEnumeration list(Name name) throws NamingException {
267: Context context = getContext(name);
268: return context.list(name);
269: }
270:
271: /**
272: * Enumerates the names bound in the named context, along with the class
273: * names of objects bound to them.
274: *
275: * @return The list of names bound to this context.
276: * @param name The list of names.
277: * @exception NamingException
278: */
279: public NamingEnumeration list(String name) throws NamingException {
280: Context context = getContext(name);
281: return context.list(name);
282: }
283:
284: /**
285: * Enumerates the names bound in the named context, along with the objects
286: * bound to them.
287: *
288: * @return The list of bindings for the name
289: * @param name The name to perform the search below.
290: * @exception NamingException
291: */
292: public NamingEnumeration listBindings(Name name)
293: throws NamingException {
294: Context context = getContext(name);
295: return context.listBindings(name);
296: }
297:
298: /**
299: * Enumerates the names bound in the named context, along with the objects
300: * bound to them.
301: *
302: * @return The list of binding for the name.
303: * @param name The name to perform the search for.
304: * @exception NamingException
305: */
306: public NamingEnumeration listBindings(String name)
307: throws NamingException {
308: Context context = getContext(name);
309: return context.listBindings(name);
310: }
311:
312: /**
313: * Retrieves the named object.
314: *
315: * @return The named object.
316: * @param name The name to retrieve the object for.
317: * @exception NamingException
318: */
319: public Object lookup(Name name) throws NamingException {
320: Context context = getContext(name);
321: try {
322: return processResult(context.lookup(name), name);
323: } catch (javax.naming.NameNotFoundException ex) {
324: if (context != masterMemoryContext) {
325: return processResult(masterMemoryContext.lookup(name),
326: name);
327: }
328: throw ex;
329: }
330: }
331:
332: /**
333: * Retrieves the named object.
334: *
335: * @return The object to retrieve by name.
336: * @param name The name of the object to retrieve.
337: * @exception NamingException
338: */
339: public Object lookup(String name) throws NamingException {
340: Context context = getContext(name);
341: try {
342: return processResult(context.lookup(name), name);
343: } catch (javax.naming.NameNotFoundException ex) {
344: if (context != masterMemoryContext) {
345: return processResult(masterMemoryContext.lookup(name),
346: name);
347: }
348: throw ex;
349: }
350: }
351:
352: /**
353: * Retrieves the named object, following links except for the terminal
354: * atomic component of the name.
355: *
356: * @return The object to retrieve.
357: * @param name The name of the object to lookup.
358: * @exception NamingException
359: */
360: public Object lookupLink(Name name) throws NamingException {
361: Context context = getContext(name);
362: try {
363: return processResult(context.lookupLink(name), name);
364: } catch (javax.naming.NameNotFoundException ex) {
365: if (context != masterMemoryContext) {
366: return processResult(masterMemoryContext
367: .lookupLink(name), name);
368: }
369: throw ex;
370: }
371: }
372:
373: /**
374: * Retrieves the named object, following links except for the terminal
375: * atomic component of the name.
376: *
377: * @return The results of the lookup link.
378: * @param name The name of the object to lookup.
379: * @exception NamingException
380: */
381: public Object lookupLink(String name) throws NamingException {
382: Context context = getContext(name);
383: try {
384: return processResult(context.lookupLink(name), name);
385: } catch (javax.naming.NameNotFoundException ex) {
386: if (context != masterMemoryContext) {
387: return processResult(masterMemoryContext
388: .lookupLink(name), name);
389: }
390: throw ex;
391: }
392: }
393:
394: /**
395: * Binds a name to an object, overwriting any existing binding.
396: *
397: * @param name The name to rebind.
398: * @param obj The object to rebind.
399: * @exception NamingException
400: */
401: public void rebind(Name name, Object obj) throws NamingException {
402: Context context = getContext(name);
403: context.rebind(name, obj);
404: }
405:
406: /**
407: * Binds a name to an object, overwriting any existing binding.
408: *
409: * @param name The name to rebind.
410: * @param obj The object to rebind.
411: * @exception NamingException
412: */
413: public void rebind(String name, Object obj) throws NamingException {
414: Context context = getContext(name);
415: context.rebind(name, obj);
416: }
417:
418: /**
419: * Removes an environment property from the environment of this context.
420: *
421: * @param propName The name of the entry to remove from the environment.
422: * @exception NamingException
423: */
424: public Object removeFromEnvironment(String propName)
425: throws NamingException {
426: synchronized (env) {
427: Object original = null;
428: if (env.containsKey(propName)) {
429: original = env.get(propName);
430: env.remove(propName);
431: }
432: return original;
433: }
434: }
435:
436: /**
437: * Binds a new name to the object bound to an old name, and unbinds the old
438: * name.
439: *
440: * @param oldName The old name to rename.
441: * @param newName The name to replace it with.
442: * @exception NamingException
443: */
444: public void rename(Name oldName, Name newName)
445: throws NamingException {
446: Context oldContext = getContext(oldName);
447: Context newContext = getContext(newName);
448: Object ref = oldContext.lookup(oldName);
449: newContext.bind(newName, ref);
450: oldContext.unbind(oldName);
451: }
452:
453: /**
454: * Binds a new name to the object bound to an old name, and unbinds the old
455: * name.
456: *
457: * @param oldName The old name to rename.
458: * @param newName The name to replace it with.
459: * @exception NamingException
460: */
461: public void rename(String oldName, String newName)
462: throws NamingException {
463: Context oldContext = getContext(oldName);
464: Context newContext = getContext(newName);
465: Object ref = oldContext.lookup(oldName);
466: newContext.bind(newName, ref);
467: oldContext.unbind(oldName);
468: }
469:
470: /**
471: * Unbinds the named object.
472: *
473: * @param name The name to unbind.
474: * @exception NamingException
475: */
476: public void unbind(Name name) throws NamingException {
477: Context context = getContext(name);
478: context.unbind(name);
479: }
480:
481: /**
482: * Unbinds the named objec.
483: *
484: * @param name The name to unbind.
485: * @exception NamingException
486: */
487: public void unbind(String name) throws NamingException {
488: Context context = getContext(name);
489: context.unbind(name);
490: }
491:
492: /**
493: * This method is called to init the context for a class loader.
494: *
495: * @exception NamingException
496: */
497: public void initContext()
498: throws com.rift.coad.lib.naming.NamingException {
499: try {
500: ClassLoader loader = Thread.currentThread()
501: .getContextClassLoader();
502: synchronized (classLoaderMemoryContexts) {
503: classLoaderMemoryContexts.put(loader,
504: new MemoryContext(env, new NamingParser()
505: .parse("")));
506: }
507: } catch (Exception ex) {
508: log.error(
509: "Failed to init the context for a class loader : "
510: + ex.getMessage(), ex);
511: throw new com.rift.coad.lib.naming.NamingException(
512: "Failed to init the context for a class loader : "
513: + ex.getMessage(), ex);
514: }
515: }
516:
517: /**
518: * This method is called to release the context for class loader.
519: */
520: public void releaseContext() {
521: ClassLoader loader = Thread.currentThread()
522: .getContextClassLoader();
523: synchronized (classLoaderMemoryContexts) {
524: classLoaderMemoryContexts.remove(loader);
525: }
526: }
527:
528: /**
529: * This method terminates the processing of the MasterContext by terminating
530: * the processing of its sub contexts
531: */
532: public void terminate() {
533: cosContext.terminate();
534: }
535:
536: /**
537: * This method returns the context object responsible for managing the
538: * given name.
539: */
540: private Context getContext(String name) throws NamingException {
541: return getContext(new NamingParser().parse(name));
542: }
543:
544: /**
545: * This method returns the context object responsible for managing the
546: * given name.
547: */
548: private Context getContext(Name name) {
549: ClassLoader loader = Thread.currentThread()
550: .getContextClassLoader();
551: // check if the naming being supplied is a JNDI standard url or if
552: // it should go into the COS naming service
553: if (!name.get(0).equals(NamingConstants.JAVA_JNDI_PREFIX)) {
554: return cosContext;
555: }
556: // look for a local context to support the lookup
557: synchronized (classLoaderMemoryContexts) {
558: if (classLoaderMemoryContexts.containsKey(loader)) {
559: return (Context) classLoaderMemoryContexts.get(loader);
560: }
561: }
562: // return the master memory context
563: return masterMemoryContext;
564: }
565:
566: /**
567: * This method process the result of the call
568: *
569: * @return The result of the processing.
570: * @param result The result to process.
571: */
572: private Object processResult(Object result, String name)
573: throws NamingException {
574: return processResult(result, new NamingParser().parse(name));
575: }
576:
577: /**
578: * This method process the result of the object lookup.
579: *
580: * @return The result of the processing.
581: * @param result The result to process.
582: */
583: private Object processResult(Object result, Name name)
584: throws NamingException {
585: try {
586: if (result instanceof Reference) {
587: Reference ref = (Reference) result;
588: ObjectFactory objFactory = (ObjectFactory) (Class
589: .forName(ref.getFactoryClassName()))
590: .newInstance();
591: return objFactory.getObjectInstance(ref, name, this ,
592: this .getEnvironment());
593: }
594: return result;
595: } catch (Exception ex) {
596: log.error("Failed to process the result : "
597: + ex.getMessage(), ex);
598: throw new NamingException("Failed to process the result : "
599: + ex.getMessage());
600: }
601: }
602: }
|