View Javadoc

1   /*
2    * Copyright 2005-2008 the original author or authors.
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.springframework.ldap.pool;
18  
19  import javax.naming.Context;
20  import javax.naming.Name;
21  import javax.naming.NamingEnumeration;
22  import javax.naming.NamingException;
23  import javax.naming.directory.Attributes;
24  import javax.naming.directory.DirContext;
25  import javax.naming.directory.ModificationItem;
26  import javax.naming.directory.SearchControls;
27  
28  import org.apache.commons.lang.Validate;
29  import org.apache.commons.pool.KeyedObjectPool;
30  import org.springframework.ldap.core.DirContextProxy;
31  import org.springframework.ldap.pool.factory.PoolingContextSource;
32  
33  
34  /**
35   * Used by {@link PoolingContextSource} to wrap a {@link DirContext}, delegating most methods
36   * to the underlying context. This class extends {@link DelegatingContext} which handles returning
37   * the context to the pool on a call to {@link #close()}
38   * 
39   * @author Eric Dalquist
40   */
41  public class DelegatingDirContext extends DelegatingContext implements DirContext, DirContextProxy {
42      private DirContext delegateDirContext;
43  
44      /**
45       * Create a new delegating dir context for the specified pool, context and context type.
46       * 
47       * @param keyedObjectPool The pool the delegate context was checked out from.
48       * @param delegateDirContext The dir context to delegate operations to.
49       * @param dirContextType The type of context, used as a key for the pool.
50       * @throws IllegalArgumentException if any of the arguments are null
51       */
52      public DelegatingDirContext(KeyedObjectPool keyedObjectPool, DirContext delegateDirContext, DirContextType dirContextType) {
53          super(keyedObjectPool, delegateDirContext, dirContextType);
54          Validate.notNull(delegateDirContext, "delegateDirContext may not be null");
55  
56          this.delegateDirContext = delegateDirContext;
57      }
58      
59      
60      //***** Helper Methods *****//
61      
62      /**
63       * @return The direct delegate for this dir context proxy
64       */
65      public DirContext getDelegateDirContext() {
66          return this.delegateDirContext;
67      }
68      
69      public Context getDelegateContext() {
70          return this.getDelegateDirContext();
71      }
72  
73      /**
74       * Recursivley inspect delegates until a non-delegating dir context is found.
75       * 
76       * @return The innermost (real) DirContext that is being delegated to.
77       */
78      public DirContext getInnermostDelegateDirContext() {
79          final DirContext delegateDirContext = this.getDelegateDirContext();
80  
81          if (delegateDirContext instanceof DelegatingDirContext) {
82              return ((DelegatingDirContext)delegateDirContext).getInnermostDelegateDirContext();
83          }
84  
85          return delegateDirContext;
86      }
87  
88      protected void assertOpen() throws NamingException {
89          if (this.delegateDirContext == null) {
90              throw new NamingException("DirContext is closed.");
91          }
92  
93          super.assertOpen();
94      }
95  
96      
97      //***** Object methods *****//
98  
99      /**
100      * @see java.lang.Object#equals(java.lang.Object)
101      */
102     public boolean equals(Object obj) {
103         if (this == obj) {
104             return true;
105         }
106         if (!(obj instanceof DirContext)) {
107             return false;
108         }
109         
110         final DirContext thisDirContext = this.getInnermostDelegateDirContext();
111         DirContext otherDirContext = (DirContext)obj;
112         if (otherDirContext instanceof DelegatingDirContext) {
113             otherDirContext = ((DelegatingDirContext)otherDirContext).getInnermostDelegateDirContext();
114         }
115         
116         return thisDirContext == otherDirContext || (thisDirContext != null && thisDirContext.equals(otherDirContext));
117     }
118 
119     /**
120      * @see java.lang.Object#hashCode()
121      */
122     public int hashCode() {
123         final DirContext context = this.getInnermostDelegateDirContext();
124         return (context != null ? context.hashCode() : 0);
125     }
126 
127     /**
128      * @see java.lang.Object#toString()
129      */
130     public String toString() {
131         final DirContext context = this.getInnermostDelegateDirContext();
132         return (context != null ? context.toString() : "DirContext is closed");
133     }
134 
135 
136     //***** DirContextProxy Interface Methods *****//
137 
138     /* (non-Javadoc)
139      * @see org.springframework.ldap.core.DirContextProxy#getTargetContext()
140      */
141     public DirContext getTargetContext() {
142         return this.getInnermostDelegateDirContext();
143     }
144     
145     
146     //***** DirContext Interface Delegates *****//
147 
148     /**
149      * @see javax.naming.directory.DirContext#bind(javax.naming.Name, java.lang.Object, javax.naming.directory.Attributes)
150      */
151     public void bind(Name name, Object obj, Attributes attrs) throws NamingException {
152         this.assertOpen();
153         this.getDelegateDirContext().bind(name, obj, attrs);
154     }
155 
156     /**
157      * @see javax.naming.directory.DirContext#bind(java.lang.String, java.lang.Object, javax.naming.directory.Attributes)
158      */
159     public void bind(String name, Object obj, Attributes attrs) throws NamingException {
160         this.assertOpen();
161         this.getDelegateDirContext().bind(name, obj, attrs);
162     }
163 
164     /**
165      * @see javax.naming.directory.DirContext#createSubcontext(javax.naming.Name, javax.naming.directory.Attributes)
166      */
167     public DirContext createSubcontext(Name name, Attributes attrs) throws NamingException {
168         throw new UnsupportedOperationException("Cannot call createSubcontext on a pooled context");
169     }
170 
171     /**
172      * @see javax.naming.directory.DirContext#createSubcontext(java.lang.String, javax.naming.directory.Attributes)
173      */
174     public DirContext createSubcontext(String name, Attributes attrs) throws NamingException {
175         throw new UnsupportedOperationException("Cannot call createSubcontext on a pooled context");
176     }
177 
178     /**
179      * @see javax.naming.directory.DirContext#getAttributes(javax.naming.Name, java.lang.String[])
180      */
181     public Attributes getAttributes(Name name, String[] attrIds) throws NamingException {
182         this.assertOpen();
183         return this.getDelegateDirContext().getAttributes(name, attrIds);
184     }
185 
186     /**
187      * @see javax.naming.directory.DirContext#getAttributes(javax.naming.Name)
188      */
189     public Attributes getAttributes(Name name) throws NamingException {
190         this.assertOpen();
191         return this.getDelegateDirContext().getAttributes(name);
192     }
193 
194     /**
195      * @see javax.naming.directory.DirContext#getAttributes(java.lang.String, java.lang.String[])
196      */
197     public Attributes getAttributes(String name, String[] attrIds) throws NamingException {
198         this.assertOpen();
199         return this.getDelegateDirContext().getAttributes(name, attrIds);
200     }
201 
202     /**
203      * @see javax.naming.directory.DirContext#getAttributes(java.lang.String)
204      */
205     public Attributes getAttributes(String name) throws NamingException {
206         this.assertOpen();
207         return this.getDelegateDirContext().getAttributes(name);
208     }
209 
210     /**
211      * @see javax.naming.directory.DirContext#getSchema(javax.naming.Name)
212      */
213     public DirContext getSchema(Name name) throws NamingException {
214         throw new UnsupportedOperationException("Cannot call getSchema on a pooled context");
215     }
216 
217     /**
218      * @see javax.naming.directory.DirContext#getSchema(java.lang.String)
219      */
220     public DirContext getSchema(String name) throws NamingException {
221         throw new UnsupportedOperationException("Cannot call getSchema on a pooled context");
222     }
223 
224     /**
225      * @see javax.naming.directory.DirContext#getSchemaClassDefinition(javax.naming.Name)
226      */
227     public DirContext getSchemaClassDefinition(Name name) throws NamingException {
228         throw new UnsupportedOperationException("Cannot call getSchemaClassDefinition on a pooled context");
229     }
230 
231     /**
232      * @see javax.naming.directory.DirContext#getSchemaClassDefinition(java.lang.String)
233      */
234     public DirContext getSchemaClassDefinition(String name) throws NamingException {
235         throw new UnsupportedOperationException("Cannot call getSchemaClassDefinition on a pooled context");
236     }
237 
238     /**
239      * @see javax.naming.directory.DirContext#modifyAttributes(javax.naming.Name, int, javax.naming.directory.Attributes)
240      */
241     public void modifyAttributes(Name name, int mod_op, Attributes attrs) throws NamingException {
242         this.assertOpen();
243         this.getDelegateDirContext().modifyAttributes(name, mod_op, attrs);
244     }
245 
246     /**
247      * @see javax.naming.directory.DirContext#modifyAttributes(javax.naming.Name, javax.naming.directory.ModificationItem[])
248      */
249     public void modifyAttributes(Name name, ModificationItem[] mods) throws NamingException {
250         this.assertOpen();
251         this.getDelegateDirContext().modifyAttributes(name, mods);
252     }
253 
254     /**
255      * @see javax.naming.directory.DirContext#modifyAttributes(java.lang.String, int, javax.naming.directory.Attributes)
256      */
257     public void modifyAttributes(String name, int mod_op, Attributes attrs) throws NamingException {
258         this.assertOpen();
259         this.getDelegateDirContext().modifyAttributes(name, mod_op, attrs);
260     }
261 
262     /**
263      * @see javax.naming.directory.DirContext#modifyAttributes(java.lang.String, javax.naming.directory.ModificationItem[])
264      */
265     public void modifyAttributes(String name, ModificationItem[] mods) throws NamingException {
266         this.assertOpen();
267         this.getDelegateDirContext().modifyAttributes(name, mods);
268     }
269 
270     /**
271      * @see javax.naming.directory.DirContext#rebind(javax.naming.Name, java.lang.Object, javax.naming.directory.Attributes)
272      */
273     public void rebind(Name name, Object obj, Attributes attrs) throws NamingException {
274         this.assertOpen();
275         this.getDelegateDirContext().rebind(name, obj, attrs);
276     }
277 
278     /**
279      * @see javax.naming.directory.DirContext#rebind(java.lang.String, java.lang.Object, javax.naming.directory.Attributes)
280      */
281     public void rebind(String name, Object obj, Attributes attrs) throws NamingException {
282         this.assertOpen();
283         this.getDelegateDirContext().rebind(name, obj, attrs);
284     }
285 
286     /**
287      * @see javax.naming.directory.DirContext#search(javax.naming.Name, javax.naming.directory.Attributes, java.lang.String[])
288      */
289     public NamingEnumeration search(Name name, Attributes matchingAttributes, String[] attributesToReturn) throws NamingException {
290         this.assertOpen();
291         return this.getDelegateDirContext().search(name, matchingAttributes, attributesToReturn);
292     }
293 
294     /**
295      * @see javax.naming.directory.DirContext#search(javax.naming.Name, javax.naming.directory.Attributes)
296      */
297     public NamingEnumeration search(Name name, Attributes matchingAttributes) throws NamingException {
298         this.assertOpen();
299         return this.getDelegateDirContext().search(name, matchingAttributes);
300     }
301 
302     /**
303      * @see javax.naming.directory.DirContext#search(javax.naming.Name, java.lang.String, java.lang.Object[], javax.naming.directory.SearchControls)
304      */
305     public NamingEnumeration search(Name name, String filterExpr, Object[] filterArgs, SearchControls cons) throws NamingException {
306         this.assertOpen();
307         return this.getDelegateDirContext().search(name, filterExpr, filterArgs, cons);
308     }
309 
310     /**
311      * @see javax.naming.directory.DirContext#search(javax.naming.Name, java.lang.String, javax.naming.directory.SearchControls)
312      */
313     public NamingEnumeration search(Name name, String filter, SearchControls cons) throws NamingException {
314         this.assertOpen();
315         return this.getDelegateDirContext().search(name, filter, cons);
316     }
317 
318     /**
319      * @see javax.naming.directory.DirContext#search(java.lang.String, javax.naming.directory.Attributes, java.lang.String[])
320      */
321     public NamingEnumeration search(String name, Attributes matchingAttributes, String[] attributesToReturn) throws NamingException {
322         this.assertOpen();
323         return this.getDelegateDirContext().search(name, matchingAttributes, attributesToReturn);
324     }
325 
326     /**
327      * @see javax.naming.directory.DirContext#search(java.lang.String, javax.naming.directory.Attributes)
328      */
329     public NamingEnumeration search(String name, Attributes matchingAttributes) throws NamingException {
330         this.assertOpen();
331         return this.getDelegateDirContext().search(name, matchingAttributes);
332     }
333 
334     /**
335      * @see javax.naming.directory.DirContext#search(java.lang.String, java.lang.String, java.lang.Object[], javax.naming.directory.SearchControls)
336      */
337     public NamingEnumeration search(String name, String filterExpr, Object[] filterArgs, SearchControls cons) throws NamingException {
338         this.assertOpen();
339         return this.getDelegateDirContext().search(name, filterExpr, filterArgs, cons);
340     }
341 
342     /**
343      * @see javax.naming.directory.DirContext#search(java.lang.String, java.lang.String, javax.naming.directory.SearchControls)
344      */
345     public NamingEnumeration search(String name, String filter, SearchControls cons) throws NamingException {
346         this.assertOpen();
347         return this.getDelegateDirContext().search(name, filter, cons);
348     }
349 
350     /**
351      * @see DelegatingContext#close()
352      */
353     public void close() throws NamingException {
354         if (this.delegateDirContext == null) {
355             return;
356         }
357 
358         super.close();
359         this.delegateDirContext = null;
360     }
361 }