View Javadoc

1   // 
2   //Copyright (c) 2003, Caltha - Gajda, Krzewski, Mach, Potempski Sp.J. 
3   //All rights reserved. 
4   //   
5   //Redistribution and use in source and binary forms, with or without modification,  
6   //are permitted provided that the following conditions are met: 
7   //   
8   //* Redistributions of source code must retain the above copyright notice,  
9   //this list of conditions and the following disclaimer. 
10  //* Redistributions in binary form must reproduce the above copyright notice,  
11  //this list of conditions and the following disclaimer in the documentation  
12  //and/or other materials provided with the distribution. 
13  //* Neither the name of the Caltha - Gajda, Krzewski, Mach, Potempski Sp.J.  
14  //nor the names of its contributors may be used to endorse or promote products  
15  //derived from this software without specific prior written permission. 
16  // 
17  //THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"  
18  //AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED  
19  //WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 
20  //IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,  
21  //INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,  
22  //BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, 
23  //OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,  
24  //WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)  
25  //ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE  
26  //POSSIBILITY OF SUCH DAMAGE. 
27  //
28  
29  package org.objectledge.naming;
30  
31  import javax.naming.Context;
32  import javax.naming.InvalidNameException;
33  import javax.naming.Name;
34  import javax.naming.NameParser;
35  import javax.naming.NamingException;
36  import javax.naming.directory.DirContext;
37  
38  import org.jcontainer.dna.Logger;
39  
40  /**
41   * Helps you in looking up objects in a context using their fully qualified
42   * distinguished names.
43   *
44   * <p>It is a very common situation that your directory provider URL contains
45   * a non empty base name. Because of that, whenever you need to perform a
46   * directory lookup using a fully qualified DN, you need to transform the DN
47   * to be relative to the directory providers base DN. This class simplifies
48   * this task.</p>
49   *
50   * @author <a href="mailto:rafal@caltha.pl">Rafal Krzewski</a>
51   * @version $Id: ContextHelper.java,v 1.2 2006/06/01 06:37:49 rafal Exp $
52   */
53  public class ContextHelper
54  {
55      // instance variables ////////////////////////////////////////////////////
56  
57      private final ContextFactory contextFactory;
58      
59      private final String contextAlias;
60      
61      /*** The wrapped context. */
62      private Context context;
63  
64      /*** Fully qualified name of the wrapped context. */
65      private final Name baseName;
66  
67      /*** The name parser. */
68      private final NameParser parser;
69      
70      /*** The logger. */
71      private final Logger logger;
72  
73      // initialization ////////////////////////////////////////////////////////
74  
75      /***
76       * Constructs a lookup helper.
77       *
78       * @param context the context to construct helper for.
79       * @throws NamingException if failed.
80       */
81      public ContextHelper(ContextFactory contextFactory, String contextAlias, Logger logger)
82          throws NamingException
83      {
84          this.contextFactory = contextFactory;
85          this.contextAlias = contextAlias;
86          this.context = contextFactory.getContext(contextAlias);
87          this.parser = context.getNameParser("");
88          this.baseName = parser.parse(context.getNameInNamespace());
89          this.logger = logger;
90      }
91      
92      // public interface /////////////////////////////////////////////////////
93      
94      /***
95       * Checks if a name is within wrapped context's namespace.
96       *
97       * @param name the fully qualified name.
98       * @return <code>true</code> if the name is within wrapped context's
99       *         namespace.
100      * @throws NamingException if failed. 
101      */
102     public boolean isInNamespace(String name)
103         throws NamingException
104     {
105         return isInNamespace(parser.parse(name));
106     }
107 
108     /***
109      * Checks if a name is within wrapped context's namespace.
110      *
111      * @param name the fully qualified name.
112      * @return <code>true</code> if the name is within wrapped context's
113      *         namespace.
114      * @throws NamingException if failed. 
115      */
116     public boolean isInNamespace(Name name)
117         throws NamingException
118     {
119         return name.startsWith(baseName);
120     }
121 
122     /***
123      * Performs a lookup using a fully qualified DN.
124      *
125      * @param name the fully qualified name.
126      * @return an Object.
127      * @throws NamingException if failed.
128      */
129     public Object lookup(Name name)
130         throws NamingException
131     {
132         Name relativeName;
133         if(name.isEmpty())
134         {
135             relativeName = name;
136         }
137         else
138         {
139             if(!name.startsWith(baseName))
140             {
141                 throw new InvalidNameException(name+" is not in "+baseName+" namespace");
142             }
143             relativeName = name.getSuffix(baseName.size());
144         }
145         try
146         {
147             return context.lookup(relativeName);
148         }
149         catch(Exception e)
150         {
151             logger.error("context lookup failed, will attempt to reconnect", e);
152             reconnect();
153             logger.info("reconnect successful");
154             return context.lookup(relativeName);
155         }
156     }
157     
158     /***
159      * Performs a lookup using a fully qualified DN.
160      *
161      * @param name the fully qualified name. 
162      * @return an Object.
163      * @throws NamingException if failed.
164      */
165     public Object lookup(String name)
166         throws NamingException
167     {
168         return lookup(parser.parse(name));
169     }
170     
171     /***
172      * Performs a lookup using a fully qualified DN.
173      *
174      * @param name the fully qualified name.
175      * @return a Context.
176      * @throws NamingException if failed.
177      */
178     public Context lookupContext(String name)
179         throws NamingException
180     {
181         return (Context)lookup(name);
182     }
183     
184     /***
185      * Performs a lookup using a fully qualified DN.
186      *
187      * @param name the fully qualified name.
188      * @return a Context.
189      * @throws NamingException if failed.
190      */
191     public Context lookupContext(Name name)
192         throws NamingException
193     {
194         return (Context)lookup(name);
195     }
196 
197     /***
198      * Performs a lookup using a fully qualified DN.
199      *
200      * @param name the fully qualified name.
201      * @return a DirContext.
202      * @throws NamingException if failed.
203      */
204     public DirContext lookupDirContext(String name)
205         throws NamingException
206     {
207         return (DirContext)lookup(name);
208     }
209     
210     /***
211      * Performs a lookup using a fully qualified DN.
212      *
213      * @param name the fully qualified name.
214      * @return a DirContext.
215      * @throws NamingException if failed.
216      */
217     public DirContext lookupDirContext(Name name)
218         throws NamingException
219     {
220         return (DirContext)lookup(name);
221     }
222 
223     /***
224      * Returns get base context.
225      *
226      * @return the base context.
227      */
228     public Context getBaseContext() throws NamingException
229     {
230         return (Context)lookup(parser.parse(""));
231     }
232 
233     /***
234      * Returns the base directory context.
235      *
236      * @return the base directory context.
237      */
238     public DirContext getBaseDirContext() throws NamingException
239     {
240         return (DirContext)lookup(parser.parse(""));
241     }
242 
243     /***
244      * Get the base name.
245      * 
246      * @return the base name.
247      */    
248     public Name getBaseName()
249     {
250         return baseName;
251     }
252     
253     /***
254      * Converts the name to be relative to the lookupCtx.
255      *
256      * @param name the name to convert.
257      * @return the relative name.
258      * @throws NamingException if name is not in lookupCtx's namespace.
259      */
260     public Name getRelativeName(String name)
261         throws NamingException
262     {
263         Name parsedName = parser.parse(name);
264         if(!parsedName.startsWith(baseName))
265         {
266             throw new InvalidNameException(parsedName+" is not in "+baseName+" namespace");
267         }
268         return parsedName.getSuffix(baseName.size());
269     }    
270     
271     private void reconnect() throws NamingException
272     {
273         contextFactory.reconnect(contextAlias);
274         context = contextFactory.getContext(contextAlias);
275     }
276 }