Source Code Cross Referenced for MockContext.java in  » Testing » MockEJB » org » mockejb » jndi » Java Source Code / Java DocumentationJava Source Code and Java Documentation

Java Source Code / Java Documentation
1. 6.0 JDK Core
2. 6.0 JDK Modules
3. 6.0 JDK Modules com.sun
4. 6.0 JDK Modules com.sun.java
5. 6.0 JDK Modules sun
6. 6.0 JDK Platform
7. Ajax
8. Apache Harmony Java SE
9. Aspect oriented
10. Authentication Authorization
11. Blogger System
12. Build
13. Byte Code
14. Cache
15. Chart
16. Chat
17. Code Analyzer
18. Collaboration
19. Content Management System
20. Database Client
21. Database DBMS
22. Database JDBC Connection Pool
23. Database ORM
24. Development
25. EJB Server geronimo
26. EJB Server GlassFish
27. EJB Server JBoss 4.2.1
28. EJB Server resin 3.1.5
29. ERP CRM Financial
30. ESB
31. Forum
32. GIS
33. Graphic Library
34. Groupware
35. HTML Parser
36. IDE
37. IDE Eclipse
38. IDE Netbeans
39. Installer
40. Internationalization Localization
41. Inversion of Control
42. Issue Tracking
43. J2EE
44. JBoss
45. JMS
46. JMX
47. Library
48. Mail Clients
49. Net
50. Parser
51. PDF
52. Portal
53. Profiler
54. Project Management
55. Report
56. RSS RDF
57. Rule Engine
58. Science
59. Scripting
60. Search Engine
61. Security
62. Sevlet Container
63. Source Control
64. Swing Library
65. Template Engine
66. Test Coverage
67. Testing
68. UML
69. Web Crawler
70. Web Framework
71. Web Mail
72. Web Server
73. Web Services
74. Web Services apache cxf 2.0.1
75. Web Services AXIS2
76. Wiki Engine
77. Workflow Engines
78. XML
79. XML UI
Java
Java Tutorial
Java Open Source
Jar File Download
Java Articles
Java Products
Java by API
Photoshop Tutorials
Maya Tutorials
Flash Tutorials
3ds-Max Tutorials
Illustrator Tutorials
GIMP Tutorials
C# / C Sharp
C# / CSharp Tutorial
C# / CSharp Open Source
ASP.Net
ASP.NET Tutorial
JavaScript DHTML
JavaScript Tutorial
JavaScript Reference
HTML / CSS
HTML CSS Reference
C / ANSI-C
C Tutorial
C++
C++ Tutorial
Ruby
PHP
Python
Python Tutorial
Python Open Source
SQL Server / T-SQL
SQL Server / T-SQL Tutorial
Oracle PL / SQL
Oracle PL/SQL Tutorial
PostgreSQL
SQL / MySQL
MySQL Tutorial
VB.Net
VB.Net Tutorial
Flash / Flex / ActionScript
VBA / Excel / Access / Word
XML
XML Tutorial
Microsoft Office PowerPoint 2007 Tutorial
Microsoft Office Excel 2007 Tutorial
Microsoft Office Word 2007 Tutorial
Java Source Code / Java Documentation » Testing » MockEJB » org.mockejb.jndi 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


001:        package org.mockejb.jndi;
002:
003:        import java.util.*;
004:        import javax.naming.*;
005:
006:        import org.apache.commons.logging.*;
007:        import org.mockejb.MethodNotImplementedException;
008:
009:        /**
010:         * Provides implementation of <code>javax.naming.Context</code> interface for
011:         * hierarchical in memory single-namespace naming system.
012:         * A name in the <code>MockContext</code> namespace is a sequence of one or more
013:         * atomic names, relative to a root initial context.
014:         * When a name consist of more than one atomic names it is a <code>CompoundName</code>
015:         * where atomic names are separated with separator character - '/' or '.'.
016:         * It is possible to use both separator characters in the same name. In such cases
017:         * any occurrences of '.' are replaced with '/' before parsing.
018:         * <p>
019:         * Leading and terminal components of a <code>CompoundName</code> can not be empty - 
020:         * for example "name1/name2/name3" is a valid name, while the following names are
021:         * not valid - "/name1/name2/name3", "name1/name2/name3/", "/name1/name2/name3/".
022:         * If such name is passed, all empty leading/terminal components will be removed
023:         * before the name is actually used (this will not affect the original value) -
024:         * from the above three examples the actual name will be "name1/name2/name3".
025:         * If a name contains intermediate empty components (for example "a//b") then
026:         * <code>InvalidNameException</code> will be thrown.
027:         * <p>
028:         * Composite names (instances of <code>CompositeName</code>) must contain zero or one
029:         * component from the <code>MockContext</code> namespace.
030:         * <p>
031:         * The namespace of <code>MockContext</code> can be represented as a tree of atomic names.
032:         * Each name is bound to an instance of MockContext (subcontext) or to an arbitrary object.
033:         * Each subcontext has collection of names bound to other subcontexts or arbitrary objects.
034:         * <p>
035:         * When instance of <code>Name</code> is used as parameter to any of the
036:         * MockContext methods, if the object is not <code>CompositeName</code> then
037:         * it is assumed that it is <code>CompoundName</code>
038:         * <p>
039:         * Example:
040:         * <pre><code>
041:         * myContext = initialContext.lookup("foo");
042:         * myObject = myContext.lookup("bar");
043:         * </code>
044:         * is equivalent to
045:         * <code>myObject = initialContext.lookup("foo/bar");</code>
046:         * </pre>
047:         * <p>
048:         * Instances of <code>MockContext</code> are created only through
049:         * <code>MockContextFactory</code>, when <code>InitialContext</code> is instantiated.
050:         * <p>
051:         * If a remote context is provided, this class will search in that remote context if the 
052:         * object is not found locally.
053:         * <p>
054:         * For overloaded methods that accept name as <code>String</code> or
055:         * <code>Name</code> only the version for <code>Name</code> is documented.
056:         * The <code>String</code> version creates <code>CompoundName</code>, from
057:         * the string name passed as parameter, and calls the <code>Name</code> version of
058:         * the same method. 
059:         * 
060:         * @author Alexander Ananiev
061:         * @author Dimitar Gospodinov
062:         */
063:        public class MockContext implements  Context {
064:
065:            private static final String ROOT_CONTEXT_NAME = "ROOT";
066:            // MockContext supports single naming scheme and all instances use the same parser.
067:            private static final NameParser nameParser = new MockContextNameParser();
068:
069:            // logger for this class
070:            private static Log logger = LogFactory.getLog(MockContext.class
071:                    .getName());
072:            /**
073:             * Map of objects registered for this context representing the local context
074:             */
075:            private final Map objects = Collections
076:                    .synchronizedMap(new HashMap());
077:            // Parent Context of this Context
078:            private MockContext parent;
079:            // Atomic name of this Context
080:            private String contextName;
081:            /**
082:             * Container context used for delegated lookups
083:             */
084:            private Context remoteContext;
085:            // Shows if this context has been destroyed
086:            private boolean isDestroyed;
087:
088:            /**
089:             * Creates a new instance of the context. 
090:             * This class can only be instantiated by its factory.
091:             * @param remoteContext remote context that MockContext will  
092:             * delegate to if it fails to lookup an object locally
093:             */
094:            protected MockContext(Context remoteContext) {
095:
096:                this (remoteContext, null, ROOT_CONTEXT_NAME);
097:            }
098:
099:            /**
100:             * Creates new instance of <code>MockContext</code>.
101:             * @param remoteContext remote context that MockContext will 
102:             * delegate to if it fails to lookup an object locally
103:             * @param parent parent context of this context. <code>null</code> if
104:             * this is the root context.
105:             * @param name atomic name for this context
106:             */
107:            private MockContext(Context remoteContext, MockContext parent,
108:                    String name) {
109:
110:                this .remoteContext = remoteContext;
111:                this .parent = parent;
112:                this .contextName = name;
113:                this .isDestroyed = false;
114:            }
115:
116:            /**
117:             * Not implemented 
118:             * @see javax.naming.Context#addToEnvironment(java.lang.String, java.lang.Object)
119:             */
120:            public Object addToEnvironment(String arg0, Object arg1)
121:                    throws NamingException {
122:
123:                throwMethodNotImplemented("addToEnvironment( String, Object)");
124:                return null;
125:            }
126:
127:            /**
128:             * Binds object <code>obj</code> to name <code>name</code> in this context.
129:             * Intermediate contexts that do not exist will be created. 
130:             * 
131:             * @param name name of the object to bind
132:             * @param obj object to bind. Can be <code>null</code>.
133:             * 
134:             * @throws NoPermissionException if this context has been destroyed
135:             * @throws InvalidNameException if <code>name</code> is empty or is
136:             * <code>CompositeName</code> that spans more than one naming system
137:             * @throws NotContextException if <code>name</code> has more than one
138:             * atomic name and intermediate atomic name is bound to object that is
139:             * not context.
140:             * 
141:             * @see javax.naming.Context#bind(javax.naming.Name, java.lang.Object)
142:             */
143:            public void bind(Name name, Object obj) throws NamingException {
144:
145:                checkIsDestroyed();
146:                // Do not check for already bound name. Simply replace the existing value.
147:                rebind(name, obj);
148:            }
149:
150:            /**
151:             * Binds object <code>obj</code> to name <code>name</code> in this context.
152:             * @param name name of the object to add
153:             * @param obj object to bind
154:             * @throws NamingException if naming error occurs 
155:             * @see #bind(Name, Object)
156:             */
157:            public void bind(String name, Object obj) throws NamingException {
158:
159:                bind(nameParser.parse(name), obj);
160:            }
161:
162:            /**
163:             * Does nothing.
164:             */
165:            public void close() throws NamingException {
166:            }
167:
168:            /**
169:             * Returns composition of <code>prefix</code> and <code>name</code>.
170:             * @param name name relative to this context
171:             * @param prefix name of this context
172:             * @see javax.naming.Context#composeName(javax.naming.Name, javax.naming.Name)
173:             */
174:            public Name composeName(Name name, Name prefix)
175:                    throws NamingException {
176:
177:                checkIsDestroyed();
178:                /*
179:                 * We do not want to modify any of the parameters (JNDI requirement).
180:                 * Clone <code>prefix</code> to satisfy the requirement. 
181:                 */
182:                Name parsedPrefix = getParsedName((Name) prefix.clone());
183:                Name parsedName = getParsedName(name);
184:
185:                return parsedPrefix.addAll(parsedName);
186:            }
187:
188:            /**
189:             * Composes the name of this context with a name relative to this context. 
190:             * Given a name (name) relative to this context, and the name (prefix) 
191:             * of this context relative to one of its ancestors, this method returns 
192:             * the composition of the two names using the syntax appropriate for 
193:             * the naming system(s) involved.
194:             * Example: 
195:             * composeName("a","b")  b/a
196:             * composeName("a","")  a
197:             * @param name name relative to this context
198:             * @param prefix name of this context
199:             * @see javax.naming.Context#composeName(java.lang.String, java.lang.String)
200:             */
201:            public String composeName(String name, String prefix)
202:                    throws NamingException {
203:
204:                checkIsDestroyed();
205:                return composeName(nameParser.parse(name),
206:                        nameParser.parse(prefix)).toString();
207:            }
208:
209:            /**
210:             * Creates subcontext with name <code>name</code>, relative to this Context.
211:             * @param name subcontext name.
212:             * @return new subcontext named <code>name</code> relative to this context
213:             * @throws NoPermissionException if this context has been destroyed 
214:             * @throws InvalidNameException	if <code>name</code> is empty or is
215:             * <code>CompositeName</code> that spans more than one naming system
216:             * @throws NameAlreadyBoundException if <code>name</code> is already bound in this Context
217:             * @throws NotContextException if any intermediate name from <code>name</code>
218:             * is not bound to instance of <code>javax.naming.Context</code>
219:             * @see javax.naming.Context#createSubcontext(javax.naming.Name)
220:             */
221:            public Context createSubcontext(Name name) throws NamingException {
222:
223:                checkIsDestroyed();
224:                Name parsedName = getParsedName(name);
225:                if (parsedName.size() == 0 || parsedName.get(0).length() == 0) {
226:                    throw new InvalidNameException("Name can not be empty!");
227:                }
228:                String subContextName = parsedName.get(0);
229:                Object boundObject = objects.get(parsedName.get(0));
230:
231:                if (parsedName.size() == 1) {
232:                    // Check if <code>name</code> is already in use
233:                    if (boundObject == null) {
234:                        Context subContext = new MockContext(remoteContext,
235:                                this , subContextName);
236:                        objects.put(subContextName, subContext);
237:                        return subContext;
238:                    } else {
239:                        throw new NameAlreadyBoundException("Name "
240:                                + subContextName + " is already bound!");
241:                    }
242:                } else {
243:                    if (boundObject instanceof  Context) {
244:                        // Let the subcontext create new subcontext
245:                        return ((Context) boundObject)
246:                                .createSubcontext(parsedName.getSuffix(1));
247:                    } else {
248:                        throw new NotContextException(
249:                                "Expected Context but found " + boundObject);
250:                    }
251:                }
252:            }
253:
254:            /**
255:             * Creates subcontext with name <code>name</code>, relative to this Context.
256:             * @param name subcontext name
257:             * @return new subcontext named <code>name</code> relative to this context 
258:             * @throws NamingException if naming error occurs
259:             * @see #createSubcontext(javax.naming.Name)
260:             */
261:            public Context createSubcontext(String name) throws NamingException {
262:
263:                return createSubcontext(nameParser.parse(name));
264:            }
265:
266:            /**
267:             * Destroys subcontext with name <code>name</code>
268:             * The subcontext must be empty otherwise <code>ContextNotEmptyException</code>
269:             * is thrown.
270:             * <p>
271:             * Once a context is destroyed, the instance should not be used.
272:             * @param name subcontext to destroy
273:             * @throws NoPermissionException if this context has been destroyed
274:             * @throws InvalidNameException if <code>name</code> is empty or is
275:             * <code>CompositeName</code> that spans more than one naming system
276:             * @throws ContextNotEmptyException if Context <code>name</code> is not empty
277:             * @throws NameNotFoundException if subcontext with name <code>name</code> can not be found
278:             * @throws NotContextException if <code>name</code> is not bound to instance of
279:             * <code>MockContext</code>
280:             * @see javax.naming.Context#destroySubcontext(javax.naming.Name)
281:             */
282:            public void destroySubcontext(Name name) throws NamingException {
283:
284:                checkIsDestroyed();
285:                Name parsedName = getParsedName(name);
286:                if (parsedName.size() == 0 || parsedName.get(0).length() == 0) {
287:                    throw new InvalidNameException("Name can not be empty!");
288:                }
289:                String subContextName = parsedName.get(0);
290:                Object boundObject = objects.get(subContextName);
291:                if (boundObject == null) {
292:                    throw new NameNotFoundException("Name " + subContextName
293:                            + "not found in the context!");
294:                }
295:                if (!(boundObject instanceof  MockContext)) {
296:                    throw new NotContextException();
297:                }
298:                MockContext contextToDestroy = (MockContext) boundObject;
299:                if (parsedName.size() == 1) {
300:                    /*
301:                     * Check if the Context to be destroyed is empty.
302:                     * Can not destroy non-empty Context.
303:                     */
304:                    if (contextToDestroy.objects.size() == 0) {
305:                        objects.remove(subContextName);
306:                        contextToDestroy.destroyInternal();
307:                    } else {
308:                        throw new ContextNotEmptyException(
309:                                "Can not destroy non-empty Context!");
310:                    }
311:                } else {
312:                    // Let the subcontext destroy the context
313:                    ((MockContext) boundObject).destroySubcontext(parsedName
314:                            .getSuffix(1));
315:                }
316:            }
317:
318:            /**
319:             * Destroys subcontext with name <code>name</code>
320:             * @param name name of subcontext to destroy
321:             * @throws NamingException if naming error occurs
322:             * @see #destroySubcontext(javax.naming.Name)
323:             */
324:            public void destroySubcontext(String name) throws NamingException {
325:
326:                destroySubcontext(nameParser.parse(name));
327:            }
328:
329:            /**
330:             * Not implemented
331:             * @see javax.naming.Context#getEnvironment()
332:             */
333:            public Hashtable getEnvironment() throws NamingException {
334:
335:                throwMethodNotImplemented("getEnvironment()");
336:                return null;
337:            }
338:
339:            /**
340:             * Not implemented
341:             * @see javax.naming.Context#getNameInNamespace()
342:             */
343:            public String getNameInNamespace() throws NamingException {
344:
345:                throwMethodNotImplemented("getNameInNamespace()");
346:                return null;
347:            }
348:
349:            /**
350:             * Retrieves name parser used to parse context with name <code>name</code>.
351:             * @param name context name
352:             * @return <code>NameParser</code>
353:             * @throws NoPermissionException if this context has been destroyed 
354:             * @throws NamingException if any other naming error occurs
355:             * @see javax.naming.Context#getNameParser(javax.naming.Name)
356:             */
357:            public NameParser getNameParser(Name name) throws NamingException {
358:
359:                checkIsDestroyed();
360:                return nameParser;
361:            }
362:
363:            /**
364:             * Retrieves name parser used to parse context with name <code>name</code>.
365:             * @param name context name
366:             * @return <code>NameParser</code>
367:             * @throws NamingException if naming error occurs
368:             * @see #getNameParser(javax.naming.Name)
369:             */
370:            public NameParser getNameParser(String name) throws NamingException {
371:
372:                checkIsDestroyed();
373:                return nameParser;
374:            }
375:
376:            /**
377:             * The same as <code>listBindings(String)</code>
378:             * @param name name of Context, relative to this Context
379:             * @return <code>NamingEnumeration</code> of all name-class pairs. Each
380:             * element from the enumeration is instance of <code>NameClassPair</code> 
381:             * @throws NamingException if naming error occurs
382:             * @see #listBindings(javax.naming.Name)
383:             */
384:            public NamingEnumeration list(Name name) throws NamingException {
385:
386:                return listBindings(name);
387:            }
388:
389:            /**
390:             * The same as <code>listBindings(String)</code>
391:             * @param name name of Context, relative to this Context
392:             * @return <code>NamingEnumeration</code> of all name-class pairs. Each
393:             * element from the enumeration is instance of <code>NameClassPair</code> 
394:             * @throws NamingException if naming error occurs
395:             * @see #listBindings(java.lang.String)
396:             */
397:            public NamingEnumeration list(String name) throws NamingException {
398:
399:                return list(nameParser.parse(name));
400:            }
401:
402:            /**
403:             * Lists all bindings for Context with name <code>name</code>.
404:             * If <code>name</code> is empty then this Context is assumed.
405:             * @param name name of Context, relative to this Context
406:             * @return <code>NamingEnumeration</code> of all name-object pairs. Each
407:             * element from the enumeration is instance of <code>Binding</code> 
408:             * @throws NoPermissionException if this context has been destroyed
409:             * @throws InvalidNameException if <code>name</code> is <code>CompositeName</code>
410:             * that spans more than one naming system
411:             * @throws NameNotFoundException if <code>name</code> can not be found
412:             * @throws NotContextException component of <code>name</code> is not bound to instance of
413:             * <code>MockContext</code>, when <code>name</code> is not an atomic name
414:             * @throws NamingException if any other naming error occurs
415:             * @see javax.naming.Context#listBindings(javax.naming.Name)
416:             */
417:            public NamingEnumeration listBindings(Name name)
418:                    throws NamingException {
419:
420:                checkIsDestroyed();
421:                Name parsedName = getParsedName(name);
422:                if (parsedName.size() == 0) {
423:                    Vector bindings = new Vector();
424:                    Iterator iterat = objects.keySet().iterator();
425:                    while (iterat.hasNext()) {
426:                        String bindingName = (String) iterat.next();
427:                        bindings.addElement(new Binding(bindingName, objects
428:                                .get(bindingName)));
429:                    }
430:                    return new NamingEnumerationImpl(bindings);
431:                } else {
432:                    Object subContext = objects.get(parsedName.get(0));
433:                    if (subContext instanceof  Context) {
434:                        return ((Context) subContext).list(parsedName
435:                                .getSuffix(1));
436:                    }
437:                    if (subContext == null
438:                            && !objects.containsKey(parsedName.get(0))) {
439:                        throw new NameNotFoundException("Name " + name
440:                                + " not found");
441:                    } else {
442:                        throw new NotContextException(
443:                                "Expected Context but found " + subContext);
444:                    }
445:                }
446:            }
447:
448:            /**
449:             * Lists all bindings for Context with name <code>name</code>.
450:             * If <code>name</code> is empty then this Context is assumed.
451:             * @param name name of Context, relative to this Context
452:             * @return <code>NamingEnumeration</code> of all name-object pairs. Each
453:             * element from the enumeration is instance of <code>Binding</code> 
454:             * @throws NamingException if naming error occurs
455:             * @see #listBindings(javax.naming.Name)
456:             */
457:            public NamingEnumeration listBindings(String name)
458:                    throws NamingException {
459:
460:                return listBindings(nameParser.parse(name));
461:            }
462:
463:            /**
464:             * Looks up object with name <code>name</code> in this context. If the object is not
465:             * found and the remote context was provided, calls the remote 
466:             * context to lookup the object.
467:             * @param name name to look up
468:             * @return object reference bound to name <code>name</code> 
469:             * @throws NoPermissionException if this context has been destroyed
470:             * @throws InvalidNameException if <code>name</code> is <code>CompositeName</code>
471:             * that spans more than one naming system
472:             * @throws NameNotFoundException if <code>name</code> can not be found
473:             * @throws NotContextException component of <code>name</code> is not bound to instance of
474:             * <code>MockContext</code>, when <code>name</code> is not atomic name.
475:             * @throws NamingException if any other naming error occurs 
476:             * @see javax.naming.Context#lookup(javax.naming.Name)
477:             */
478:            public Object lookup(Name name) throws NamingException {
479:
480:                checkIsDestroyed();
481:                try {
482:                    return lookupInternal(name);
483:                } catch (NameNotFoundException ex) {
484:                    // Shall we delegate?
485:                    if (remoteContext != null) {
486:                        logger
487:                                .debug("Was not able to find name "
488:                                        + name
489:                                        + " in the local context. Will try remote context.");
490:
491:                        return remoteContext.lookup(name);
492:                    } else {
493:                        throw new NameNotFoundException("Name " + name
494:                                + " not found. ");
495:                    }
496:                }
497:            }
498:
499:            private Object lookupInternal(Name name) throws NamingException {
500:
501:                Name parsedName = getParsedName(name);
502:                String nameComponent = parsedName.get(0);
503:
504:                Object res = objects.get(nameComponent);
505:
506:                // if not found
507:                if (!objects.containsKey(nameComponent)) {
508:                    throw new NameNotFoundException("Name " + name
509:                            + " not found.");
510:                }
511:                // if this is a compound name 
512:                else if (parsedName.size() > 1) {
513:
514:                    if (res instanceof  MockContext) {
515:                        res = ((MockContext) res).lookupInternal(parsedName
516:                                .getSuffix(1));
517:                    } else {
518:                        throw new NotContextException(
519:                                "Expected MockContext but found " + res);
520:                    }
521:                }
522:
523:                return res;
524:            }
525:
526:            /**
527:             * Looks up the object in this context. If the object is not
528:             * found and the remote context was provided, calls the remote 
529:             * context to lookup the object.
530:             * @param name object to search
531:             * @return object reference bound to name <code>name</code> 
532:             * @throws NamingException if naming error occurs 
533:             * @see #lookup(javax.naming.Name)
534:             */
535:            public Object lookup(String name) throws NamingException {
536:                checkIsDestroyed();
537:                try {
538:                    return lookupInternal(name);
539:                } catch (NameNotFoundException ex) {
540:                    //          Shall we delegate?
541:                    if (remoteContext != null) {
542:                        logger
543:                                .debug("Was not able to find name "
544:                                        + name
545:                                        + " in the local context. Will try remote context.");
546:
547:                        return remoteContext.lookup(name);
548:                    } else {
549:                        throw new NameNotFoundException("Name " + name
550:                                + " not found. ");
551:                    }
552:                }
553:            }
554:
555:            private Object lookupInternal(String name) throws NamingException {
556:                return lookupInternal(nameParser.parse(name));
557:            }
558:
559:            /**
560:             * Not implemented
561:             * @see javax.naming.Context#lookupLink(javax.naming.Name)
562:             */
563:            public Object lookupLink(Name arg0) throws NamingException {
564:
565:                throwMethodNotImplemented("lookupLink(Name)");
566:                return null;
567:            }
568:
569:            /**
570:             * Not implemented
571:             * @see javax.naming.Context#lookupLink(java.lang.String)
572:             */
573:            public Object lookupLink(String arg0) throws NamingException {
574:
575:                throwMethodNotImplemented("lookupLink(String)");
576:                return null;
577:            }
578:
579:            /**
580:             * Rebinds object <code>obj</code> to name <code>name</code>.
581:             * If there is existing binding it will be overwritten.
582:             * @param name name of the object to rebind
583:             * @param obj object to add. Can be <code>null</code>
584:             * @throws NoPermissionException if this context has been destroyed
585:             * @throws InvalidNameException if <code>name</code> is empty or is
586:             * <code>CompositeName</code> that spans more than one naming system
587:             * @throws NotContextException if <code>name</code> has more than one
588:             * atomic name and intermediate context is not found
589:             * @throws NamingException if any other naming error occurs 
590:             * @see javax.naming.Context#rebind(javax.naming.Name, java.lang.Object)
591:             */
592:            public void rebind(Name name, Object obj) throws NamingException {
593:
594:                checkIsDestroyed();
595:                Name parsedName = getParsedName(name);
596:                if (parsedName.size() == 0 || parsedName.get(0).length() == 0) {
597:                    throw new InvalidNameException("Name can not be empty!");
598:                }
599:                String nameToBind = parsedName.get(0);
600:
601:                if (parsedName.size() == 1) {
602:                    objects.put(nameToBind, obj);
603:                    logger.debug("Bound object " + obj + " to the name "
604:                            + nameToBind);
605:                } else {
606:                    Object boundObject = objects.get(nameToBind);
607:                    if (boundObject instanceof  Context) {
608:                        /*
609:                         * Let the subcontext bind the object.
610:                         */
611:                        ((Context) boundObject).bind(parsedName.getSuffix(1),
612:                                obj);
613:                    } else {
614:                        if (boundObject == null) {
615:                            // Create new subcontext and let it do the binding
616:                            Context sub = createSubcontext(nameToBind);
617:                            sub.bind(parsedName.getSuffix(1), obj);
618:                        } else {
619:                            throw new NotContextException(
620:                                    "Expected Context but found " + boundObject);
621:                        }
622:                    }
623:                }
624:            }
625:
626:            /**
627:             * Same as bind except that if <code>name</code> is already bound in
628:             * the context, it will be re-bound to object <code>obj</code>
629:             * @param name name of the object to rebind
630:             * @param obj object to add. Can be <code>null</code>
631:             * @throws NamingException if naming error occurs 
632:             * @see #rebind(javax.naming.Name, Object)
633:             */
634:            public void rebind(String name, Object obj) throws NamingException {
635:
636:                rebind(nameParser.parse(name), obj);
637:            }
638:
639:            /** 
640:             * Not implemented
641:             * @see javax.naming.Context#removeFromEnvironment(java.lang.String)
642:             */
643:            public Object removeFromEnvironment(String arg0)
644:                    throws NamingException {
645:
646:                throwMethodNotImplemented("removeFromEnvironment(String)");
647:                return null;
648:            }
649:
650:            /** 
651:             * Not implemented
652:             * @see javax.naming.Context#rename(javax.naming.Name, javax.naming.Name)
653:             */
654:            public void rename(Name arg0, Name arg1) throws NamingException {
655:
656:                throwMethodNotImplemented("rename(Name arg0, Name arg1)");
657:
658:            }
659:
660:            /**
661:             * Not implemented
662:             * @see javax.naming.Context#rename(java.lang.String, java.lang.String)
663:             */
664:            public void rename(String arg0, String arg1) throws NamingException {
665:
666:                throwMethodNotImplemented("rename(String arg0, String arg1)");
667:
668:            }
669:
670:            /**
671:             * Removes <code>name</code> and its associated object from the context.
672:             * @param name name to remove
673:             * @throws NoPermissionException if this context has been destroyed
674:             * @throws InvalidNameException if <code>name</code> is empty or is
675:             * <code>CompositeName</code> that spans more than one naming system
676:             * @throws NameNotFoundException if intermediate context can not be found
677:             * @throws NotContextException if <code>name</code> has more than one
678:             * atomic name and intermediate context is not found
679:             * @throws NamingException if any other naming exception occurs 
680:             * @see javax.naming.Context#unbind(javax.naming.Name)
681:             */
682:            public void unbind(Name name) throws NamingException {
683:
684:                checkIsDestroyed();
685:                Name parsedName = getParsedName(name);
686:                if (parsedName.size() == 0 || parsedName.get(0).length() == 0) {
687:                    throw new InvalidNameException("Name can not be empty!");
688:                }
689:                String nameToRemove = parsedName.get(0);
690:
691:                if (parsedName.size() == 1) {
692:                    objects.remove(nameToRemove);
693:                    logger.debug("Unbound name " + name);
694:                } else {
695:                    Object boundObject = objects.get(nameToRemove);
696:                    if (boundObject instanceof  Context) {
697:                        /*
698:                         * Let the subcontext do the unbind
699:                         */
700:                        ((Context) boundObject).unbind(parsedName.getSuffix(1));
701:                    } else {
702:                        if (!objects.containsKey(nameToRemove)) {
703:                            throw new NameNotFoundException("Can not find "
704:                                    + name);
705:                        }
706:                        throw new NotContextException(
707:                                "Expected Context but found " + boundObject);
708:                    }
709:                }
710:            }
711:
712:            /**
713:             * Removes object from the object map
714:             * @param name object to remove
715:             * @throws NamingException if naming error occurs
716:             * @see #unbind(javax.naming.Name)
717:             */
718:            public void unbind(String name) throws NamingException {
719:
720:                unbind(nameParser.parse(name));
721:            }
722:
723:            // ** Non-standard methods
724:
725:            /**
726:             * Checks if this context has been destroyed.
727:             * <code>isDestroyed</code> is set to <code>true</code> when a context is
728:             * destroyed by calling <code>destroySubcontext</code> method.
729:             * @throws NoPermissionException if this context has been destroyed
730:             */
731:            private void checkIsDestroyed() throws NamingException {
732:
733:                if (isDestroyed) {
734:                    throw new NoPermissionException(
735:                            "Can not invoke operations on destroyed context!");
736:                }
737:            }
738:
739:            /**
740:             * Marks this context as destroyed.
741:             * Method called only by <code>destroySubcontext</code>.
742:             */
743:            private void destroyInternal() {
744:
745:                isDestroyed = true;
746:            }
747:
748:            /**
749:             * Parses <code>name</code> which is <code>CompositeName</code> or <code>CompoundName</code>.
750:             * If <code>name</code> is not <code>CompositeName</code> then it is
751:             * assumed to be <code>CompoundName</code>.
752:             * <p>
753:             * If the name contains leading and/or terminal empty components, they will not
754:             * be included in the result.
755:             * @param name <code>Name</code> to parse
756:             * @return parsed name as instance of <code>CompoundName</code>
757:             * @throws InvalidNameException if <code>name</code> is
758:             * <code>CompositeName</code> and spans more than one name space
759:             * @throws NamingException if any other naming exception occurs
760:             */
761:            private Name getParsedName(Name name) throws NamingException {
762:                Name result = null;
763:
764:                if (name instanceof  CompositeName) {
765:                    if (name.size() == 0) {
766:                        // Return empty CompositeName
767:                        result = nameParser.parse("");
768:                    } else if (name.size() > 1) {
769:                        throw new InvalidNameException(
770:                                "Multiple name systems are not supported!");
771:                    }
772:                    result = nameParser.parse(name.get(0));
773:                } else {
774:                    result = (Name) name.clone();
775:                }
776:
777:                while (!result.isEmpty()) {
778:                    if (result.get(0).length() == 0) {
779:                        result.remove(0);
780:                        continue;
781:                    }
782:                    if (result.get(result.size() - 1).length() == 0) {
783:                        result.remove(result.size() - 1);
784:                        continue;
785:                    }
786:                    break;
787:                }
788:                // Validate that there are not intermediate empty components.
789:                // Skip first and last element, they are valid
790:                for (int i = 1; i < result.size() - 1; i++) {
791:                    if (result.get(i).length() == 0) {
792:                        throw new InvalidNameException(
793:                                "Empty intermediate components are not supported!");
794:                    }
795:                }
796:                return result;
797:            }
798:
799:            /**
800:             * Returns the compound string name of this context.
801:             * Suppose a/b/c/d is the full name and this context is "c". 
802:             * It's compound string name is a/b/c
803:             *   
804:             * @return compound string name of the context
805:             */
806:            String getCompoundStringName() throws NamingException {
807:
808:                //StringBuffer compositeName  = new StringBuffer();
809:                String compositeName = "";
810:                MockContext curCtx = this ;
811:                while (!curCtx.isRootContext()) {
812:                    compositeName = composeName(compositeName, curCtx
813:                            .getAtomicName());
814:                    curCtx = curCtx.getParentContext();
815:                }
816:
817:                return compositeName;
818:
819:            }
820:
821:            /**
822:             * Returns parent context of this context
823:             */
824:            MockContext getParentContext() {
825:                return parent;
826:            }
827:
828:            /**
829:             * Returns the "atomic" (as opposed to "composite") name of the context.
830:             * @return name of the context
831:             */
832:            String getAtomicName() {
833:                return contextName;
834:            }
835:
836:            /**
837:             * Returns true if this context is the root context
838:             * @return true if the context is the root context
839:             */
840:            boolean isRootContext() {
841:                return getParentContext() == null;
842:            }
843:
844:            private void throwMethodNotImplemented(String methodName) {
845:
846:                throw new MethodNotImplementedException(methodName, this 
847:                        .getClass().getName());
848:
849:            }
850:
851:            private class NamingEnumerationImpl implements  NamingEnumeration {
852:
853:                private Vector elements;
854:                private int currentElement;
855:
856:                NamingEnumerationImpl(Vector elements) {
857:
858:                    this .elements = elements;
859:                    this .currentElement = 0;
860:                }
861:
862:                public void close() {
863:
864:                    currentElement = 0;
865:                    elements.clear();
866:                }
867:
868:                public boolean hasMore() {
869:
870:                    return hasMoreElements();
871:                }
872:
873:                public boolean hasMoreElements() {
874:
875:                    if (currentElement < elements.size()) {
876:                        return true;
877:                    }
878:                    close();
879:                    return false;
880:                }
881:
882:                public Object next() {
883:
884:                    return nextElement();
885:                }
886:
887:                public Object nextElement() {
888:
889:                    if (hasMoreElements()) {
890:                        return elements.get(currentElement++);
891:                    }
892:                    throw new NoSuchElementException();
893:                }
894:            }
895:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.