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;
021    
022    
023    import org.apache.directory.server.core.DirectoryService;
024    import org.apache.directory.server.core.entry.ClonedServerEntry;
025    import org.apache.directory.server.core.filtering.EntryFilteringCursor;
026    import org.apache.directory.server.core.interceptor.context.AddContextPartitionOperationContext;
027    import org.apache.directory.server.core.interceptor.context.AddOperationContext;
028    import org.apache.directory.server.core.interceptor.context.BindOperationContext;
029    import org.apache.directory.server.core.interceptor.context.CompareOperationContext;
030    import org.apache.directory.server.core.interceptor.context.DeleteOperationContext;
031    import org.apache.directory.server.core.interceptor.context.EntryOperationContext;
032    import org.apache.directory.server.core.interceptor.context.GetMatchedNameOperationContext;
033    import org.apache.directory.server.core.interceptor.context.GetRootDSEOperationContext;
034    import org.apache.directory.server.core.interceptor.context.GetSuffixOperationContext;
035    import org.apache.directory.server.core.interceptor.context.ListOperationContext;
036    import org.apache.directory.server.core.interceptor.context.ListSuffixOperationContext;
037    import org.apache.directory.server.core.interceptor.context.LookupOperationContext;
038    import org.apache.directory.server.core.interceptor.context.ModifyOperationContext;
039    import org.apache.directory.server.core.interceptor.context.MoveAndRenameOperationContext;
040    import org.apache.directory.server.core.interceptor.context.MoveOperationContext;
041    import org.apache.directory.server.core.interceptor.context.RemoveContextPartitionOperationContext;
042    import org.apache.directory.server.core.interceptor.context.RenameOperationContext;
043    import org.apache.directory.server.core.interceptor.context.SearchOperationContext;
044    import org.apache.directory.server.core.interceptor.context.UnbindOperationContext;
045    import org.apache.directory.server.core.partition.Partition;
046    import org.apache.directory.shared.ldap.name.DN;
047    
048    import java.util.Set;
049    
050    
051    /**
052     * Filters invocations on {@link DefaultPartitionNexus}.  {@link Interceptor}
053     * filters most method calls performed on {@link DefaultPartitionNexus} just
054     * like Servlet filters do.
055     * <p/>
056     * <h2>Interceptor Chaining</h2>
057     * 
058     * Interceptors should usually pass the control
059     * of current invocation to the next interceptor by calling an appropriate method
060     * on {@link NextInterceptor}.  The flow control is returned when the next 
061     * interceptor's filter method returns. You can therefore implement pre-, post-,
062     * around- invocation handler by how you place the statement.  Otherwise, you
063     * can transform the invocation into other(s).
064     * <p/>
065     * <h3>Pre-invocation Filtering</h3>
066     * <pre>
067     * public void delete( NextInterceptor nextInterceptor, Name name )
068     * {
069     *     System.out.println( "Starting invocation." );
070     *     nextInterceptor.delete( name );
071     * }
072     * </pre>
073     * <p/>
074     * <h3>Post-invocation Filtering</h3>
075     * <pre>
076     * public void delete( NextInterceptor nextInterceptor, Name name )
077     * {
078     *     nextInterceptor.delete( name );
079     *     System.out.println( "Invocation ended." );
080     * }
081     * </pre>
082     * <p/>
083     * <h3>Around-invocation Filtering</h3>
084     * <pre>
085     * public void delete( NextInterceptor nextInterceptor, Name name )
086     * {
087     *     long startTime = System.currentTimeMillis();
088     *     try
089     *     {
090     *         nextInterceptor.delete( name );
091     *     }
092     *     finally
093     *     {
094     *         long endTime = System.currentTimeMillis();
095     *         System.out.println( ( endTime - startTime ) + "ms elapsed." );
096     *     }
097     * }
098     * </pre>
099     * <p/>
100     * <h3>Transforming invocations</h3>
101     * <pre>
102     * public void delete( NextInterceptor nextInterceptor, Name name )
103     * {
104     *     // transform deletion into modification.
105     *     Attribute mark = new AttributeImpl( "entryDeleted", "true" );
106     *     nextInterceptor.modify( name, DirIteratorContext.REPLACE_ATTRIBUTE, mark );
107     * }
108     * </pre>
109     *
110     * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
111     * @version $Rev: 918766 $, $Date: 2010-03-04 00:25:11 +0100 (Thu, 04 Mar 2010) $
112     * @see NextInterceptor
113     */
114    public interface Interceptor
115    {
116        /**
117         * Name that must be unique in an interceptor chain
118         * @return name of this interceptor, must be unique in an interceptor chain.
119         */
120        String getName();
121    
122        /**
123         * Intializes this interceptor.  This is invoked by {@link InterceptorChain}
124         * when this intercepter is loaded into interceptor chain.
125         * @throws Exception 
126         */
127        void init( DirectoryService directoryService ) throws Exception;
128    
129    
130        /**
131         * Deinitializes this interceptor.  This is invoked by {@link InterceptorChain}
132         * when this intercepter is unloaded from interceptor chain.
133         */
134        void destroy();
135    
136    
137        /**
138         * Filters {@link DefaultPartitionNexus#getRootDSE( GetRootDSEOperationContext )} call.
139         */
140        ClonedServerEntry getRootDSE( NextInterceptor next, GetRootDSEOperationContext  opContext ) throws Exception;
141    
142    
143        /**
144         * Filters {@link DefaultPartitionNexus#getMatchedName( GetMatchedNameOperationContext )} call.
145         */
146        DN getMatchedName( NextInterceptor next, GetMatchedNameOperationContext opContext ) throws Exception;
147    
148    
149        /**
150         * Filters {@link DefaultPartitionNexus#getSuffix( GetSuffixOperationContext )} call.
151         */
152        DN getSuffix ( NextInterceptor next, GetSuffixOperationContext opContext ) throws Exception;
153    
154    
155        /**
156         * Filters {@link DefaultPartitionNexus#listSuffixes( ListSuffixOperationContext )} call.
157         */
158        Set<String> listSuffixes( NextInterceptor next, ListSuffixOperationContext opContext ) throws Exception;
159    
160    
161        /**
162         * Filters {@link DefaultPartitionNexus#addContextPartition( AddContextPartitionOperationContext )} call.
163         */
164        void addContextPartition( NextInterceptor next, AddContextPartitionOperationContext opContext ) throws Exception;
165    
166    
167        /**
168         * Filters {@link DefaultPartitionNexus#removeContextPartition( RemoveContextPartitionOperationContext )} call.
169         */
170        void removeContextPartition( NextInterceptor next, RemoveContextPartitionOperationContext opContext ) throws Exception;
171    
172    
173        /**
174         * Filters {@link DefaultPartitionNexus#compare( CompareOperationContext )} call.
175         */
176        boolean compare( NextInterceptor next, CompareOperationContext opContext) throws Exception;
177    
178    
179        /**
180         * Filters {@link Partition#delete( DeleteOperationContext )} call.
181         */
182        void delete( NextInterceptor next, DeleteOperationContext opContext ) throws Exception;
183    
184    
185        /**
186         * Filters {@link Partition#add( AddOperationContext )} call.
187         */
188        void add( NextInterceptor next, AddOperationContext opContext ) throws Exception;
189    
190    
191        /**
192         * Filters {@link Partition#modify( ModifyOperationContext )} call.
193         */
194        void modify( NextInterceptor next, ModifyOperationContext opContext ) throws Exception;
195    
196    
197        /**
198         * Filters {@link Partition#list( ListOperationContext )} call.
199         */
200        EntryFilteringCursor list( NextInterceptor next, ListOperationContext opContext ) throws Exception;
201    
202    
203        /**
204         * Filters {@link Partition#search( SearchOperationContext )} call.
205         */
206        EntryFilteringCursor search( NextInterceptor next, SearchOperationContext opContext ) throws Exception;
207    
208    
209        /**
210         * Filters {@link Partition#lookup( LookupOperationContext )} call.
211         */
212        ClonedServerEntry lookup( NextInterceptor next, LookupOperationContext opContext ) throws Exception;
213    
214    
215        /**
216         * Filters {@link Partition#hasEntry( EntryOperationContext )} call.
217         */
218        boolean hasEntry( NextInterceptor next, EntryOperationContext opContext ) throws Exception;
219    
220    
221        /**
222         * Filters {@link Partition#rename( RenameOperationContext )} call.
223         */
224        void rename( NextInterceptor next, RenameOperationContext opContext ) throws Exception;
225    
226    
227        /**
228         * Filters {@link Partition#move( MoveOperationContext )} call.
229         */
230        void move( NextInterceptor next, MoveOperationContext opContext ) throws Exception;
231    
232    
233        /**
234         * Filters {@link Partition#moveAndRename( MoveAndRenameOperationContext) } call.
235         */
236        void moveAndRename( NextInterceptor next, MoveAndRenameOperationContext opContext )
237            throws Exception;
238    
239        /**
240         * Filters {@link Partition#bind( BindOperationContext )} call.
241         */
242        void bind( NextInterceptor next, BindOperationContext opContext )
243            throws Exception;
244    
245        /**
246         * Filters {@link Partition#unbind( UnbindOperationContext )} call.
247         */
248        void unbind( NextInterceptor next, UnbindOperationContext opContext ) throws Exception;
249    }