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