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