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 */
020package org.apache.directory.server.core.api.interceptor;
021
022
023import org.apache.directory.api.ldap.model.entry.Entry;
024import org.apache.directory.api.ldap.model.exception.LdapException;
025import org.apache.directory.server.core.api.DirectoryService;
026import org.apache.directory.server.core.api.filtering.EntryFilteringCursor;
027import org.apache.directory.server.core.api.interceptor.context.AddOperationContext;
028import org.apache.directory.server.core.api.interceptor.context.BindOperationContext;
029import org.apache.directory.server.core.api.interceptor.context.CompareOperationContext;
030import org.apache.directory.server.core.api.interceptor.context.DeleteOperationContext;
031import org.apache.directory.server.core.api.interceptor.context.HasEntryOperationContext;
032import org.apache.directory.server.core.api.interceptor.context.GetRootDseOperationContext;
033import org.apache.directory.server.core.api.interceptor.context.LookupOperationContext;
034import org.apache.directory.server.core.api.interceptor.context.ModifyOperationContext;
035import org.apache.directory.server.core.api.interceptor.context.MoveAndRenameOperationContext;
036import org.apache.directory.server.core.api.interceptor.context.MoveOperationContext;
037import org.apache.directory.server.core.api.interceptor.context.RenameOperationContext;
038import org.apache.directory.server.core.api.interceptor.context.SearchOperationContext;
039import org.apache.directory.server.core.api.interceptor.context.UnbindOperationContext;
040import org.apache.directory.server.core.api.partition.Partition;
041
042
043/**
044 * Filters invocations on DefaultPartitionNexus. Interceptor
045 * filters most method calls performed on DefaultPartitionNexus just
046 * like Servlet filters do.
047 *
048 * <h2>Interceptor Chaining</h2>
049 * 
050 * Interceptors should usually pass the control
051 * of current invocation to the next interceptor by calling an appropriate method
052 * on NextInterceptor.  The flow control is returned when the next
053 * interceptor's filter method returns. You can therefore implement pre-, post-,
054 * around- invocation handler by how you place the statement.  Otherwise, you
055 * can transform the invocation into other(s).
056 * 
057 * <h3>Pre-invocation Filtering</h3>
058 * <pre>
059 * public void delete( NextInterceptor nextInterceptor, Name name )
060 * {
061 *     System.out.println( "Starting invocation." );
062 *     nextInterceptor.delete( name );
063 * }
064 * </pre>
065 * 
066 * <h3>Post-invocation Filtering</h3>
067 * <pre>
068 * public void delete( NextInterceptor nextInterceptor, Name name )
069 * {
070 *     nextInterceptor.delete( name );
071 *     System.out.println( "Invocation ended." );
072 * }
073 * </pre>
074 *
075 * <h3>Around-invocation Filtering</h3>
076 * <pre>
077 * public void delete( NextInterceptor nextInterceptor, Name name )
078 * {
079 *     long startTime = System.currentTimeMillis();
080 *     try
081 *     {
082 *         nextInterceptor.delete( name );
083 *     }
084 *     finally
085 *     {
086 *         long endTime = System.currentTimeMillis();
087 *         System.out.println( ( endTime - startTime ) + "ms elapsed." );
088 *     }
089 * }
090 * </pre>
091 * 
092 * <h3>Transforming invocations</h3>
093 * <pre>
094 * public void delete( NextInterceptor nextInterceptor, Name name )
095 * {
096 *     // transform deletion into modification.
097 *     Attribute mark = new AttributeImpl( "entryDeleted", "true" );
098 *     nextInterceptor.modify( name, DirIteratorContext.REPLACE_ATTRIBUTE, mark );
099 * }
100 * </pre>
101 *
102 * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
103 */
104public interface Interceptor
105{
106    /**
107     * Name that must be unique in an interceptor chain
108     * @return name of this interceptor, must be unique in an interceptor chain.
109     */
110    String getName();
111
112
113    /**
114     * Intializes this interceptor.
115     *  
116     * @param directoryService The DirectoryService instance
117     * @throws LdapException If the initialization failed
118     */
119    void init( DirectoryService directoryService ) throws LdapException;
120
121
122    /**
123     * Deinitializes this interceptor. 
124     */
125    void destroy();
126
127
128    /**
129     * Filters {@link Partition#add( AddOperationContext )} call.
130     * 
131     * @param addContext The {@link AddOperationContext} instance
132     * @throws LdapException If we had some error while processing the Add operation
133     */
134    void add( AddOperationContext addContext ) throws LdapException;
135
136
137    /**
138     * Filters {@link BindOperationContext} call.
139     * 
140     * @param bindContext The {@link BindOperationContext} instance
141     * @throws LdapException If we had some error while processing the Bind operation
142     */
143    void bind( BindOperationContext bindContext ) throws LdapException;
144
145
146    /**
147     * Filters Compare call.
148     * 
149     * @param compareContext The {@link CompareOperationContext} instance
150     * @throws LdapException If we had some error while processing the Compare operation
151     * @return <tt>true</tt> if teh comparaison is successful
152     */
153    boolean compare( CompareOperationContext compareContext ) throws LdapException;
154
155
156    /**
157     * Filters {@link Partition#delete( DeleteOperationContext )} call.
158     * 
159     * @param deleteContext The {@link DeleteOperationContext} instance
160     * @throws LdapException If we had some error while processing the Delete operation
161     */
162    void delete( DeleteOperationContext deleteContext ) throws LdapException;
163
164
165    /**
166     * Filters getRootDse call.
167     * 
168     * @param getRootDseContext The getRootDSE operation context
169     * @return The RootDSE entry, if found
170     * @throws LdapException If we can't get back the RootDSE entry
171     */
172    Entry getRootDse( GetRootDseOperationContext getRootDseContext ) throws LdapException;
173
174
175    /**
176     * Filters {@link Partition#hasEntry( HasEntryOperationContext )} call.
177     * 
178     * @param hasEntryContext The {@link HasEntryOperationContext} instance
179     * @throws LdapException If we had some error while processing the HasEntry operation
180     * @return <tt>true</tt> f the entry is present in the DIT
181     */
182    boolean hasEntry( HasEntryOperationContext hasEntryContext ) throws LdapException;
183
184
185    /**
186     * Filters {@link Partition#lookup( LookupOperationContext )} call.
187     * 
188     * @param lookupContext The {@link LookupOperationContext} instance
189     * @throws LdapException If we had some error while processing the Lookup operation
190     * @return The found entry
191     */
192    Entry lookup( LookupOperationContext lookupContext ) throws LdapException;
193
194
195    /**
196     * Filters {@link Partition#modify( ModifyOperationContext )} call.
197     * 
198     * @param modifyContext The {@link ModifyOperationContext} instance
199     * @throws LdapException If we had some error while processing the Modify operation
200     */
201    void modify( ModifyOperationContext modifyContext ) throws LdapException;
202
203
204    /**
205     * Filters {@link Partition#move( MoveOperationContext )} call.
206     * 
207     * @param moveContext The {@link MoveOperationContext} instance
208     * @throws LdapException If we had some error while processing the Move operation
209     */
210    void move( MoveOperationContext moveContext ) throws LdapException;
211
212
213    /**
214     * Filters MoveAndRename call.
215     * 
216     * @param moveAndRenameContext The {@link MoveAndRenameOperationContext} instance
217     * @throws LdapException If we had some error while processing the MoveAndRename operation
218     */
219    void moveAndRename( MoveAndRenameOperationContext moveAndRenameContext ) throws LdapException;
220
221
222    /**
223     * Filters {@link Partition#rename( RenameOperationContext )} call.
224     * 
225     * @param renameContext The {@link RenameOperationContext} instance
226     * @throws LdapException If we had some error while processing the Rename operation
227     */
228    void rename( RenameOperationContext renameContext ) throws LdapException;
229
230
231    /**
232     * Filters {@link Partition#search( SearchOperationContext )} call.
233     * 
234     * @param searchContext The {@link SearchOperationContext} instance
235     * @throws LdapException If we had some error while processing the Search operation
236     * @return A cursror over the found entries
237     */
238    EntryFilteringCursor search( SearchOperationContext searchContext ) throws LdapException;
239
240
241    /**
242     * Filters {@link Partition#unbind( UnbindOperationContext )} call.
243     * 
244     * @param unbindContext The {@link UnbindOperationContext} instance
245     * @throws LdapException If we had some error while processing the Unbind operation
246     */
247    void unbind( UnbindOperationContext unbindContext ) throws LdapException;
248}