View Javadoc

1   /*
2    *  Licensed to the Apache Software Foundation (ASF) under one
3    *  or more contributor license agreements.  See the NOTICE file
4    *  distributed with this work for additional information
5    *  regarding copyright ownership.  The ASF licenses this file
6    *  to you under the Apache License, Version 2.0 (the
7    *  "License"); you may not use this file except in compliance
8    *  with the License.  You may obtain a copy of the License at
9    *  
10   *    http://www.apache.org/licenses/LICENSE-2.0
11   *  
12   *  Unless required by applicable law or agreed to in writing,
13   *  software distributed under the License is distributed on an
14   *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15   *  KIND, either express or implied.  See the License for the
16   *  specific language governing permissions and limitations
17   *  under the License. 
18   *  
19   */
20  package org.apache.directory.server.core.interceptor.context;
21  
22  
23  import java.util.Collection;
24  import java.util.Collections;
25  import java.util.HashMap;
26  import java.util.List;
27  import java.util.Map;
28  
29  import javax.naming.ldap.Control;
30  
31  import org.apache.directory.server.core.CoreSession;
32  import org.apache.directory.server.core.authn.LdapPrincipal;
33  import org.apache.directory.server.core.entry.ClonedServerEntry;
34  import org.apache.directory.server.core.entry.ServerEntry;
35  import org.apache.directory.shared.ldap.entry.Modification;
36  import org.apache.directory.shared.ldap.name.LdapDN;
37  
38  
39  /**
40   * This abstract class stores common context elements, like the DN, which is used
41   * in all the contexts.
42   *
43   * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
44   * @version $Rev$, $Date$
45   */
46  public abstract class AbstractOperationContext implements OperationContext
47  {
48      protected static final Control[] EMPTY_CONTROLS = new Control[0];
49  
50      /** The DN associated with the context */
51      protected LdapDN dn;
52      
53      /** The entry associated with the target entry of this OperationContext */
54      protected ClonedServerEntry entry;
55      
56      /** The associated request's controls */
57      protected Map<String, Control> requestControls = new HashMap<String, Control>(4);
58  
59      /** The associated response's controls */
60      protected Map<String, Control> responseControls = new HashMap<String, Control>(4);
61  
62      /** the Interceptors bypassed by this operation */
63      protected Collection<String> byPassed;
64      
65      protected LdapPrincipal authorizedPrincipal;
66      
67      protected CoreSession session;
68      
69      protected OperationContext next;
70      
71      protected OperationContext previous;
72  
73  
74      /**
75       * Creates a new instance of AbstractOperationContext.
76       */
77      public AbstractOperationContext( CoreSession session )
78      {
79          this.session = session;
80      }
81      
82      
83      /**
84       * Creates a new instance of AbstractOperationContext.
85       *
86       * @param dn The associated DN
87       */
88      public AbstractOperationContext( CoreSession session, LdapDN dn )
89      {
90          this.dn = dn;
91          this.session = session;
92      }
93  
94  
95      public CoreSession getSession()
96      {
97          return session;
98      }
99      
100     
101     protected void setSession( CoreSession session )
102     {
103         this.session = session;
104     }
105     
106     
107     protected void setAuthorizedPrincipal( LdapPrincipal authorizedPrincipal )
108     {
109         this.authorizedPrincipal = authorizedPrincipal;
110     }
111 
112 
113     /**
114      * @return The associated DN
115      */
116     public LdapDN getDn()
117     {
118         return dn;
119     }
120 
121     
122     /**
123      * Set the context DN
124      *
125      * @param dn The DN to set
126      */
127     public void setDn( LdapDN dn )
128     {
129         this.dn = dn;
130     }
131 
132     
133     public void addRequestControl( Control requestControl )
134     {
135         requestControls.put( requestControl.getID(), requestControl );
136     }
137 
138     
139     public Control getRequestControl( String numericOid )
140     {
141         return requestControls.get( numericOid );
142     }
143 
144     
145     public boolean hasRequestControl( String numericOid )
146     {
147         return requestControls.containsKey( numericOid );
148     }
149 
150     
151     public boolean hasRequestControls()
152     {
153         return ! requestControls.isEmpty();
154     }
155 
156 
157     public void addResponseControl( Control responseControl )
158     {
159         responseControls.put( responseControl.getID(), responseControl );
160     }
161 
162 
163     public Control getResponseControl( String numericOid )
164     {
165         return responseControls.get( numericOid );
166     }
167 
168 
169     public boolean hasResponseControl( String numericOid )
170     {
171         return responseControls.containsKey( numericOid );
172     }
173 
174 
175     public Control[] getResponseControls()
176     {
177         if ( responseControls.isEmpty() )
178         {
179             return EMPTY_CONTROLS;
180         }
181         
182         return responseControls.values().toArray( EMPTY_CONTROLS );
183     }
184 
185 
186     public boolean hasResponseControls()
187     {
188         return ! responseControls.isEmpty();
189     }
190 
191 
192     public int getResponseControlCount()
193     {
194         return responseControls.size();
195     }
196 
197 
198     public void addRequestControls( Control[] requestControls )
199     {
200         for ( Control c : requestControls )
201         {
202             this.requestControls.put( c.getID(), c );
203         }
204     }
205 
206     
207     public void setRequestControls( Map<String, Control> requestControls )
208     {
209         this.requestControls = requestControls;
210     }
211 
212     
213     /**
214      * @return the operation name
215      */
216     public abstract String getName();
217 
218 
219     /**
220      * Gets the set of bypassed Interceptors.
221      *
222      * @return the set of bypassed Interceptors
223      */
224     public Collection<String> getByPassed()
225     {
226         if ( byPassed == null )
227         {
228             return Collections.emptyList();
229         }
230         
231         return Collections.unmodifiableCollection( byPassed );
232     }
233     
234     
235     /**
236      * Sets the set of bypassed Interceptors.
237      * 
238      * @param byPassed the set of bypassed Interceptors
239      */
240     public void setByPassed( Collection<String> byPassed )
241     {
242         this.byPassed = byPassed;
243     }
244 
245     
246     /**
247      * Checks to see if an Interceptor is bypassed for this operation.
248      *
249      * @param interceptorName the interceptorName of the Interceptor to check for bypass
250      * @return true if the Interceptor should be bypassed, false otherwise
251      */
252     public boolean isBypassed( String interceptorName )
253     {
254         return byPassed != null && byPassed.contains( interceptorName );
255     }
256 
257 
258     /**
259      * Checks to see if any Interceptors are bypassed by this operation.
260      *
261      * @return true if at least one bypass exists
262      */
263     public boolean hasBypass()
264     {
265         return byPassed != null && !byPassed.isEmpty();
266     }
267 
268     
269     private void setup( AbstractOperationContext opContext )
270     {
271         opContext.setPreviousOperation( this );
272         next = opContext;
273         opContext.setByPassed( byPassed );
274         opContext.setAuthorizedPrincipal( authorizedPrincipal );
275     }
276     
277     
278     public boolean hasEntry( LdapDN dn, Collection<String> byPassed ) throws Exception
279     {
280         EntryOperationContext opContext = new EntryOperationContext( session, dn );
281         setup( opContext );
282         opContext.setByPassed( byPassed );
283         return session.getDirectoryService().getOperationManager().hasEntry( opContext );
284     }
285     
286     
287     public void add( ServerEntry entry, Collection<String> byPassed ) throws Exception
288     {
289         AddOperationContext opContext = new AddOperationContext( session, entry );
290         setup( opContext );
291         opContext.setByPassed( byPassed );
292         session.getDirectoryService().getOperationManager().add( opContext );
293     }
294     
295     
296     public void delete( LdapDN dn, Collection<String> byPassed ) throws Exception
297     {
298         DeleteOperationContext opContext = new DeleteOperationContext( session, dn );
299         setup( opContext );
300         opContext.setByPassed( byPassed );
301         session.getDirectoryService().getOperationManager().delete( opContext );
302     }
303     
304     
305     public void modify( LdapDN dn, List<Modification> mods, Collection<String> byPassed ) throws Exception
306     {
307         ModifyOperationContext opContext = new ModifyOperationContext( session, dn, mods );
308         setup( opContext );
309         opContext.setByPassed( byPassed );
310         session.getDirectoryService().getOperationManager().modify( opContext );
311     }
312     
313     
314     // TODO - need synchronization here and where we update links
315     public LookupOperationContext newLookupContext( LdapDN dn )
316     {
317         LookupOperationContext opContext = new LookupOperationContext( session, dn );
318         setup( opContext );
319         return opContext;
320     }
321 
322 
323     public ClonedServerEntry lookup( LookupOperationContext opContext ) throws Exception
324     {
325         if ( opContext != next )
326         {
327             throw new IllegalStateException( "Cannot execute indirect lookup if it is not the next operation." );
328         }
329         return session.getDirectoryService().getOperationManager().lookup( opContext );
330     }
331 
332 
333     public ClonedServerEntry lookup( LdapDN dn, Collection<String> byPassed ) throws Exception
334     {
335         LookupOperationContext opContext = newLookupContext( dn );
336         opContext.setByPassed( byPassed );
337         return session.getDirectoryService().getOperationManager().lookup( opContext );
338     }
339     
340 
341     public LdapPrincipal getEffectivePrincipal()
342     {
343         if ( authorizedPrincipal != null )
344         {
345             return authorizedPrincipal;
346         }
347         
348         return session.getEffectivePrincipal();
349     }
350     
351     
352     // -----------------------------------------------------------------------
353     // OperationContext Linked List Methods
354     // -----------------------------------------------------------------------
355     
356     
357     public boolean isFirstOperation()
358     {
359         return previous == null;
360     }
361     
362     
363     public OperationContext getFirstOperation()
364     {
365         if ( previous == null )
366         {
367             return this;
368         }
369         
370         return previous.getFirstOperation();
371     }
372     
373     
374     public OperationContext getLastOperation()
375     {
376         if ( next == null )
377         {
378             return this;
379         }
380         
381         return next.getLastOperation();
382     }
383     
384     
385     public OperationContext getNextOperation()
386     {
387         return next;
388     }
389     
390     
391     protected void setNextOperation( OperationContext next )
392     {
393         this.next = next;
394     }
395     
396     
397     public OperationContext getPreviousOperation()
398     {
399         return previous;
400     }
401     
402     
403     protected void setPreviousOperation( OperationContext previous )
404     {
405         this.previous = previous;
406     }
407 
408 
409     /**
410      * @param entry the entry to set
411      */
412     public void setEntry( ClonedServerEntry entry )
413     {
414         this.entry = entry;
415     }
416 
417 
418     /**
419      * @return the entry
420      */
421     public ClonedServerEntry getEntry()
422     {
423         return entry;
424     }
425 }