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}