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.CompositeName;
13  import javax.naming.Context;
14  import javax.naming.Name;
15  import javax.naming.NameParser;
16  import javax.naming.spi.ResolveResult;
17  
18  /***
19   * Abstract JNDI Context that can be inherited from to
20   * provide a particular type of Context.
21   *
22   * @author <a href="mailto:donaldp@apache.org">Peter Donald</a>
23   * @version $Revision: 1.2 $
24   */
25  public abstract class AbstractURLContext
26      extends AbstractContext
27      implements NameParser
28  {
29      protected final String   m_scheme;
30  
31      public AbstractURLContext( final String scheme, final Hashtable environment )
32      {
33          super( environment );
34          m_scheme = scheme;
35      }
36  
37      public Name parse( final String name )
38          throws NamingException
39      {
40          return (new CompositeName().add( name ));
41      }
42  
43      protected NameParser getNameParser()
44          throws NamingException
45      {
46          return this;
47      }
48  
49      /***
50       * Helper method to bind
51       */
52      protected void bind( final Name name, final Object object, final boolean rebind )
53          throws NamingException
54      {
55          final ResolveResult resolveResult = getBaseURLContext( name, m_environment );
56          final Context context = (Context)resolveResult.getResolvedObj();
57  
58          try
59          {
60              if( rebind )
61              {
62                  context.rebind( resolveResult.getRemainingName(), object );
63              }
64              else
65              {
66                  context.bind( resolveResult.getRemainingName(), object );
67              }
68          }
69          finally
70          {
71              context.close();
72          }
73      }
74  
75      /***
76       * Create a Subcontext.
77       *
78       * @param name the name of subcontext
79       * @return the created context
80       * @exception NamingException if an error occurs (ie context exists, badly formated name etc)
81       */
82      public Context createSubcontext( final Name name )
83          throws NamingException
84      {
85          final ResolveResult resolveResult = getBaseURLContext( name, m_environment );
86          final Context context = (Context)resolveResult.getResolvedObj();
87  
88          try
89          {
90              return context.createSubcontext( resolveResult.getRemainingName() );
91          }
92          finally
93          {
94              context.close();
95          }
96      }
97  
98      public void destroySubcontext( final Name name )
99          throws NamingException
100     {
101         final ResolveResult resolveResult = getBaseURLContext( name, m_environment );
102         final Context context = (Context)resolveResult.getResolvedObj();
103 
104         try
105         {
106             context.destroySubcontext( resolveResult.getRemainingName() );
107         }
108         finally
109         {
110             context.close();
111         }
112     }
113 
114     public String getNameInNamespace()
115         throws NamingException
116     {
117         return "";
118     }
119 
120     /***
121      * Enumerates the names bound in the named context.
122      *
123      * @param name the name of the context
124      * @return the enumeration
125      * @exception NamingException if an error occurs
126      */
127     public NamingEnumeration list( final Name name )
128         throws NamingException
129     {
130         final ResolveResult resolveResult = getBaseURLContext( name, m_environment );
131         final Context context = (Context)resolveResult.getResolvedObj();
132 
133         try
134         {
135             return context.list( resolveResult.getRemainingName() );
136         }
137         finally
138         {
139             context.close();
140         }
141     }
142 
143     /***
144      * Enumerates the names bound in the named context, along with the objects bound to them.
145      *
146      * @param name the name of the context
147      * @return the enumeration
148      * @exception NamingException if an error occurs
149      */
150     public NamingEnumeration listBindings( final Name name )
151         throws NamingException
152     {
153         final ResolveResult resolveResult = getBaseURLContext( name, m_environment );
154         final Context context = (Context)resolveResult.getResolvedObj();
155 
156         try
157         {
158             return context.listBindings( resolveResult.getRemainingName() );
159         }
160         finally
161         {
162             context.close();
163         }
164     }
165 
166     /***
167      * Get the object named.
168      *
169      * @param name the name
170      * @return the object
171      * @exception NamingException if an error occurs (ie object name is inavlid or unbound)
172      */
173     public Object lookup( final Name name )
174         throws NamingException
175     {
176         final ResolveResult resolveResult = getBaseURLContext( name, m_environment );
177         final Context context = (Context)resolveResult.getResolvedObj();
178 
179         try
180         {
181             return context.lookup( resolveResult.getRemainingName() );
182         }
183         finally
184         {
185             context.close();
186         }
187     }
188 
189     /***
190      * Unbind a object from a name.
191      *
192      * @param name the name
193      * @exception NamingException if an error occurs
194      */
195     public void unbind( final Name name )
196         throws NamingException
197     {
198         final ResolveResult resolveResult = getBaseURLContext( name, m_environment );
199         final Context context = (Context)resolveResult.getResolvedObj();
200 
201         try
202         {
203             context.unbind( resolveResult.getRemainingName() );
204         }
205         finally
206         {
207             context.close();
208         }
209     }
210 
211     protected ResolveResult getBaseURLContext( final Name name, final Hashtable environment )
212         throws NamingException
213     {
214         if( name.isEmpty() )
215         {
216             throw new InvalidNameException( "Unable to locate URLContext will empty name" );
217         }
218 
219         final String nameString = name.toString();
220         int index = nameString.indexOf( ':' );
221 
222         if( -1 == index )
223         {
224             throw new InvalidNameException( "Unable to build URLContext as it does not specify scheme" );
225         }
226 
227         final String scheme = nameString.substring( 0, index );
228         final int end = getEndIndexOfURLPart( nameString, index + 1 );
229         final String urlPart = nameString.substring( index + 1, end );
230         final String namePart = nameString.substring( end );
231 
232         if( !m_scheme.equals( scheme ) )
233         {
234             throw new InvalidNameException( "Bad Scheme use to build URLContext (" + scheme + "). " +
235                                             "Expected " + m_scheme );
236         }
237 
238         final Context context = newContext( urlPart );
239 
240         return new ResolveResult( context, new CompositeName( namePart ) );
241     }
242 
243     /***
244      * Find end index of url part in string.
245      * Default implementation looks for
246      * //.../[name-part]
247      * ///[name-part]
248      * //... (no name part)
249      * [name-part]
250      *
251      * @param name the name
252      * @param index the index where "scheme:" ends
253      * @return the index where url ends
254      * @exception NamingException if an error occurs
255      */
256     protected int getEndIndexOfURLPart( final String name, final int index )
257         throws NamingException
258     {
259         int result = 0;
260 
261         //does it start with //
262         if( name.startsWith( "//", index ) )
263         {
264             //does it have .../  following ???
265             int end = name.indexOf( "/", index + 2 );
266 
267             if( -1 != end )
268             {
269                 result = end;
270             }
271             else
272             {
273                 result = name.length();
274             }
275         }
276 
277         return result;
278     }
279 
280     /***
281      * Return a new instance of the base context for a URL.
282      * This must be implemented in particular URLContext.
283      *
284      * @param urlPart the part of url string not including "scheme:"
285      * @return a base URLContext for urlPart
286      * @exception NamingException if an error occurs
287      */
288     protected abstract Context newContext( String urlPart )
289         throws NamingException;
290 }