KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > commons > configuration > JNDIConfiguration


1 /*
2  * Copyright 2001-2004 The Apache Software Foundation.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License")
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */

16
17 package org.apache.commons.configuration;
18
19 import java.util.ArrayList JavaDoc;
20 import java.util.HashSet JavaDoc;
21 import java.util.Iterator JavaDoc;
22 import java.util.List JavaDoc;
23 import java.util.Set JavaDoc;
24
25 import javax.naming.Context JavaDoc;
26 import javax.naming.InitialContext JavaDoc;
27 import javax.naming.NameClassPair JavaDoc;
28 import javax.naming.NamingEnumeration JavaDoc;
29 import javax.naming.NamingException JavaDoc;
30
31 import org.apache.commons.lang.StringUtils;
32 import org.apache.commons.logging.Log;
33 import org.apache.commons.logging.LogFactory;
34
35 /**
36  * This Configuration class allows you to interface with a JNDI datasource.
37  * A JNDIConfiguration is read-only, write operations will throw an
38  * UnsupportedOperationException. The clear operations are supported but the
39  * underlying JNDI data source is not changed.
40  *
41  * @author <a HREF="mailto:epugh@upstate.com">Eric Pugh</a>
42  * @version $Id: JNDIConfiguration.java 155408 2005-02-26 12:56:39Z dirkv $
43  */

44 public class JNDIConfiguration extends AbstractConfiguration
45 {
46     /** Logger. */
47     private static Log log = LogFactory.getLog(JNDIConfiguration.class);
48
49     /** The prefix of the context. */
50     private String JavaDoc prefix;
51
52     /** The initial JNDI context. */
53     private Context JavaDoc context;
54
55     /** The base JNDI context. */
56     private Context JavaDoc baseContext;
57
58     /** The Set of keys that have been virtually cleared. */
59     private Set JavaDoc clearedProperties = new HashSet JavaDoc();
60
61     /**
62      * Creates a JNDIConfiguration using the default initial context as the
63      * root of the properties.
64      *
65      * @throws NamingException thrown if an error occurs when initializing the default context
66      */

67     public JNDIConfiguration() throws NamingException JavaDoc
68     {
69         this((String JavaDoc) null);
70     }
71
72     /**
73      * Creates a JNDIConfiguration using the default initial context, shifted
74      * with the specified prefix, as the root of the properties.
75      *
76      * @param prefix
77      *
78      * @throws NamingException thrown if an error occurs when initializing the default context
79      */

80     public JNDIConfiguration(String JavaDoc prefix) throws NamingException JavaDoc
81     {
82         this(new InitialContext JavaDoc(), prefix);
83     }
84
85     /**
86      * Creates a JNDIConfiguration using the specified initial context as the
87      * root of the properties.
88      *
89      * @param context the initial context
90      */

91     public JNDIConfiguration(Context JavaDoc context)
92     {
93         this(context, null);
94     }
95
96     /**
97      * Creates a JNDIConfiguration using the specified initial context shifted
98      * by the specified prefix as the root of the properties.
99      *
100      * @param context the initial context
101      * @param prefix
102      */

103     public JNDIConfiguration(Context JavaDoc context, String JavaDoc prefix)
104     {
105         this.context = context;
106         this.prefix = prefix;
107     }
108
109     /**
110      * This method recursive traverse the JNDI tree, looking for Context objects.
111      * When it finds them, it traverses them as well. Otherwise it just adds the
112      * values to the list of keys found.
113      *
114      * @param keys All the keys that have been found.
115      * @param context The parent context
116      * @param prefix What prefix we are building on.
117      * @throws NamingException If JNDI has an issue.
118      */

119     private void recursiveGetKeys(Set JavaDoc keys, Context JavaDoc context, String JavaDoc prefix) throws NamingException JavaDoc
120     {
121         NamingEnumeration JavaDoc elements = null;
122
123         try
124         {
125             elements = context.list("");
126
127             // iterates through the context's elements
128
while (elements.hasMore())
129             {
130                 NameClassPair JavaDoc nameClassPair = (NameClassPair JavaDoc) elements.next();
131                 String JavaDoc name = nameClassPair.getName();
132                 Object JavaDoc object = context.lookup(name);
133
134                 // build the key
135
StringBuffer JavaDoc key = new StringBuffer JavaDoc();
136                 key.append(prefix);
137                 if (key.length() > 0)
138                 {
139                     key.append(".");
140                 }
141                 key.append(name);
142
143                 if (object instanceof Context JavaDoc)
144                 {
145                     // add the keys of the sub context
146
Context JavaDoc subcontext = (Context JavaDoc) object;
147                     recursiveGetKeys(keys, subcontext, key.toString());
148                 }
149                 else
150                 {
151                     // add the key
152
keys.add(key.toString());
153                 }
154             }
155         }
156         finally
157         {
158             // close the enumeration
159
if (elements != null)
160             {
161                 elements.close();
162             }
163         }
164     }
165
166     /**
167      * {@inheritDoc}
168      */

169     public Iterator JavaDoc getKeys()
170     {
171         return getKeys("");
172     }
173
174     /**
175      * {@inheritDoc}
176      */

177     public Iterator JavaDoc getKeys(String JavaDoc prefix)
178     {
179         // build the path
180
String JavaDoc[] splitPath = StringUtils.split(prefix, ".");
181
182         List JavaDoc path = new ArrayList JavaDoc();
183
184         for (int i = 0; i < splitPath.length; i++)
185         {
186             path.add(splitPath[i]);
187         }
188
189         try
190         {
191             // find the context matching the specified path
192
Context JavaDoc context = getContext(path, getBaseContext());
193
194             // return all the keys under the context found
195
Set JavaDoc keys = new HashSet JavaDoc();
196             if (context != null)
197             {
198                 recursiveGetKeys(keys, context, prefix);
199             }
200             else if (containsKey(prefix))
201             {
202                 // add the prefix if it matches exactly a property key
203
keys.add(prefix);
204             }
205
206             return keys.iterator();
207         }
208         catch (NamingException JavaDoc e)
209         {
210             log.error(e.getMessage(), e);
211             return new ArrayList JavaDoc().iterator();
212         }
213     }
214
215     /**
216      * Because JNDI is based on a tree configuration, we need to filter down the
217      * tree, till we find the Context specified by the key to start from.
218      * Otherwise return null.
219      *
220      * @param path the path of keys to traverse in order to find the context
221      * @param context the context to start from
222      * @return The context at that key's location in the JNDI tree, or null if not found
223      * @throws NamingException if JNDI has an issue
224      */

225     private Context JavaDoc getContext(List JavaDoc path, Context JavaDoc context) throws NamingException JavaDoc
226     {
227         // return the current context if the path is empty
228
if (path == null || path.isEmpty())
229         {
230             return context;
231         }
232
233         String JavaDoc key = (String JavaDoc) path.get(0);
234
235         // search a context matching the key in the context's elements
236
NamingEnumeration JavaDoc elements = null;
237
238         try
239         {
240             elements = context.list("");
241             while (elements.hasMore())
242             {
243                 NameClassPair JavaDoc nameClassPair = (NameClassPair JavaDoc) elements.next();
244                 String JavaDoc name = nameClassPair.getName();
245                 Object JavaDoc object = context.lookup(name);
246
247                 if (object instanceof Context JavaDoc && name.equals(key))
248                 {
249                     Context JavaDoc subcontext = (Context JavaDoc) object;
250
251                     // recursive search in the sub context
252
return getContext(path.subList(1, path.size()), subcontext);
253                 }
254             }
255         }
256         finally
257         {
258             if (elements != null)
259             {
260                 elements.close();
261             }
262         }
263
264         return null;
265     }
266
267     /**
268      * {@inheritDoc}
269      */

270     public boolean isEmpty()
271     {
272         try
273         {
274             NamingEnumeration JavaDoc enumeration = null;
275
276             try
277             {
278                 enumeration = getBaseContext().list("");
279                 return !enumeration.hasMore();
280             }
281             finally
282             {
283                 // close the enumeration
284
if (enumeration != null)
285                 {
286                     enumeration.close();
287                 }
288             }
289         }
290         catch (NamingException JavaDoc e)
291         {
292             log.error(e.getMessage(), e);
293             return true;
294         }
295     }
296
297     /**
298      * <p><strong>This operation is not supported and will throw an
299      * UnsupportedOperationException.</strong></p>
300      *
301      * @throws UnsupportedOperationException
302      */

303     public void setProperty(String JavaDoc key, Object JavaDoc value)
304     {
305         throw new UnsupportedOperationException JavaDoc("This operation is not supported");
306     }
307
308     /**
309      * {@inheritDoc}
310      */

311     public void clearProperty(String JavaDoc key)
312     {
313         clearedProperties.add(key);
314     }
315
316     /**
317      * {@inheritDoc}
318      */

319     public boolean containsKey(String JavaDoc key)
320     {
321         if (clearedProperties.contains(key))
322         {
323             return false;
324         }
325         key = StringUtils.replace(key, ".", "/");
326         try
327         {
328             // throws a NamingException if JNDI doesn't contain the key.
329
getBaseContext().lookup(key);
330             return true;
331         }
332         catch (NamingException JavaDoc e)
333         {
334             log.error(e.getMessage(), e);
335             return false;
336         }
337     }
338
339     /**
340      * @return String
341      */

342     public String JavaDoc getPrefix()
343     {
344         return prefix;
345     }
346
347     /**
348      * Sets the prefix.
349      *
350      * @param prefix The prefix to set
351      */

352     public void setPrefix(String JavaDoc prefix)
353     {
354         this.prefix = prefix;
355
356         // clear the previous baseContext
357
baseContext = null;
358     }
359
360     /**
361      * {@inheritDoc}
362      */

363     public Object JavaDoc getProperty(String JavaDoc key)
364     {
365         if (clearedProperties.contains(key))
366         {
367             return null;
368         }
369
370         try
371         {
372             key = StringUtils.replace(key, ".", "/");
373             return getBaseContext().lookup(key);
374         }
375         catch (NamingException JavaDoc e)
376         {
377             log.error(e.getMessage(), e);
378             return null;
379         }
380     }
381
382     /**
383      * <p><strong>This operation is not supported and will throw an
384      * UnsupportedOperationException.</strong></p>
385      *
386      * @throws UnsupportedOperationException
387      */

388     protected void addPropertyDirect(String JavaDoc key, Object JavaDoc obj)
389     {
390         throw new UnsupportedOperationException JavaDoc("This operation is not supported");
391     }
392
393     /**
394      * Return the base context with the prefix applied.
395      */

396     public Context JavaDoc getBaseContext() throws NamingException JavaDoc
397     {
398         if (baseContext == null)
399         {
400             baseContext = (Context JavaDoc) getContext().lookup(prefix == null ? "" : prefix);
401         }
402
403         return baseContext;
404     }
405
406     /**
407      * Return the initial context used by this configuration. This context is
408      * independent of the prefix specified.
409      */

410     public Context JavaDoc getContext()
411     {
412         return context;
413     }
414
415     /**
416      * Set the initial context of the configuration.
417      */

418     public void setContext(Context JavaDoc context)
419     {
420         // forget the removed properties
421
clearedProperties.clear();
422
423         // change the context
424
this.context = context;
425     }
426 }
427
Popular Tags