From 93240e26b8bb610e87ba12194f82cfe41fafcabc Mon Sep 17 00:00:00 2001
From: jcambon <jcambon@localhost>
Date: Wed, 18 Jun 2008 08:48:26 +0000
Subject: [PATCH] New top level object in RootConfiguration.xml : "extension", that allows to create a configuration object for an extension, that does not inherit from an existing configuration object.
---
opends/resource/schema/02-config.ldif | 8
opends/src/messages/messages/config.properties | 7
opends/src/server/org/opends/server/core/DirectoryServer.java | 72 +++++
opends/src/server/org/opends/server/api/Extension.java | 114 ++++++++
opends/src/admin/defn/org/opends/server/admin/std/ExtensionConfiguration.xml | 90 ++++++
opends/src/admin/defn/org/opends/server/admin/std/RootConfiguration.xml | 6
opends/src/server/org/opends/server/core/ExtensionConfigManager.java | 448 ++++++++++++++++++++++++++++++++++
opends/resource/config/config.ldif | 6
8 files changed, 751 insertions(+), 0 deletions(-)
diff --git a/opends/resource/config/config.ldif b/opends/resource/config/config.ldif
index 3b762ca..ecfb9f5 100644
--- a/opends/resource/config/config.ldif
+++ b/opends/resource/config/config.ldif
@@ -2220,3 +2220,9 @@
ds-cfg-num-worker-threads: 24
ds-cfg-max-work-queue-capacity: 0
+dn: cn=Extensions,cn=config
+objectClass: top
+objectClass: ds-cfg-branch
+objectClass: ds-cfg-plugin-root
+cn: Extensions
+
diff --git a/opends/resource/schema/02-config.ldif b/opends/resource/schema/02-config.ldif
index 0934302..b4a5b9e 100644
--- a/opends/resource/schema/02-config.ldif
+++ b/opends/resource/schema/02-config.ldif
@@ -3737,3 +3737,11 @@
ds-cfg-security-agent-file $
ds-cfg-opendmk-jarfile )
X-ORIGIN 'OpenDS Directory Server' )
+objectClasses: ( 1.3.6.1.4.1.26027.1.2.182
+ NAME 'ds-cfg-extension'
+ SUP top
+ STRUCTURAL
+ MUST ( cn $
+ ds-cfg-java-class $
+ ds-cfg-enabled )
+ X-ORIGIN 'OpenDS Directory Server' )
diff --git a/opends/src/admin/defn/org/opends/server/admin/std/ExtensionConfiguration.xml b/opends/src/admin/defn/org/opends/server/admin/std/ExtensionConfiguration.xml
new file mode 100644
index 0000000..b05c233
--- /dev/null
+++ b/opends/src/admin/defn/org/opends/server/admin/std/ExtensionConfiguration.xml
@@ -0,0 +1,90 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ ! CDDL HEADER START
+ !
+ ! The contents of this file are subject to the terms of the
+ ! Common Development and Distribution License, Version 1.0 only
+ ! (the "License"). You may not use this file except in compliance
+ ! with the License.
+ !
+ ! You can obtain a copy of the license at
+ ! trunk/opends/resource/legal-notices/OpenDS.LICENSE
+ ! or https://OpenDS.dev.java.net/OpenDS.LICENSE.
+ ! See the License for the specific language governing permissions
+ ! and limitations under the License.
+ !
+ ! When distributing Covered Code, include this CDDL HEADER in each
+ ! file and include the License file at
+ ! trunk/opends/resource/legal-notices/OpenDS.LICENSE. If applicable,
+ ! add the following below this CDDL HEADER, with the fields enclosed
+ ! by brackets "[]" replaced with your own identifying information:
+ ! Portions Copyright [yyyy] [name of copyright owner]
+ !
+ ! CDDL HEADER END
+ !
+ !
+ ! Copyright 2007-2008 Sun Microsystems, Inc.
+ ! -->
+<adm:managed-object name="extension"
+ plural-name="extensions"
+ package="org.opends.server.admin.std"
+ xmlns:adm="http://www.opends.org/admin"
+ xmlns:ldap="http://www.opends.org/admin-ldap"
+ xmlns:cli="http://www.opends.org/admin-cli">
+ <adm:synopsis>
+ The
+ <adm:user-friendly-name />
+ allows to extend the configuration with new type of objects.
+ </adm:synopsis>
+ <adm:description>
+ It is an entry point for extensions that requires configuration objects
+ that does not inherit from an existing top-level object.
+ </adm:description>
+ <adm:tag name="core-server" />
+ <adm:profile name="ldap">
+ <ldap:object-class>
+ <ldap:name>ds-cfg-extension</ldap:name>
+ <ldap:superior>top</ldap:superior>
+ </ldap:object-class>
+ </adm:profile>
+ <adm:profile name="cli">
+ <cli:managed-object custom="true" />
+ </adm:profile>
+ <adm:property name="enabled" mandatory="true">
+ <adm:synopsis>
+ Indicates whether the
+ <adm:user-friendly-name />
+ is enabled.
+ </adm:synopsis>
+ <adm:syntax>
+ <adm:boolean />
+ </adm:syntax>
+ <adm:profile name="ldap">
+ <ldap:attribute>
+ <ldap:name>ds-cfg-enabled</ldap:name>
+ </ldap:attribute>
+ </adm:profile>
+ </adm:property>
+ <adm:property name="java-class" mandatory="true">
+ <adm:synopsis>
+ Specifies the fully-qualified name of the Java class that provides the
+ <adm:user-friendly-name />
+ implementation.
+ </adm:synopsis>
+ <adm:requires-admin-action>
+ <adm:component-restart />
+ </adm:requires-admin-action>
+ <adm:syntax>
+ <adm:java-class>
+ <adm:instance-of>
+ org.opends.server.api.Extension
+ </adm:instance-of>
+ </adm:java-class>
+ </adm:syntax>
+ <adm:profile name="ldap">
+ <ldap:attribute>
+ <ldap:name>ds-cfg-java-class</ldap:name>
+ </ldap:attribute>
+ </adm:profile>
+ </adm:property>
+</adm:managed-object>
diff --git a/opends/src/admin/defn/org/opends/server/admin/std/RootConfiguration.xml b/opends/src/admin/defn/org/opends/server/admin/std/RootConfiguration.xml
index 3a5bbef..0f4f5aa 100644
--- a/opends/src/admin/defn/org/opends/server/admin/std/RootConfiguration.xml
+++ b/opends/src/admin/defn/org/opends/server/admin/std/RootConfiguration.xml
@@ -450,6 +450,12 @@
</cli:relation>
</adm:profile>
</adm:relation>
+ <adm:relation name="extension">
+ <adm:one-to-many />
+ <adm:profile name="ldap">
+ <ldap:rdn-sequence>cn=Extensions,cn=config</ldap:rdn-sequence>
+ </adm:profile>
+ </adm:relation>
<adm:product-name>OpenDS Directory Server</adm:product-name>
<adm:tag-definition name="logging">
<adm:synopsis>Logging</adm:synopsis>
diff --git a/opends/src/messages/messages/config.properties b/opends/src/messages/messages/config.properties
index 960e3ef..38acbca 100644
--- a/opends/src/messages/messages/config.properties
+++ b/opends/src/messages/messages/config.properties
@@ -2138,3 +2138,10 @@
SEVERE_ERR_CONFIG_LOGGING_INSANE_MODE_715=Invalid UNIX file permissions %s \
does not allow write access to the log file by the log publisher
SEVERE_ERR_CONFIG_LOGGING_MODE_INVALID_716=Invalid UNIX file permissions %s: %s
+MILD_ERR_CONFIG_EXTENSION_CONFIG_NOT_ACCEPTABLE_717=The configuration for \
+ the extension defined in configuration entry %s was not \
+ acceptable: %s
+MILD_ERR_CONFIG_EXTENSION_INITIALIZATION_FAILED_718=An error occurred while \
+ trying to initialize an instance of class %s as an extension as \
+ defined in configuration entry %s: %s
+
diff --git a/opends/src/server/org/opends/server/api/Extension.java b/opends/src/server/org/opends/server/api/Extension.java
new file mode 100644
index 0000000..72a46f8
--- /dev/null
+++ b/opends/src/server/org/opends/server/api/Extension.java
@@ -0,0 +1,114 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License, Version 1.0 only
+ * (the "License"). You may not use this file except in compliance
+ * with the License.
+ *
+ * You can obtain a copy of the license at
+ * trunk/opends/resource/legal-notices/OpenDS.LICENSE
+ * or https://OpenDS.dev.java.net/OpenDS.LICENSE.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at
+ * trunk/opends/resource/legal-notices/OpenDS.LICENSE. If applicable,
+ * add the following below this CDDL HEADER, with the fields enclosed
+ * by brackets "[]" replaced with your own identifying information:
+ * Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ *
+ *
+ * Copyright 2006-2008 Sun Microsystems, Inc.
+ */
+package org.opends.server.api;
+
+import org.opends.messages.Message;
+
+import java.util.List;
+import org.opends.server.admin.std.server.ExtensionCfg;
+import org.opends.server.config.ConfigException;
+import org.opends.server.types.InitializationException;
+
+
+
+/**
+ * This class defines the set of methods and structures that must be
+ * implemented by a Directory Server extension.
+ *
+ * @param <T>
+ * The type of extension configuration handled by
+ * this extension implementation.
+ */
+@org.opends.server.types.PublicAPI(
+ stability=org.opends.server.types.StabilityLevel.VOLATILE,
+ mayInstantiate=false,
+ mayExtend=true,
+ mayInvoke=true)
+public abstract class Extension
+ <T extends ExtensionCfg>
+{
+ /**
+ * Initializes this extension based on the
+ * information in the provided extension configuration.
+ *
+ * @param configuration
+ * The extension configuration that contains the
+ * information to use to initialize this connection
+ * handler.
+ * @throws ConfigException
+ * If an unrecoverable problem arises in the process of
+ * performing the initialization as a result of the server
+ * configuration.
+ * @throws InitializationException
+ * If a problem occurs during initialization that is not
+ * related to the server configuration.
+ */
+ public abstract void initializeExtension(T configuration)
+ throws ConfigException, InitializationException;
+
+
+
+ /**
+ * Indicates whether the provided configuration is acceptable for
+ * this extension. It should be possible to call this
+ * method on an uninitialized extension instance in order
+ * to determine whether the extension would be able to use
+ * the provided configuration.
+ * <BR><BR>
+ * Note that implementations which use a subclass of the provided
+ * configuration class will likely need to cast the configuration
+ * to the appropriate subclass type.
+ *
+ * @param configuration The extension configuration
+ * for which to make the determination.
+ * @param unacceptableReasons A list that may be used to hold the
+ * reasons that the provided
+ * configuration is not acceptable.
+ *
+ * @return {@code true} if the provided configuration is acceptable
+ * for this extension, or {@code false} if not.
+ */
+ public boolean isConfigurationAcceptable(
+ ExtensionCfg configuration,
+ List<Message> unacceptableReasons)
+ {
+ // This default implementation does not perform any special
+ // validation. It should be overridden by extension
+ // implementations that wish to perform more detailed validation.
+ return true;
+ }
+
+
+
+ /**
+ * Performs any finalization that may be necessary for
+ * this extension.
+ *
+ */
+ public abstract void finalizeExtension();
+
+ }
diff --git a/opends/src/server/org/opends/server/core/DirectoryServer.java b/opends/src/server/org/opends/server/core/DirectoryServer.java
index efbf7f0..4d108ef 100644
--- a/opends/src/server/org/opends/server/core/DirectoryServer.java
+++ b/opends/src/server/org/opends/server/core/DirectoryServer.java
@@ -56,6 +56,7 @@
import org.opends.server.api.ImportTaskListener;
import org.opends.server.api.InvokableComponent;
import org.opends.server.api.KeyManagerProvider;
+import org.opends.server.api.Extension;
import org.opends.server.api.MatchingRule;
import org.opends.server.api.MonitorProvider;
import org.opends.server.api.OrderingMatchingRule;
@@ -400,6 +401,9 @@
// The set of key manager providers registered with the server.
private ConcurrentHashMap<DN,KeyManagerProvider> keyManagerProviders;
+ // The set of extensions registered with the server.
+ private ConcurrentHashMap<DN,Extension> extensions;
+
// The set of password generators registered with the Directory Server, as a
// mapping between the DN of the associated configuration entry and the
// generator implementation.
@@ -577,6 +581,9 @@
// The key manager provider configuration manager for the Directory Server.
private KeyManagerProviderConfigManager keyManagerProviderConfigManager;
+ // The extension configuration manager for the Directory Server.
+ private ExtensionConfigManager extensionConfigManager;
+
// The set of connections that are currently established.
private LinkedHashSet<ClientConnection> establishedConnections;
@@ -896,6 +903,8 @@
directoryServer.alternateRootBindDNs = new ConcurrentHashMap<DN,DN>();
directoryServer.keyManagerProviders =
new ConcurrentHashMap<DN,KeyManagerProvider>();
+ directoryServer.extensions =
+ new ConcurrentHashMap<DN,Extension>();
directoryServer.trustManagerProviders =
new ConcurrentHashMap<DN,TrustManagerProvider>();
directoryServer.rotationPolicies =
@@ -1326,6 +1335,11 @@
keyManagerProviderConfigManager.initializeKeyManagerProviders();
+ // Initialize the extension.
+ extensionConfigManager = new ExtensionConfigManager();
+ extensionConfigManager.initializeExtensions();
+
+
// Initialize the trust manager provider.
trustManagerProviderConfigManager =
new TrustManagerProviderConfigManager();
@@ -7631,6 +7645,64 @@
/**
+ * Retrieves the set of extensions registered with the Directory
+ * Server.
+ *
+ * @return The set of extensions registered with the Directory
+ * Server.
+ */
+ public static Map<DN,Extension> getExtensions()
+ {
+ return directoryServer.extensions;
+ }
+
+
+
+ /**
+ * Retrieves the extension registered with the provided entry DN.
+ *
+ * @param providerDN The DN with which the extension is
+ * registered.
+ *
+ * @return The extension registered with the provided entry DN, or
+ * {@code null} if there is no such extension registered
+ * with the server.
+ */
+ public static Extension getExtension(DN providerDN)
+ {
+ return directoryServer.extensions.get(providerDN);
+ }
+
+
+
+ /**
+ * Registers the provided extension with the Directory Server.
+ *
+ * @param providerDN The DN with which to register the extension.
+ * @param provider The extension to register with the server.
+ */
+ public static void registerExtension(DN providerDN,
+ Extension provider)
+ {
+ directoryServer.extensions.put(providerDN, provider);
+ }
+
+
+
+ /**
+ * Deregisters the specified extension with the Directory Server.
+ *
+ * @param providerDN The DN with which the extension is
+ * registered.
+ */
+ public static void deregisterExtension(DN providerDN)
+ {
+ directoryServer.extensions.remove(providerDN);
+ }
+
+
+
+ /**
* Retrieves a set containing the names of the allowed tasks that may be
* invoked in the server.
*
diff --git a/opends/src/server/org/opends/server/core/ExtensionConfigManager.java b/opends/src/server/org/opends/server/core/ExtensionConfigManager.java
new file mode 100644
index 0000000..745270c
--- /dev/null
+++ b/opends/src/server/org/opends/server/core/ExtensionConfigManager.java
@@ -0,0 +1,448 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License, Version 1.0 only
+ * (the "License"). You may not use this file except in compliance
+ * with the License.
+ *
+ * You can obtain a copy of the license at
+ * trunk/opends/resource/legal-notices/OpenDS.LICENSE
+ * or https://OpenDS.dev.java.net/OpenDS.LICENSE.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at
+ * trunk/opends/resource/legal-notices/OpenDS.LICENSE. If applicable,
+ * add the following below this CDDL HEADER, with the fields enclosed
+ * by brackets "[]" replaced with your own identifying information:
+ * Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ *
+ *
+ * Copyright 2006-2008 Sun Microsystems, Inc.
+ */
+package org.opends.server.core;
+import org.opends.messages.Message;
+
+
+
+import java.lang.reflect.Method;
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+import java.util.concurrent.ConcurrentHashMap;
+
+import org.opends.server.admin.ClassPropertyDefinition;
+import org.opends.server.admin.server.ConfigurationAddListener;
+import org.opends.server.admin.server.ConfigurationChangeListener;
+import org.opends.server.admin.server.ConfigurationDeleteListener;
+import org.opends.server.admin.std.meta.ExtensionCfgDefn;
+import org.opends.server.admin.std.server.ExtensionCfg;
+import org.opends.server.admin.std.server.RootCfg;
+import org.opends.server.admin.server.ServerManagementContext;
+import org.opends.server.api.Extension;
+import org.opends.server.config.ConfigException;
+import org.opends.server.types.ConfigChangeResult;
+import org.opends.server.types.DN;
+import org.opends.server.types.InitializationException;
+import org.opends.server.types.ResultCode;
+
+import static org.opends.messages.ConfigMessages.*;
+
+import static org.opends.server.loggers.ErrorLogger.*;
+import static org.opends.server.util.StaticUtils.*;
+
+
+
+/**
+ * This class defines a utility that will be used to manage the set of
+ * extensions defined in the Directory Server. It will initialize the
+ * extensions when the server starts, and then will manage any
+ * additions, removals, or modifications to any extensions while
+ * the server is running.
+ */
+public class ExtensionConfigManager
+ implements ConfigurationChangeListener<ExtensionCfg>,
+ ConfigurationAddListener<ExtensionCfg>,
+ ConfigurationDeleteListener<ExtensionCfg>
+
+{
+ // A mapping between the DNs of the config entries and the associated
+ // extensions.
+ private ConcurrentHashMap<DN,Extension> extensions;
+
+
+
+ /**
+ * Creates a new instance of this extension config manager.
+ */
+ public ExtensionConfigManager()
+ {
+ extensions = new ConcurrentHashMap<DN,Extension>();
+ }
+
+
+
+ /**
+ * Initializes all extensions currently defined in the Directory
+ * Server configuration. This should only be called at Directory Server
+ * startup.
+ *
+ * @throws ConfigException If a configuration problem causes the
+ * extension initialization process to fail.
+ *
+ * @throws InitializationException If a problem occurs while initializing
+ * the extensions that is not
+ * related to the server configuration.
+ */
+ public void initializeExtensions()
+ throws ConfigException, InitializationException
+ {
+ // Get the root configuration object.
+ ServerManagementContext managementContext =
+ ServerManagementContext.getInstance();
+ RootCfg rootConfiguration =
+ managementContext.getRootConfiguration();
+
+
+ // Register as an add and delete listener with the root configuration so we
+ // can be notified if any extension entries are added or removed.
+ rootConfiguration.addExtensionAddListener(this);
+ rootConfiguration.addExtensionDeleteListener(this);
+
+
+ //Initialize the existing extensions.
+ for (String name : rootConfiguration.listExtensions())
+ {
+ ExtensionCfg extensionConfig =
+ rootConfiguration.getExtension(name);
+ extensionConfig.addChangeListener(this);
+
+ if (extensionConfig.isEnabled())
+ {
+ String className = extensionConfig.getJavaClass();
+ try
+ {
+ Extension extension =
+ loadExtension(className, extensionConfig, true);
+ extensions.put(extensionConfig.dn(), extension);
+ DirectoryServer.registerExtension(extensionConfig.dn(),
+ extension);
+ }
+ catch (InitializationException ie)
+ {
+ logError(ie.getMessageObject());
+ continue;
+ }
+ }
+ }
+ }
+
+
+
+ /**
+ * {@inheritDoc}
+ */
+ public boolean isConfigurationAddAcceptable(
+ ExtensionCfg configuration,
+ List<Message> unacceptableReasons)
+ {
+ if (configuration.isEnabled())
+ {
+ // Get the name of the class and make sure we can instantiate it as a
+ // extension.
+ String className = configuration.getJavaClass();
+ try
+ {
+ loadExtension(className, configuration, false);
+ }
+ catch (InitializationException ie)
+ {
+ unacceptableReasons.add(ie.getMessageObject());
+ return false;
+ }
+ }
+
+ // If we've gotten here, then it's fine.
+ return true;
+ }
+
+
+
+ /**
+ * {@inheritDoc}
+ */
+ public ConfigChangeResult applyConfigurationAdd(
+ ExtensionCfg configuration)
+ {
+ ResultCode resultCode = ResultCode.SUCCESS;
+ boolean adminActionRequired = false;
+ ArrayList<Message> messages = new ArrayList<Message>();
+
+ configuration.addChangeListener(this);
+
+ if (! configuration.isEnabled())
+ {
+ return new ConfigChangeResult(resultCode, adminActionRequired, messages);
+ }
+
+ Extension extension = null;
+
+ // Get the name of the class and make sure we can instantiate it as an
+ // extension.
+ String className = configuration.getJavaClass();
+ try
+ {
+ extension = loadExtension(className, configuration, true);
+ }
+ catch (InitializationException ie)
+ {
+ if (resultCode == ResultCode.SUCCESS)
+ {
+ resultCode = DirectoryServer.getServerErrorResultCode();
+ }
+
+ messages.add(ie.getMessageObject());
+ }
+
+ if (resultCode == ResultCode.SUCCESS)
+ {
+ extensions.put(configuration.dn(), extension);
+ DirectoryServer.registerExtension(configuration.dn(), extension);
+ }
+
+ return new ConfigChangeResult(resultCode, adminActionRequired, messages);
+ }
+
+
+
+ /**
+ * {@inheritDoc}
+ */
+ public boolean isConfigurationDeleteAcceptable(
+ ExtensionCfg configuration,
+ List<Message> unacceptableReasons)
+ {
+ return true;
+ }
+
+
+
+ /**
+ * {@inheritDoc}
+ */
+ public ConfigChangeResult applyConfigurationDelete(
+ ExtensionCfg configuration)
+ {
+ ResultCode resultCode = ResultCode.SUCCESS;
+ boolean adminActionRequired = false;
+ ArrayList<Message> messages = new ArrayList<Message>();
+
+ DirectoryServer.deregisterExtension(configuration.dn());
+
+ Extension extension = extensions.remove(configuration.dn());
+ if (extension != null)
+ {
+ extension.finalizeExtension();
+ }
+
+ return new ConfigChangeResult(resultCode, adminActionRequired, messages);
+ }
+
+
+
+ /**
+ * {@inheritDoc}
+ */
+ public boolean isConfigurationChangeAcceptable(
+ ExtensionCfg configuration,
+ List<Message> unacceptableReasons)
+ {
+ if (configuration.isEnabled())
+ {
+ // Get the name of the class and make sure we can instantiate it as an
+ // extension.
+ String className = configuration.getJavaClass();
+ try
+ {
+ loadExtension(className, configuration, false);
+ }
+ catch (InitializationException ie)
+ {
+ unacceptableReasons.add(ie.getMessageObject());
+ return false;
+ }
+ }
+
+ // If we've gotten here, then it's fine.
+ return true;
+ }
+
+
+
+ /**
+ * {@inheritDoc}
+ */
+ public ConfigChangeResult applyConfigurationChange(
+ ExtensionCfg configuration)
+ {
+ ResultCode resultCode = ResultCode.SUCCESS;
+ boolean adminActionRequired = false;
+ ArrayList<Message> messages = new ArrayList<Message>();
+
+
+ // Get the existing extension if it's already enabled.
+ Extension existingExtension = extensions.get(configuration.dn());
+
+
+ // If the new configuration has the extension disabled, then disable it if
+ // it is enabled, or do nothing if it's already disabled.
+ if (! configuration.isEnabled())
+ {
+ if (existingExtension != null)
+ {
+ DirectoryServer.deregisterExtension(configuration.dn());
+
+ Extension extension = extensions.remove(configuration.dn());
+ if (extension != null)
+ {
+ extension.finalizeExtension();
+ }
+ }
+
+ return new ConfigChangeResult(resultCode, adminActionRequired, messages);
+ }
+
+
+ // Get the class for the extension. If the extension is already
+ // enabled, then we shouldn't do anything with it although if the class has
+ // changed then we'll at least need to indicate that administrative action
+ // is required. If the extension is disabled, then instantiate the class
+ // and initialize and register it as a extension.
+ String className = configuration.getJavaClass();
+ if (existingExtension != null)
+ {
+ if (! className.equals(existingExtension.getClass().getName()))
+ {
+ adminActionRequired = true;
+ }
+
+ return new ConfigChangeResult(resultCode, adminActionRequired, messages);
+ }
+
+ Extension extension = null;
+ try
+ {
+ extension = loadExtension(className, configuration, true);
+ }
+ catch (InitializationException ie)
+ {
+ if (resultCode == ResultCode.SUCCESS)
+ {
+ resultCode = DirectoryServer.getServerErrorResultCode();
+ }
+
+ messages.add(ie.getMessageObject());
+ }
+
+ if (resultCode == ResultCode.SUCCESS)
+ {
+ extensions.put(configuration.dn(), extension);
+ DirectoryServer.registerExtension(configuration.dn(), extension);
+ }
+
+ return new ConfigChangeResult(resultCode, adminActionRequired, messages);
+ }
+
+
+
+ /**
+ * Loads the specified class, instantiates it as a extension, and
+ * optionally initializes that instance.
+ *
+ * @param className The fully-qualified name of the extension
+ * class to load, instantiate, and initialize.
+ * @param configuration The configuration to use to initialize the
+ * extension. It must not be {@code null}.
+ * @param initialize Indicates whether the extension instance
+ * should be initialized.
+ *
+ * @return The possibly initialized extension.
+ *
+ * @throws InitializationException If the provided configuration is not
+ * acceptable, or if a problem occurred
+ * while attempting to initialize the
+ * extension using that
+ * configuration.
+ */
+ private Extension loadExtension(String className,
+ ExtensionCfg configuration,
+ boolean initialize)
+ throws InitializationException
+ {
+ try
+ {
+ ExtensionCfgDefn definition =
+ ExtensionCfgDefn.getInstance();
+ ClassPropertyDefinition propertyDefinition =
+ definition.getJavaClassPropertyDefinition();
+ Class<? extends Extension> extensionClass =
+ propertyDefinition.loadClass(className, Extension.class);
+ Extension extension = extensionClass.newInstance();
+
+
+ if (initialize)
+ {
+ Method method = extension.getClass().getMethod(
+ "initializeExtension", configuration.configurationClass());
+ method.invoke(extension, configuration);
+ }
+ else
+ {
+ Method method =
+ extension.getClass().getMethod("isConfigurationAcceptable",
+ ExtensionCfg.class,
+ List.class);
+
+ List<Message> unacceptableReasons = new ArrayList<Message>();
+ Boolean acceptable = (Boolean) method.invoke(extension, configuration,
+ unacceptableReasons);
+ if (! acceptable)
+ {
+ StringBuilder buffer = new StringBuilder();
+ if (! unacceptableReasons.isEmpty())
+ {
+ Iterator<Message> iterator = unacceptableReasons.iterator();
+ buffer.append(iterator.next());
+ while (iterator.hasNext())
+ {
+ buffer.append(". ");
+ buffer.append(iterator.next());
+ }
+ }
+
+ Message message = ERR_CONFIG_EXTENSION_CONFIG_NOT_ACCEPTABLE.get(
+ String.valueOf(configuration.dn()), buffer.toString());
+ throw new InitializationException(message);
+ }
+ }
+
+ return extension;
+ }
+ catch (InitializationException ie)
+ {
+ throw ie;
+ }
+ catch (Exception e)
+ {
+ Message message = ERR_CONFIG_EXTENSION_INITIALIZATION_FAILED.
+ get(className, String.valueOf(configuration.dn()),
+ stackTraceToSingleLineString(e));
+ throw new InitializationException(message, e);
+ }
+ }
+}
+
--
Gitblit v1.10.0