View Javadoc

1   /*
2    * Copyright (C) The Apache Software Foundation. All rights reserved.
3    *
4    * This software is published under the terms of the Apache Software License
5    * version 1.1, a copy of which has been included with this distribution in
6    * the LICENSE file.
7    */
8   package org.apache.avalon.excalibur.naming;
9   
10  import java.util.Hashtable;
11  import javax.naming.*;
12  import javax.naming.Context;
13  
14  /***
15   * Abstract JNDI Context that can be inherited from to
16   * provide a particular type of Context.
17   *
18   * @author <a href="mailto:donaldp@apache.org">Peter Donald</a>
19   * @version $Revision: 1.2 $
20   */
21  public abstract class AbstractContext
22      implements Context
23  {
24      protected Hashtable  m_environment;
25  
26      public AbstractContext()
27      {
28          this( new Hashtable() );
29      }
30  
31      public AbstractContext( final Hashtable environment )
32      {
33          m_environment = environment;
34      }
35  
36      protected abstract NameParser getNameParser()
37          throws NamingException;
38  
39      /***
40       * Add a key-value pair to environment
41       *
42       * @param key the key
43       * @param value the value
44       * @return the value
45       */
46      public Object addToEnvironment( final String key, final Object value )
47          throws NamingException
48      {
49          if( null == m_environment ) m_environment = new Hashtable( 5, 0.75f );
50          return m_environment.put( key, value );
51      }
52  
53      /***
54       * Release resources associated with context.
55       *
56       */
57      public void close()
58      {
59          m_environment = null;
60      }
61  
62      protected boolean isSelf( final Name name )
63      {
64          return ( name.isEmpty() || name.get( 0 ).equals( "" ) );
65      }
66  
67      /***
68       * Bind an object to a name.
69       *
70       * @param name the name to bind to
71       * @param object the object
72       * @exception NamingException if an error occurs such as bad name or invalid binding
73       */
74      public void bind( final String name, final Object object )
75          throws NamingException
76      {
77          bind( getNameParser().parse( name ), object );
78      }
79  
80      /***
81       * Bind an object to a name.
82       *
83       * @param name the name to bind to
84       * @param object the object
85       * @exception NamingException if an error occurs such as bad name or invalid binding
86       */
87      public void bind( final Name name, final Object object )
88          throws NamingException
89      {
90          bind( name, object, false );
91      }
92  
93      /***
94       * Helper method to bind
95       */
96      protected abstract void bind( Name name, Object object, boolean rebind )
97          throws NamingException;
98  
99      /***
100      * Compose a name form a name and a prefix.
101      *
102      * @param name the name
103      * @param prefix the prefix
104      * @return the composed name
105      * @exception NamingException if a badly formatted name for context
106      */
107     public String composeName( final String name, final String prefix )
108         throws NamingException
109     {
110         final NameParser nameParser = getNameParser();
111         final Name result =
112             composeName( nameParser.parse( name ), nameParser.parse( prefix ) );
113         return result.toString();
114     }
115 
116     /***
117      * Compose a name form a name and a prefix.
118      *
119      * @param name the name
120      * @param prefix the prefix
121      * @return the composed name
122      * @exception NamingException if a badly formatted name for context
123      */
124     public Name composeName( final Name name, final Name prefix )
125         throws NamingException
126     {
127         final Name result = (Name)(prefix.clone());
128         result.addAll( name );
129         return result;
130     }
131 
132     /***
133      * Create a Subcontext.
134      *
135      * @param name the name of subcontext
136      * @return the created context
137      * @exception NamingException if an error occurs (ie context exists, badly formated name etc)
138      */
139     public Context createSubcontext( final String name )
140         throws NamingException
141     {
142         return createSubcontext( getNameParser().parse( name ) );
143     }
144 
145     /***
146      * Destroy a Subcontext.
147      *
148      * @param name the name of subcontext to destroy
149      * @exception NamingException if an error occurs such as malformed name or
150      *            context not exiting or not empty
151      */
152     public void destroySubcontext( final String name )
153         throws NamingException
154     {
155         destroySubcontext( getNameParser().parse( name ) );
156     }
157 
158     /***
159      * Return a copy of environment.
160      *
161      * @return the environment
162      */
163     public Hashtable getEnvironment()
164         throws NamingException
165     {
166         if( null == m_environment ) return new Hashtable( 3, 0.75f );
167         else return (Hashtable)m_environment.clone();
168     }
169 
170     /***
171      * Get the NameParser for the named context.
172      *
173      * @param name
174      * @return the NameParser
175      * @exception NamingException if an error occurs
176      */
177     public NameParser getNameParser( final String name )
178         throws NamingException
179     {
180         return getNameParser( getNameParser().parse( name ) );
181     }
182 
183     /***
184      * Get the NameParser for the named context.
185      *
186      * @param name
187      * @return the NameParser
188      * @exception NamingException if an error occurs
189      */
190     public NameParser getNameParser( final Name name )
191         throws NamingException
192     {
193         if( name.isEmpty() )
194         {
195             return getNameParser();
196         }
197 
198         Object object = lookup( name );
199         if( !(object instanceof Context) )
200         {
201             object = lookup( getPathName( name ) );
202         }
203 
204         final Context context = (Context)object;
205         final NameParser parser = context.getNameParser( "" );
206         context.close();
207         return parser;
208     }
209 
210     /***
211      * Enumerates the names bound in the named context, along with the objects bound to them.
212      *
213      * @param name the name of the context
214      * @return the enumeration
215      * @exception NamingException if an error occurs
216      */
217     public NamingEnumeration list( final String name )
218         throws NamingException
219     {
220         return list( getNameParser().parse( name ) );
221     }
222 
223     /***
224      * Enumerates the names bound in the named context, along with the objects bound to them.
225      *
226      * @param name the name of the context
227      * @return the enumeration
228      * @exception NamingException if an error occurs
229      */
230     public NamingEnumeration listBindings( final String name )
231         throws NamingException
232     {
233         return listBindings( getNameParser().parse( name ) );
234     }
235 
236     /***
237      * Get the object named.
238      *
239      * @param name the name
240      * @return the object
241      * @exception NamingException if an error occurs (ie object name is inavlid or unbound)
242      */
243     public Object lookup( final String name )
244         throws NamingException
245     {
246         return lookup( getNameParser().parse( name ) );
247     }
248 
249     /***
250      * Get the object named following all links.
251      *
252      * @param name the name
253      * @return the object
254      * @exception NamingException if an error occurs (ie object name is inavlid or unbound)
255      */
256     public Object lookupLink( final String name )
257         throws NamingException
258     {
259         return lookupLink( getNameParser().parse( name ) );
260     }
261 
262     /***
263      * Get the object named following all links.
264      *
265      * @param name the name
266      * @return the object
267      * @exception NamingException if an error occurs (ie object name is inavlid or unbound)
268      */
269     public Object lookupLink( final Name name )
270         throws NamingException
271     {
272         return lookup( name );
273     }
274 
275     /***
276      * Binds a name to an object, overwriting any existing binding.
277      *
278      * @param name the name
279      * @param object the object
280      * @exception NamingException if an error occurs
281      */
282     public void rebind( final String name, final Object object )
283         throws NamingException
284     {
285         rebind( getNameParser().parse( name ), object );
286     }
287 
288     /***
289      * Binds a name to an object, overwriting any existing binding.
290      *
291      * @param name the name
292      * @param object the object
293      * @exception NamingException if an error occurs
294      */
295     public void rebind( final Name name, final Object object )
296         throws NamingException
297     {
298         bind( name, object, true );
299     }
300 
301     /***
302      * Remove a key-value pair form environment and return it.
303      *
304      * @param key the key
305      * @return the value
306      */
307     public Object removeFromEnvironment( final String key )
308         throws NamingException
309     {
310         if( null == m_environment ) return null;
311         return m_environment.remove( key );
312     }
313 
314     /***
315      * Rename a already bound object
316      *
317      * @param oldName the old name
318      * @param newName the new name
319      * @exception NamingException if an error occurs
320      */
321     public void rename( final String oldName, final String newName )
322         throws NamingException
323     {
324         rename( getNameParser().parse( oldName ), getNameParser().parse( newName ) );
325     }
326 
327     public void rename( final Name oldName, final Name newName )
328         throws NamingException
329     {
330         if( isSelf( oldName ) || isSelf( newName ) )
331         {
332             throw new InvalidNameException( "Failed to rebind self" );
333         }
334         else if( oldName.equals( newName ) )
335         {
336             throw new InvalidNameException( "Failed to rebind identical names" );
337         }
338 
339         bind( newName, lookup( oldName ) );
340         unbind( oldName );
341     }
342 
343     /***
344      * Unbind a object from a name.
345      *
346      * @param name the name
347      * @exception NamingException if an error occurs
348      */
349     public void unbind( final String name )
350         throws NamingException
351     {
352         unbind( getNameParser().parse( name ) );
353     }
354 
355     /***
356      * Get name components minus leaf name component.
357      *
358      * @param name the name elements leading up to last element
359      * @return the name
360      * @exception NamingException if an error occurs
361      */
362     protected Name getPathName( final Name name )
363         throws NamingException
364     {
365         return name.getPrefix( name.size() - 1 );
366     }
367 
368     /***
369      * Get leaf name component from specified Name object.
370      *
371      * @param name a value of type 'Name'
372      * @return a value of type 'Name'
373      * @exception NamingException if an error occurs
374      */
375     protected Name getLeafName( final Name name )
376         throws NamingException
377     {
378         return name.getSuffix( name.size() - 1 );
379     }
380 }