View Javadoc

1   /*
2    *   Copyright 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.ldap.server.jndi;
18  
19  import java.util.Iterator;
20  import java.util.Map;
21  
22  import javax.naming.Context;
23  import javax.naming.Name;
24  import javax.naming.NamingEnumeration;
25  import javax.naming.NamingException;
26  import javax.naming.ServiceUnavailableException;
27  import javax.naming.directory.Attributes;
28  import javax.naming.directory.ModificationItem;
29  import javax.naming.directory.SearchControls;
30  import javax.naming.ldap.LdapContext;
31  
32  import org.apache.ldap.common.filter.ExprNode;
33  import org.apache.ldap.server.configuration.ContextPartitionConfiguration;
34  import org.apache.ldap.server.interceptor.InterceptorChain;
35  import org.apache.ldap.server.invocation.Invocation;
36  import org.apache.ldap.server.invocation.InvocationStack;
37  import org.apache.ldap.server.partition.ContextPartition;
38  import org.apache.ldap.server.partition.ContextPartitionNexus;
39  
40  /***
41   * A decorator that wraps other {@link ContextPartitionNexus} to enable
42   * {@link InterceptorChain} and {@link InvocationStack} support.
43   * All {@link Invocation}s made to this nexus is automatically pushed to
44   * {@link InvocationStack} of the current thread, and popped when
45   * the operation ends.  All invocations are filtered by {@link InterceptorChain}.
46   *
47   * @author The Apache Directory Project
48   * @version $Rev: 264732 $, $Date: 2005-08-30 04:04:51 -0400 (Tue, 30 Aug 2005) $
49   */
50  class ContextPartitionNexusProxy extends ContextPartitionNexus
51  {
52      private final Context caller;
53      private final ContextFactoryService service;
54      private final ContextFactoryConfiguration configuration;
55  
56      /***
57       * Creates a new instance.
58       * 
59       * @param caller a JNDI {@link Context} object that will call this proxy
60       * @param service a JNDI service
61       */
62      ContextPartitionNexusProxy( Context caller, ContextFactoryService service )
63      {
64          this.caller = caller;
65          this.service = service;
66          this.configuration = service.getConfiguration();
67      }
68      
69      public LdapContext getLdapContext() {
70          return this.configuration.getPartitionNexus().getLdapContext();
71      }
72  
73      public void init( ContextFactoryConfiguration factoryCfg, ContextPartitionConfiguration cfg )
74      {
75      }
76  
77      public void destroy()
78      {
79      }
80  
81      public ContextPartition getSystemPartition()
82      {
83          return this.configuration.getPartitionNexus().getSystemPartition();
84      }
85  
86      public Name getSuffix( boolean normalized ) throws NamingException
87      {
88          return this.configuration.getPartitionNexus().getSuffix( normalized );
89      }
90  
91      public void sync() throws NamingException {
92          this.service.sync();
93      }
94  
95      public void close() throws NamingException {
96          this.service.shutdown();
97      }
98  
99      public boolean isInitialized() {
100         return this.service.isStarted();
101     }
102 
103     public Name getMatchedName(Name dn, boolean normalized) throws NamingException {
104         ensureStarted();
105         InvocationStack stack = InvocationStack.getInstance();
106         stack.push( new Invocation(
107                 caller, "getMatchedDn",
108                 new Object[] { dn, normalized? Boolean.TRUE : Boolean.FALSE } ) );
109         try
110         {
111             return this.configuration.getInterceptorChain().getMatchedName( dn, normalized );
112         }
113         finally
114         {
115             stack.pop();
116         }
117     }
118 
119     public Name getSuffix(Name dn, boolean normalized) throws NamingException {
120         ensureStarted();
121         InvocationStack stack = InvocationStack.getInstance();
122         stack.push( new Invocation(
123                 caller, "getSuffix",
124                 new Object[] { dn, normalized? Boolean.TRUE : Boolean.FALSE } ) );
125         try
126         {
127             return this.configuration.getInterceptorChain().getSuffix( dn, normalized );
128         }
129         finally
130         {
131             stack.pop();
132         }
133     }
134 
135     public Iterator listSuffixes(boolean normalized) throws NamingException {
136         ensureStarted();
137         InvocationStack stack = InvocationStack.getInstance();
138         stack.push( new Invocation(
139                 caller, "listSuffixes",
140                 new Object[] { normalized? Boolean.TRUE : Boolean.FALSE } ) );
141         try
142         {
143             return this.configuration.getInterceptorChain().listSuffixes( normalized );
144         }
145         finally
146         {
147             stack.pop();
148         }
149     }
150 
151     public void delete(Name name) throws NamingException {
152         ensureStarted();
153         InvocationStack stack = InvocationStack.getInstance();
154         stack.push( new Invocation(
155                 caller, "delete",
156                 new Object[] { name } ) );
157         try
158         {
159             this.configuration.getInterceptorChain().delete( name );
160         }
161         finally
162         {
163             stack.pop();
164         }
165     }
166 
167     public void add(String upName, Name normName, Attributes entry) throws NamingException {
168         ensureStarted();
169         InvocationStack stack = InvocationStack.getInstance();
170         stack.push( new Invocation(
171                 caller, "add",
172                 new Object[] { upName, normName, entry } ) );
173         try
174         {
175             this.configuration.getInterceptorChain().add( upName, normName, entry );
176         }
177         finally
178         {
179             stack.pop();
180         }
181     }
182 
183     public void modify(Name name, int modOp, Attributes mods) throws NamingException {
184         ensureStarted();
185         InvocationStack stack = InvocationStack.getInstance();
186         // TODO Use predefined modOp Interger constants.
187         stack.push( new Invocation(
188                 caller, "modify",
189                 new Object[] { name, new Integer( modOp ), mods } ) );
190         try
191         {
192             this.configuration.getInterceptorChain().modify( name, modOp, mods );
193         }
194         finally
195         {
196             stack.pop();
197         }
198     }
199 
200     public void modify(Name name, ModificationItem[] mods) throws NamingException {
201         ensureStarted();
202         InvocationStack stack = InvocationStack.getInstance();
203         stack.push( new Invocation(
204                 caller, "modify",
205                 new Object[] { name, mods } ) );
206         try
207         {
208             this.configuration.getInterceptorChain().modify( name, mods );
209         }
210         finally
211         {
212             stack.pop();
213         }
214     }
215 
216     public NamingEnumeration list(Name base) throws NamingException {
217         ensureStarted();
218         InvocationStack stack = InvocationStack.getInstance();
219         stack.push( new Invocation(
220                 caller, "list",
221                 new Object[] { base } ) );
222         try
223         {
224             return this.configuration.getInterceptorChain().list( base );
225         }
226         finally
227         {
228             stack.pop();
229         }
230     }
231 
232     public NamingEnumeration search(Name base, Map env, ExprNode filter, SearchControls searchCtls) throws NamingException {
233         ensureStarted();
234         InvocationStack stack = InvocationStack.getInstance();
235         stack.push( new Invocation(
236                 caller, "search",
237                 new Object[] { base, env, filter, searchCtls } ) );
238         try
239         {
240             return this.configuration.getInterceptorChain().search( base, env, filter, searchCtls );
241         }
242         finally
243         {
244             stack.pop();
245         }
246     }
247 
248     public Attributes lookup(Name name) throws NamingException {
249         ensureStarted();
250         InvocationStack stack = InvocationStack.getInstance();
251         stack.push( new Invocation(
252                 caller, "lookup",
253                 new Object[] { name } ) );
254         try
255         {
256             return this.configuration.getInterceptorChain().lookup( name );
257         }
258         finally
259         {
260             stack.pop();
261         }
262     }
263 
264     public Attributes lookup(Name dn, String[] attrIds) throws NamingException {
265         ensureStarted();
266         InvocationStack stack = InvocationStack.getInstance();
267         stack.push( new Invocation(
268                 caller, "lookup",
269                 new Object[] { dn, attrIds } ) );
270         try
271         {
272             return this.configuration.getInterceptorChain().lookup( dn, attrIds );
273         }
274         finally
275         {
276             stack.pop();
277         }
278     }
279 
280     public boolean hasEntry(Name name) throws NamingException {
281         ensureStarted();
282         InvocationStack stack = InvocationStack.getInstance();
283         stack.push( new Invocation(
284                 caller, "hasEntry",
285                 new Object[] { name } ) );
286         try
287         {
288             return this.configuration.getInterceptorChain().hasEntry( name );
289         }
290         finally
291         {
292             stack.pop();
293         }
294     }
295 
296     public boolean isSuffix(Name name) throws NamingException {
297         ensureStarted();
298         InvocationStack stack = InvocationStack.getInstance();
299         stack.push( new Invocation(
300                 caller, "isSuffix",
301                 new Object[] { name } ) );
302         try
303         {
304             return this.configuration.getInterceptorChain().isSuffix( name );
305         }
306         finally
307         {
308             stack.pop();
309         }
310     }
311 
312     public void modifyRn(Name name, String newRn, boolean deleteOldRn) throws NamingException {
313         ensureStarted();
314         InvocationStack stack = InvocationStack.getInstance();
315         stack.push( new Invocation(
316                 caller, "modifyRn",
317                 new Object[] { name, newRn, deleteOldRn? Boolean.TRUE : Boolean.FALSE } ) );
318         try
319         {
320             this.configuration.getInterceptorChain().modifyRn( name, newRn, deleteOldRn );
321         }
322         finally
323         {
324             stack.pop();
325         }
326     }
327 
328     public void move(Name oriChildName, Name newParentName) throws NamingException {
329         ensureStarted();
330         InvocationStack stack = InvocationStack.getInstance();
331         stack.push( new Invocation(
332                 caller, "move",
333                 new Object[] { oriChildName, newParentName } ) );
334         try
335         {
336             this.configuration.getInterceptorChain().move( oriChildName, newParentName );
337         }
338         finally
339         {
340             stack.pop();
341         }
342     }
343 
344     public void move(Name oriChildName, Name newParentName, String newRn, boolean deleteOldRn) throws NamingException {
345         ensureStarted();
346         InvocationStack stack = InvocationStack.getInstance();
347         stack.push( new Invocation(
348                 caller, "move",
349                 new Object[] { oriChildName, newParentName, newRn, deleteOldRn? Boolean.TRUE : Boolean.FALSE } ) );
350         try
351         {
352             this.configuration.getInterceptorChain().move( oriChildName, newParentName, newRn, deleteOldRn );
353         }
354         finally
355         {
356             stack.pop();
357         }
358     }
359 
360     public Attributes getRootDSE() throws NamingException
361     {
362         ensureStarted();
363         InvocationStack stack = InvocationStack.getInstance();
364         stack.push( new Invocation( caller, "getRootDSE" ) );
365         try
366         {
367             return this.configuration.getInterceptorChain().getRootDSE();
368         }
369         finally
370         {
371             stack.pop();
372         }
373     }
374 
375     public void addContextPartition( ContextPartitionConfiguration config ) throws NamingException
376     {
377         ensureStarted();
378         InvocationStack stack = InvocationStack.getInstance();
379         stack.push( new Invocation(
380                 caller, "addContextPartition",
381                 new Object[] { config } ) );
382         try
383         {
384             this.configuration.getInterceptorChain().addContextPartition( config );
385         }
386         finally
387         {
388             stack.pop();
389         }
390     }
391 
392     public void removeContextPartition( Name suffix ) throws NamingException
393     {
394         ensureStarted();
395         InvocationStack stack = InvocationStack.getInstance();
396         stack.push( new Invocation(
397                 caller, "removeContextPartition",
398                 new Object[] { suffix } ) );
399         try
400         {
401             this.configuration.getInterceptorChain().removeContextPartition( suffix );
402         }
403         finally
404         {
405             stack.pop();
406         }
407     }
408 
409     private void ensureStarted() throws ServiceUnavailableException {
410         if( !service.isStarted() )
411         {
412             throw new ServiceUnavailableException( "ContextFactoryService is not started." );
413         }
414     }
415 }