001    /*
002     *  Licensed to the Apache Software Foundation (ASF) under one
003     *  or more contributor license agreements.  See the NOTICE file
004     *  distributed with this work for additional information
005     *  regarding copyright ownership.  The ASF licenses this file
006     *  to you under the Apache License, Version 2.0 (the
007     *  "License"); you may not use this file except in compliance
008     *  with the License.  You may obtain a copy of the License at
009     *  
010     *    http://www.apache.org/licenses/LICENSE-2.0
011     *  
012     *  Unless required by applicable law or agreed to in writing,
013     *  software distributed under the License is distributed on an
014     *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
015     *  KIND, either express or implied.  See the License for the
016     *  specific language governing permissions and limitations
017     *  under the License. 
018     *  
019     */
020    package org.apache.directory.server.core.interceptor.context;
021    
022    
023    import java.util.Collection;
024    import java.util.List;
025    
026    import org.apache.directory.server.core.CoreSession;
027    import org.apache.directory.server.core.LdapPrincipal;
028    import org.apache.directory.server.core.entry.ClonedServerEntry;
029    import org.apache.directory.server.core.interceptor.Interceptor;
030    import org.apache.directory.shared.ldap.entry.Modification;
031    import org.apache.directory.shared.ldap.entry.ServerEntry;
032    import org.apache.directory.shared.ldap.message.control.Control;
033    import org.apache.directory.shared.ldap.name.DN;
034    
035    
036    /**
037     * This interface represent the context passed as an argument to each interceptor.
038     * It will contain data used by all the operations.
039     *
040     * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
041     * @version $Rev$, $Date$
042     */
043    public interface OperationContext
044    {
045        /**
046         * Checks to see if this operation is the first operation in a chain of 
047         * operations performed on the DirectoryService.  The first operation in  
048         * a sequence of operations, is not a byproduct of another operation 
049         * unlike operations following in the sequence.  The other operations 
050         * following the first, occur as a side effect to complete this first 
051         * operation.
052         * 
053         * @return true if the operation is the first, false otherwise
054         */
055        boolean isFirstOperation();
056        
057        
058        /**
059         * Gets the first, direct operation issued against the DirectoryService.
060         *
061         * @return the first, direct operation issued 
062         */
063        OperationContext getFirstOperation();
064        
065        
066        /**
067         * Gets the previous, operation issued on the DirectoryService.
068         *
069         * @return the previous, operation issued
070         */
071        OperationContext getPreviousOperation();
072        
073        
074        /**
075         * Gets the next, indirect operation issued on the DirectoryService.
076         *
077         * @return the next, indirect operation issued 
078         */
079        OperationContext getNextOperation();
080        
081        
082        /**
083         * Gets the last, operation issued on the DirectoryService.
084         *
085         * @return the last, operation issued
086         */
087        OperationContext getLastOperation();
088    
089    
090        /**
091         * Gets the effective principal for this operation which may not be the 
092         * same as the authenticated principal when the session for this context
093         * has an explicit authorization id, or this operation was applied with 
094         * the proxy authorization control.
095         * 
096         * @see CoreSession#getAuthenticatedPrincipal()
097         * @see CoreSession#getEffectivePrincipal()
098         * @return the effective principal for this operation
099         */
100        LdapPrincipal getEffectivePrincipal();
101    
102    
103        /**
104         * @return The associated DN
105         */
106        DN getDn();
107        
108        
109        /**
110         * Set the context DN
111         *
112         * @param dn The DN to set
113         */
114        void setDn( DN dn );
115    
116        
117        /**
118         * Gets the server entry associated with the target DN of this 
119         * OperationContext.  The entry associated with the DN may be altered 
120         * during the course of processing an LDAP operation through the 
121         * InterceptorChain.  This place holder is put here to prevent the need
122         * for repetitive lookups of the target entry.  Furthermore the returned
123         * entry may be altered by any Interceptor in the chain and this is why a
124         * ClonedServerEntry is returned instead of a ServerEntry.  A 
125         * ClonedServerEntry has an immutable reference to the original state of
126         * the target entry.  The original state can be accessed via a call to
127         * {@link ClonedServerEntry#getOriginalEntry()}.  The return value may be 
128         * null in which case any lookup performed to access it may set it to 
129         * prevent the need for subsequent lookups.
130         * 
131         * Also note that during the course of handling some operations such as 
132         * those that rename, move or rename and move the entry, may alter the DN 
133         * of this entry.  Interceptor implementors should not presume the DN or 
134         * the values contained in this entry are currently what is present in the 
135         * DIT.  The original entry contained in the ClonedServerEntry shoudl be 
136         * used as the definitive source of information about the state of the 
137         * entry in the DIT before returning from the Partition subsystem.
138         * 
139         * @return target entry associated with the DN of this OperationContext
140         */
141        ClonedServerEntry getEntry();
142        
143        
144        /**
145         * Sets the server entry associated with the target DN of this 
146         * OperationContext.
147         *
148         * @param entry the entry whose DN is associated with this OperationContext.
149         */
150        void setEntry( ClonedServerEntry entry );
151        
152        
153        /**
154         * Adds a response control to this operation.
155         *
156         * @param responseControl the response control to add to this operation
157         */
158        void addResponseControl( Control responseControl );
159        
160        
161        /** 
162         * Checks to see if a response control is present on this operation.
163         *
164         * @param numericOid the numeric OID of the control also known as it's type OID
165         * @return true if the control is associated with this operation, false otherwise
166         */
167        boolean hasResponseControl( String numericOid );
168        
169        
170        /**
171         * Gets a response control if present for this request.
172         * 
173         * @param numericOid the numeric OID of the control also known as it's type OID
174         * @return the control if present
175         */
176        Control getResponseControl( String numericOid );
177        
178        
179        /**
180         * Gets all the response controls producted during this operation.
181         *
182         * @return an array over all the response controls 
183         */
184        Control[] getResponseControls();
185        
186        
187        /**
188         * Checks if any response controls have been generated for this operation.
189         *
190         * @return true if any response controls have been generated, false otherwise
191         */
192        boolean hasResponseControls();
193        
194        
195        /**
196         * Checks the number of response controls have been generated for this operation.
197         *
198         * @return the number of response controls that have been generated
199         */
200        int getResponseControlCount();
201        
202        
203        /**
204         * Adds a request control to this operation.
205         *
206         * @param requestControl the request control to add to this operation
207         */
208        void addRequestControl( Control requestControl );
209        
210        
211        /** 
212         * Checks to see if a request control is present on this request.
213         *
214         * @param numericOid the numeric OID of the control also known as it's type OID
215         * @return true if the control is associated with this operation, false otherwise
216         */
217        boolean hasRequestControl( String numericOid );
218        
219        
220        /**
221         * Checks if any request controls exists for this operation.
222         *
223         * @return true if any request controls exist, false otherwise
224         */
225        boolean hasRequestControls();
226        
227        
228        /**
229         * Gets a request control if present for this request.
230         * 
231         * @param numericOid the numeric OID of the control also known as it's type OID
232         * @return the control if present
233         */
234        Control getRequestControl( String numericOid );
235    
236    
237        /**
238         * Adds many request controls to this operation.
239         *
240         * @param requestControls the request controls to add to this operation
241         */
242        void addRequestControls( Control[] requestControls );
243        
244        
245        /**
246         * @return the operation's name
247         */
248        String getName();
249        
250        
251        /**
252         * Checks to see if an Interceptor is bypassed for this operation.
253         *
254         * @param interceptorName the interceptorName of the Interceptor to check for bypass
255         * @return true if the Interceptor should be bypassed, false otherwise
256         */
257        boolean isBypassed( String interceptorName );
258    
259    
260        /**
261         * Checks to see if any Interceptors are bypassed by this Invocation.
262         *
263         * @return true if at least one bypass exists
264         */
265        boolean hasBypass();
266        
267        
268        /**
269         * Gets the set of bypassed Interceptors.
270         *
271         * @return the set of bypassed Interceptors
272         */
273        Collection<String> getByPassed();
274        
275        
276        /**
277         * Sets the set of bypassed Interceptors.
278         * 
279         * @param byPassed the set of bypassed Interceptors
280         */
281        void setByPassed( Collection<String> byPassed );
282        
283        
284        /**
285         * Gets the session associated with this operation.
286         *
287         * @return the session associated with this operation
288         */
289        CoreSession getSession();
290        
291        
292        // -----------------------------------------------------------------------
293        // Utility Factory Methods to Create New OperationContexts
294        // -----------------------------------------------------------------------
295        
296        
297        LookupOperationContext newLookupContext( DN dn );
298    
299        
300        ClonedServerEntry lookup( DN dn, Collection<String> byPass ) throws Exception;
301        
302        
303        ClonedServerEntry lookup( LookupOperationContext lookupContext ) throws Exception;
304        
305        
306        void modify( DN dn, List<Modification> mods, Collection<String> byPass ) throws Exception;
307        
308        
309        void add( ServerEntry entry, Collection<String> byPass ) throws Exception;
310        
311        
312        void delete( DN dn, Collection<String> byPass ) throws Exception;
313    
314    
315        /**
316         * Checks to see if an entry exists.
317         *
318         * @param dn the distinguished name of the entry to check
319         * @param byPass collection of {@link Interceptor}'s to bypass for this check
320         * @return true if the entry exists, false if it does not
321         * @throws Exception on failure to perform this operation
322         */
323        boolean hasEntry( DN dn, Collection<String> byPass ) throws Exception;
324        
325        
326        /**
327         * Set the throwReferral flag to true
328         */
329        void throwReferral();
330        
331        
332        /**
333         * @return <code>true</code> if the referrals are thrown
334         */
335        boolean isReferralThrown();
336    
337    
338        /**
339         * Set the throwReferral flag to false
340         */
341        void ignoreReferral();
342    
343    
344        /**
345         * @return <code>true</code> if the referrals are ignored
346         */
347        boolean isReferralIgnored();
348    }