001/* 002 * The contents of this file are subject to the terms of the Common Development and 003 * Distribution License (the License). You may not use this file except in compliance with the 004 * License. 005 * 006 * You can obtain a copy of the License at legal/CDDLv1.0.txt. See the License for the 007 * specific language governing permission and limitations under the License. 008 * 009 * When distributing Covered Software, include this CDDL Header Notice in each file and include 010 * the License file at legal/CDDLv1.0.txt. If applicable, add the following below the CDDL 011 * Header, with the fields enclosed by brackets [] replaced by your own identifying 012 * information: "Portions Copyright [year] [name of copyright owner]". 013 * 014 * Copyright 2006-2010 Sun Microsystems, Inc. 015 * Portions Copyright 2011-2016 ForgeRock AS. 016 */ 017package org.opends.server.core; 018 019import static org.opends.messages.ConfigMessages.*; 020import static org.opends.messages.PluginMessages.*; 021import static org.opends.server.util.StaticUtils.*; 022 023import java.util.ArrayList; 024import java.util.HashMap; 025import java.util.HashSet; 026import java.util.LinkedHashSet; 027import java.util.List; 028import java.util.Set; 029import java.util.StringTokenizer; 030import java.util.concurrent.ConcurrentHashMap; 031import java.util.concurrent.locks.ReentrantLock; 032 033import org.forgerock.i18n.LocalizableMessage; 034import org.forgerock.i18n.LocalizableMessageDescriptor.Arg4; 035import org.forgerock.i18n.LocalizableMessageDescriptor.Arg5; 036import org.forgerock.i18n.slf4j.LocalizedLogger; 037import org.forgerock.opendj.config.server.ConfigChangeResult; 038import org.forgerock.opendj.config.server.ConfigException; 039import org.forgerock.opendj.ldap.DN; 040import org.forgerock.opendj.ldap.ResultCode; 041import org.forgerock.util.Utils; 042import org.forgerock.opendj.config.ClassPropertyDefinition; 043import org.forgerock.opendj.config.server.ConfigurationAddListener; 044import org.forgerock.opendj.config.server.ConfigurationChangeListener; 045import org.forgerock.opendj.config.server.ConfigurationDeleteListener; 046import org.forgerock.opendj.server.config.meta.PluginCfgDefn; 047import org.forgerock.opendj.server.config.server.PluginCfg; 048import org.forgerock.opendj.server.config.server.PluginRootCfg; 049import org.opends.server.api.ClientConnection; 050import org.opends.server.api.plugin.DirectoryServerPlugin; 051import org.opends.server.api.plugin.InternalDirectoryServerPlugin; 052import org.opends.server.api.plugin.PluginResult; 053import org.opends.server.api.plugin.PluginType; 054import org.opends.server.types.CanceledOperationException; 055import org.opends.server.types.DisconnectReason; 056import org.opends.server.types.Entry; 057import org.opends.server.types.InitializationException; 058import org.opends.server.types.IntermediateResponse; 059import org.opends.server.types.LDIFExportConfig; 060import org.opends.server.types.LDIFImportConfig; 061import org.opends.server.types.Modification; 062import org.opends.server.types.Operation; 063import org.opends.server.types.SearchResultEntry; 064import org.opends.server.types.SearchResultReference; 065import org.opends.server.types.operation.PluginOperation; 066import org.opends.server.types.operation.PostOperationAbandonOperation; 067import org.opends.server.types.operation.PostOperationAddOperation; 068import org.opends.server.types.operation.PostOperationBindOperation; 069import org.opends.server.types.operation.PostOperationCompareOperation; 070import org.opends.server.types.operation.PostOperationDeleteOperation; 071import org.opends.server.types.operation.PostOperationExtendedOperation; 072import org.opends.server.types.operation.PostOperationModifyDNOperation; 073import org.opends.server.types.operation.PostOperationModifyOperation; 074import org.opends.server.types.operation.PostOperationSearchOperation; 075import org.opends.server.types.operation.PostOperationUnbindOperation; 076import org.opends.server.types.operation.PostResponseAddOperation; 077import org.opends.server.types.operation.PostResponseBindOperation; 078import org.opends.server.types.operation.PostResponseCompareOperation; 079import org.opends.server.types.operation.PostResponseDeleteOperation; 080import org.opends.server.types.operation.PostResponseExtendedOperation; 081import org.opends.server.types.operation.PostResponseModifyDNOperation; 082import org.opends.server.types.operation.PostResponseModifyOperation; 083import org.opends.server.types.operation.PostResponseSearchOperation; 084import org.opends.server.types.operation.PostSynchronizationAddOperation; 085import org.opends.server.types.operation.PostSynchronizationDeleteOperation; 086import org.opends.server.types.operation.PostSynchronizationModifyDNOperation; 087import org.opends.server.types.operation.PostSynchronizationModifyOperation; 088import org.opends.server.types.operation.PreOperationAddOperation; 089import org.opends.server.types.operation.PreOperationBindOperation; 090import org.opends.server.types.operation.PreOperationCompareOperation; 091import org.opends.server.types.operation.PreOperationDeleteOperation; 092import org.opends.server.types.operation.PreOperationExtendedOperation; 093import org.opends.server.types.operation.PreOperationModifyDNOperation; 094import org.opends.server.types.operation.PreOperationModifyOperation; 095import org.opends.server.types.operation.PreOperationOperation; 096import org.opends.server.types.operation.PreOperationSearchOperation; 097import org.opends.server.types.operation.PreParseAbandonOperation; 098import org.opends.server.types.operation.PreParseAddOperation; 099import org.opends.server.types.operation.PreParseBindOperation; 100import org.opends.server.types.operation.PreParseCompareOperation; 101import org.opends.server.types.operation.PreParseDeleteOperation; 102import org.opends.server.types.operation.PreParseExtendedOperation; 103import org.opends.server.types.operation.PreParseModifyDNOperation; 104import org.opends.server.types.operation.PreParseModifyOperation; 105import org.opends.server.types.operation.PreParseOperation; 106import org.opends.server.types.operation.PreParseSearchOperation; 107import org.opends.server.types.operation.PreParseUnbindOperation; 108import org.opends.server.types.operation.SearchEntrySearchOperation; 109import org.opends.server.types.operation.SearchReferenceSearchOperation; 110import org.opends.server.types.operation.SubordinateModifyDNOperation; 111 112/** 113 * This class defines a utility that will be used to manage the configuration 114 * for the set of plugins defined in the Directory Server. It will perform the 115 * necessary initialization of those plugins when the server is first started, 116 * and then will manage any changes to them while the server is running. It 117 * also provides methods for invoking all the plugins of a given type. 118 */ 119public class PluginConfigManager 120 implements ConfigurationAddListener<PluginCfg>, 121 ConfigurationDeleteListener<PluginCfg>, 122 ConfigurationChangeListener<PluginCfg> 123{ 124 private static final LocalizedLogger logger = LocalizedLogger.getLoggerForThisClass(); 125 126 // Arrays for holding the plugins of each type. 127 private DirectoryServerPlugin[] startupPlugins; 128 private DirectoryServerPlugin[] shutdownPlugins; 129 private DirectoryServerPlugin[] postConnectPlugins; 130 private DirectoryServerPlugin[] postDisconnectPlugins; 131 private DirectoryServerPlugin[] ldifImportPlugins; 132 private DirectoryServerPlugin[] ldifImportEndPlugins; 133 private DirectoryServerPlugin[] ldifImportBeginPlugins; 134 private DirectoryServerPlugin[] ldifExportPlugins; 135 private DirectoryServerPlugin[] preParseAbandonPlugins; 136 private DirectoryServerPlugin[] preParseAddPlugins; 137 private DirectoryServerPlugin[] preParseBindPlugins; 138 private DirectoryServerPlugin[] preParseComparePlugins; 139 private DirectoryServerPlugin[] preParseDeletePlugins; 140 private DirectoryServerPlugin[] preParseExtendedPlugins; 141 private DirectoryServerPlugin[] preParseModifyPlugins; 142 private DirectoryServerPlugin[] preParseModifyDNPlugins; 143 private DirectoryServerPlugin[] preParseSearchPlugins; 144 private DirectoryServerPlugin[] preParseUnbindPlugins; 145 private DirectoryServerPlugin[] preOperationAddPlugins; 146 private DirectoryServerPlugin[] preOperationBindPlugins; 147 private DirectoryServerPlugin[] preOperationComparePlugins; 148 private DirectoryServerPlugin[] preOperationDeletePlugins; 149 private DirectoryServerPlugin[] preOperationExtendedPlugins; 150 private DirectoryServerPlugin[] preOperationModifyPlugins; 151 private DirectoryServerPlugin[] preOperationModifyDNPlugins; 152 private DirectoryServerPlugin[] preOperationSearchPlugins; 153 private DirectoryServerPlugin[] postOperationAbandonPlugins; 154 private DirectoryServerPlugin[] postOperationAddPlugins; 155 private DirectoryServerPlugin[] postOperationBindPlugins; 156 private DirectoryServerPlugin[] postOperationComparePlugins; 157 private DirectoryServerPlugin[] postOperationDeletePlugins; 158 private DirectoryServerPlugin[] postOperationExtendedPlugins; 159 private DirectoryServerPlugin[] postOperationModifyPlugins; 160 private DirectoryServerPlugin[] postOperationModifyDNPlugins; 161 private DirectoryServerPlugin[] postOperationSearchPlugins; 162 private DirectoryServerPlugin[] postOperationUnbindPlugins; 163 private DirectoryServerPlugin[] postResponseAddPlugins; 164 private DirectoryServerPlugin[] postResponseBindPlugins; 165 private DirectoryServerPlugin[] postResponseComparePlugins; 166 private DirectoryServerPlugin[] postResponseDeletePlugins; 167 private DirectoryServerPlugin[] postResponseExtendedPlugins; 168 private DirectoryServerPlugin[] postResponseModifyPlugins; 169 private DirectoryServerPlugin[] postResponseModifyDNPlugins; 170 private DirectoryServerPlugin[] postResponseSearchPlugins; 171 private DirectoryServerPlugin[] postSynchronizationAddPlugins; 172 private DirectoryServerPlugin[] postSynchronizationDeletePlugins; 173 private DirectoryServerPlugin[] postSynchronizationModifyPlugins; 174 private DirectoryServerPlugin[] postSynchronizationModifyDNPlugins; 175 private DirectoryServerPlugin[] searchResultEntryPlugins; 176 private DirectoryServerPlugin[] searchResultReferencePlugins; 177 private DirectoryServerPlugin[] subordinateModifyDNPlugins; 178 private DirectoryServerPlugin[] subordinateDeletePlugins; 179 private DirectoryServerPlugin[] intermediateResponsePlugins; 180 181 /** The mapping between the DN of a plugin entry and the plugin instance loaded from that entry. */ 182 private ConcurrentHashMap<DN, 183 DirectoryServerPlugin<? extends PluginCfg>> 184 registeredPlugins; 185 186 /** 187 * The mapping between an operation and a set of post operation plugins 188 * it should skip. This pairs up pre and post operation plugin processing 189 * such that only plugins that successfully execute its pre op plugin will 190 * have its post op plugin executed on a per operation basis. If an 191 * operation is not registered on this list then all all pre op plugins 192 * executed successfully for this operation so all post op plugins should 193 * execute. 194 */ 195 private ConcurrentHashMap<PluginOperation, ArrayList<DirectoryServerPlugin>> 196 skippedPreOperationPlugins; 197 198 /** The plugin root configuration read at server startup. */ 199 private PluginRootCfg pluginRootConfig; 200 201 /** The lock that will provide threadsafe access to the sets of registered plugins. */ 202 private ReentrantLock pluginLock; 203 204 private final ServerContext serverContext; 205 206 /** 207 * Creates a new instance of this plugin config manager. 208 * 209 * @param serverContext 210 * The server context. 211 */ 212 public PluginConfigManager(ServerContext serverContext) 213 { 214 this.serverContext = serverContext; 215 pluginLock = new ReentrantLock(); 216 217 startupPlugins = new DirectoryServerPlugin[0]; 218 shutdownPlugins = new DirectoryServerPlugin[0]; 219 postConnectPlugins = new DirectoryServerPlugin[0]; 220 postDisconnectPlugins = new DirectoryServerPlugin[0]; 221 ldifImportPlugins = new DirectoryServerPlugin[0]; 222 ldifImportEndPlugins = new DirectoryServerPlugin[0]; 223 ldifImportBeginPlugins = new DirectoryServerPlugin[0]; 224 ldifExportPlugins = new DirectoryServerPlugin[0]; 225 preParseAbandonPlugins = new DirectoryServerPlugin[0]; 226 preParseAddPlugins = new DirectoryServerPlugin[0]; 227 preParseBindPlugins = new DirectoryServerPlugin[0]; 228 preParseComparePlugins = new DirectoryServerPlugin[0]; 229 preParseDeletePlugins = new DirectoryServerPlugin[0]; 230 preParseExtendedPlugins = new DirectoryServerPlugin[0]; 231 preParseModifyPlugins = new DirectoryServerPlugin[0]; 232 preParseModifyDNPlugins = new DirectoryServerPlugin[0]; 233 preParseSearchPlugins = new DirectoryServerPlugin[0]; 234 preParseUnbindPlugins = new DirectoryServerPlugin[0]; 235 preOperationAddPlugins = new DirectoryServerPlugin[0]; 236 preOperationBindPlugins = new DirectoryServerPlugin[0]; 237 preOperationComparePlugins = new DirectoryServerPlugin[0]; 238 preOperationDeletePlugins = new DirectoryServerPlugin[0]; 239 preOperationExtendedPlugins = new DirectoryServerPlugin[0]; 240 preOperationModifyPlugins = new DirectoryServerPlugin[0]; 241 preOperationModifyDNPlugins = new DirectoryServerPlugin[0]; 242 preOperationSearchPlugins = new DirectoryServerPlugin[0]; 243 postOperationAbandonPlugins = new DirectoryServerPlugin[0]; 244 postOperationAddPlugins = new DirectoryServerPlugin[0]; 245 postOperationBindPlugins = new DirectoryServerPlugin[0]; 246 postOperationComparePlugins = new DirectoryServerPlugin[0]; 247 postOperationDeletePlugins = new DirectoryServerPlugin[0]; 248 postOperationExtendedPlugins = new DirectoryServerPlugin[0]; 249 postOperationModifyPlugins = new DirectoryServerPlugin[0]; 250 postOperationModifyDNPlugins = new DirectoryServerPlugin[0]; 251 postOperationSearchPlugins = new DirectoryServerPlugin[0]; 252 postOperationUnbindPlugins = new DirectoryServerPlugin[0]; 253 postResponseAddPlugins = new DirectoryServerPlugin[0]; 254 postResponseBindPlugins = new DirectoryServerPlugin[0]; 255 postResponseComparePlugins = new DirectoryServerPlugin[0]; 256 postResponseDeletePlugins = new DirectoryServerPlugin[0]; 257 postResponseExtendedPlugins = new DirectoryServerPlugin[0]; 258 postResponseModifyPlugins = new DirectoryServerPlugin[0]; 259 postResponseModifyDNPlugins = new DirectoryServerPlugin[0]; 260 postResponseSearchPlugins = new DirectoryServerPlugin[0]; 261 postSynchronizationAddPlugins = new DirectoryServerPlugin[0]; 262 postSynchronizationDeletePlugins = new DirectoryServerPlugin[0]; 263 postSynchronizationModifyPlugins = new DirectoryServerPlugin[0]; 264 postSynchronizationModifyDNPlugins = new DirectoryServerPlugin[0]; 265 searchResultEntryPlugins = new DirectoryServerPlugin[0]; 266 searchResultReferencePlugins = new DirectoryServerPlugin[0]; 267 subordinateModifyDNPlugins = new DirectoryServerPlugin[0]; 268 subordinateDeletePlugins = new DirectoryServerPlugin[0]; 269 intermediateResponsePlugins = new DirectoryServerPlugin[0]; 270 registeredPlugins = new ConcurrentHashMap<>(); 271 skippedPreOperationPlugins = new ConcurrentHashMap<>(); 272 } 273 274 /** 275 * Initializes this plugin configuration manager. This should only be called 276 * at Directory Server startup and before user plugins are loaded. 277 * 278 * @throws ConfigException 279 * If a critical configuration problem prevents the plugin 280 * initialization from succeeding. 281 */ 282 public void initializePluginConfigManager() throws ConfigException 283 { 284 registeredPlugins.clear(); 285 286 pluginRootConfig = serverContext.getRootConfig().getPluginRoot(); 287 pluginRootConfig.addPluginAddListener(this); 288 pluginRootConfig.addPluginDeleteListener(this); 289 } 290 291 /** 292 * Initializes any plugins defined in the directory server 293 * configuration. This should only be called at Directory Server 294 * startup and after this plugin configuration manager has been 295 * initialized. 296 * 297 * @param pluginTypes 298 * The set of plugin types for the plugins to initialize, or 299 * <CODE>null</CODE> to initialize all types of plugins 300 * defined in the server configuration. In general, this 301 * should only be non-null for cases in which the server is 302 * running in a special mode that only uses a minimal set of 303 * plugins (e.g., LDIF import or export). 304 * @throws ConfigException 305 * If a critical configuration problem prevents the plugin 306 * initialization from succeeding. 307 * @throws InitializationException 308 * If a problem occurs while initializing the plugins that 309 * is not related to the server configuration. 310 */ 311 public void initializeUserPlugins(Set<PluginType> pluginTypes) 312 throws ConfigException, InitializationException 313 { 314 //Initialize the user plugins. 315 for (String pluginName : pluginRootConfig.listPlugins()) 316 { 317 PluginCfg pluginConfiguration = pluginRootConfig.getPlugin(pluginName); 318 pluginConfiguration.addChangeListener(this); 319 320 if (! pluginConfiguration.isEnabled()) 321 { 322 continue; 323 } 324 325 // Create a set of plugin types for the plugin. 326 HashSet<PluginType> initTypes = new HashSet<>(); 327 for (PluginCfgDefn.PluginType pluginType : pluginConfiguration.getPluginType()) 328 { 329 PluginType t = getPluginType(pluginType); 330 if (pluginTypes == null || pluginTypes.contains(t)) 331 { 332 initTypes.add(t); 333 } 334 } 335 336 if (initTypes.isEmpty()) 337 { 338 continue; 339 } 340 341 try 342 { 343 DirectoryServerPlugin<? extends PluginCfg> plugin = 344 loadPlugin(pluginConfiguration.getJavaClass(), initTypes, 345 pluginConfiguration, true); 346 registerPlugin(plugin, pluginConfiguration.dn(), initTypes); 347 } 348 catch (InitializationException ie) 349 { 350 logger.error(ie.getMessageObject()); 351 continue; 352 } 353 } 354 } 355 356 /** 357 * Loads the specified class, instantiates it as a plugin, and optionally 358 * initializes that plugin. 359 * 360 * @param className The fully-qualified name of the plugin class to 361 * load, instantiate, and initialize. 362 * @param pluginTypes The set of plugin types for the plugins to 363 * initialize, or {@code null} to initialize all types 364 * of plugins defined in the server configuration. In 365 * general, this should only be non-null for cases in 366 * which the server is running in a special mode that 367 * only uses a minimal set of plugins (e.g., LDIF 368 * import or export). 369 * @param configuration The configuration to use to initialize the plugin. 370 * It must not be {@code null}. 371 * @param initialize Indicates whether the plugin instance should be 372 * initialized. 373 * 374 * @return The possibly initialized plugin. 375 * 376 * @throws InitializationException If a problem occurred while attempting to 377 * initialize the plugin. 378 */ 379 private <T extends PluginCfg> DirectoryServerPlugin<T> 380 loadPlugin(String className, Set<PluginType> pluginTypes, 381 T configuration, boolean initialize) 382 throws InitializationException 383 { 384 try 385 { 386 PluginCfgDefn definition = 387 PluginCfgDefn.getInstance(); 388 ClassPropertyDefinition propertyDefinition = 389 definition.getJavaClassPropertyDefinition(); 390 Class<? extends DirectoryServerPlugin> pluginClass = 391 propertyDefinition.loadClass(className, DirectoryServerPlugin.class); 392 DirectoryServerPlugin<T> plugin = pluginClass.newInstance(); 393 394 if (initialize) 395 { 396 plugin.initializeInternal(serverContext, configuration.dn(), pluginTypes, 397 configuration.isInvokeForInternalOperations()); 398 plugin.initializePlugin(pluginTypes, configuration); 399 } 400 else 401 { 402 List<LocalizableMessage> unacceptableReasons = new ArrayList<>(); 403 if (!plugin.isConfigurationAcceptable(configuration, unacceptableReasons)) 404 { 405 String buffer = Utils.joinAsString(". ", unacceptableReasons); 406 throw new InitializationException( 407 ERR_CONFIG_PLUGIN_CONFIG_NOT_ACCEPTABLE.get(configuration.dn(), buffer)); 408 } 409 } 410 411 return plugin; 412 } 413 catch (Exception e) 414 { 415 LocalizableMessage message = ERR_CONFIG_PLUGIN_CANNOT_INITIALIZE. 416 get(className, configuration.dn(), stackTraceToSingleLineString(e)); 417 throw new InitializationException(message, e); 418 } 419 } 420 421 /** 422 * Gets the OpenDS plugin type object that corresponds to the configuration 423 * counterpart. 424 * 425 * @param configPluginType The configuration plugin type for which to 426 * retrieve the OpenDS plugin type. 427 */ 428 private PluginType getPluginType(PluginCfgDefn.PluginType 429 configPluginType) 430 { 431 switch (configPluginType) 432 { 433 case STARTUP: return PluginType.STARTUP; 434 case SHUTDOWN: return PluginType.SHUTDOWN; 435 case POSTCONNECT: return PluginType.POST_CONNECT; 436 case POSTDISCONNECT: return PluginType.POST_DISCONNECT; 437 case LDIFIMPORT: return PluginType.LDIF_IMPORT; 438 case LDIFIMPORTEND: return PluginType.LDIF_IMPORT_END; 439 case LDIFIMPORTBEGIN: return PluginType.LDIF_IMPORT_BEGIN; 440 case LDIFEXPORT: return PluginType.LDIF_EXPORT; 441 case PREPARSEABANDON: return PluginType.PRE_PARSE_ABANDON; 442 case PREPARSEADD: return PluginType.PRE_PARSE_ADD; 443 case PREPARSEBIND: return PluginType.PRE_PARSE_BIND; 444 case PREPARSECOMPARE: return PluginType.PRE_PARSE_COMPARE; 445 case PREPARSEDELETE: return PluginType.PRE_PARSE_DELETE; 446 case PREPARSEEXTENDED: return PluginType.PRE_PARSE_EXTENDED; 447 case PREPARSEMODIFY: return PluginType.PRE_PARSE_MODIFY; 448 case PREPARSEMODIFYDN: return PluginType.PRE_PARSE_MODIFY_DN; 449 case PREPARSESEARCH: return PluginType.PRE_PARSE_SEARCH; 450 case PREPARSEUNBIND: return PluginType.PRE_PARSE_UNBIND; 451 case PREOPERATIONADD: return PluginType.PRE_OPERATION_ADD; 452 case PREOPERATIONBIND: return PluginType.PRE_OPERATION_BIND; 453 case PREOPERATIONCOMPARE: return PluginType.PRE_OPERATION_COMPARE; 454 case PREOPERATIONDELETE: return PluginType.PRE_OPERATION_DELETE; 455 case PREOPERATIONEXTENDED: return PluginType.PRE_OPERATION_EXTENDED; 456 case PREOPERATIONMODIFY: return PluginType.PRE_OPERATION_MODIFY; 457 case PREOPERATIONMODIFYDN: return PluginType.PRE_OPERATION_MODIFY_DN; 458 case PREOPERATIONSEARCH: return PluginType.PRE_OPERATION_SEARCH; 459 case POSTOPERATIONABANDON: return PluginType.POST_OPERATION_ABANDON; 460 case POSTOPERATIONADD: return PluginType.POST_OPERATION_ADD; 461 case POSTOPERATIONBIND: return PluginType.POST_OPERATION_BIND; 462 case POSTOPERATIONCOMPARE: return PluginType.POST_OPERATION_COMPARE; 463 case POSTOPERATIONDELETE: return PluginType.POST_OPERATION_DELETE; 464 case POSTOPERATIONEXTENDED: return PluginType.POST_OPERATION_EXTENDED; 465 case POSTOPERATIONMODIFY: return PluginType.POST_OPERATION_MODIFY; 466 case POSTOPERATIONMODIFYDN: return PluginType.POST_OPERATION_MODIFY_DN; 467 case POSTOPERATIONSEARCH: return PluginType.POST_OPERATION_SEARCH; 468 case POSTOPERATIONUNBIND: return PluginType.POST_OPERATION_UNBIND; 469 case POSTRESPONSEADD: return PluginType.POST_RESPONSE_ADD; 470 case POSTRESPONSEBIND: return PluginType.POST_RESPONSE_BIND; 471 case POSTRESPONSECOMPARE: return PluginType.POST_RESPONSE_COMPARE; 472 case POSTRESPONSEDELETE: return PluginType.POST_RESPONSE_DELETE; 473 case POSTRESPONSEEXTENDED: return PluginType.POST_RESPONSE_EXTENDED; 474 case POSTRESPONSEMODIFY: return PluginType.POST_RESPONSE_MODIFY; 475 case POSTRESPONSEMODIFYDN: return PluginType.POST_RESPONSE_MODIFY_DN; 476 case POSTRESPONSESEARCH: return PluginType.POST_RESPONSE_SEARCH; 477 case SEARCHRESULTENTRY: return PluginType.SEARCH_RESULT_ENTRY; 478 case SEARCHRESULTREFERENCE: return PluginType.SEARCH_RESULT_REFERENCE; 479 case SUBORDINATEMODIFYDN: return PluginType.SUBORDINATE_MODIFY_DN; 480 case SUBORDINATEDELETE: return PluginType.SUBORDINATE_DELETE; 481 case INTERMEDIATERESPONSE: return PluginType.INTERMEDIATE_RESPONSE; 482 case POSTSYNCHRONIZATIONADD: 483 return PluginType.POST_SYNCHRONIZATION_ADD; 484 case POSTSYNCHRONIZATIONDELETE: 485 return PluginType.POST_SYNCHRONIZATION_DELETE; 486 case POSTSYNCHRONIZATIONMODIFY: 487 return PluginType.POST_SYNCHRONIZATION_MODIFY; 488 case POSTSYNCHRONIZATIONMODIFYDN: 489 return PluginType.POST_SYNCHRONIZATION_MODIFY_DN; 490 default: return null; 491 } 492 } 493 494 /** Finalizes all plugins that are registered with the Directory Server. */ 495 public void finalizePlugins() 496 { 497 pluginLock.lock(); 498 499 try 500 { 501 for (DirectoryServerPlugin<? extends PluginCfg> plugin : registeredPlugins.values()) 502 { 503 try 504 { 505 plugin.finalizePlugin(); 506 } 507 catch (Exception e) 508 { 509 logger.traceException(e); 510 } 511 } 512 513 registeredPlugins.clear(); 514 } 515 finally 516 { 517 pluginLock.unlock(); 518 } 519 } 520 521 /** 522 * Retrieves the set of plugins that have been registered with the Directory 523 * Server. 524 * 525 * @return The set of plugins that have been registered with the Directory 526 * Server. 527 */ 528 public ConcurrentHashMap<DN, 529 DirectoryServerPlugin<? extends PluginCfg>> 530 getRegisteredPlugins() 531 { 532 return registeredPlugins; 533 } 534 535 /** 536 * Retrieves the plugin with the specified configuration entry DN. 537 * 538 * @param pluginDN The DN of the configuration entry for the plugin to 539 * retrieve. 540 * 541 * @return The requested plugin, or <CODE>null</CODE> if there is no such 542 * plugin. 543 */ 544 public DirectoryServerPlugin getRegisteredPlugin(DN pluginDN) 545 { 546 return registeredPlugins.get(pluginDN); 547 } 548 549 /** 550 * Registers the provided internal plugin with this plugin config 551 * manager and ensures that it will be invoked in the specified ways. 552 * 553 * @param plugin 554 * The internal plugin to register with the server. The 555 * plugin must specify a configuration entry which is 556 * guaranteed to be unique. 557 */ 558 void registerInternalPlugin(InternalDirectoryServerPlugin plugin) 559 { 560 pluginLock.lock(); 561 try 562 { 563 registerPlugin0(plugin, plugin.getPluginTypes()); 564 } 565 finally 566 { 567 pluginLock.unlock(); 568 } 569 } 570 571 /** 572 * Register a plugin in the appropriate tables. 573 * 574 * @param plugin 575 * The plugin to register with the server. 576 * @param pluginTypes 577 * The plugin types that will be used to control the points 578 * at which the provided plugin is invoked. 579 */ 580 private void registerPlugin0( 581 DirectoryServerPlugin<? extends PluginCfg> plugin, 582 Set<PluginType> pluginTypes) 583 { 584 for (PluginType t : pluginTypes) 585 { 586 switch (t) 587 { 588 case STARTUP: 589 startupPlugins = 590 addPlugin(startupPlugins, plugin, t, pluginRootConfig 591 .getPluginOrderStartup()); 592 break; 593 case SHUTDOWN: 594 shutdownPlugins = 595 addPlugin(shutdownPlugins, plugin, t, pluginRootConfig 596 .getPluginOrderShutdown()); 597 break; 598 case POST_CONNECT: 599 postConnectPlugins = 600 addPlugin(postConnectPlugins, plugin, t, pluginRootConfig 601 .getPluginOrderPostConnect()); 602 break; 603 case POST_DISCONNECT: 604 postDisconnectPlugins = 605 addPlugin(postDisconnectPlugins, plugin, t, 606 pluginRootConfig.getPluginOrderPostDisconnect()); 607 break; 608 case LDIF_IMPORT: 609 ldifImportPlugins = 610 addPlugin(ldifImportPlugins, plugin, t, pluginRootConfig 611 .getPluginOrderLDIFImport()); 612 break; 613 case LDIF_IMPORT_END: 614 ldifImportEndPlugins = 615 addPlugin(ldifImportEndPlugins, plugin, t, pluginRootConfig 616 .getPluginOrderLDIFImportEnd()); 617 break; 618 case LDIF_IMPORT_BEGIN: 619 ldifImportBeginPlugins = 620 addPlugin(ldifImportBeginPlugins, plugin, t, 621 pluginRootConfig.getPluginOrderLDIFImportBegin()); 622 break; 623 case LDIF_EXPORT: 624 ldifExportPlugins = 625 addPlugin(ldifExportPlugins, plugin, t, pluginRootConfig 626 .getPluginOrderLDIFExport()); 627 break; 628 case PRE_PARSE_ABANDON: 629 preParseAbandonPlugins = 630 addPlugin(preParseAbandonPlugins, plugin, t, 631 pluginRootConfig.getPluginOrderPreParseAbandon()); 632 break; 633 case PRE_PARSE_ADD: 634 preParseAddPlugins = 635 addPlugin(preParseAddPlugins, plugin, t, pluginRootConfig 636 .getPluginOrderPreParseAdd()); 637 break; 638 case PRE_PARSE_BIND: 639 preParseBindPlugins = 640 addPlugin(preParseBindPlugins, plugin, t, pluginRootConfig 641 .getPluginOrderPreParseBind()); 642 break; 643 case PRE_PARSE_COMPARE: 644 preParseComparePlugins = 645 addPlugin(preParseComparePlugins, plugin, t, 646 pluginRootConfig.getPluginOrderPreParseCompare()); 647 break; 648 case PRE_PARSE_DELETE: 649 preParseDeletePlugins = 650 addPlugin(preParseDeletePlugins, plugin, t, 651 pluginRootConfig.getPluginOrderPreParseDelete()); 652 break; 653 case PRE_PARSE_EXTENDED: 654 preParseExtendedPlugins = 655 addPlugin(preParseExtendedPlugins, plugin, t, 656 pluginRootConfig.getPluginOrderPreParseExtended()); 657 break; 658 case PRE_PARSE_MODIFY: 659 preParseModifyPlugins = 660 addPlugin(preParseModifyPlugins, plugin, t, 661 pluginRootConfig.getPluginOrderPreParseModify()); 662 break; 663 case PRE_PARSE_MODIFY_DN: 664 preParseModifyDNPlugins = 665 addPlugin(preParseModifyDNPlugins, plugin, t, 666 pluginRootConfig.getPluginOrderPreParseModifyDN()); 667 break; 668 case PRE_PARSE_SEARCH: 669 preParseSearchPlugins = 670 addPlugin(preParseSearchPlugins, plugin, t, 671 pluginRootConfig.getPluginOrderPreParseSearch()); 672 break; 673 case PRE_PARSE_UNBIND: 674 preParseUnbindPlugins = 675 addPlugin(preParseUnbindPlugins, plugin, t, 676 pluginRootConfig.getPluginOrderPreParseUnbind()); 677 break; 678 case PRE_OPERATION_ADD: 679 preOperationAddPlugins = 680 addPlugin(preOperationAddPlugins, plugin, t, 681 pluginRootConfig.getPluginOrderPreOperationAdd()); 682 break; 683 case PRE_OPERATION_BIND: 684 preOperationBindPlugins = 685 addPlugin(preOperationBindPlugins, plugin, t, 686 pluginRootConfig.getPluginOrderPreOperationBind()); 687 break; 688 case PRE_OPERATION_COMPARE: 689 preOperationComparePlugins = 690 addPlugin(preOperationComparePlugins, plugin, t, 691 pluginRootConfig.getPluginOrderPreOperationCompare()); 692 break; 693 case PRE_OPERATION_DELETE: 694 preOperationDeletePlugins = 695 addPlugin(preOperationDeletePlugins, plugin, t, 696 pluginRootConfig.getPluginOrderPreOperationDelete()); 697 break; 698 case PRE_OPERATION_EXTENDED: 699 preOperationExtendedPlugins = 700 addPlugin(preOperationExtendedPlugins, plugin, t, 701 pluginRootConfig.getPluginOrderPreOperationExtended()); 702 break; 703 case PRE_OPERATION_MODIFY: 704 preOperationModifyPlugins = 705 addPlugin(preOperationModifyPlugins, plugin, t, 706 pluginRootConfig.getPluginOrderPreOperationModify()); 707 break; 708 case PRE_OPERATION_MODIFY_DN: 709 preOperationModifyDNPlugins = 710 addPlugin(preOperationModifyDNPlugins, plugin, t, 711 pluginRootConfig.getPluginOrderPreOperationModifyDN()); 712 break; 713 case PRE_OPERATION_SEARCH: 714 preOperationSearchPlugins = 715 addPlugin(preOperationSearchPlugins, plugin, t, 716 pluginRootConfig.getPluginOrderPreOperationSearch()); 717 break; 718 case POST_OPERATION_ABANDON: 719 postOperationAbandonPlugins = 720 addPlugin(postOperationAbandonPlugins, plugin, t, 721 pluginRootConfig.getPluginOrderPostOperationAbandon()); 722 break; 723 case POST_OPERATION_ADD: 724 postOperationAddPlugins = 725 addPlugin(postOperationAddPlugins, plugin, t, 726 pluginRootConfig.getPluginOrderPostOperationAdd()); 727 break; 728 case POST_OPERATION_BIND: 729 postOperationBindPlugins = 730 addPlugin(postOperationBindPlugins, plugin, t, 731 pluginRootConfig.getPluginOrderPostOperationBind()); 732 break; 733 case POST_OPERATION_COMPARE: 734 postOperationComparePlugins = 735 addPlugin(postOperationComparePlugins, plugin, t, 736 pluginRootConfig.getPluginOrderPostOperationCompare()); 737 break; 738 case POST_OPERATION_DELETE: 739 postOperationDeletePlugins = 740 addPlugin(postOperationDeletePlugins, plugin, t, 741 pluginRootConfig.getPluginOrderPostOperationDelete()); 742 break; 743 case POST_OPERATION_EXTENDED: 744 postOperationExtendedPlugins = 745 addPlugin(postOperationExtendedPlugins, plugin, t, 746 pluginRootConfig.getPluginOrderPostOperationExtended()); 747 break; 748 case POST_OPERATION_MODIFY: 749 postOperationModifyPlugins = 750 addPlugin(postOperationModifyPlugins, plugin, t, 751 pluginRootConfig.getPluginOrderPostOperationModify()); 752 break; 753 case POST_OPERATION_MODIFY_DN: 754 postOperationModifyDNPlugins = 755 addPlugin(postOperationModifyDNPlugins, plugin, t, 756 pluginRootConfig.getPluginOrderPostOperationModifyDN()); 757 break; 758 case POST_OPERATION_SEARCH: 759 postOperationSearchPlugins = 760 addPlugin(postOperationSearchPlugins, plugin, t, 761 pluginRootConfig.getPluginOrderPostOperationSearch()); 762 break; 763 case POST_OPERATION_UNBIND: 764 postOperationUnbindPlugins = 765 addPlugin(postOperationUnbindPlugins, plugin, t, 766 pluginRootConfig.getPluginOrderPostOperationUnbind()); 767 break; 768 case POST_RESPONSE_ADD: 769 postResponseAddPlugins = 770 addPlugin(postResponseAddPlugins, plugin, t, 771 pluginRootConfig.getPluginOrderPostResponseAdd()); 772 break; 773 case POST_RESPONSE_BIND: 774 postResponseBindPlugins = 775 addPlugin(postResponseBindPlugins, plugin, t, 776 pluginRootConfig.getPluginOrderPostResponseBind()); 777 break; 778 case POST_RESPONSE_COMPARE: 779 postResponseComparePlugins = 780 addPlugin(postResponseComparePlugins, plugin, t, 781 pluginRootConfig.getPluginOrderPostResponseCompare()); 782 break; 783 case POST_RESPONSE_DELETE: 784 postResponseDeletePlugins = 785 addPlugin(postResponseDeletePlugins, plugin, t, 786 pluginRootConfig.getPluginOrderPostResponseDelete()); 787 break; 788 case POST_RESPONSE_EXTENDED: 789 postResponseExtendedPlugins = 790 addPlugin(postResponseExtendedPlugins, plugin, t, 791 pluginRootConfig.getPluginOrderPostResponseExtended()); 792 break; 793 case POST_RESPONSE_MODIFY: 794 postResponseModifyPlugins = 795 addPlugin(postResponseModifyPlugins, plugin, t, 796 pluginRootConfig.getPluginOrderPostResponseModify()); 797 break; 798 case POST_RESPONSE_MODIFY_DN: 799 postResponseModifyDNPlugins = 800 addPlugin(postResponseModifyDNPlugins, plugin, t, 801 pluginRootConfig.getPluginOrderPostResponseModifyDN()); 802 break; 803 case POST_RESPONSE_SEARCH: 804 postResponseSearchPlugins = 805 addPlugin(postResponseSearchPlugins, plugin, t, 806 pluginRootConfig.getPluginOrderPostResponseSearch()); 807 break; 808 case POST_SYNCHRONIZATION_ADD: 809 postSynchronizationAddPlugins = 810 addPlugin(postSynchronizationAddPlugins, plugin, t, 811 pluginRootConfig.getPluginOrderPostSynchronizationAdd()); 812 break; 813 case POST_SYNCHRONIZATION_DELETE: 814 postSynchronizationDeletePlugins = 815 addPlugin(postSynchronizationDeletePlugins, plugin, t, 816 pluginRootConfig 817 .getPluginOrderPostSynchronizationDelete()); 818 break; 819 case POST_SYNCHRONIZATION_MODIFY: 820 postSynchronizationModifyPlugins = 821 addPlugin(postSynchronizationModifyPlugins, plugin, t, 822 pluginRootConfig 823 .getPluginOrderPostSynchronizationModify()); 824 break; 825 case POST_SYNCHRONIZATION_MODIFY_DN: 826 postSynchronizationModifyDNPlugins = 827 addPlugin(postSynchronizationModifyDNPlugins, plugin, t, 828 pluginRootConfig 829 .getPluginOrderPostSynchronizationModifyDN()); 830 break; 831 case SEARCH_RESULT_ENTRY: 832 searchResultEntryPlugins = 833 addPlugin(searchResultEntryPlugins, plugin, t, 834 pluginRootConfig.getPluginOrderSearchResultEntry()); 835 break; 836 case SEARCH_RESULT_REFERENCE: 837 searchResultReferencePlugins = 838 addPlugin(searchResultReferencePlugins, plugin, t, 839 pluginRootConfig.getPluginOrderSearchResultReference()); 840 break; 841 case SUBORDINATE_MODIFY_DN: 842 subordinateModifyDNPlugins = 843 addPlugin(subordinateModifyDNPlugins, plugin, t, 844 pluginRootConfig.getPluginOrderSubordinateModifyDN()); 845 break; 846 case SUBORDINATE_DELETE: 847 subordinateDeletePlugins = 848 addPlugin(subordinateDeletePlugins, plugin, t, 849 pluginRootConfig.getPluginOrderSubordinateDelete()); 850 break; 851 case INTERMEDIATE_RESPONSE: 852 intermediateResponsePlugins = 853 addPlugin(intermediateResponsePlugins, plugin, t, 854 pluginRootConfig.getPluginOrderIntermediateResponse()); 855 break; 856 default: 857 } 858 } 859 } 860 861 /** 862 * Registers the provided plugin with this plugin config manager and 863 * ensures that it will be invoked in the specified ways. 864 * 865 * @param plugin 866 * The plugin to register with the server. 867 * @param pluginEntryDN 868 * The DN of the configuration entry for the provided plugin. 869 * @param pluginTypes 870 * The plugin types that will be used to control the points 871 * at which the provided plugin is invoked. 872 */ 873 private void registerPlugin( 874 DirectoryServerPlugin<? extends PluginCfg> plugin, 875 DN pluginEntryDN, Set<PluginType> pluginTypes) 876 { 877 pluginLock.lock(); 878 try 879 { 880 registeredPlugins.put(pluginEntryDN, plugin); 881 registerPlugin0(plugin, pluginTypes); 882 } 883 finally 884 { 885 pluginLock.unlock(); 886 } 887 } 888 889 /** 890 * Adds the provided plugin to the given array. The provided array will not 891 * itself be modified, but rather a new array will be created with one 892 * additional element. The provided plugin will be the last element in the 893 * new array. 894 * <BR><BR> 895 * Note that the only use of this method outside of this class should be for 896 * testing purposes. 897 * 898 * @param pluginArray The array containing the existing set of plugins. 899 * @param plugin The plugin to be added to the array. 900 * @param pluginType The plugin type for the plugin being registered. 901 * @param pluginOrder A string that represents the order in which plugins of 902 * this type should be invoked, or {@code null} if the 903 * order is not considered important. 904 * 905 * @return The new array containing the new set of plugins. 906 */ 907 static DirectoryServerPlugin[] addPlugin(DirectoryServerPlugin[] pluginArray, 908 DirectoryServerPlugin plugin, 909 PluginType pluginType, 910 String pluginOrder) 911 { 912 // If the provided plugin order string is null, empty, or contains only a 913 // wildcard, then simply add the new plugin to the end of the list. 914 // Otherwise, parse the order string and figure out where to put the 915 // provided plugin. 916 if (pluginOrder == null 917 || (pluginOrder = pluginOrder.trim()).length() == 0 918 || pluginOrder.equals("*")) 919 { 920 DirectoryServerPlugin[] newPlugins = 921 new DirectoryServerPlugin[pluginArray.length+1]; 922 System.arraycopy(pluginArray, 0, newPlugins, 0, pluginArray.length); 923 newPlugins[pluginArray.length] = plugin; 924 925 return newPlugins; 926 } 927 else 928 { 929 // Parse the plugin order into initial and final plugin names. 930 boolean starFound = false; 931 LinkedHashSet<String> initialPluginNames = new LinkedHashSet<>(); 932 LinkedHashSet<String> finalPluginNames = new LinkedHashSet<>(); 933 934 StringTokenizer tokenizer = new StringTokenizer(pluginOrder, ","); 935 while (tokenizer.hasMoreTokens()) 936 { 937 String token = tokenizer.nextToken().trim(); 938 if (token.length() == 0) 939 { 940 // Only log the warning once per plugin type. The plugin array will 941 // be empty the first time through, so we can use that to make the 942 // determination. 943 if (pluginArray.length == 0) 944 { 945 logger.warn(WARN_CONFIG_PLUGIN_EMPTY_ELEMENT_IN_ORDER, pluginType.getName()); 946 } 947 } 948 else if (token.equals("*")) 949 { 950 if (starFound) 951 { 952 // Only log the warning once per plugin type. The plugin array will 953 // be empty the first time through, so we can use that to make the 954 // determination. 955 if (pluginArray.length == 0) 956 { 957 logger.warn(WARN_CONFIG_PLUGIN_MULTIPLE_WILDCARDS_IN_ORDER, pluginType.getName()); 958 } 959 } 960 else 961 { 962 starFound = true; 963 } 964 } 965 else 966 { 967 String lowerName = toLowerCase(token); 968 if (starFound) 969 { 970 if (initialPluginNames.contains(lowerName) || 971 finalPluginNames.contains(lowerName)) 972 { 973 // Only log the warning once per plugin type. The plugin array 974 // will be empty the first time through, so we can use that to 975 // make the determination. 976 if (pluginArray.length == 0) 977 { 978 logger.warn(WARN_CONFIG_PLUGIN_LISTED_MULTIPLE_TIMES, 979 pluginType.getName(), token); 980 } 981 } 982 983 finalPluginNames.add(lowerName); 984 } 985 else 986 { 987 if (initialPluginNames.contains(lowerName)) 988 { 989 // Only log the warning once per plugin type. The plugin array 990 // will be empty the first time through, so we can use that to 991 // make the determination. 992 if (pluginArray.length == 0) 993 { 994 logger.warn(WARN_CONFIG_PLUGIN_LISTED_MULTIPLE_TIMES, 995 pluginType.getName(), token); 996 } 997 } 998 999 initialPluginNames.add(lowerName); 1000 } 1001 } 1002 } 1003 1004 if (! starFound) 1005 { 1006 // Only log the warning once per plugin type. The plugin array will be 1007 // empty the first time through, so we can use that to make the 1008 // determination. 1009 if (pluginArray.length == 0) 1010 { 1011 logger.warn(WARN_CONFIG_PLUGIN_ORDER_NO_WILDCARD, pluginType.getName()); 1012 } 1013 } 1014 1015 // Parse the array of already registered plugins to sort them accordingly. 1016 HashMap<String,DirectoryServerPlugin> initialPlugins = new HashMap<>(initialPluginNames.size()); 1017 HashMap<String,DirectoryServerPlugin> finalPlugins = new HashMap<>(finalPluginNames.size()); 1018 ArrayList<DirectoryServerPlugin> otherPlugins = new ArrayList<>(); 1019 for (DirectoryServerPlugin p : pluginArray) 1020 { 1021 DN dn = p.getPluginEntryDN(); 1022 String lowerName = toLowerCase(dn.rdn().getFirstAVA().getAttributeValue().toString()); 1023 if (initialPluginNames.contains(lowerName)) 1024 { 1025 initialPlugins.put(lowerName, p); 1026 } 1027 else if (finalPluginNames.contains(lowerName)) 1028 { 1029 finalPlugins.put(lowerName, p); 1030 } 1031 else 1032 { 1033 otherPlugins.add(p); 1034 } 1035 } 1036 1037 // Get the name of the provided plugin from its RDN value and put it in 1038 // the correct category. 1039 DN dn = plugin.getPluginEntryDN(); 1040 String lowerName = toLowerCase(dn.rdn().getFirstAVA().getAttributeValue().toString()); 1041 if (initialPluginNames.contains(lowerName)) 1042 { 1043 initialPlugins.put(lowerName, plugin); 1044 } 1045 else if (finalPluginNames.contains(lowerName)) 1046 { 1047 finalPlugins.put(lowerName, plugin); 1048 } 1049 else 1050 { 1051 otherPlugins.add(plugin); 1052 } 1053 1054 // Compile a list of all the plugins in the correct order, convert it to 1055 // an array, and return it. 1056 ArrayList<DirectoryServerPlugin> newList = new ArrayList<>(pluginArray.length + 1); 1057 for (String name : initialPluginNames) 1058 { 1059 DirectoryServerPlugin p = initialPlugins.get(name); 1060 if (p != null) 1061 { 1062 newList.add(p); 1063 } 1064 } 1065 1066 newList.addAll(otherPlugins); 1067 1068 for (String name : finalPluginNames) 1069 { 1070 DirectoryServerPlugin p = finalPlugins.get(name); 1071 if (p != null) 1072 { 1073 newList.add(p); 1074 } 1075 } 1076 1077 DirectoryServerPlugin[] newPlugins = 1078 new DirectoryServerPlugin[newList.size()]; 1079 newList.toArray(newPlugins); 1080 return newPlugins; 1081 } 1082 } 1083 1084 /** 1085 * Deregisters the provided internal plugin. 1086 * 1087 * @param plugin 1088 * The internal plugin to deregister from the server. 1089 */ 1090 void deregisterInternalPlugin(InternalDirectoryServerPlugin plugin) 1091 { 1092 pluginLock.lock(); 1093 try 1094 { 1095 deregisterPlugin0(plugin); 1096 plugin.finalizePlugin(); 1097 } 1098 finally 1099 { 1100 pluginLock.unlock(); 1101 } 1102 } 1103 1104 /** 1105 * Deregisters the plugin with the provided configuration entry DN. 1106 * 1107 * @param configEntryDN 1108 * The DN of the configuration entry for the plugin to 1109 * deregister. 1110 */ 1111 private void deregisterPlugin(DN configEntryDN) 1112 { 1113 pluginLock.lock(); 1114 DirectoryServerPlugin<? extends PluginCfg> plugin; 1115 try 1116 { 1117 plugin = registeredPlugins.remove(configEntryDN); 1118 if (plugin != null) 1119 { 1120 deregisterPlugin0(plugin); 1121 plugin.finalizePlugin(); 1122 } 1123 } 1124 finally 1125 { 1126 pluginLock.unlock(); 1127 } 1128 } 1129 1130 /** 1131 * Deregisters the provided plugin. 1132 * 1133 * @param plugin 1134 * The plugin to deregister from the server. 1135 */ 1136 private void deregisterPlugin0( 1137 DirectoryServerPlugin<? extends PluginCfg> plugin) 1138 { 1139 for (PluginType t : plugin.getPluginTypes()) 1140 { 1141 switch (t) 1142 { 1143 case STARTUP: 1144 startupPlugins = removePlugin(startupPlugins, plugin); 1145 break; 1146 case SHUTDOWN: 1147 shutdownPlugins = removePlugin(shutdownPlugins, plugin); 1148 break; 1149 case POST_CONNECT: 1150 postConnectPlugins = removePlugin(postConnectPlugins, plugin); 1151 break; 1152 case POST_DISCONNECT: 1153 postDisconnectPlugins = removePlugin(postDisconnectPlugins, plugin); 1154 break; 1155 case LDIF_IMPORT: 1156 ldifImportPlugins = removePlugin(ldifImportPlugins, plugin); 1157 break; 1158 case LDIF_IMPORT_END: 1159 ldifImportEndPlugins = removePlugin(ldifImportEndPlugins, plugin); 1160 break; 1161 case LDIF_IMPORT_BEGIN: 1162 ldifImportBeginPlugins = 1163 removePlugin(ldifImportBeginPlugins, plugin); 1164 break; 1165 case LDIF_EXPORT: 1166 ldifExportPlugins = removePlugin(ldifExportPlugins, plugin); 1167 break; 1168 case PRE_PARSE_ABANDON: 1169 preParseAbandonPlugins = removePlugin(preParseAbandonPlugins, 1170 plugin); 1171 break; 1172 case PRE_PARSE_ADD: 1173 preParseAddPlugins = removePlugin(preParseAddPlugins, plugin); 1174 break; 1175 case PRE_PARSE_BIND: 1176 preParseBindPlugins = removePlugin(preParseBindPlugins, plugin); 1177 break; 1178 case PRE_PARSE_COMPARE: 1179 preParseComparePlugins = removePlugin(preParseComparePlugins, 1180 plugin); 1181 break; 1182 case PRE_PARSE_DELETE: 1183 preParseDeletePlugins = removePlugin(preParseDeletePlugins, plugin); 1184 break; 1185 case PRE_PARSE_EXTENDED: 1186 preParseExtendedPlugins = removePlugin(preParseExtendedPlugins, 1187 plugin); 1188 break; 1189 case PRE_PARSE_MODIFY: 1190 preParseModifyPlugins = removePlugin(preParseModifyPlugins, plugin); 1191 break; 1192 case PRE_PARSE_MODIFY_DN: 1193 preParseModifyDNPlugins = removePlugin(preParseModifyDNPlugins, 1194 plugin); 1195 break; 1196 case PRE_PARSE_SEARCH: 1197 preParseSearchPlugins = removePlugin(preParseSearchPlugins, plugin); 1198 break; 1199 case PRE_PARSE_UNBIND: 1200 preParseUnbindPlugins = removePlugin(preParseUnbindPlugins, plugin); 1201 break; 1202 case PRE_OPERATION_ADD: 1203 preOperationAddPlugins = removePlugin(preOperationAddPlugins, 1204 plugin); 1205 break; 1206 case PRE_OPERATION_BIND: 1207 preOperationBindPlugins = removePlugin(preOperationBindPlugins, 1208 plugin); 1209 break; 1210 case PRE_OPERATION_COMPARE: 1211 preOperationComparePlugins = 1212 removePlugin(preOperationComparePlugins, plugin); 1213 break; 1214 case PRE_OPERATION_DELETE: 1215 preOperationDeletePlugins = removePlugin(preOperationDeletePlugins, 1216 plugin); 1217 break; 1218 case PRE_OPERATION_EXTENDED: 1219 preOperationExtendedPlugins = 1220 removePlugin(preOperationExtendedPlugins, plugin); 1221 break; 1222 case PRE_OPERATION_MODIFY: 1223 preOperationModifyPlugins = removePlugin(preOperationModifyPlugins, 1224 plugin); 1225 break; 1226 case PRE_OPERATION_MODIFY_DN: 1227 preOperationModifyDNPlugins = 1228 removePlugin(preOperationModifyDNPlugins, plugin); 1229 break; 1230 case PRE_OPERATION_SEARCH: 1231 preOperationSearchPlugins = removePlugin(preOperationSearchPlugins, 1232 plugin); 1233 break; 1234 case POST_OPERATION_ABANDON: 1235 postOperationAbandonPlugins = 1236 removePlugin(postOperationAbandonPlugins, plugin); 1237 break; 1238 case POST_OPERATION_ADD: 1239 postOperationAddPlugins = removePlugin(postOperationAddPlugins, 1240 plugin); 1241 break; 1242 case POST_OPERATION_BIND: 1243 postOperationBindPlugins = removePlugin(postOperationBindPlugins, 1244 plugin); 1245 break; 1246 case POST_OPERATION_COMPARE: 1247 postOperationComparePlugins = 1248 removePlugin(postOperationComparePlugins, plugin); 1249 break; 1250 case POST_OPERATION_DELETE: 1251 postOperationDeletePlugins = 1252 removePlugin(postOperationDeletePlugins, plugin); 1253 break; 1254 case POST_OPERATION_EXTENDED: 1255 postOperationExtendedPlugins = 1256 removePlugin(postOperationExtendedPlugins, plugin); 1257 break; 1258 case POST_OPERATION_MODIFY: 1259 postOperationModifyPlugins = 1260 removePlugin(postOperationModifyPlugins, plugin); 1261 break; 1262 case POST_OPERATION_MODIFY_DN: 1263 postOperationModifyDNPlugins = 1264 removePlugin(postOperationModifyDNPlugins, plugin); 1265 break; 1266 case POST_OPERATION_SEARCH: 1267 postOperationSearchPlugins = 1268 removePlugin(postOperationSearchPlugins, plugin); 1269 break; 1270 case POST_OPERATION_UNBIND: 1271 postOperationUnbindPlugins = 1272 removePlugin(postOperationUnbindPlugins, plugin); 1273 break; 1274 case POST_RESPONSE_ADD: 1275 postResponseAddPlugins = removePlugin(postResponseAddPlugins, 1276 plugin); 1277 break; 1278 case POST_RESPONSE_BIND: 1279 postResponseBindPlugins = removePlugin(postResponseBindPlugins, 1280 plugin); 1281 break; 1282 case POST_RESPONSE_COMPARE: 1283 postResponseComparePlugins = 1284 removePlugin(postResponseComparePlugins, plugin); 1285 break; 1286 case POST_RESPONSE_DELETE: 1287 postResponseDeletePlugins = removePlugin(postResponseDeletePlugins, 1288 plugin); 1289 break; 1290 case POST_RESPONSE_EXTENDED: 1291 postResponseExtendedPlugins = 1292 removePlugin(postResponseExtendedPlugins, plugin); 1293 break; 1294 case POST_RESPONSE_MODIFY: 1295 postResponseModifyPlugins = removePlugin(postResponseModifyPlugins, 1296 plugin); 1297 break; 1298 case POST_RESPONSE_MODIFY_DN: 1299 postResponseModifyDNPlugins = 1300 removePlugin(postResponseModifyDNPlugins, plugin); 1301 break; 1302 case POST_RESPONSE_SEARCH: 1303 postResponseSearchPlugins = removePlugin(postResponseSearchPlugins, 1304 plugin); 1305 break; 1306 case POST_SYNCHRONIZATION_ADD: 1307 postSynchronizationAddPlugins = 1308 removePlugin(postSynchronizationAddPlugins, plugin); 1309 break; 1310 case POST_SYNCHRONIZATION_DELETE: 1311 postSynchronizationDeletePlugins = 1312 removePlugin(postSynchronizationDeletePlugins, plugin); 1313 break; 1314 case POST_SYNCHRONIZATION_MODIFY: 1315 postSynchronizationModifyPlugins = 1316 removePlugin(postSynchronizationModifyPlugins, plugin); 1317 break; 1318 case POST_SYNCHRONIZATION_MODIFY_DN: 1319 postSynchronizationModifyDNPlugins = 1320 removePlugin(postSynchronizationModifyDNPlugins, plugin); 1321 break; 1322 case SEARCH_RESULT_ENTRY: 1323 searchResultEntryPlugins = removePlugin(searchResultEntryPlugins, 1324 plugin); 1325 break; 1326 case SEARCH_RESULT_REFERENCE: 1327 searchResultReferencePlugins = 1328 removePlugin(searchResultReferencePlugins, plugin); 1329 break; 1330 case SUBORDINATE_MODIFY_DN: 1331 subordinateModifyDNPlugins = 1332 removePlugin(subordinateModifyDNPlugins, plugin); 1333 break; 1334 case SUBORDINATE_DELETE: 1335 subordinateDeletePlugins = 1336 removePlugin(subordinateDeletePlugins, plugin); 1337 break; 1338 case INTERMEDIATE_RESPONSE: 1339 intermediateResponsePlugins = 1340 removePlugin(intermediateResponsePlugins, plugin); 1341 break; 1342 default: 1343 } 1344 } 1345 } 1346 1347 /** 1348 * Removes the provided plugin from the given array. The provided array will 1349 * not itself be modified, but rather a new array will be created with one 1350 * fewer element (assuming that the specified plugin was found). 1351 * 1352 * @param pluginArray The array containing the existing set of plugins. 1353 * @param plugin The plugin to be removed from the array. 1354 * 1355 * @return The new array containing the new set of plugins. 1356 */ 1357 private DirectoryServerPlugin[] 1358 removePlugin(DirectoryServerPlugin[] pluginArray, 1359 DirectoryServerPlugin plugin) 1360 { 1361 int slot = -1; 1362 int length = pluginArray.length; 1363 for (int i=0; i < length; i++) 1364 { 1365 if (pluginArray[i].getPluginEntryDN().equals(plugin.getPluginEntryDN())) 1366 { 1367 slot = i; 1368 break; 1369 } 1370 } 1371 1372 if (slot < 0) 1373 { 1374 // The plugin wasn't found in the list, so return the same list. 1375 return pluginArray; 1376 } 1377 1378 // If it was the only element in the array, then return an empty array. 1379 if (length == 0) 1380 { 1381 return new DirectoryServerPlugin[0]; 1382 } 1383 1384 // Create an array that's one element smaller and copy the remaining "good" 1385 // elements into it. 1386 DirectoryServerPlugin[] newPlugins = new DirectoryServerPlugin[length-1]; 1387 if (slot > 0) 1388 { 1389 System.arraycopy(pluginArray, 0, newPlugins, 0, slot); 1390 } 1391 1392 if (slot < length-1) 1393 { 1394 System.arraycopy(pluginArray, slot+1, newPlugins, slot, length-slot-1); 1395 } 1396 1397 return newPlugins; 1398 } 1399 1400 /** 1401 * Invokes the set of startup plugins that have been registered with the 1402 * Directory Server. 1403 * 1404 * @return The result of processing the startup plugins. 1405 */ 1406 public PluginResult.Startup invokeStartupPlugins() 1407 { 1408 PluginResult.Startup result = null; 1409 1410 for (DirectoryServerPlugin p : startupPlugins) 1411 { 1412 try 1413 { 1414 result = p.doStartup(); 1415 } 1416 catch (Exception e) 1417 { 1418 logger.traceException(e); 1419 1420 LocalizableMessage message = ERR_PLUGIN_STARTUP_PLUGIN_EXCEPTION.get( 1421 p.getPluginEntryDN(), stackTraceToSingleLineString(e)); 1422 return PluginResult.Startup.stopStartup(message); 1423 } 1424 1425 if (result == null) 1426 { 1427 LocalizableMessage message = ERR_PLUGIN_STARTUP_PLUGIN_RETURNED_NULL.get(p.getPluginEntryDN()); 1428 logger.error(message); 1429 return PluginResult.Startup.stopStartup(message); 1430 } 1431 else if (! result.continueProcessing()) 1432 { 1433 logger.error(ERR_PLUGIN_STARTUP_PLUGIN_FAIL_ABORT, 1434 p.getPluginEntryDN(), 1435 result.getErrorMessage(), 1436 result.getErrorMessage().ordinal()); 1437 return result; 1438 } 1439 } 1440 1441 if (result == null) 1442 { 1443 // This should only happen if there were no startup plugins registered, 1444 // which is fine. 1445 result = PluginResult.Startup.continueStartup(); 1446 } 1447 1448 return result; 1449 } 1450 1451 /** 1452 * Invokes the set of shutdown plugins that have been configured in the 1453 * Directory Server. 1454 * 1455 * @param reason The human-readable reason for the shutdown. 1456 */ 1457 public void invokeShutdownPlugins(LocalizableMessage reason) 1458 { 1459 for (DirectoryServerPlugin p : shutdownPlugins) 1460 { 1461 try 1462 { 1463 p.doShutdown(reason); 1464 } 1465 catch (Exception e) 1466 { 1467 logger.traceException(e); 1468 logger.error(ERR_PLUGIN_SHUTDOWN_PLUGIN_EXCEPTION, p.getPluginEntryDN(), stackTraceToSingleLineString(e)); 1469 } 1470 } 1471 } 1472 1473 /** 1474 * Invokes the set of post-connect plugins that have been configured in the 1475 * Directory Server. 1476 * 1477 * @param clientConnection The client connection that has been established. 1478 * 1479 * @return The result of processing the post-connect plugins. 1480 */ 1481 public PluginResult.PostConnect invokePostConnectPlugins(ClientConnection 1482 clientConnection) 1483 { 1484 PluginResult.PostConnect result = null; 1485 1486 for (DirectoryServerPlugin p : postConnectPlugins) 1487 { 1488 try 1489 { 1490 result = p.doPostConnect(clientConnection); 1491 } 1492 catch (Exception e) 1493 { 1494 logger.traceException(e); 1495 1496 LocalizableMessage message = ERR_PLUGIN_POST_CONNECT_PLUGIN_EXCEPTION. 1497 get(p.getPluginEntryDN(), 1498 clientConnection.getConnectionID(), 1499 clientConnection.getClientAddress(), 1500 stackTraceToSingleLineString(e)); 1501 logger.error(message); 1502 1503 return PluginResult.PostConnect.disconnectClient( 1504 DisconnectReason.SERVER_ERROR, true, message); 1505 } 1506 1507 if (result == null) 1508 { 1509 LocalizableMessage message = ERR_PLUGIN_POST_CONNECT_PLUGIN_RETURNED_NULL. 1510 get(p.getPluginEntryDN(), clientConnection.getConnectionID(), clientConnection.getClientAddress()); 1511 logger.error(message); 1512 1513 return PluginResult.PostConnect.disconnectClient( 1514 DisconnectReason.SERVER_ERROR, true, message); 1515 } 1516 else if (!result.continuePluginProcessing()) 1517 { 1518 return result; 1519 } 1520 } 1521 1522 if (result == null) 1523 { 1524 // This should only happen if there were no post-connect plugins 1525 // registered, which is fine. 1526 result = PluginResult.PostConnect.continueConnectProcessing(); 1527 } 1528 1529 return result; 1530 } 1531 1532 /** 1533 * Invokes the set of post-disconnect plugins that have been configured in the 1534 * Directory Server. 1535 * 1536 * @param clientConnection The client connection that has been closed. 1537 * @param disconnectReason The general reason that the connection was 1538 * closed. 1539 * @param message A human-readable message that may provide 1540 * additional information about the closure. 1541 * 1542 * @return The result of processing the post-connect plugins. 1543 */ 1544 public PluginResult.PostDisconnect invokePostDisconnectPlugins( 1545 ClientConnection clientConnection, 1546 DisconnectReason disconnectReason, 1547 LocalizableMessage message) 1548 { 1549 PluginResult.PostDisconnect result = null; 1550 1551 for (DirectoryServerPlugin p : postDisconnectPlugins) 1552 { 1553 try 1554 { 1555 result = p.doPostDisconnect(clientConnection, disconnectReason, 1556 message); 1557 } 1558 catch (Exception e) 1559 { 1560 logger.traceException(e); 1561 logger.error(ERR_PLUGIN_POST_DISCONNECT_PLUGIN_EXCEPTION, 1562 p.getPluginEntryDN(), 1563 clientConnection.getConnectionID(), 1564 clientConnection.getClientAddress(), 1565 stackTraceToSingleLineString(e)); 1566 } 1567 1568 if (result == null) 1569 { 1570 logger.error(ERR_PLUGIN_POST_DISCONNECT_PLUGIN_RETURNED_NULL, 1571 p.getPluginEntryDN(), 1572 clientConnection.getConnectionID(), 1573 clientConnection.getClientAddress()); 1574 } 1575 else if (! result.continuePluginProcessing()) 1576 { 1577 return result; 1578 } 1579 } 1580 1581 if (result == null) 1582 { 1583 // This should only happen if there were no post-disconnect plugins 1584 // registered, which is fine. 1585 result = PluginResult.PostDisconnect.continueDisconnectProcessing(); 1586 } 1587 1588 return result; 1589 } 1590 1591 /** 1592 * Invokes the set of LDIF import plugins that have been configured in the 1593 * Directory Server. 1594 * 1595 * @param importConfig The LDIF import configuration used to read the 1596 * associated entry. 1597 * @param entry The entry that has been read from LDIF. 1598 * 1599 * @return The result of processing the LDIF import plugins. 1600 */ 1601 public PluginResult.ImportLDIF invokeLDIFImportPlugins( 1602 LDIFImportConfig importConfig, Entry entry) 1603 { 1604 PluginResult.ImportLDIF result = null; 1605 1606 for (DirectoryServerPlugin p : ldifImportPlugins) 1607 { 1608 try 1609 { 1610 result = p.doLDIFImport(importConfig, entry); 1611 } 1612 catch (Exception e) 1613 { 1614 logger.traceException(e); 1615 1616 LocalizableMessage message = ERR_PLUGIN_LDIF_IMPORT_PLUGIN_EXCEPTION.get( 1617 p.getPluginEntryDN(), entry.getName(), stackTraceToSingleLineString(e)); 1618 logger.error(message); 1619 1620 return PluginResult.ImportLDIF.stopEntryProcessing(message); 1621 } 1622 1623 if (result == null) 1624 { 1625 LocalizableMessage message = ERR_PLUGIN_LDIF_IMPORT_PLUGIN_RETURNED_NULL. 1626 get(p.getPluginEntryDN(), entry.getName()); 1627 logger.error(message); 1628 1629 return PluginResult.ImportLDIF.stopEntryProcessing(message); 1630 } 1631 else if (! result.continuePluginProcessing()) 1632 { 1633 return result; 1634 } 1635 } 1636 1637 if (result == null) 1638 { 1639 // This should only happen if there were no LDIF import plugins 1640 // registered, which is fine. 1641 result = PluginResult.ImportLDIF.continueEntryProcessing(); 1642 } 1643 1644 return result; 1645 } 1646 1647 /** 1648 * Invokes the LDIF import session finalization of LDIF import plugins that 1649 * have been configured in the Directory Server. 1650 * 1651 * @param importConfig The LDIF import configuration used for the LDIF 1652 * import session. 1653 */ 1654 public void invokeLDIFImportEndPlugins( 1655 LDIFImportConfig importConfig) 1656 { 1657 for (DirectoryServerPlugin p : ldifImportEndPlugins) 1658 { 1659 p.doLDIFImportEnd(importConfig); 1660 } 1661 } 1662 1663 /** 1664 * Invokes the LDIF import session initialization of LDIF import plugins that 1665 * have been configured in the Directory Server. 1666 * 1667 * @param importConfig The LDIF import configuration used for the LDIF 1668 * import session. 1669 */ 1670 public void invokeLDIFImportBeginPlugins( 1671 LDIFImportConfig importConfig) 1672 { 1673 for (DirectoryServerPlugin p : ldifImportBeginPlugins) 1674 { 1675 p.doLDIFImportBegin(importConfig); 1676 } 1677 } 1678 1679 /** 1680 * Invokes the set of LDIF export plugins that have been configured in the 1681 * Directory Server. 1682 * 1683 * @param exportConfig The LDIF export configuration used to read the 1684 * associated entry. 1685 * @param entry The entry that has been read from LDIF. 1686 * 1687 * @return The result of processing the LDIF export plugins. 1688 */ 1689 public PluginResult.ImportLDIF invokeLDIFExportPlugins( 1690 LDIFExportConfig exportConfig, Entry entry) 1691 { 1692 PluginResult.ImportLDIF result = null; 1693 1694 for (DirectoryServerPlugin p : ldifExportPlugins) 1695 { 1696 try 1697 { 1698 result = p.doLDIFExport(exportConfig, entry); 1699 } 1700 catch (Exception e) 1701 { 1702 logger.traceException(e); 1703 1704 LocalizableMessage message = ERR_PLUGIN_LDIF_EXPORT_PLUGIN_EXCEPTION. 1705 get(p.getPluginEntryDN(), 1706 entry.getName(), 1707 stackTraceToSingleLineString(e)); 1708 logger.error(message); 1709 1710 return PluginResult.ImportLDIF.stopEntryProcessing(message); 1711 } 1712 1713 if (result == null) 1714 { 1715 LocalizableMessage message = ERR_PLUGIN_LDIF_EXPORT_PLUGIN_RETURNED_NULL. 1716 get(p.getPluginEntryDN(), entry.getName()); 1717 logger.error(message); 1718 1719 return PluginResult.ImportLDIF.stopEntryProcessing(message); 1720 } 1721 else if (! result.continuePluginProcessing()) 1722 { 1723 return result; 1724 } 1725 } 1726 1727 if (result == null) 1728 { 1729 // This should only happen if there were no LDIF export plugins 1730 // registered, which is fine. 1731 result = PluginResult.ImportLDIF.continueEntryProcessing(); 1732 } 1733 1734 return result; 1735 } 1736 1737 /** 1738 * Invokes the set of pre-parse abandon plugins that have been configured in 1739 * the Directory Server. 1740 * 1741 * @param abandonOperation The abandon operation for which to invoke the 1742 * pre-parse plugins. 1743 * 1744 * @return The result of processing the pre-parse abandon plugins. 1745 */ 1746 public PluginResult.PreParse invokePreParseAbandonPlugins( 1747 PreParseAbandonOperation abandonOperation) 1748 { 1749 PluginResult.PreParse result = null; 1750 1751 for (DirectoryServerPlugin p : preParseAbandonPlugins) 1752 { 1753 if (isInternalOperation(abandonOperation, p)) 1754 { 1755 continue; 1756 } 1757 1758 try 1759 { 1760 result = p.doPreParse(abandonOperation); 1761 } 1762 catch (Exception e) 1763 { 1764 return handlePreParseException(e, abandonOperation, p); 1765 } 1766 1767 if (result == null) 1768 { 1769 return handlePreParseResult(abandonOperation, p); 1770 } 1771 else if (!result.continuePluginProcessing()) 1772 { 1773 return result; 1774 } 1775 } 1776 1777 if (result == null) 1778 { 1779 // This should only happen if there were no pre-parse abandon plugins 1780 // registered, which is fine. 1781 result = PluginResult.PreParse.continueOperationProcessing(); 1782 } 1783 1784 return result; 1785 } 1786 1787 private PluginResult.PreParse handlePreParseException( 1788 Exception e, PreParseOperation operation, DirectoryServerPlugin plugin) 1789 { 1790 logger.traceException(e); 1791 1792 LocalizableMessage message = 1793 ERR_PLUGIN_PRE_PARSE_PLUGIN_EXCEPTION.get(operation.getOperationType() 1794 .getOperationName(), plugin.getPluginEntryDN(), 1795 operation.getConnectionID(), operation.getOperationID(), 1796 stackTraceToSingleLineString(e)); 1797 logger.error(message); 1798 1799 return PluginResult.PreParse.stopProcessing(DirectoryServer 1800 .getServerErrorResultCode(), message); 1801 } 1802 1803 private PluginResult.PreParse handlePreParseResult( 1804 PreParseOperation operation, DirectoryServerPlugin plugin) 1805 { 1806 LocalizableMessage message = 1807 ERR_PLUGIN_PRE_PARSE_PLUGIN_RETURNED_NULL.get(operation 1808 .getOperationType().getOperationName(), plugin 1809 .getPluginEntryDN(), operation.getConnectionID(), operation.getOperationID()); 1810 logger.error(message); 1811 1812 return PluginResult.PreParse.stopProcessing(DirectoryServer 1813 .getServerErrorResultCode(), message); 1814 } 1815 1816 /** 1817 * Invokes the set of pre-parse add plugins that have been configured in the 1818 * Directory Server. 1819 * 1820 * @param addOperation The add operation for which to invoke the pre-parse 1821 * plugins. 1822 * 1823 * @return The result of processing the pre-parse add plugins. 1824 * 1825 * @throws CanceledOperationException if the operation should be canceled. 1826 */ 1827 public PluginResult.PreParse invokePreParseAddPlugins( 1828 PreParseAddOperation addOperation) 1829 throws CanceledOperationException { 1830 PluginResult.PreParse result = null; 1831 1832 for (DirectoryServerPlugin p : preParseAddPlugins) 1833 { 1834 if (isInternalOperation(addOperation, p)) 1835 { 1836 continue; 1837 } 1838 1839 try 1840 { 1841 result = p.doPreParse(addOperation); 1842 } 1843 catch (CanceledOperationException coe) 1844 { 1845 throw coe; 1846 } 1847 catch (Exception e) 1848 { 1849 return handlePreParseException(e, addOperation, p); 1850 } 1851 1852 if (result == null) 1853 { 1854 return handlePreParseResult(addOperation, p); 1855 } 1856 else if (!result.continuePluginProcessing()) 1857 { 1858 return result; 1859 } 1860 } 1861 1862 if (result == null) 1863 { 1864 // This should only happen if there were no pre-parse add plugins 1865 // registered, which is fine. 1866 result = PluginResult.PreParse.continueOperationProcessing(); 1867 } 1868 1869 return result; 1870 } 1871 1872 /** 1873 * Invokes the set of pre-parse bind plugins that have been configured in 1874 * the Directory Server. 1875 * 1876 * @param bindOperation The bind operation for which to invoke the pre-parse 1877 * plugins. 1878 * 1879 * @return The result of processing the pre-parse bind plugins. 1880 */ 1881 public PluginResult.PreParse invokePreParseBindPlugins( 1882 PreParseBindOperation bindOperation) 1883 { 1884 PluginResult.PreParse result = null; 1885 1886 for (DirectoryServerPlugin p : preParseBindPlugins) 1887 { 1888 if (isInternalOperation(bindOperation, p)) 1889 { 1890 continue; 1891 } 1892 1893 try 1894 { 1895 result = p.doPreParse(bindOperation); 1896 } 1897 catch (Exception e) 1898 { 1899 return handlePreParseException(e, bindOperation, p); 1900 } 1901 1902 if (result == null) 1903 { 1904 return handlePreParseResult(bindOperation, p); 1905 } 1906 else if (!result.continuePluginProcessing()) 1907 { 1908 return result; 1909 } 1910 } 1911 1912 if (result == null) 1913 { 1914 // This should only happen if there were no pre-parse bind plugins 1915 // registered, which is fine. 1916 result = PluginResult.PreParse.continueOperationProcessing(); 1917 } 1918 1919 return result; 1920 } 1921 1922 /** 1923 * Invokes the set of pre-parse compare plugins that have been configured in 1924 * the Directory Server. 1925 * 1926 * @param compareOperation The compare operation for which to invoke the 1927 * pre-parse plugins. 1928 * 1929 * @return The result of processing the pre-parse compare plugins. 1930 * 1931 * @throws CanceledOperationException if the operation should be canceled. 1932 */ 1933 public PluginResult.PreParse invokePreParseComparePlugins( 1934 PreParseCompareOperation compareOperation) 1935 throws CanceledOperationException { 1936 PluginResult.PreParse result = null; 1937 1938 for (DirectoryServerPlugin p : preParseComparePlugins) 1939 { 1940 if (isInternalOperation(compareOperation, p)) 1941 { 1942 continue; 1943 } 1944 1945 try 1946 { 1947 result = p.doPreParse(compareOperation); 1948 } 1949 catch (CanceledOperationException coe) 1950 { 1951 throw coe; 1952 } 1953 catch (Exception e) 1954 { 1955 return handlePreParseException(e, compareOperation, p); 1956 } 1957 1958 if (result == null) 1959 { 1960 return handlePreParseResult(compareOperation, p); 1961 } 1962 else if (!result.continuePluginProcessing()) 1963 { 1964 return result; 1965 } 1966 } 1967 1968 if (result == null) 1969 { 1970 // This should only happen if there were no pre-parse compare plugins 1971 // registered, which is fine. 1972 result = PluginResult.PreParse.continueOperationProcessing(); 1973 } 1974 1975 return result; 1976 } 1977 1978 /** 1979 * Invokes the set of pre-parse delete plugins that have been configured in 1980 * the Directory Server. 1981 * 1982 * @param deleteOperation The delete operation for which to invoke the 1983 * pre-parse plugins. 1984 * 1985 * @return The result of processing the pre-parse delete plugins. 1986 * 1987 * @throws CanceledOperationException if the operation should be canceled. 1988 */ 1989 public PluginResult.PreParse invokePreParseDeletePlugins( 1990 PreParseDeleteOperation deleteOperation) 1991 throws CanceledOperationException { 1992 PluginResult.PreParse result = null; 1993 1994 for (DirectoryServerPlugin p : preParseDeletePlugins) 1995 { 1996 if (isInternalOperation(deleteOperation, p)) 1997 { 1998 continue; 1999 } 2000 2001 try 2002 { 2003 result = p.doPreParse(deleteOperation); 2004 } 2005 catch (CanceledOperationException coe) 2006 { 2007 throw coe; 2008 } 2009 catch (Exception e) 2010 { 2011 return handlePreParseException(e, deleteOperation, p); 2012 } 2013 2014 if (result == null) 2015 { 2016 return handlePreParseResult(deleteOperation, p); 2017 } 2018 else if (!result.continuePluginProcessing()) 2019 { 2020 return result; 2021 } 2022 } 2023 2024 if (result == null) 2025 { 2026 // This should only happen if there were no pre-parse delete plugins 2027 // registered, which is fine. 2028 result = PluginResult.PreParse.continueOperationProcessing(); 2029 } 2030 2031 return result; 2032 } 2033 2034 /** 2035 * Invokes the set of pre-parse extended plugins that have been configured in 2036 * the Directory Server. 2037 * 2038 * @param extendedOperation The extended operation for which to invoke the 2039 * pre-parse plugins. 2040 * 2041 * @return The result of processing the pre-parse extended plugins. 2042 * 2043 * @throws CanceledOperationException if the operation should be canceled. 2044 */ 2045 public PluginResult.PreParse invokePreParseExtendedPlugins( 2046 PreParseExtendedOperation extendedOperation) 2047 throws CanceledOperationException { 2048 PluginResult.PreParse result = null; 2049 2050 for (DirectoryServerPlugin p : preParseExtendedPlugins) 2051 { 2052 if (isInternalOperation(extendedOperation, p)) 2053 { 2054 continue; 2055 } 2056 2057 try 2058 { 2059 result = p.doPreParse(extendedOperation); 2060 } 2061 catch (CanceledOperationException coe) 2062 { 2063 throw coe; 2064 } 2065 catch (Exception e) 2066 { 2067 return handlePreParseException(e, extendedOperation, p); 2068 } 2069 2070 if (result == null) 2071 { 2072 return handlePreParseResult(extendedOperation, p); 2073 } 2074 else if (!result.continuePluginProcessing()) 2075 { 2076 return result; 2077 } 2078 } 2079 2080 if (result == null) 2081 { 2082 // This should only happen if there were no pre-parse extended plugins 2083 // registered, which is fine. 2084 result = PluginResult.PreParse.continueOperationProcessing(); 2085 } 2086 2087 return result; 2088 } 2089 2090 /** 2091 * Invokes the set of pre-parse modify plugins that have been configured in 2092 * the Directory Server. 2093 * 2094 * @param modifyOperation The modify operation for which to invoke the 2095 * pre-parse plugins. 2096 * 2097 * @return The result of processing the pre-parse modify plugins. 2098 * 2099 * @throws CanceledOperationException if the operation should be canceled. 2100 */ 2101 public PluginResult.PreParse invokePreParseModifyPlugins( 2102 PreParseModifyOperation modifyOperation) 2103 throws CanceledOperationException { 2104 PluginResult.PreParse result = null; 2105 2106 for (DirectoryServerPlugin p : preParseModifyPlugins) 2107 { 2108 if (isInternalOperation(modifyOperation, p)) 2109 { 2110 continue; 2111 } 2112 2113 try 2114 { 2115 result = p.doPreParse(modifyOperation); 2116 } 2117 catch (CanceledOperationException coe) 2118 { 2119 throw coe; 2120 } 2121 catch (Exception e) 2122 { 2123 return handlePreParseException(e, modifyOperation, p); 2124 } 2125 2126 if (result == null) 2127 { 2128 return handlePreParseResult(modifyOperation, p); 2129 } 2130 else if (!result.continuePluginProcessing()) 2131 { 2132 return result; 2133 } 2134 } 2135 2136 if (result == null) 2137 { 2138 // This should only happen if there were no pre-parse modify plugins 2139 // registered, which is fine. 2140 result = PluginResult.PreParse.continueOperationProcessing(); 2141 } 2142 2143 return result; 2144 } 2145 2146 /** 2147 * Invokes the set of pre-parse modify DN plugins that have been configured in 2148 * the Directory Server. 2149 * 2150 * @param modifyDNOperation The modify DN operation for which to invoke the 2151 * pre-parse plugins. 2152 * 2153 * @return The result of processing the pre-parse modify DN plugins. 2154 * 2155 * @throws CanceledOperationException if the operation should be canceled. 2156 */ 2157 public PluginResult.PreParse invokePreParseModifyDNPlugins( 2158 PreParseModifyDNOperation modifyDNOperation) 2159 throws CanceledOperationException { 2160 PluginResult.PreParse result = null; 2161 2162 for (DirectoryServerPlugin p : preParseModifyDNPlugins) 2163 { 2164 if (isInternalOperation(modifyDNOperation, p)) 2165 { 2166 continue; 2167 } 2168 2169 try 2170 { 2171 result = p.doPreParse(modifyDNOperation); 2172 } 2173 catch (CanceledOperationException coe) 2174 { 2175 throw coe; 2176 } 2177 catch (Exception e) 2178 { 2179 return handlePreParseException(e, modifyDNOperation, p); 2180 } 2181 2182 if (result == null) 2183 { 2184 return handlePreParseResult(modifyDNOperation, p); 2185 } 2186 else if (!result.continuePluginProcessing()) 2187 { 2188 return result; 2189 } 2190 } 2191 2192 if (result == null) 2193 { 2194 // This should only happen if there were no pre-parse modify DN plugins 2195 // registered, which is fine. 2196 result = PluginResult.PreParse.continueOperationProcessing(); 2197 } 2198 2199 return result; 2200 } 2201 2202 /** 2203 * Invokes the set of pre-parse search plugins that have been configured in 2204 * the Directory Server. 2205 * 2206 * @param searchOperation The search operation for which to invoke the 2207 * pre-parse plugins. 2208 * 2209 * @return The result of processing the pre-parse search plugins. 2210 * 2211 * @throws CanceledOperationException if the operation should be canceled. 2212 */ 2213 public PluginResult.PreParse invokePreParseSearchPlugins( 2214 PreParseSearchOperation searchOperation) 2215 throws CanceledOperationException { 2216 PluginResult.PreParse result = null; 2217 2218 for (DirectoryServerPlugin p : preParseSearchPlugins) 2219 { 2220 if (isInternalOperation(searchOperation, p)) 2221 { 2222 continue; 2223 } 2224 2225 try 2226 { 2227 result = p.doPreParse(searchOperation); 2228 } 2229 catch (CanceledOperationException coe) 2230 { 2231 throw coe; 2232 } 2233 catch (Exception e) 2234 { 2235 return handlePreParseException(e, searchOperation, p); 2236 } 2237 2238 if (result == null) 2239 { 2240 return handlePreParseResult(searchOperation, p); 2241 } 2242 else if (!result.continuePluginProcessing()) 2243 { 2244 return result; 2245 } 2246 } 2247 2248 if (result == null) 2249 { 2250 // This should only happen if there were no pre-parse search plugins 2251 // registered, which is fine. 2252 result = PluginResult.PreParse.continueOperationProcessing(); 2253 } 2254 2255 return result; 2256 } 2257 2258 /** 2259 * Invokes the set of pre-parse unbind plugins that have been configured in 2260 * the Directory Server. 2261 * 2262 * @param unbindOperation The unbind operation for which to invoke the 2263 * pre-parse plugins. 2264 * 2265 * @return The result of processing the pre-parse unbind plugins. 2266 */ 2267 public PluginResult.PreParse invokePreParseUnbindPlugins( 2268 PreParseUnbindOperation unbindOperation) 2269 { 2270 PluginResult.PreParse result = null; 2271 2272 for (DirectoryServerPlugin p : preParseUnbindPlugins) 2273 { 2274 if (isInternalOperation(unbindOperation, p)) 2275 { 2276 continue; 2277 } 2278 2279 try 2280 { 2281 result = p.doPreParse(unbindOperation); 2282 } 2283 catch (Exception e) 2284 { 2285 return handlePreParseException(e, unbindOperation, p); 2286 } 2287 2288 if (result == null) 2289 { 2290 return handlePreParseResult(unbindOperation, p); 2291 } 2292 else if (!result.continuePluginProcessing()) 2293 { 2294 return result; 2295 } 2296 } 2297 2298 if (result == null) 2299 { 2300 // This should only happen if there were no pre-parse unbind plugins 2301 // registered, which is fine. 2302 result = PluginResult.PreParse.continueOperationProcessing(); 2303 } 2304 2305 return result; 2306 } 2307 2308 /** 2309 * Invokes the set of pre-operation add plugins that have been configured in 2310 * the Directory Server. 2311 * 2312 * @param addOperation The add operation for which to invoke the 2313 * pre-operation plugins. 2314 * 2315 * @return The result of processing the pre-operation add plugins. 2316 * 2317 * @throws CanceledOperationException if the operation should be canceled. 2318 */ 2319 public PluginResult.PreOperation invokePreOperationAddPlugins( 2320 PreOperationAddOperation addOperation) 2321 throws CanceledOperationException { 2322 PluginResult.PreOperation result = null; 2323 2324 for (int i = 0; i < preOperationAddPlugins.length; i++) 2325 { 2326 DirectoryServerPlugin p = preOperationAddPlugins[i]; 2327 if (isInternalOperation(addOperation, p)) 2328 { 2329 continue; 2330 } 2331 2332 try 2333 { 2334 result = p.doPreOperation(addOperation); 2335 } 2336 catch (CanceledOperationException coe) 2337 { 2338 throw coe; 2339 } 2340 catch (Exception e) 2341 { 2342 return handlePreOperationException(e, i, preOperationAddPlugins, 2343 addOperation, p); 2344 } 2345 2346 if (result == null) 2347 { 2348 return handlePreOperationResult(addOperation, i, preOperationAddPlugins, 2349 p); 2350 } 2351 else if (!result.continuePluginProcessing()) 2352 { 2353 registerSkippedPreOperationPlugins(i, preOperationAddPlugins, 2354 addOperation); 2355 return result; 2356 } 2357 } 2358 2359 if (result == null) 2360 { 2361 // This should only happen if there were no pre-operation add plugins 2362 // registered, which is fine. 2363 result = PluginResult.PreOperation.continueOperationProcessing(); 2364 } 2365 2366 return result; 2367 } 2368 2369 /** 2370 * Invokes the set of pre-operation bind plugins that have been configured in 2371 * the Directory Server. 2372 * 2373 * @param bindOperation The bind operation for which to invoke the 2374 * pre-operation plugins. 2375 * 2376 * @return The result of processing the pre-operation bind plugins. 2377 */ 2378 public PluginResult.PreOperation invokePreOperationBindPlugins( 2379 PreOperationBindOperation bindOperation) 2380 { 2381 PluginResult.PreOperation result = null; 2382 2383 for (int i = 0; i < preOperationBindPlugins.length; i++) 2384 { 2385 DirectoryServerPlugin p = preOperationBindPlugins[i]; 2386 if (isInternalOperation(bindOperation, p)) 2387 { 2388 continue; 2389 } 2390 2391 try 2392 { 2393 result = p.doPreOperation(bindOperation); 2394 } 2395 catch (Exception e) 2396 { 2397 return handlePreOperationException(e, i, preOperationBindPlugins, 2398 bindOperation, p); 2399 } 2400 2401 if (result == null) 2402 { 2403 return handlePreOperationResult(bindOperation, i, 2404 preOperationBindPlugins, p); 2405 } 2406 else if (!result.continuePluginProcessing()) 2407 { 2408 registerSkippedPreOperationPlugins(i, preOperationBindPlugins, 2409 bindOperation); 2410 2411 return result; 2412 } 2413 } 2414 2415 if (result == null) 2416 { 2417 // This should only happen if there were no pre-operation add plugins 2418 // registered, which is fine. 2419 result = PluginResult.PreOperation.continueOperationProcessing(); 2420 } 2421 2422 return result; 2423 } 2424 2425 /** 2426 * Invokes the set of pre-operation compare plugins that have been configured 2427 * in the Directory Server. 2428 * 2429 * @param compareOperation The compare operation for which to invoke the 2430 * pre-operation plugins. 2431 * 2432 * @return The result of processing the pre-operation compare plugins. 2433 * 2434 * @throws CanceledOperationException if the operation should be canceled. 2435 */ 2436 public PluginResult.PreOperation invokePreOperationComparePlugins( 2437 PreOperationCompareOperation compareOperation) 2438 throws CanceledOperationException { 2439 PluginResult.PreOperation result = null; 2440 2441 for (int i = 0; i < preOperationComparePlugins.length; i++) 2442 { 2443 DirectoryServerPlugin p = preOperationComparePlugins[i]; 2444 if (isInternalOperation(compareOperation, p)) 2445 { 2446 continue; 2447 } 2448 2449 try 2450 { 2451 result = p.doPreOperation(compareOperation); 2452 } 2453 catch (CanceledOperationException coe) 2454 { 2455 throw coe; 2456 } 2457 catch (Exception e) 2458 { 2459 return handlePreOperationException(e, i, preOperationComparePlugins, 2460 compareOperation, p); 2461 } 2462 2463 if (result == null) 2464 { 2465 return handlePreOperationResult(compareOperation, i, 2466 preOperationComparePlugins, p); 2467 } 2468 else if (!result.continuePluginProcessing()) 2469 { 2470 return result; 2471 } 2472 } 2473 2474 if (result == null) 2475 { 2476 // This should only happen if there were no pre-operation add plugins 2477 // registered, which is fine. 2478 result = PluginResult.PreOperation.continueOperationProcessing(); 2479 } 2480 2481 return result; 2482 } 2483 2484 /** 2485 * Invokes the set of pre-operation delete plugins that have been configured 2486 * in the Directory Server. 2487 * 2488 * @param deleteOperation The delete operation for which to invoke the 2489 * pre-operation plugins. 2490 * 2491 * @return The result of processing the pre-operation delete plugins. 2492 * 2493 * @throws CanceledOperationException if the operation should be canceled. 2494 */ 2495 public PluginResult.PreOperation invokePreOperationDeletePlugins( 2496 PreOperationDeleteOperation deleteOperation) 2497 throws CanceledOperationException { 2498 PluginResult.PreOperation result = null; 2499 2500 for (int i = 0; i < preOperationDeletePlugins.length; i++) 2501 { 2502 DirectoryServerPlugin p = preOperationDeletePlugins[i]; 2503 if (isInternalOperation(deleteOperation, p)) 2504 { 2505 continue; 2506 } 2507 2508 try 2509 { 2510 result = p.doPreOperation(deleteOperation); 2511 } 2512 catch (CanceledOperationException coe) 2513 { 2514 throw coe; 2515 } 2516 catch (Exception e) 2517 { 2518 return handlePreOperationException(e, i, preOperationDeletePlugins, 2519 deleteOperation, p); 2520 } 2521 2522 if (result == null) 2523 { 2524 return handlePreOperationResult(deleteOperation, i, 2525 preOperationDeletePlugins, p); 2526 } 2527 else if (!result.continuePluginProcessing()) 2528 { 2529 registerSkippedPreOperationPlugins(i, preOperationDeletePlugins, 2530 deleteOperation); 2531 2532 return result; 2533 } 2534 } 2535 2536 if (result == null) 2537 { 2538 // This should only happen if there were no pre-operation add plugins 2539 // registered, which is fine. 2540 result = PluginResult.PreOperation.continueOperationProcessing(); 2541 } 2542 2543 return result; 2544 } 2545 2546 private PluginResult.PreOperation handlePreOperationException(Exception e, 2547 int i, DirectoryServerPlugin[] plugins, PreOperationOperation operation, 2548 DirectoryServerPlugin plugin) 2549 { 2550 logger.traceException(e); 2551 2552 LocalizableMessage message = 2553 ERR_PLUGIN_PRE_OPERATION_PLUGIN_EXCEPTION.get(operation 2554 .getOperationType().getOperationName(), plugin 2555 .getPluginEntryDN(), operation.getConnectionID(), operation 2556 .getOperationID(), stackTraceToSingleLineString(e)); 2557 logger.error(message); 2558 2559 registerSkippedPreOperationPlugins(i, plugins, operation); 2560 2561 return PluginResult.PreOperation.stopProcessing(DirectoryServer 2562 .getServerErrorResultCode(), message); 2563 } 2564 2565 private PluginResult.PreOperation handlePreOperationResult( 2566 PreOperationOperation operation, int i, DirectoryServerPlugin[] plugins, 2567 DirectoryServerPlugin plugin) 2568 { 2569 LocalizableMessage message = 2570 ERR_PLUGIN_PRE_OPERATION_PLUGIN_RETURNED_NULL.get(operation 2571 .getOperationType().getOperationName(), plugin 2572 .getPluginEntryDN(), operation.getConnectionID(), operation 2573 .getOperationID()); 2574 logger.error(message); 2575 2576 registerSkippedPreOperationPlugins(i, plugins, operation); 2577 2578 return PluginResult.PreOperation.stopProcessing(DirectoryServer 2579 .getServerErrorResultCode(), message); 2580 } 2581 2582 /** 2583 * Invokes the set of pre-operation extended plugins that have been configured 2584 * in the Directory Server. 2585 * 2586 * @param extendedOperation The extended operation for which to invoke the 2587 * pre-operation plugins. 2588 * 2589 * @return The result of processing the pre-operation extended plugins. 2590 * 2591 * @throws CanceledOperationException if the operation should be canceled. 2592 */ 2593 public PluginResult.PreOperation invokePreOperationExtendedPlugins( 2594 PreOperationExtendedOperation extendedOperation) 2595 throws CanceledOperationException { 2596 PluginResult.PreOperation result = null; 2597 2598 for (int i = 0; i < preOperationExtendedPlugins.length; i++) 2599 { 2600 DirectoryServerPlugin p = preOperationExtendedPlugins[i]; 2601 if (isInternalOperation(extendedOperation, p)) 2602 { 2603 registerSkippedPreOperationPlugin(p, extendedOperation); 2604 continue; 2605 } 2606 2607 try 2608 { 2609 result = p.doPreOperation(extendedOperation); 2610 } 2611 catch (CanceledOperationException coe) 2612 { 2613 throw coe; 2614 } 2615 catch (Exception e) 2616 { 2617 return handlePreOperationException(e, i, preOperationExtendedPlugins, 2618 extendedOperation, p); 2619 } 2620 2621 if (result == null) 2622 { 2623 return handlePreOperationResult(extendedOperation, i, 2624 preOperationExtendedPlugins, p); 2625 } 2626 else if (!result.continuePluginProcessing()) 2627 { 2628 registerSkippedPreOperationPlugins(i, preOperationExtendedPlugins, 2629 extendedOperation); 2630 2631 return result; 2632 } 2633 } 2634 2635 if (result == null) 2636 { 2637 // This should only happen if there were no pre-operation add plugins 2638 // registered, which is fine. 2639 result = PluginResult.PreOperation.continueOperationProcessing(); 2640 } 2641 2642 return result; 2643 } 2644 2645 /** 2646 * Invokes the set of pre-operation modify plugins that have been configured 2647 * in the Directory Server. 2648 * 2649 * @param modifyOperation The modify operation for which to invoke the 2650 * pre-operation plugins. 2651 * 2652 * @return The result of processing the pre-operation modify plugins. 2653 * 2654 * @throws CanceledOperationException if the operation should be canceled. 2655 */ 2656 public PluginResult.PreOperation invokePreOperationModifyPlugins( 2657 PreOperationModifyOperation modifyOperation) 2658 throws CanceledOperationException { 2659 PluginResult.PreOperation result = null; 2660 2661 for (int i = 0; i < preOperationModifyPlugins.length; i++) 2662 { 2663 DirectoryServerPlugin p = preOperationModifyPlugins[i]; 2664 if (isInternalOperation(modifyOperation, p)) 2665 { 2666 continue; 2667 } 2668 2669 try 2670 { 2671 result = p.doPreOperation(modifyOperation); 2672 } 2673 catch (CanceledOperationException coe) 2674 { 2675 throw coe; 2676 } 2677 catch (Exception e) 2678 { 2679 return handlePreOperationException(e, i, preOperationModifyPlugins, 2680 modifyOperation, p); 2681 } 2682 2683 if (result == null) 2684 { 2685 return handlePreOperationResult(modifyOperation, i, 2686 preOperationModifyPlugins, p); 2687 } 2688 else if (!result.continuePluginProcessing()) 2689 { 2690 registerSkippedPreOperationPlugins(i, preOperationModifyPlugins, 2691 modifyOperation); 2692 2693 return result; 2694 } 2695 } 2696 2697 if (result == null) 2698 { 2699 // This should only happen if there were no pre-operation add plugins 2700 // registered, which is fine. 2701 result = PluginResult.PreOperation.continueOperationProcessing(); 2702 } 2703 2704 return result; 2705 } 2706 2707 /** 2708 * Invokes the set of pre-operation modify DN plugins that have been 2709 * configured in the Directory Server. 2710 * 2711 * @param modifyDNOperation The modify DN operation for which to invoke the 2712 * pre-operation plugins. 2713 * 2714 * @return The result of processing the pre-operation modify DN plugins. 2715 * 2716 * @throws CanceledOperationException if the operation should be canceled. 2717 */ 2718 public PluginResult.PreOperation invokePreOperationModifyDNPlugins( 2719 PreOperationModifyDNOperation modifyDNOperation) 2720 throws CanceledOperationException { 2721 PluginResult.PreOperation result = null; 2722 2723 for (int i = 0; i < preOperationModifyDNPlugins.length; i++) 2724 { 2725 DirectoryServerPlugin p = preOperationModifyDNPlugins[i]; 2726 if (isInternalOperation(modifyDNOperation, p)) 2727 { 2728 continue; 2729 } 2730 2731 try 2732 { 2733 result = p.doPreOperation(modifyDNOperation); 2734 } 2735 catch (CanceledOperationException coe) 2736 { 2737 throw coe; 2738 } 2739 catch (Exception e) 2740 { 2741 return handlePreOperationException(e, i, preOperationModifyDNPlugins, 2742 modifyDNOperation, p); 2743 } 2744 2745 if (result == null) 2746 { 2747 return handlePreOperationResult(modifyDNOperation, i, 2748 preOperationModifyDNPlugins, p); 2749 } 2750 else if (!result.continuePluginProcessing()) 2751 { 2752 registerSkippedPreOperationPlugins(i, preOperationModifyDNPlugins, 2753 modifyDNOperation); 2754 2755 return result; 2756 } 2757 } 2758 2759 if (result == null) 2760 { 2761 // This should only happen if there were no pre-operation add plugins 2762 // registered, which is fine. 2763 result = PluginResult.PreOperation.continueOperationProcessing(); 2764 } 2765 2766 return result; 2767 } 2768 2769 /** 2770 * Invokes the set of pre-operation search plugins that have been configured 2771 * in the Directory Server. 2772 * 2773 * @param searchOperation The search operation for which to invoke the 2774 * pre-operation plugins. 2775 * 2776 * @return The result of processing the pre-operation search plugins. 2777 * 2778 * @throws CanceledOperationException if the operation should be canceled. 2779 */ 2780 public PluginResult.PreOperation invokePreOperationSearchPlugins( 2781 PreOperationSearchOperation searchOperation) 2782 throws CanceledOperationException { 2783 PluginResult.PreOperation result = null; 2784 2785 for (int i = 0; i < preOperationSearchPlugins.length; i++) 2786 { 2787 DirectoryServerPlugin p = preOperationSearchPlugins[i]; 2788 if (isInternalOperation(searchOperation, p)) 2789 { 2790 continue; 2791 } 2792 2793 try 2794 { 2795 result = p.doPreOperation(searchOperation); 2796 } 2797 catch (CanceledOperationException coe) 2798 { 2799 throw coe; 2800 } 2801 catch (Exception e) 2802 { 2803 return handlePreOperationException(e, i, preOperationSearchPlugins, 2804 searchOperation, p); 2805 } 2806 2807 if (result == null) 2808 { 2809 return handlePreOperationResult(searchOperation, i, 2810 preOperationSearchPlugins, p); 2811 } 2812 else if (!result.continuePluginProcessing()) 2813 { 2814 registerSkippedPreOperationPlugins(i, preOperationSearchPlugins, 2815 searchOperation); 2816 2817 return result; 2818 } 2819 } 2820 2821 if (result == null) 2822 { 2823 // This should only happen if there were no pre-operation add plugins 2824 // registered, which is fine. 2825 result = PluginResult.PreOperation.continueOperationProcessing(); 2826 } 2827 2828 return result; 2829 } 2830 2831 /** 2832 * Invokes the set of post-operation abandon plugins that have been configured 2833 * in the Directory Server. 2834 * 2835 * @param abandonOperation The abandon operation for which to invoke the 2836 * post-operation plugins. 2837 * 2838 * @return The result of processing the post-operation abandon plugins. 2839 */ 2840 public PluginResult.PostOperation invokePostOperationAbandonPlugins( 2841 PostOperationAbandonOperation abandonOperation) 2842 { 2843 PluginResult.PostOperation result = null; 2844 PluginResult.PostOperation finalResult = null; 2845 2846 for (DirectoryServerPlugin p : postOperationAbandonPlugins) 2847 { 2848 if (isInternalOperation(abandonOperation, p)) 2849 { 2850 continue; 2851 } 2852 2853 try 2854 { 2855 result = p.doPostOperation(abandonOperation); 2856 } 2857 catch (Exception e) 2858 { 2859 logException(abandonOperation, p, e, ERR_PLUGIN_POST_OPERATION_PLUGIN_EXCEPTION); 2860 } 2861 2862 if (result == null) 2863 { 2864 logNullResult(abandonOperation, p, ERR_PLUGIN_POST_OPERATION_PLUGIN_RETURNED_NULL); 2865 } 2866 else if (!result.continueProcessing()) 2867 { 2868 // This plugin requested operation processing to stop. However, we 2869 // still have to invoke all the post op plugins that successfully 2870 // invoked its pre op plugins. We will just take this plugin's 2871 // results as the final result. 2872 finalResult = result; 2873 } 2874 } 2875 2876 if (result == null) 2877 { 2878 // This should only happen if there were no post-operation add plugins 2879 // registered, which is fine. 2880 finalResult = PluginResult.PostOperation.continueOperationProcessing(); 2881 } 2882 else if(finalResult == null) 2883 { 2884 // None of the plugins requested processing to stop so all results 2885 // have equal priority. Just return the last one. 2886 finalResult = result; 2887 } 2888 2889 return finalResult; 2890 } 2891 2892 /** 2893 * Invokes the set of post-operation add plugins that have been configured in 2894 * the Directory Server. 2895 * 2896 * @param addOperation The add operation for which to invoke the 2897 * post-operation plugins. 2898 * 2899 * @return The result of processing the post-operation add plugins. 2900 */ 2901 public PluginResult.PostOperation invokePostOperationAddPlugins( 2902 PostOperationAddOperation addOperation) 2903 { 2904 PluginResult.PostOperation result = null; 2905 PluginResult.PostOperation finalResult = null; 2906 2907 ArrayList<DirectoryServerPlugin> skippedPlugins = 2908 skippedPreOperationPlugins.remove(addOperation); 2909 2910 for (DirectoryServerPlugin p : postOperationAddPlugins) 2911 { 2912 if (isInternalOperation(addOperation, p) 2913 || isSkipped(skippedPlugins, p)) 2914 { 2915 continue; 2916 } 2917 2918 try 2919 { 2920 result = p.doPostOperation(addOperation); 2921 } 2922 catch (Exception e) 2923 { 2924 logException(addOperation, p, e, ERR_PLUGIN_POST_OPERATION_PLUGIN_EXCEPTION); 2925 } 2926 2927 if (result == null) 2928 { 2929 logNullResult(addOperation, p, ERR_PLUGIN_POST_OPERATION_PLUGIN_RETURNED_NULL); 2930 } 2931 else if (!result.continueProcessing()) 2932 { 2933 // This plugin requested operation processing to stop. However, we 2934 // still have to invoke all the post op plugins that successfully 2935 // invoked its pre op plugins. We will just take this plugin's 2936 // results as the final result. 2937 finalResult = result; 2938 } 2939 } 2940 2941 if (result == null) 2942 { 2943 // This should only happen if there were no post-operation add plugins 2944 // registered, which is fine. 2945 finalResult = PluginResult.PostOperation.continueOperationProcessing(); 2946 } 2947 else if(finalResult == null) 2948 { 2949 // None of the plugins requested processing to stop so all results 2950 // have equal priority. Just return the last one. 2951 finalResult = result; 2952 } 2953 2954 return finalResult; 2955 } 2956 2957 /** 2958 * Invokes the set of post-operation bind plugins that have been configured 2959 * in the Directory Server. 2960 * 2961 * @param bindOperation The bind operation for which to invoke the 2962 * post-operation plugins. 2963 * 2964 * @return The result of processing the post-operation bind plugins. 2965 */ 2966 public PluginResult.PostOperation invokePostOperationBindPlugins( 2967 PostOperationBindOperation bindOperation) 2968 { 2969 PluginResult.PostOperation result = null; 2970 PluginResult.PostOperation finalResult = null; 2971 2972 ArrayList<DirectoryServerPlugin> skippedPlugins = 2973 skippedPreOperationPlugins.remove(bindOperation); 2974 2975 for (DirectoryServerPlugin p : postOperationBindPlugins) 2976 { 2977 if (isInternalOperation(bindOperation, p) 2978 || isSkipped(skippedPlugins, p)) 2979 { 2980 continue; 2981 } 2982 2983 try 2984 { 2985 result = p.doPostOperation(bindOperation); 2986 } 2987 catch (Exception e) 2988 { 2989 logException(bindOperation, p, e, ERR_PLUGIN_POST_OPERATION_PLUGIN_EXCEPTION); 2990 } 2991 2992 if (result == null) 2993 { 2994 logNullResult(bindOperation, p, ERR_PLUGIN_POST_OPERATION_PLUGIN_RETURNED_NULL); 2995 } 2996 else if (!result.continueProcessing()) 2997 { 2998 // This plugin requested operation processing to stop. However, we 2999 // still have to invoke all the post op plugins that successfully 3000 // invoked its pre op plugins. We will just take this plugin's 3001 // results as the final result. 3002 finalResult = result; 3003 } 3004 } 3005 3006 if (result == null) 3007 { 3008 // This should only happen if there were no post-operation add plugins 3009 // registered, which is fine. 3010 finalResult = PluginResult.PostOperation.continueOperationProcessing(); 3011 } 3012 else if(finalResult == null) 3013 { 3014 // None of the plugins requested processing to stop so all results 3015 // have equal priority. Just return the last one. 3016 finalResult = result; 3017 } 3018 3019 return finalResult; 3020 } 3021 3022 /** 3023 * Invokes the set of post-operation compare plugins that have been configured 3024 * in the Directory Server. 3025 * 3026 * @param compareOperation The compare operation for which to invoke the 3027 * post-operation plugins. 3028 * 3029 * @return The result of processing the post-operation compare plugins. 3030 */ 3031 public PluginResult.PostOperation invokePostOperationComparePlugins( 3032 PostOperationCompareOperation compareOperation) 3033 { 3034 PluginResult.PostOperation result = null; 3035 PluginResult.PostOperation finalResult = null; 3036 3037 ArrayList<DirectoryServerPlugin> skippedPlugins = 3038 skippedPreOperationPlugins.remove(compareOperation); 3039 3040 for (DirectoryServerPlugin p : postOperationComparePlugins) 3041 { 3042 if (isInternalOperation(compareOperation, p) 3043 || isSkipped(skippedPlugins, p)) 3044 { 3045 continue; 3046 } 3047 3048 try 3049 { 3050 result = p.doPostOperation(compareOperation); 3051 } 3052 catch (Exception e) 3053 { 3054 logException(compareOperation, p, e, ERR_PLUGIN_POST_OPERATION_PLUGIN_EXCEPTION); 3055 } 3056 3057 if (result == null) 3058 { 3059 logNullResult(compareOperation, p, ERR_PLUGIN_POST_OPERATION_PLUGIN_RETURNED_NULL); 3060 } 3061 else if (!result.continueProcessing()) 3062 { 3063 // This plugin requested operation processing to stop. However, we 3064 // still have to invoke all the post op plugins that successfully 3065 // invoked its pre op plugins. We will just take this plugin's 3066 // results as the final result. 3067 finalResult = result; 3068 } 3069 } 3070 3071 if (result == null) 3072 { 3073 // This should only happen if there were no post-operation add plugins 3074 // registered, which is fine. 3075 finalResult = PluginResult.PostOperation.continueOperationProcessing(); 3076 } 3077 else if(finalResult == null) 3078 { 3079 // None of the plugins requested processing to stop so all results 3080 // have equal priority. Just return the last one. 3081 finalResult = result; 3082 } 3083 3084 return finalResult; 3085 } 3086 3087 private boolean isInternalOperation(PluginOperation op, DirectoryServerPlugin p) 3088 { 3089 return op.isInternalOperation() && !p.invokeForInternalOperations(); 3090 } 3091 3092 private boolean isSkipped(ArrayList<DirectoryServerPlugin> skippedPlugins, DirectoryServerPlugin p) 3093 { 3094 return skippedPlugins != null && skippedPlugins.contains(p); 3095 } 3096 3097 /** 3098 * Invokes the set of post-operation delete plugins that have been configured 3099 * in the Directory Server. 3100 * 3101 * @param deleteOperation The delete operation for which to invoke the 3102 * post-operation plugins. 3103 * 3104 * @return The result of processing the post-operation delete plugins. 3105 */ 3106 public PluginResult.PostOperation invokePostOperationDeletePlugins( 3107 PostOperationDeleteOperation deleteOperation) 3108 { 3109 PluginResult.PostOperation result = null; 3110 PluginResult.PostOperation finalResult = null; 3111 3112 ArrayList<DirectoryServerPlugin> skippedPlugins = 3113 skippedPreOperationPlugins.remove(deleteOperation); 3114 3115 for (DirectoryServerPlugin p : postOperationDeletePlugins) 3116 { 3117 if (isInternalOperation(deleteOperation, p) 3118 || isSkipped(skippedPlugins, p)) 3119 { 3120 continue; 3121 } 3122 3123 try 3124 { 3125 result = p.doPostOperation(deleteOperation); 3126 } 3127 catch (Exception e) 3128 { 3129 logException(deleteOperation, p, e, ERR_PLUGIN_POST_OPERATION_PLUGIN_EXCEPTION); 3130 } 3131 3132 if (result == null) 3133 { 3134 logNullResult(deleteOperation, p, ERR_PLUGIN_POST_OPERATION_PLUGIN_RETURNED_NULL); 3135 } 3136 else if (!result.continueProcessing()) 3137 { 3138 // This plugin requested operation processing to stop. However, we 3139 // still have to invoke all the post op plugins that successfully 3140 // invoked its pre op plugins. We will just take this plugin's 3141 // results as the final result. 3142 finalResult = result; 3143 } 3144 } 3145 3146 if (result == null) 3147 { 3148 // This should only happen if there were no post-operation add plugins 3149 // registered, which is fine. 3150 finalResult = PluginResult.PostOperation.continueOperationProcessing(); 3151 } 3152 else if(finalResult == null) 3153 { 3154 // None of the plugins requested processing to stop so all results 3155 // have equal priority. Just return the last one. 3156 finalResult = result; 3157 } 3158 3159 return finalResult; 3160 } 3161 3162 /** 3163 * Invokes the set of post-operation extended plugins that have been 3164 * configured in the Directory Server. 3165 * 3166 * @param extendedOperation The extended operation for which to invoke the 3167 * post-operation plugins. 3168 * 3169 * @return The result of processing the post-operation extended plugins. 3170 */ 3171 public PluginResult.PostOperation invokePostOperationExtendedPlugins( 3172 PostOperationExtendedOperation extendedOperation) 3173 { 3174 PluginResult.PostOperation result = null; 3175 PluginResult.PostOperation finalResult = null; 3176 3177 ArrayList<DirectoryServerPlugin> skippedPlugins = 3178 skippedPreOperationPlugins.remove(extendedOperation); 3179 3180 for (DirectoryServerPlugin p : postOperationExtendedPlugins) 3181 { 3182 if (isInternalOperation(extendedOperation, p) 3183 || isSkipped(skippedPlugins, p)) 3184 { 3185 continue; 3186 } 3187 3188 try 3189 { 3190 result = p.doPostOperation(extendedOperation); 3191 } 3192 catch (Exception e) 3193 { 3194 logException(extendedOperation, p, e, ERR_PLUGIN_POST_OPERATION_PLUGIN_EXCEPTION); 3195 } 3196 3197 if (result == null) 3198 { 3199 logNullResult(extendedOperation, p, ERR_PLUGIN_POST_OPERATION_PLUGIN_RETURNED_NULL); 3200 } 3201 else if (!result.continueProcessing()) 3202 { 3203 // This plugin requested operation processing to stop. However, we 3204 // still have to invoke all the post op plugins that successfully 3205 // invoked its pre op plugins. We will just take this plugin's 3206 // results as the final result. 3207 finalResult = result; 3208 } 3209 } 3210 3211 if (result == null) 3212 { 3213 // This should only happen if there were no post-operation add plugins 3214 // registered, which is fine. 3215 finalResult = PluginResult.PostOperation.continueOperationProcessing(); 3216 } 3217 else if(finalResult == null) 3218 { 3219 // None of the plugins requested processing to stop so all results 3220 // have equal priority. Just return the last one. 3221 finalResult = result; 3222 } 3223 3224 return finalResult; 3225 } 3226 3227 /** 3228 * Invokes the set of post-operation modify plugins that have been configured 3229 * in the Directory Server. 3230 * 3231 * @param modifyOperation The modify operation for which to invoke the 3232 * post-operation plugins. 3233 * 3234 * @return The result of processing the post-operation modify plugins. 3235 */ 3236 public PluginResult.PostOperation invokePostOperationModifyPlugins( 3237 PostOperationModifyOperation modifyOperation) 3238 { 3239 PluginResult.PostOperation result = null; 3240 PluginResult.PostOperation finalResult = null; 3241 3242 ArrayList<DirectoryServerPlugin> skippedPlugins = 3243 skippedPreOperationPlugins.remove(modifyOperation); 3244 3245 for (DirectoryServerPlugin p : postOperationModifyPlugins) 3246 { 3247 if (isInternalOperation(modifyOperation, p) 3248 || isSkipped(skippedPlugins, p)) 3249 { 3250 continue; 3251 } 3252 3253 try 3254 { 3255 result = p.doPostOperation(modifyOperation); 3256 } 3257 catch (Exception e) 3258 { 3259 logException(modifyOperation, p, e, ERR_PLUGIN_POST_OPERATION_PLUGIN_EXCEPTION); 3260 } 3261 3262 if (result == null) 3263 { 3264 logNullResult(modifyOperation, p, ERR_PLUGIN_POST_OPERATION_PLUGIN_RETURNED_NULL); 3265 } 3266 else if (!result.continueProcessing()) 3267 { 3268 // This plugin requested operation processing to stop. However, we 3269 // still have to invoke all the post op plugins that successfully 3270 // invoked its pre op plugins. We will just take this plugin's 3271 // results as the final result. 3272 finalResult = result; 3273 } 3274 } 3275 3276 if (result == null) 3277 { 3278 // This should only happen if there were no post-operation add plugins 3279 // registered, which is fine. 3280 finalResult = PluginResult.PostOperation.continueOperationProcessing(); 3281 } 3282 else if(finalResult == null) 3283 { 3284 // None of the plugins requested processing to stop so all results 3285 // have equal priority. Just return the last one. 3286 finalResult = result; 3287 } 3288 return finalResult; 3289 } 3290 3291 /** 3292 * Invokes the set of post-operation modify DN plugins that have been 3293 * configured in the Directory Server. 3294 * 3295 * @param modifyDNOperation The modify DN operation for which to invoke the 3296 * post-operation plugins. 3297 * 3298 * @return The result of processing the post-operation modify DN plugins. 3299 */ 3300 public PluginResult.PostOperation invokePostOperationModifyDNPlugins( 3301 PostOperationModifyDNOperation modifyDNOperation) 3302 { 3303 PluginResult.PostOperation result = null; 3304 PluginResult.PostOperation finalResult = null; 3305 3306 ArrayList<DirectoryServerPlugin> skippedPlugins = 3307 skippedPreOperationPlugins.remove(modifyDNOperation); 3308 3309 for (DirectoryServerPlugin p : postOperationModifyDNPlugins) 3310 { 3311 if (isInternalOperation(modifyDNOperation, p) 3312 || isSkipped(skippedPlugins, p)) 3313 { 3314 continue; 3315 } 3316 3317 try 3318 { 3319 result = p.doPostOperation(modifyDNOperation); 3320 } 3321 catch (Exception e) 3322 { 3323 logException(modifyDNOperation, p, e, ERR_PLUGIN_POST_OPERATION_PLUGIN_EXCEPTION); 3324 } 3325 3326 if (result == null) 3327 { 3328 logNullResult(modifyDNOperation, p, ERR_PLUGIN_POST_OPERATION_PLUGIN_RETURNED_NULL); 3329 } 3330 else if (!result.continueProcessing()) 3331 { 3332 // This plugin requested operation processing to stop. However, we 3333 // still have to invoke all the post op plugins that successfully 3334 // invoked its pre op plugins. We will just take this plugin's 3335 // results as the final result. 3336 finalResult = result; 3337 } 3338 } 3339 3340 if (result == null) 3341 { 3342 // This should only happen if there were no post-operation add plugins 3343 // registered, which is fine. 3344 finalResult = PluginResult.PostOperation.continueOperationProcessing(); 3345 } 3346 else if(finalResult == null) 3347 { 3348 // None of the plugins requested processing to stop so all results 3349 // have equal priority. Just return the last one. 3350 finalResult = result; 3351 } 3352 3353 return finalResult; 3354 } 3355 3356 /** 3357 * Invokes the set of post-operation search plugins that have been configured 3358 * in the Directory Server. 3359 * 3360 * @param searchOperation The search operation for which to invoke the 3361 * post-operation plugins. 3362 * 3363 * @return The result of processing the post-operation search plugins. 3364 */ 3365 public PluginResult.PostOperation invokePostOperationSearchPlugins( 3366 PostOperationSearchOperation searchOperation) 3367 { 3368 PluginResult.PostOperation result = null; 3369 PluginResult.PostOperation finalResult = null; 3370 3371 ArrayList<DirectoryServerPlugin> skippedPlugins = 3372 skippedPreOperationPlugins.remove(searchOperation); 3373 3374 for (DirectoryServerPlugin p : postOperationSearchPlugins) 3375 { 3376 if (isInternalOperation(searchOperation, p) 3377 || isSkipped(skippedPlugins, p)) 3378 { 3379 continue; 3380 } 3381 3382 try 3383 { 3384 result = p.doPostOperation(searchOperation); 3385 } 3386 catch (Exception e) 3387 { 3388 logException(searchOperation, p, e, ERR_PLUGIN_POST_OPERATION_PLUGIN_EXCEPTION); 3389 } 3390 3391 if (result == null) 3392 { 3393 logNullResult(searchOperation, p, ERR_PLUGIN_POST_OPERATION_PLUGIN_RETURNED_NULL); 3394 } 3395 else if (!result.continueProcessing()) 3396 { 3397 // This plugin requested operation processing to stop. However, we 3398 // still have to invoke all the post op plugins that successfully 3399 // invoked its pre op plugins. We will just take this plugin's 3400 // results as the final result. 3401 finalResult = result; 3402 } 3403 } 3404 3405 if (result == null) 3406 { 3407 // This should only happen if there were no post-operation add plugins 3408 // registered, which is fine. 3409 finalResult = PluginResult.PostOperation.continueOperationProcessing(); 3410 } 3411 else if(finalResult == null) 3412 { 3413 // None of the plugins requested processing to stop so all results 3414 // have equal priority. Just return the last one. 3415 finalResult = result; 3416 } 3417 3418 return finalResult; 3419 } 3420 3421 /** 3422 * Invokes the set of post-operation unbind plugins that have been configured 3423 * in the Directory Server. 3424 * 3425 * @param unbindOperation The unbind operation for which to invoke the 3426 * post-operation plugins. 3427 * 3428 * @return The result of processing the post-operation unbind plugins. 3429 */ 3430 public PluginResult.PostOperation invokePostOperationUnbindPlugins( 3431 PostOperationUnbindOperation unbindOperation) 3432 { 3433 PluginResult.PostOperation result = null; 3434 PluginResult.PostOperation finalResult = null; 3435 3436 ArrayList<DirectoryServerPlugin> skippedPlugins = 3437 skippedPreOperationPlugins.remove(unbindOperation); 3438 3439 for (DirectoryServerPlugin p : postOperationUnbindPlugins) 3440 { 3441 if (isInternalOperation(unbindOperation, p) 3442 || isSkipped(skippedPlugins, p)) 3443 { 3444 continue; 3445 } 3446 3447 try 3448 { 3449 result = p.doPostOperation(unbindOperation); 3450 } 3451 catch (Exception e) 3452 { 3453 logException(unbindOperation, p, e, ERR_PLUGIN_POST_OPERATION_PLUGIN_EXCEPTION); 3454 } 3455 3456 if (result == null) 3457 { 3458 logNullResult(unbindOperation, p, ERR_PLUGIN_POST_OPERATION_PLUGIN_RETURNED_NULL); 3459 } 3460 else if (!result.continueProcessing()) 3461 { 3462 // This plugin requested operation processing to stop. However, we 3463 // still have to invoke all the post op plugins that successfully 3464 // invoked its pre op plugins. We will just take this plugin's 3465 // results as the final result. 3466 finalResult = result; 3467 } 3468 } 3469 3470 if (result == null) 3471 { 3472 // This should only happen if there were no post-operation add plugins 3473 // registered, which is fine. 3474 finalResult = PluginResult.PostOperation.continueOperationProcessing(); 3475 } 3476 else if(finalResult == null) 3477 { 3478 // None of the plugins requested processing to stop so all results 3479 // have equal priority. Just return the last one. 3480 finalResult = result; 3481 } 3482 3483 return finalResult; 3484 } 3485 3486 /** 3487 * Invokes the set of post-response add plugins that have been configured in 3488 * the Directory Server. 3489 * 3490 * @param addOperation The add operation for which to invoke the 3491 * post-response plugins. 3492 * 3493 * @return The result of processing the post-response add plugins. 3494 */ 3495 public PluginResult.PostResponse invokePostResponseAddPlugins( 3496 PostResponseAddOperation addOperation) 3497 { 3498 PluginResult.PostResponse result = null; 3499 3500 for (DirectoryServerPlugin p : postResponseAddPlugins) 3501 { 3502 if (isInternalOperation(addOperation, p)) 3503 { 3504 continue; 3505 } 3506 3507 try 3508 { 3509 result = p.doPostResponse(addOperation); 3510 } 3511 catch (Exception e) 3512 { 3513 logException(addOperation, p, e, ERR_PLUGIN_POST_RESPONSE_PLUGIN_EXCEPTION); 3514 } 3515 3516 if (result == null) 3517 { 3518 logNullResult(addOperation, p, ERR_PLUGIN_POST_RESPONSE_PLUGIN_RETURNED_NULL); 3519 } 3520 else if (!result.continuePluginProcessing()) 3521 { 3522 return result; 3523 } 3524 } 3525 3526 if (result == null) 3527 { 3528 // This should only happen if there were no post-response add plugins 3529 // registered, which is fine. 3530 result = PluginResult.PostResponse.continueOperationProcessing(); 3531 } 3532 3533 return result; 3534 } 3535 3536 /** 3537 * Invokes the set of post-response bind plugins that have been configured in 3538 * the Directory Server. 3539 * 3540 * @param bindOperation The bind operation for which to invoke the 3541 * post-response plugins. 3542 * 3543 * @return The result of processing the post-response bind plugins. 3544 */ 3545 public PluginResult.PostResponse invokePostResponseBindPlugins( 3546 PostResponseBindOperation bindOperation) 3547 { 3548 PluginResult.PostResponse result = null; 3549 3550 for (DirectoryServerPlugin p : postResponseBindPlugins) 3551 { 3552 if (isInternalOperation(bindOperation, p)) 3553 { 3554 continue; 3555 } 3556 3557 try 3558 { 3559 result = p.doPostResponse(bindOperation); 3560 } 3561 catch (Exception e) 3562 { 3563 logException(bindOperation, p, e, ERR_PLUGIN_POST_RESPONSE_PLUGIN_EXCEPTION); 3564 } 3565 3566 if (result == null) 3567 { 3568 logNullResult(bindOperation, p, ERR_PLUGIN_POST_RESPONSE_PLUGIN_RETURNED_NULL); 3569 } 3570 else if (!result.continuePluginProcessing()) 3571 { 3572 return result; 3573 } 3574 } 3575 3576 if (result == null) 3577 { 3578 // This should only happen if there were no post-response add plugins 3579 // registered, which is fine. 3580 result = PluginResult.PostResponse.continueOperationProcessing(); 3581 } 3582 3583 return result; 3584 } 3585 3586 /** 3587 * Invokes the set of post-response compare plugins that have been configured 3588 * in the Directory Server. 3589 * 3590 * @param compareOperation The compare operation for which to invoke the 3591 * post-response plugins. 3592 * 3593 * @return The result of processing the post-response compare plugins. 3594 */ 3595 public PluginResult.PostResponse invokePostResponseComparePlugins( 3596 PostResponseCompareOperation compareOperation) 3597 { 3598 PluginResult.PostResponse result = null; 3599 3600 for (DirectoryServerPlugin p : postResponseComparePlugins) 3601 { 3602 if (isInternalOperation(compareOperation, p)) 3603 { 3604 continue; 3605 } 3606 3607 try 3608 { 3609 result = p.doPostResponse(compareOperation); 3610 } 3611 catch (Exception e) 3612 { 3613 logException(compareOperation, p, e, ERR_PLUGIN_POST_RESPONSE_PLUGIN_EXCEPTION); 3614 } 3615 3616 if (result == null) 3617 { 3618 logNullResult(compareOperation, p, ERR_PLUGIN_POST_RESPONSE_PLUGIN_RETURNED_NULL); 3619 } 3620 else if (!result.continuePluginProcessing()) 3621 { 3622 return result; 3623 } 3624 } 3625 3626 if (result == null) 3627 { 3628 // This should only happen if there were no post-response add plugins 3629 // registered, which is fine. 3630 result = PluginResult.PostResponse.continueOperationProcessing(); 3631 } 3632 3633 return result; 3634 } 3635 3636 /** 3637 * Invokes the set of post-response delete plugins that have been configured 3638 * in the Directory Server. 3639 * 3640 * @param deleteOperation The delete operation for which to invoke the 3641 * post-response plugins. 3642 * 3643 * @return The result of processing the post-response delete plugins. 3644 */ 3645 public PluginResult.PostResponse invokePostResponseDeletePlugins( 3646 PostResponseDeleteOperation deleteOperation) 3647 { 3648 PluginResult.PostResponse result = null; 3649 3650 for (DirectoryServerPlugin p : postResponseDeletePlugins) 3651 { 3652 if (isInternalOperation(deleteOperation, p)) 3653 { 3654 continue; 3655 } 3656 3657 try 3658 { 3659 result = p.doPostResponse(deleteOperation); 3660 } 3661 catch (Exception e) 3662 { 3663 logException(deleteOperation, p, e, ERR_PLUGIN_POST_RESPONSE_PLUGIN_EXCEPTION); 3664 } 3665 3666 if (result == null) 3667 { 3668 logNullResult(deleteOperation, p, ERR_PLUGIN_POST_RESPONSE_PLUGIN_RETURNED_NULL); 3669 } 3670 else if (!result.continuePluginProcessing()) 3671 { 3672 return result; 3673 } 3674 } 3675 3676 if (result == null) 3677 { 3678 // This should only happen if there were no post-response add plugins 3679 // registered, which is fine. 3680 result = PluginResult.PostResponse.continueOperationProcessing(); 3681 } 3682 return result; 3683 } 3684 3685 /** 3686 * Invokes the set of post-response extended plugins that have been configured 3687 * in the Directory Server. 3688 * 3689 * @param extendedOperation The extended operation for which to invoke the 3690 * post-response plugins. 3691 * 3692 * @return The result of processing the post-response extended plugins. 3693 */ 3694 public PluginResult.PostResponse invokePostResponseExtendedPlugins( 3695 PostResponseExtendedOperation extendedOperation) 3696 { 3697 PluginResult.PostResponse result = null; 3698 3699 for (DirectoryServerPlugin p : postResponseExtendedPlugins) 3700 { 3701 if (isInternalOperation(extendedOperation, p)) 3702 { 3703 continue; 3704 } 3705 3706 try 3707 { 3708 result = p.doPostResponse(extendedOperation); 3709 } 3710 catch (Exception e) 3711 { 3712 logException(extendedOperation, p, e, ERR_PLUGIN_POST_RESPONSE_PLUGIN_EXCEPTION); 3713 } 3714 3715 if (result == null) 3716 { 3717 logNullResult(extendedOperation, p, ERR_PLUGIN_POST_RESPONSE_PLUGIN_RETURNED_NULL); 3718 } 3719 else if (!result.continuePluginProcessing()) 3720 { 3721 return result; 3722 } 3723 } 3724 3725 if (result == null) 3726 { 3727 // This should only happen if there were no post-response add plugins 3728 // registered, which is fine. 3729 result = PluginResult.PostResponse.continueOperationProcessing(); 3730 } 3731 3732 return result; 3733 } 3734 3735 /** 3736 * Invokes the set of post-response modify plugins that have been configured 3737 * in the Directory Server. 3738 * 3739 * @param modifyOperation The modify operation for which to invoke the 3740 * post-response plugins. 3741 * 3742 * @return The result of processing the post-response modify plugins. 3743 */ 3744 public PluginResult.PostResponse invokePostResponseModifyPlugins( 3745 PostResponseModifyOperation modifyOperation) 3746 { 3747 PluginResult.PostResponse result = null; 3748 3749 for (DirectoryServerPlugin p : postResponseModifyPlugins) 3750 { 3751 if (isInternalOperation(modifyOperation, p)) 3752 { 3753 continue; 3754 } 3755 3756 try 3757 { 3758 result = p.doPostResponse(modifyOperation); 3759 } 3760 catch (Exception e) 3761 { 3762 logException(modifyOperation, p, e, ERR_PLUGIN_POST_RESPONSE_PLUGIN_EXCEPTION); 3763 } 3764 3765 if (result == null) 3766 { 3767 logNullResult(modifyOperation, p, ERR_PLUGIN_POST_RESPONSE_PLUGIN_RETURNED_NULL); 3768 } 3769 else if (!result.continuePluginProcessing()) 3770 { 3771 return result; 3772 } 3773 } 3774 3775 if (result == null) 3776 { 3777 // This should only happen if there were no post-response add plugins 3778 // registered, which is fine. 3779 result = PluginResult.PostResponse.continueOperationProcessing(); 3780 } 3781 3782 return result; 3783 } 3784 3785 /** 3786 * Invokes the set of post-response modify DN plugins that have been 3787 * configured in the Directory Server. 3788 * 3789 * @param modifyDNOperation The modify DN operation for which to invoke the 3790 * post-response plugins. 3791 * 3792 * @return The result of processing the post-response modify DN plugins. 3793 */ 3794 public PluginResult.PostResponse invokePostResponseModifyDNPlugins( 3795 PostResponseModifyDNOperation modifyDNOperation) 3796 { 3797 PluginResult.PostResponse result = null; 3798 3799 for (DirectoryServerPlugin p : postResponseModifyDNPlugins) 3800 { 3801 if (isInternalOperation(modifyDNOperation, p)) 3802 { 3803 continue; 3804 } 3805 3806 try 3807 { 3808 result = p.doPostResponse(modifyDNOperation); 3809 } 3810 catch (Exception e) 3811 { 3812 logException(modifyDNOperation, p, e, ERR_PLUGIN_POST_RESPONSE_PLUGIN_EXCEPTION); 3813 } 3814 3815 if (result == null) 3816 { 3817 logNullResult(modifyDNOperation, p, ERR_PLUGIN_POST_RESPONSE_PLUGIN_RETURNED_NULL); 3818 } 3819 else if (!result.continuePluginProcessing()) 3820 { 3821 return result; 3822 } 3823 } 3824 3825 if (result == null) 3826 { 3827 // This should only happen if there were no post-response add plugins 3828 // registered, which is fine. 3829 result = PluginResult.PostResponse.continueOperationProcessing(); 3830 } 3831 3832 return result; 3833 } 3834 3835 /** 3836 * Invokes the set of post-response search plugins that have been configured 3837 * in the Directory Server. 3838 * 3839 * @param searchOperation The search operation for which to invoke the 3840 * post-response plugins. 3841 * 3842 * @return The result of processing the post-response search plugins. 3843 */ 3844 public PluginResult.PostResponse invokePostResponseSearchPlugins( 3845 PostResponseSearchOperation searchOperation) 3846 { 3847 PluginResult.PostResponse result = null; 3848 3849 for (DirectoryServerPlugin p : postResponseSearchPlugins) 3850 { 3851 if (isInternalOperation(searchOperation, p)) 3852 { 3853 continue; 3854 } 3855 3856 try 3857 { 3858 result = p.doPostResponse(searchOperation); 3859 } 3860 catch (Exception e) 3861 { 3862 logException(searchOperation, p, e, ERR_PLUGIN_POST_RESPONSE_PLUGIN_EXCEPTION); 3863 } 3864 3865 if (result == null) 3866 { 3867 logNullResult(searchOperation, p, ERR_PLUGIN_POST_RESPONSE_PLUGIN_RETURNED_NULL); 3868 } 3869 else if (!result.continuePluginProcessing()) 3870 { 3871 return result; 3872 } 3873 } 3874 3875 if (result == null) 3876 { 3877 // This should only happen if there were no post-response add plugins 3878 // registered, which is fine. 3879 result = PluginResult.PostResponse.continueOperationProcessing(); 3880 } 3881 3882 return result; 3883 } 3884 3885 private void logException(PluginOperation op, DirectoryServerPlugin p, Exception e, 3886 Arg5<Object, Object, Number, Number, Object> errorMsg) 3887 { 3888 logger.traceException(e); 3889 logger.error(errorMsg, 3890 op.getOperationType().getOperationName(), 3891 p.getPluginEntryDN(), 3892 op.getConnectionID(), op.getOperationID(), 3893 stackTraceToSingleLineString(e)); 3894 } 3895 3896 private void logNullResult(PluginOperation op, DirectoryServerPlugin p, 3897 Arg4<Object, Object, Number, Number> nullResultMsg) 3898 { 3899 logger.error(nullResultMsg, 3900 op.getOperationType().getOperationName(), 3901 p.getPluginEntryDN(), 3902 op.getConnectionID(), op.getOperationID()); 3903 } 3904 3905 /** 3906 * Invokes the set of post-synchronization add plugins that have been 3907 * configured in the Directory Server. 3908 * 3909 * @param addOperation The add operation for which to invoke the 3910 * post-synchronization plugins. 3911 */ 3912 public void invokePostSynchronizationAddPlugins( 3913 PostSynchronizationAddOperation addOperation) 3914 { 3915 for (DirectoryServerPlugin p : postSynchronizationAddPlugins) 3916 { 3917 try 3918 { 3919 p.doPostSynchronization(addOperation); 3920 } 3921 catch (Exception e) 3922 { 3923 logException(addOperation, p, e, ERR_PLUGIN_POST_SYNCHRONIZATION_PLUGIN_EXCEPTION); 3924 } 3925 } 3926 } 3927 3928 /** 3929 * Invokes the set of post-synchronization delete plugins that have been 3930 * configured in the Directory Server. 3931 * 3932 * @param deleteOperation The delete operation for which to invoke the 3933 * post-synchronization plugins. 3934 */ 3935 public void invokePostSynchronizationDeletePlugins( 3936 PostSynchronizationDeleteOperation deleteOperation) 3937 { 3938 for (DirectoryServerPlugin p : postSynchronizationDeletePlugins) 3939 { 3940 try 3941 { 3942 p.doPostSynchronization(deleteOperation); 3943 } 3944 catch (Exception e) 3945 { 3946 logException(deleteOperation, p, e, ERR_PLUGIN_POST_SYNCHRONIZATION_PLUGIN_EXCEPTION); 3947 } 3948 } 3949 } 3950 3951 /** 3952 * Invokes the set of post-synchronization modify plugins that have been 3953 * configured in the Directory Server. 3954 * 3955 * @param modifyOperation The modify operation for which to invoke the 3956 * post-synchronization plugins. 3957 */ 3958 public void invokePostSynchronizationModifyPlugins( 3959 PostSynchronizationModifyOperation modifyOperation) 3960 { 3961 for (DirectoryServerPlugin p : postSynchronizationModifyPlugins) 3962 { 3963 try 3964 { 3965 p.doPostSynchronization(modifyOperation); 3966 } 3967 catch (Exception e) 3968 { 3969 logException(modifyOperation, p, e, ERR_PLUGIN_POST_SYNCHRONIZATION_PLUGIN_EXCEPTION); 3970 } 3971 } 3972 } 3973 3974 /** 3975 * Invokes the set of post-synchronization modify DN plugins that have been 3976 * configured in the Directory Server. 3977 * 3978 * @param modifyDNOperation The modify DN operation for which to invoke the 3979 * post-synchronization plugins. 3980 */ 3981 public void invokePostSynchronizationModifyDNPlugins( 3982 PostSynchronizationModifyDNOperation modifyDNOperation) 3983 { 3984 for (DirectoryServerPlugin p : postSynchronizationModifyDNPlugins) 3985 { 3986 try 3987 { 3988 p.doPostSynchronization(modifyDNOperation); 3989 } 3990 catch (Exception e) 3991 { 3992 logException(modifyDNOperation, p, e, ERR_PLUGIN_POST_SYNCHRONIZATION_PLUGIN_EXCEPTION); 3993 } 3994 } 3995 } 3996 3997 /** 3998 * Invokes the set of search result entry plugins that have been configured 3999 * in the Directory Server. 4000 * 4001 * @param searchOperation The search operation for which to invoke the 4002 * search result entry plugins. 4003 * @param searchEntry The search result entry to be processed. 4004 * 4005 * @return The result of processing the search result entry plugins. 4006 */ 4007 public PluginResult.IntermediateResponse invokeSearchResultEntryPlugins( 4008 SearchEntrySearchOperation searchOperation, 4009 SearchResultEntry searchEntry) 4010 { 4011 PluginResult.IntermediateResponse result = null; 4012 4013 for (DirectoryServerPlugin p : searchResultEntryPlugins) 4014 { 4015 if (isInternalOperation(searchOperation, p)) 4016 { 4017 continue; 4018 } 4019 4020 try 4021 { 4022 result = p.processSearchEntry(searchOperation, searchEntry); 4023 } 4024 catch (Exception e) 4025 { 4026 logger.traceException(e); 4027 4028 LocalizableMessage message = ERR_PLUGIN_SEARCH_ENTRY_PLUGIN_EXCEPTION. 4029 get(p.getPluginEntryDN(), 4030 searchOperation.getConnectionID(), 4031 searchOperation.getOperationID(), 4032 searchEntry.getName(), 4033 stackTraceToSingleLineString(e)); 4034 logger.error(message); 4035 4036 return PluginResult.IntermediateResponse.stopProcessing(false, 4037 DirectoryServer.getServerErrorResultCode(), message); 4038 } 4039 4040 if (result == null) 4041 { 4042 LocalizableMessage message = ERR_PLUGIN_SEARCH_ENTRY_PLUGIN_RETURNED_NULL. 4043 get(p.getPluginEntryDN(), 4044 searchOperation.getConnectionID(), 4045 searchOperation.getOperationID(), 4046 searchEntry.getName()); 4047 logger.error(message); 4048 4049 return PluginResult.IntermediateResponse.stopProcessing(false, 4050 DirectoryServer.getServerErrorResultCode(), message); 4051 } 4052 else if (! result.continuePluginProcessing()) 4053 { 4054 return result; 4055 } 4056 } 4057 4058 if (result == null) 4059 { 4060 // This should only happen if there were no search result entry plugins 4061 // registered, which is fine. 4062 result = 4063 PluginResult.IntermediateResponse.continueOperationProcessing(true); 4064 } 4065 4066 return result; 4067 } 4068 4069 /** 4070 * Invokes the set of search result reference plugins that have been 4071 * configured in the Directory Server. 4072 * 4073 * @param searchOperation The search operation for which to invoke the 4074 * search result reference plugins. 4075 * @param searchReference The search result reference to be processed. 4076 * 4077 * @return The result of processing the search result reference plugins. 4078 */ 4079 public PluginResult.IntermediateResponse invokeSearchResultReferencePlugins( 4080 SearchReferenceSearchOperation searchOperation, 4081 SearchResultReference searchReference) 4082 { 4083 PluginResult.IntermediateResponse result = null; 4084 4085 for (DirectoryServerPlugin p : searchResultReferencePlugins) 4086 { 4087 if (isInternalOperation(searchOperation, p)) 4088 { 4089 continue; 4090 } 4091 4092 try 4093 { 4094 result = p.processSearchReference(searchOperation, searchReference); 4095 } 4096 catch (Exception e) 4097 { 4098 logger.traceException(e); 4099 4100 LocalizableMessage message = ERR_PLUGIN_SEARCH_REFERENCE_PLUGIN_EXCEPTION. 4101 get(p.getPluginEntryDN(), 4102 searchOperation.getConnectionID(), 4103 searchOperation.getOperationID(), 4104 searchReference.getReferralURLString(), 4105 stackTraceToSingleLineString(e)); 4106 logger.error(message); 4107 4108 return PluginResult.IntermediateResponse.stopProcessing(false, 4109 DirectoryServer.getServerErrorResultCode(), message); 4110 } 4111 4112 if (result == null) 4113 { 4114 LocalizableMessage message = ERR_PLUGIN_SEARCH_REFERENCE_PLUGIN_RETURNED_NULL. 4115 get(p.getPluginEntryDN(), 4116 searchOperation.getConnectionID(), 4117 searchOperation.getOperationID(), 4118 searchReference.getReferralURLString()); 4119 logger.error(message); 4120 4121 return PluginResult.IntermediateResponse.stopProcessing(false, 4122 DirectoryServer.getServerErrorResultCode(), message); 4123 } 4124 else if (! result.continuePluginProcessing()) 4125 { 4126 return result; 4127 } 4128 } 4129 4130 if (result == null) 4131 { 4132 // This should only happen if there were no search result reference 4133 // plugins registered, which is fine. 4134 result = 4135 PluginResult.IntermediateResponse.continueOperationProcessing(true); 4136 } 4137 4138 return result; 4139 } 4140 4141 /** 4142 * Invokes the set of subordinate modify DN plugins that have been configured 4143 * in the Directory Server. 4144 * 4145 * @param modifyDNOperation The modify DN operation with which the 4146 * subordinate entry is associated. 4147 * @param oldEntry The subordinate entry prior to the move/rename 4148 * operation. 4149 * @param newEntry The subordinate entry after the move/rename 4150 * operation. 4151 * @param modifications A list into which any modifications made to the 4152 * target entry should be placed. 4153 * 4154 * @return The result of processing the subordinate modify DN plugins. 4155 */ 4156 public PluginResult.SubordinateModifyDN invokeSubordinateModifyDNPlugins( 4157 SubordinateModifyDNOperation modifyDNOperation, Entry oldEntry, 4158 Entry newEntry, List<Modification> modifications) 4159 { 4160 PluginResult.SubordinateModifyDN result = null; 4161 4162 for (DirectoryServerPlugin p : subordinateModifyDNPlugins) 4163 { 4164 if (isInternalOperation(modifyDNOperation, p)) 4165 { 4166 continue; 4167 } 4168 4169 try 4170 { 4171 result = p.processSubordinateModifyDN(modifyDNOperation, oldEntry, 4172 newEntry, modifications); 4173 } 4174 catch (Exception e) 4175 { 4176 logger.traceException(e); 4177 4178 LocalizableMessage message = 4179 ERR_PLUGIN_SUBORDINATE_MODIFY_DN_PLUGIN_EXCEPTION.get( 4180 p.getPluginEntryDN(), 4181 modifyDNOperation.getConnectionID(), 4182 modifyDNOperation.getOperationID(), 4183 stackTraceToSingleLineString(e)); 4184 logger.error(message); 4185 4186 return PluginResult.SubordinateModifyDN.stopProcessing( 4187 DirectoryServer.getServerErrorResultCode(), message); 4188 } 4189 4190 if (result == null) 4191 { 4192 LocalizableMessage message = 4193 ERR_PLUGIN_SUBORDINATE_MODIFY_DN_PLUGIN_RETURNED_NULL.get( 4194 p.getPluginEntryDN(), 4195 modifyDNOperation.getConnectionID(), 4196 modifyDNOperation.getOperationID()); 4197 logger.error(message); 4198 4199 return PluginResult.SubordinateModifyDN.stopProcessing( 4200 DirectoryServer.getServerErrorResultCode(), message); 4201 } 4202 else if (! result.continuePluginProcessing()) 4203 { 4204 return result; 4205 } 4206 } 4207 4208 if (result == null) 4209 { 4210 // This should only happen if there were no subordinate modify DN plugins 4211 // registered, which is fine. 4212 result = PluginResult.SubordinateModifyDN.continueOperationProcessing(); 4213 } 4214 4215 return result; 4216 } 4217 4218 /** 4219 * Invokes the set of subordinate delete plugins that have been configured 4220 * in the Directory Server. 4221 * 4222 * @param deleteOperation The delete operation with which the 4223 * subordinate entry is associated. 4224 * @param entry The subordinate entry being deleted. 4225 * 4226 * @return The result of processing the subordinate delete plugins. 4227 */ 4228 public PluginResult.SubordinateDelete invokeSubordinateDeletePlugins( 4229 DeleteOperation deleteOperation, Entry entry) 4230 { 4231 PluginResult.SubordinateDelete result = null; 4232 4233 for (DirectoryServerPlugin p : subordinateDeletePlugins) 4234 { 4235 if (deleteOperation.isInternalOperation() && !p.invokeForInternalOperations()) 4236 { 4237 continue; 4238 } 4239 4240 try 4241 { 4242 result = p.processSubordinateDelete(deleteOperation, entry); 4243 } 4244 catch (Exception e) 4245 { 4246 logger.traceException(e); 4247 4248 LocalizableMessage message = 4249 ERR_PLUGIN_SUBORDINATE_DELETE_PLUGIN_EXCEPTION.get( 4250 p.getPluginEntryDN(), 4251 deleteOperation.getConnectionID(), 4252 deleteOperation.getOperationID(), 4253 stackTraceToSingleLineString(e)); 4254 logger.error(message); 4255 4256 return PluginResult.SubordinateDelete.stopProcessing( 4257 DirectoryServer.getServerErrorResultCode(), message); 4258 } 4259 4260 if (result == null) 4261 { 4262 LocalizableMessage message = 4263 ERR_PLUGIN_SUBORDINATE_DELETE_PLUGIN_RETURNED_NULL.get( 4264 p.getPluginEntryDN(), 4265 deleteOperation.getConnectionID(), 4266 deleteOperation.getOperationID()); 4267 logger.error(message); 4268 4269 return PluginResult.SubordinateDelete.stopProcessing( 4270 DirectoryServer.getServerErrorResultCode(), message); 4271 } 4272 else if (! result.continuePluginProcessing()) 4273 { 4274 return result; 4275 } 4276 } 4277 4278 if (result == null) 4279 { 4280 // This should only happen if there were no subordinate modify DN plugins 4281 // registered, which is fine. 4282 result = PluginResult.SubordinateDelete.continueOperationProcessing(); 4283 } 4284 4285 return result; 4286 } 4287 4288 /** 4289 * Invokes the set of intermediate response plugins that have been configured 4290 * in the Directory Server. 4291 * 4292 * @param intermediateResponse The intermediate response for which to invoke 4293 * the intermediate response plugins. 4294 * 4295 * @return The result of processing the intermediate response plugins. 4296 */ 4297 public PluginResult.IntermediateResponse 4298 invokeIntermediateResponsePlugins( 4299 IntermediateResponse intermediateResponse) 4300 { 4301 PluginResult.IntermediateResponse result = null; 4302 Operation operation = intermediateResponse.getOperation(); 4303 4304 for (DirectoryServerPlugin p : intermediateResponsePlugins) 4305 { 4306 try 4307 { 4308 result = p.processIntermediateResponse(intermediateResponse); 4309 } 4310 catch (Exception e) 4311 { 4312 logger.traceException(e); 4313 4314 LocalizableMessage message = ERR_PLUGIN_INTERMEDIATE_RESPONSE_PLUGIN_EXCEPTION. 4315 get(p.getPluginEntryDN(), 4316 operation.getConnectionID(), operation.getOperationID(), 4317 stackTraceToSingleLineString(e)); 4318 logger.error(message); 4319 4320 return PluginResult.IntermediateResponse.stopProcessing 4321 (false, DirectoryServer.getServerErrorResultCode(), message); 4322 } 4323 4324 if (result == null) 4325 { 4326 LocalizableMessage message = ERR_PLUGIN_INTERMEDIATE_RESPONSE_PLUGIN_RETURNED_NULL. 4327 get(p.getPluginEntryDN(), 4328 operation.getConnectionID(), operation.getOperationID()); 4329 logger.error(message); 4330 4331 return PluginResult.IntermediateResponse.stopProcessing 4332 (false, DirectoryServer.getServerErrorResultCode(), message); 4333 } 4334 else if (! result.continuePluginProcessing()) 4335 { 4336 return result; 4337 } 4338 } 4339 4340 if (result == null) 4341 { 4342 // This should only happen if there were no intermediate response plugins 4343 // registered, which is fine.WARN 4344 4345 result = 4346 PluginResult.IntermediateResponse.continueOperationProcessing(true); 4347 } 4348 4349 return result; 4350 } 4351 4352 @Override 4353 public boolean isConfigurationAddAcceptable(PluginCfg configuration, 4354 List<LocalizableMessage> unacceptableReasons) 4355 { 4356 if (configuration.isEnabled()) 4357 { 4358 HashSet<PluginType> pluginTypes = getPluginTypes(configuration); 4359 4360 // Get the name of the class and make sure we can instantiate it as a plugin. 4361 String className = configuration.getJavaClass(); 4362 try 4363 { 4364 loadPlugin(className, pluginTypes, configuration, false); 4365 } 4366 catch (InitializationException ie) 4367 { 4368 unacceptableReasons.add(ie.getMessageObject()); 4369 return false; 4370 } 4371 } 4372 4373 // If we've gotten here, then it's fine. 4374 return true; 4375 } 4376 4377 @Override 4378 public ConfigChangeResult applyConfigurationAdd( 4379 PluginCfg configuration) 4380 { 4381 final ConfigChangeResult ccr = new ConfigChangeResult(); 4382 4383 configuration.addChangeListener(this); 4384 4385 if (! configuration.isEnabled()) 4386 { 4387 return ccr; 4388 } 4389 4390 HashSet<PluginType> pluginTypes = getPluginTypes(configuration); 4391 4392 // Get the name of the class and make sure we can instantiate it as a plugin. 4393 DirectoryServerPlugin<? extends PluginCfg> plugin = null; 4394 String className = configuration.getJavaClass(); 4395 try 4396 { 4397 plugin = loadPlugin(className, pluginTypes, configuration, true); 4398 } 4399 catch (InitializationException ie) 4400 { 4401 ccr.setResultCodeIfSuccess(DirectoryServer.getServerErrorResultCode()); 4402 ccr.addMessage(ie.getMessageObject()); 4403 } 4404 4405 if (ccr.getResultCode() == ResultCode.SUCCESS) 4406 { 4407 registerPlugin(plugin, configuration.dn(), pluginTypes); 4408 } 4409 4410 return ccr; 4411 } 4412 4413 @Override 4414 public boolean isConfigurationDeleteAcceptable( 4415 PluginCfg configuration, 4416 List<LocalizableMessage> unacceptableReasons) 4417 { 4418 // We will always allow plugins to be removed. 4419 return true; 4420 } 4421 4422 @Override 4423 public ConfigChangeResult applyConfigurationDelete( 4424 PluginCfg configuration) 4425 { 4426 final ConfigChangeResult ccr = new ConfigChangeResult(); 4427 4428 deregisterPlugin(configuration.dn()); 4429 4430 return ccr; 4431 } 4432 4433 @Override 4434 public boolean isConfigurationChangeAcceptable( 4435 PluginCfg configuration, 4436 List<LocalizableMessage> unacceptableReasons) 4437 { 4438 if (configuration.isEnabled()) 4439 { 4440 HashSet<PluginType> pluginTypes = getPluginTypes(configuration); 4441 4442 // Get the name of the class and make sure we can instantiate it as a plugin. 4443 String className = configuration.getJavaClass(); 4444 try 4445 { 4446 loadPlugin(className, pluginTypes, configuration, false); 4447 } 4448 catch (InitializationException ie) 4449 { 4450 unacceptableReasons.add(ie.getMessageObject()); 4451 return false; 4452 } 4453 } 4454 4455 // If we've gotten here, then it's fine. 4456 return true; 4457 } 4458 4459 @Override 4460 public ConfigChangeResult applyConfigurationChange( 4461 PluginCfg configuration) 4462 { 4463 final ConfigChangeResult ccr = new ConfigChangeResult(); 4464 4465 // Get the existing plugin if it's already enabled. 4466 DirectoryServerPlugin existingPlugin = 4467 registeredPlugins.get(configuration.dn()); 4468 4469 // If the new configuration has the plugin disabled, then deregister it if 4470 // it is enabled, or do nothing if it's already disabled. 4471 if (! configuration.isEnabled()) 4472 { 4473 if (existingPlugin != null) 4474 { 4475 deregisterPlugin(configuration.dn()); 4476 } 4477 4478 return ccr; 4479 } 4480 4481 // Get the class for the identity mapper. If the mapper is already enabled, 4482 // then we shouldn't do anything with it although if the class has changed 4483 // then we'll at least need to indicate that administrative action is 4484 // required. If the mapper is disabled, then instantiate the class and 4485 // initialize and register it as an identity mapper. Also, update the 4486 // plugin to indicate whether it should be invoked for internal operations. 4487 String className = configuration.getJavaClass(); 4488 if (existingPlugin != null) 4489 { 4490 if (! className.equals(existingPlugin.getClass().getName())) 4491 { 4492 ccr.setAdminActionRequired(true); 4493 } 4494 4495 existingPlugin.setInvokeForInternalOperations( 4496 configuration.isInvokeForInternalOperations()); 4497 4498 return ccr; 4499 } 4500 4501 // Create a set of plugin types for the plugin. 4502 HashSet<PluginType> pluginTypes = getPluginTypes(configuration); 4503 4504 DirectoryServerPlugin<? extends PluginCfg> plugin = null; 4505 try 4506 { 4507 plugin = loadPlugin(className, pluginTypes, configuration, true); 4508 } 4509 catch (InitializationException ie) 4510 { 4511 ccr.setResultCodeIfSuccess(DirectoryServer.getServerErrorResultCode()); 4512 ccr.addMessage(ie.getMessageObject()); 4513 } 4514 4515 if (ccr.getResultCode() == ResultCode.SUCCESS) 4516 { 4517 registerPlugin(plugin, configuration.dn(), pluginTypes); 4518 } 4519 4520 return ccr; 4521 } 4522 4523 private HashSet<PluginType> getPluginTypes(PluginCfg configuration) 4524 { 4525 HashSet<PluginType> pluginTypes = new HashSet<>(); 4526 for (PluginCfgDefn.PluginType pluginType : configuration.getPluginType()) 4527 { 4528 pluginTypes.add(getPluginType(pluginType)); 4529 } 4530 return pluginTypes; 4531 } 4532 4533 private void registerSkippedPreOperationPlugins(int i, 4534 DirectoryServerPlugin[] plugins, 4535 PluginOperation operation) 4536 { 4537 ArrayList<DirectoryServerPlugin> skippedPlugins = new ArrayList<>(plugins.length - i); 4538 for(int j = i; j < plugins.length; j++) 4539 { 4540 skippedPlugins.add(plugins[j]); 4541 } 4542 skippedPreOperationPlugins.put(operation, skippedPlugins); 4543 } 4544 4545 private void registerSkippedPreOperationPlugin(DirectoryServerPlugin plugin, 4546 PluginOperation operation) 4547 { 4548 ArrayList<DirectoryServerPlugin> existingList = 4549 skippedPreOperationPlugins.get(operation); 4550 if(existingList == null) 4551 { 4552 existingList = new ArrayList<>(); 4553 } 4554 existingList.add(plugin); 4555 skippedPreOperationPlugins.put(operation, existingList); 4556 } 4557}