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: * MemoryContext.java
020: *
021: * This is an in memory version of a context object.
022: */
023:
024: // package path
025: package com.rift.coad.lib.naming.cos;
026:
027: // imports
028: import java.util.Enumeration;
029: import java.util.Hashtable;
030: import javax.naming.Context;
031: import javax.naming.InvalidNameException;
032: import javax.naming.Name;
033: import javax.naming.NameAlreadyBoundException;
034: import javax.naming.NameParser;
035: import javax.naming.NamingEnumeration;
036: import javax.naming.NamingException;
037: import javax.naming.NameNotFoundException;
038:
039: /**
040: * This is an in memory version of a context object.
041: *
042: * @author Brett Chaldecott
043: */
044: public class MemoryContext implements Context {
045:
046: // private member variables
047: private Hashtable env = null;
048: private Hashtable contextEnv = new Hashtable();
049: private Name nameSpace = null;
050:
051: /**
052: * Creates a new instance of MemoryContext
053: *
054: * @param env The environment in which this context is running.
055: */
056: public MemoryContext(Hashtable env, Name nameSpace) {
057: this .env = (Hashtable) env.clone();
058: this .nameSpace = nameSpace;
059: }
060:
061: /**
062: * Adds a new environment property to the environment of this context.
063: *
064: * @return The previous value of the property or null.
065: * @param propName The property to replace or add.
066: * @param propValue The new property value.
067: */
068: public Object addToEnvironment(String propName, Object propVal)
069: throws NamingException {
070: Object original = null;
071: synchronized (env) {
072: if (env.containsKey(propName)) {
073: original = env.get(propName);
074: }
075: env.put(propName, propVal);
076: }
077: return original;
078: }
079:
080: /**
081: * Binds a name to an object.
082: *
083: * @param name The name of the object to bind.
084: * @param obj The object to bind.
085: * @exception NamingException
086: */
087: public void bind(Name name, Object obj) throws NamingException {
088: if (name.size() <= 0) {
089: throw new InvalidNameException(
090: "Invalid name has been passed");
091: }
092: String key = name.get(0);
093: MemoryContext subContext = null;
094: synchronized (contextEnv) {
095: boolean contains = contextEnv.containsKey(key);
096: if ((name.size() == 1) && contains) {
097: throw new NameAlreadyBoundException("The name [" + key
098: + "] is already bound");
099: } else if (name.size() == 1) {
100: contextEnv.put(key, obj);
101: return;
102: } else if (contains) {
103: subContext = (MemoryContext) contextEnv.get(key);
104: } else {
105: subContext = new MemoryContext(env, composeName(
106: nameSpace, new NamingParser().parse(key)));
107: contextEnv.put(key, subContext);
108: }
109: }
110: subContext.bind(name.getSuffix(1), obj);
111: }
112:
113: /**
114: * Binds a name to an object.
115: */
116: public void bind(String name, Object obj) throws NamingException {
117: bind(new NamingParser().parse(name), obj);
118: }
119:
120: /**
121: * Closes this context.
122: */
123: public void close() throws NamingException {
124:
125: }
126:
127: /**
128: * Composes the name of this context with a name relative to this context.
129: *
130: * @return The compisit name.
131: * @param name The name to add to the prefix.
132: * @param prefix The prefix of the current context.
133: * @exception NamingException
134: */
135: public Name composeName(Name name, Name prefix)
136: throws NamingException {
137: Name newName = (Name) prefix.clone();
138: newName.addAll(name);
139: return newName;
140: }
141:
142: /**
143: * Composes the name of this context with a name relative to this context.
144: *
145: * @return The string version of the composed name.
146: * @param name The name to add to the preffix.
147: * @param prefix The prefix for this context.
148: */
149: public String composeName(String name, String prefix)
150: throws NamingException {
151: return composeName(new NamingParser().parse(name),
152: new NamingParser().parse(prefix)).toString();
153: }
154:
155: /**
156: * Creates and binds a new context to this context.
157: *
158: * @return The newly created context.
159: * @param name The name of the new sub context.
160: * @exception NamingException
161: */
162: public Context createSubcontext(Name name) throws NamingException {
163: if (name.size() <= 0) {
164: throw new InvalidNameException(
165: "Invalid name has been passed");
166: }
167: String key = name.get(0);
168: MemoryContext subContext = null;
169: synchronized (contextEnv) {
170: if (contextEnv.containsKey(key)) {
171: subContext = (MemoryContext) contextEnv.get(key);
172: } else {
173: subContext = new MemoryContext(env, composeName(
174: new NamingParser().parse(key), nameSpace));
175: contextEnv.put(key, subContext);
176: }
177: }
178: if (name.size() > 1) {
179: return subContext.createSubcontext(name.getSuffix(1));
180: }
181: return subContext;
182: }
183:
184: /**
185: * Creates and binds a new context.
186: *
187: * @return The newly create sub context.
188: * @exception name The name of the new sub context.
189: * @exception NamingException
190: */
191: public Context createSubcontext(String name) throws NamingException {
192: return createSubcontext(new NamingParser().parse(name));
193: }
194:
195: /**
196: * Destroys the named context and removes it from the namespace.
197: *
198: * @param name The name of the sub context to remove.
199: * @exception NamingException
200: */
201: public void destroySubcontext(Name name) throws NamingException {
202: if (name.size() <= 0) {
203: throw new InvalidNameException(
204: "Invalid name has been passed");
205: }
206: String key = name.get(0);
207: MemoryContext subContext = null;
208: synchronized (contextEnv) {
209: boolean contains = contextEnv.containsKey(key);
210: if ((name.size() == 1) && contains) {
211: contextEnv.remove(key);
212: return;
213: } else if (contains) {
214: subContext = (MemoryContext) contextEnv.get(key);
215: } else {
216: throw new NameNotFoundException("The name [" + key
217: + "] not found");
218: }
219: }
220: if (name.size() > 1) {
221: subContext.destroySubcontext(name.getSuffix(1));
222: }
223: }
224:
225: /**
226: * Destroys the named context and removes it from the namespace.
227: *
228: * @param name The name of the context to destroy.
229: */
230: public void destroySubcontext(String name) throws NamingException {
231: destroySubcontext(new NamingParser().parse(name));
232: }
233:
234: /**
235: * Retrieves the environment in effect for this context.
236: *
237: * @return The reference to the hash table.
238: * @exception NamingException
239: */
240: public Hashtable getEnvironment() throws NamingException {
241: return env;
242: }
243:
244: /**
245: * Retrieves the full name of this context within its own namespace.
246: */
247: public String getNameInNamespace() throws NamingException {
248: return nameSpace.toString();
249: }
250:
251: /**
252: * Retrieves the parser associated with the named context.
253: *
254: * @return The reference to the name parser.
255: * @param name The name to return the parser for.
256: * @exception NamingException
257: */
258: public NameParser getNameParser(Name name) throws NamingException {
259: return new NamingParser();
260: }
261:
262: /**
263: * Retrieves the parser associated with the named context.
264: */
265: public NameParser getNameParser(String name) throws NamingException {
266: return new NamingParser();
267: }
268:
269: /**
270: * Enumerates the names bound in the named context, along with the class
271: * names of objects bound to them.
272: */
273: public NamingEnumeration list(Name name) throws NamingException {
274: return new MemoryNamingEnumeration(name.getAll());
275: }
276:
277: /**
278: * Enumerates the names bound in the named context, along with the class
279: * names of objects bound to them.
280: *
281: * @return The list of names bound to this context.
282: * @param name The list of names.
283: * @exception NamingException
284: */
285: public NamingEnumeration list(String name) throws NamingException {
286: return new MemoryNamingEnumeration(new NamingParser().parse(
287: name).getAll());
288: }
289:
290: /**
291: * Enumerates the names bound in the named context, along with the objects
292: * bound to them.
293: *
294: * @return The list of bindings for the name
295: * @param name The name to perform the search below.
296: * @exception NamingException
297: */
298: public NamingEnumeration listBindings(Name name)
299: throws NamingException {
300: if (name.size() <= 0) {
301: synchronized (contextEnv) {
302: return new MemoryNamingEnumeration(contextEnv
303: .elements());
304: }
305: }
306: String key = name.get(0);
307: MemoryContext subContext = null;
308: synchronized (contextEnv) {
309: if (contextEnv.containsKey(key)) {
310: subContext = (MemoryContext) contextEnv.get(key);
311: } else {
312: throw new NameNotFoundException("The name [" + key
313: + "] not found");
314: }
315: }
316: return subContext.listBindings(name.getSuffix(1));
317: }
318:
319: /**
320: * Enumerates the names bound in the named context, along with the objects
321: * bound to them.
322: *
323: * @return The list of binding for the name.
324: * @param name The name to perform the search for.
325: * @exception NamingException
326: */
327: public NamingEnumeration listBindings(String name)
328: throws NamingException {
329: return listBindings(new NamingParser().parse(name));
330: }
331:
332: /**
333: * Retrieves the named object.
334: *
335: * @return The named object.
336: * @param name The name to retrieve the object for.
337: * @exception NamingException
338: */
339: public Object lookup(Name name) throws NamingException {
340: if (name.size() <= 0) {
341: throw new InvalidNameException(
342: "Invalid name has been passed");
343: }
344: String key = name.get(0);
345: MemoryContext subContext = null;
346: synchronized (contextEnv) {
347: boolean contains = contextEnv.containsKey(key);
348: if ((name.size() == 1) && contains) {
349: return contextEnv.get(key);
350: } else if (contains) {
351: subContext = (MemoryContext) contextEnv.get(key);
352: } else {
353: throw new NameNotFoundException("The name [" + key
354: + "] not found");
355: }
356: }
357: return subContext.lookup(name.getSuffix(1));
358: }
359:
360: /**
361: * Retrieves the named object.
362: *
363: * @return The object to retrieve by name.
364: * @param name The name of the object to retrieve.
365: * @exception NamingException
366: */
367: public Object lookup(String name) throws NamingException {
368: return lookup(new NamingParser().parse(name));
369: }
370:
371: /**
372: * Retrieves the named object, following links except for the terminal
373: * atomic component of the name.
374: *
375: * @return The object to retrieve.
376: * @param name The name of the object to lookup.
377: * @exception NamingException
378: */
379: public Object lookupLink(Name name) throws NamingException {
380: Name currentName = name;
381: while (true) {
382: Object result = lookup(currentName);
383: if (!(result instanceof Name)) {
384: return result;
385: }
386: currentName = (Name) result;
387: }
388: }
389:
390: /**
391: * Retrieves the named object, following links except for the terminal
392: * atomic component of the name.
393: *
394: * @return The results of the lookup link.
395: * @param name The name of the object to lookup.
396: * @exception NamingException
397: */
398: public Object lookupLink(String name) throws NamingException {
399: return lookupLink(new NamingParser().parse(name));
400: }
401:
402: /**
403: * Binds a name to an object, overwriting any existing binding.
404: *
405: * @param name The name to rebind.
406: * @param obj The object to rebind.
407: * @exception NamingException
408: */
409: public void rebind(Name name, Object obj) throws NamingException {
410: if (name.size() <= 0) {
411: throw new InvalidNameException(
412: "Invalid name has been passed");
413: }
414: String key = name.get(0);
415: MemoryContext subContext = null;
416: synchronized (contextEnv) {
417: boolean contains = contextEnv.containsKey(key);
418: if (name.size() == 1) {
419: contextEnv.put(key, obj);
420: return;
421: } else if (contains) {
422: subContext = (MemoryContext) contextEnv.get(key);
423: } else {
424: subContext = new MemoryContext(env, composeName(
425: new NamingParser().parse(key), nameSpace));
426: contextEnv.put(key, subContext);
427: }
428: }
429: subContext.rebind(name.getSuffix(1), obj);
430: }
431:
432: /**
433: * Binds a name to an object, overwriting any existing binding.
434: *
435: * @param name The name to rebind.
436: * @param obj The object to rebind.
437: * @exception NamingException
438: */
439: public void rebind(String name, Object obj) throws NamingException {
440: rebind(new NamingParser().parse(name), obj);
441: }
442:
443: /**
444: * Removes an environment property from the environment of this context.
445: *
446: * @return The original value.
447: * @param propName The name of the entry to remove from the environment.
448: * @exception NamingException
449: */
450: public Object removeFromEnvironment(String propName)
451: throws NamingException {
452: Object originalValue = null;
453: synchronized (env) {
454: if (env.containsKey(propName)) {
455: originalValue = env.get(propName);
456: env.remove(propName);
457: }
458: }
459: return originalValue;
460: }
461:
462: /**
463: * Binds a new name to the object bound to an old name, and unbinds the old
464: * name.
465: *
466: * @param oldName The old name to rename.
467: * @param newName The name to replace it with.
468: * @exception NamingException
469: */
470: public void rename(Name oldName, Name newName)
471: throws NamingException {
472: Object value = lookup(oldName);
473: unbind(oldName);
474: bind(newName, value);
475: }
476:
477: /**
478: * Binds a new name to the object bound to an old name, and unbinds the old
479: * name.
480: *
481: * @param oldName The old name to rename.
482: * @param newName The name to replace it with.
483: * @exception NamingException
484: */
485: public void rename(String oldName, String newName)
486: throws NamingException {
487: rename(new NamingParser().parse(oldName), new NamingParser()
488: .parse(newName));
489: }
490:
491: /**
492: * Unbinds the named object.
493: *
494: * @param name The name to unbind.
495: * @exception NamingException
496: */
497: public void unbind(Name name) throws NamingException {
498: if (name.size() <= 0) {
499: throw new InvalidNameException(
500: "Invalid name has been passed");
501: }
502: String key = name.get(0);
503: MemoryContext subContext = null;
504: synchronized (contextEnv) {
505: boolean contains = contextEnv.containsKey(key);
506: if (contains && (name.size() == 1)) {
507: contextEnv.remove(key);
508: return;
509: } else if (contains) {
510: subContext = (MemoryContext) contextEnv.get(key);
511: } else {
512: throw new NameNotFoundException("The name ["
513: + name.toString() + "] was not found.");
514: }
515: }
516: subContext.unbind(name.getSuffix(1));
517: }
518:
519: /**
520: * Unbinds the named objec.
521: *
522: * @param name The name to unbind.
523: * @exception NamingException
524: */
525: public void unbind(String name) throws NamingException {
526: unbind(new NamingParser().parse(name));
527: }
528: }
|