Configuration OpenLDAP Documentum 6.5
Cet article va permettre d'étudier la mise en place de OpenLDAP sur un serveur Documentum en version 6.5, suite à l'erreur constatée lors de la tentative de création, voir Configuration OpenLDAP Documentum. Les sources de cette analyse sont disponible sur http://www.jouvinio.net/svn/study/branches/documentum/6.5_SP1/Server/dmldap/
Sommaire
Synchronisation des utilisateurs
Une fois la configuration de LDAP réalisée sur OpenLDAP, il est nécessaire de modifier le job de synchronisation. En effet, malgré la bonne configuration, des erreurs se produisent.
Etude Job
La synchronisation s'effectue par le job dm_LDAPSynchronization
qui va exécutée la méthode du même nom.
DQL> select dm_method.object_name as methodname, dm_method.method_verb, dm_job.object_name as jobname from dm_method, dm_job where dm_job.object_name = 'dm_LDAPSynchronization' and dm_job.method_name = dm_method.object_name; methodname method_verb jobname ====================== ============================ ======================= dm_LDAPSynchronization com.documentum.ldap.LDAPSync dm_LDAPSynchronization
Le contenu de cette méthode serveur se trouve dans le fichier dmldap.jar
déployé sur le serveur de méthode.
Etude Méthode
L'annuaire OpenLDAP étant configuré comme un annuaire Sun
, la classe com.documentum.ldap.internal.processors.com.documentum.ldap.internal.processors
sera instanciée lors de la création du processeur depuis l'instance de com.documentum.ldap.internal.processors.DirectoryProcessorFactory
. Cette instance est créée depuis la méthode prepareSync
de la classe com.documentum.ldap.LDAPSync
.
private void prepareSync(IDfSysObject ldapConfigObject)
throws DmLdapException
{
m_synchronizationContext = new SynchronizationContext();
m_synchronizationContextBuilder.buildSynchronizationContext(ldapConfigObject, m_jobArgs, m_synchronizationContext);
m_userSynchronization = null;
m_groupSynchronization = null;
DirectoryProcessorFactory dirProcessorFactory = DirectoryProcessorFactory.getDirectoryProcessorFactory();
m_dirProcessor = dirProcessorFactory.createDirectoryProcessor(m_synchronizationContext, m_repoHelper);
m_dirProcessor.initialize();
SynchronizerFactory syncFactory = SynchronizerFactory.getSynchronizeFactory();
if(m_synchronizationContext.getImportMode() == ImportMode.USERS)
{
Tracer.logDebug("Initializing User Synchronization...");
m_userSynchronization = syncFactory.createUserSynchronizer(m_synchronizationContext, m_repoHelper, m_dirProcessor);
Tracer.logDebug("User Synchronization initialized");
Tracer.logDebug("");
m_userSynchronization.dumpRootDSE();
DataExchanger.setLastRunTime(m_userSynchronization.getLdapTimeStamp());
} else
if(m_synchronizationContext.getImportMode() == ImportMode.GROUPS)
{
Tracer.logDebug("Initializing Group Synchronization...");
m_groupSynchronization = syncFactory.createGroupSynchronizer(m_synchronizationContext, m_repoHelper, m_dirProcessor);
Tracer.logDebug("Group Synchronization initialized");
Tracer.logDebug("");
m_groupSynchronization.dumpRootDSE();
DataExchanger.setLastRunTime(m_groupSynchronization.getLdapTimeStamp());
} else
{
Tracer.logDebug("Initializing User Synchronization...");
m_userSynchronization = syncFactory.createUserSynchronizer(m_synchronizationContext, m_repoHelper, m_dirProcessor);
Tracer.logDebug("User Synchronization initialized");
Tracer.logDebug("");
Tracer.logDebug("Initializing Group Synchronization...");
m_groupSynchronization = syncFactory.createGroupSynchronizer(m_synchronizationContext, m_repoHelper, m_dirProcessor);
m_groupSynchronization.setMemberUserSynchronizer(m_userSynchronization);
Tracer.logDebug("Group Synchronization initialized");
Tracer.logDebug("");
m_userSynchronization.dumpRootDSE();
DataExchanger.setLastRunTime(m_userSynchronization.getLdapTimeStamp());
}
}
Ce processeur est alors utilisé lors de la synchronisation des groupes et/ou utilisateurs. Lors de l'appel de la fonction createDirectoryProcessor
, sur l'instance de DirectoryProcessorFactory
, une instance de SunDirectoryProcessor
est retournée.
public IDirectoryProcessor createDirectoryProcessor(SynchronizationContext synchronizationContext, RepositoryHelper repoHelper)
throws DmLdapException
{
if(synchronizationContext.getDirectoryType().equals(DirectoryType.NETSCAPE))
{
Tracer.logInfo("Directory Type: Sun ONE Directory Server ...");
return new SunDirectoryProcessor(synchronizationContext, repoHelper);
}
if(synchronizationContext.getDirectoryType().equals(DirectoryType.MICROSOFT))
{
Tracer.logInfo("Directory Type: Microsoft's Active Directory Server ...");
return new ActiveDirectoryProcessor(synchronizationContext, repoHelper);
}
if(synchronizationContext.getDirectoryType().equals(DirectoryType.ADAM))
{
Tracer.logInfo("Directory Type: Microsoft's ADAM Directory Server ...");
return new ActiveDirectoryProcessor(synchronizationContext, repoHelper);
}
if(synchronizationContext.getDirectoryType().equals(DirectoryType.ORACLE))
{
Tracer.logInfo("Directory Type: Oracle Internet Directory Server ...");
return new OracleDirectoryProcessor(synchronizationContext, repoHelper);
}
if(synchronizationContext.getDirectoryType().equals(DirectoryType.NOVELL))
{
Tracer.logInfo("Directory Type: Novell's eDirectory Server ...");
return new NovellDirectoryProcessor(synchronizationContext, repoHelper);
}
if(synchronizationContext.getDirectoryType().equals(DirectoryType.IBM))
{
Tracer.logInfo("Directory Type: IBM's Tivolli Directory Server ...");
return new IbmDirectoryProcessor(synchronizationContext, repoHelper);
} else
{
throw new DmLdapException((new StringBuilder()).append("Unsupported Directory Type: ").append(synchronizationContext.getDirectoryType()).toString());
}
}
Or l'analyse de cette classe permet d'identifier l'origine de l'erreur. Lors du traitement d'un objet de l'annuaire, la référence unique est recherchée depuis la fonction getUniqueId
, retournant la valeur de la propriété nsuniqueid
. Or cette valeur n'est pas présente sous OpenLDAP.
public String getUniqueId(IEntry entry)
throws DmLdapException
{
return (String)entry.getValue("nsuniqueid");
}
Mise en place du patch
La solution consiste donc à modifier le comportement de la fonction getUniqueId
afin de retourner une propriété autre que nsuniqueid
. Afin d'apporter un peu de généricité, la valeur retournée sera mise en place dans un fichier de configuration, permettant ainsi d'adapter en fonction des déploiements.
De plus, la fonction est appelée aussi bien pour les groupes que pour les utilisateurs. Or, il est probable que la propriété soit différente pour ces deux types d'information.
Une classe est mise en place pour gérer la lecture des fichiers de configurations et exposer les méthodes:
- getUniqueAttrGroup: Nom de la propriété pour l'identifiant unique des groupes.
- getUniqueAttrUser: Nom de la propriété pour l'identifiant unique des utilisateurs.
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package fr.amexio.documentum.ldap.config.impl;
import java.util.Enumeration;
import java.util.ResourceBundle;
import com.documentum.ldap.DmLdapException;
import com.documentum.ldap.internal.trace.Tracer;
import com.documentum.ldap.internal.utils.LDAPResourceBundleAccessor;
import com.documentum.ldap.internal.utils.Utilities;
import fr.amexio.documentum.ldap.config.DefaultConfig;
/**
* @author <a href="mailto:ejouvin@amexio.fr">Etienne Jouvin</a>
*
*/
public final class DefaultConfigImpl implements DefaultConfig {
/** Singleton of DefaultConfigImpl. */
private static DefaultConfigImpl config;
/** The default attribute name for group uniqueness. */
private static final String DEFAULT_UNIQUE_ATTR_GROUP = "cn";
/** The default attribute name for user uniqueness. */
private static final String DEFAULT_UNIQUE_ATTR_USER = "uid";
/** Debug message key display when loading the properties file. */
private static final String KEY_MSG_DEBUG_CONFIG_LOAD = "LDAP_DEFAULT_CONFIG_LOAD";
/** Debug message key display when setting a value. */
private static final String KEY_MSG_DEBUG_CONFIG_SET = "LDAP_DEFAULT_CONFIG_SET";
/** Property key to retrieve the configuration for attribute name on group. */
private static final String PARAM_UNIQUE_GROUP = "uniqueAttrGroup";
/** Property key to retrieve the configuration for attribute name on user. */
private static final String PARAM_UNIQUE_USER = "uniqueAttrUser";
/** The resource bundle path for tracing messages. */
private static final String RESOURCE_CONF = "fr.amexio.documentum.ldap.config.impl.openldap_config";
/** The resource bundle path for tracing messages. */
private static final String RESOURCE_MSG = "fr.amexio.documentum.ldap.config.impl.LdapDefaultConfigBundle";
/**
* Build and instance of DefaultConfigImpl as singleton.
*
* @return Instance of DefaultConfigImpl.
* @throws DmLdapException Exception on configuration manager instantiation.
*/
public static synchronized DefaultConfigImpl getInstance() throws DmLdapException {
if (null == config) {
DefaultConfigImpl built = new DefaultConfigImpl();
config = built;
}
return config;
}
/** The unique attribute name for group. */
private String uniqueAttrGroup;
/** The unique attribute name for user. */
private String uniqueAttrUser;
/**
* Load the default configuration during constructor.
*
* @throws DmLdapException Exception on configuration manager instantiation.
*/
private DefaultConfigImpl() throws DmLdapException {
loadConfiguration(RESOURCE_CONF);
}
/** {@inheritDoc} */
public String getUniqueAttrGroup() {
return this.uniqueAttrGroup;
}
/** {@inheritDoc} */
public String getUniqueAttrUser() {
return this.uniqueAttrUser;
}
/**
* Load the default configuration file and set default attributes name from the configuration.
* The configuration file should be in same package than the class.
* If the resourcePath is null, set default properties with {@link DEFAULT_UNIQUE_ATTR_GROUP} and {@link DEFAULT_UNIQUE_ATTR_USER}.
* If any attribute is not set in the configuration file, use {@link DEFAULT_UNIQUE_ATTR_GROUP} or {@link DEFAULT_UNIQUE_ATTR_USER}.
*
* @param resourceBundle The resource name to load.
* @throws DmLdapException Fired when initialize the resource bundle with Utilities.
*/
public void loadConfiguration(String resourceBundle) throws DmLdapException {
/* Initialize the utilities resource bundle */
Utilities.createResourceBundle();
/* Add the resource file for debug and error message */
LDAPResourceBundleAccessor.addResource(RESOURCE_MSG);
if (Tracer.getTraceLevel() >= Tracer.TRACE_LEVEL_DEBUG) {
Tracer.logDebug(Utilities.getMessage(KEY_MSG_DEBUG_CONFIG_LOAD));
}
/* Load the configuration file */
ResourceBundle resource = null;
if (null != resourceBundle) {
resource = ResourceBundle.getBundle(resourceBundle);
}
if (null != resource) {
/* Get and store unique attribute name for user and group */
Enumeration<String> keys = resource.getKeys();
String key = null;
boolean userSet = false, groupSet = false;
while (keys.hasMoreElements()) {
key = keys.nextElement();
if (KEY_UNIQUE_ATTR_GROUP.equals(key)) {
setUniqueAttrGroup(resource.getString(key));
groupSet = true;
} else if (KEY_UNIQUE_ATTR_USER.equals(key)) {
setUniqueAttrUser(resource.getString(key));
userSet = true;
}
}
if (!groupSet) {
setUniqueAttrGroup(DEFAULT_UNIQUE_ATTR_GROUP);
}
if (!userSet) {
setUniqueAttrUser(DEFAULT_UNIQUE_ATTR_USER);
}
} else {
/* Any error, set default value from the interface */
setUniqueAttrGroup(DEFAULT_UNIQUE_ATTR_GROUP);
setUniqueAttrUser(DEFAULT_UNIQUE_ATTR_USER);
}
}
/**
* Set the attribute name to identify unique group item.
*
* @param uniqueAttrGroup The attribute name
* @see {@link com.documentum.ldap.internal.processors.IDirectoryProcessor#getUniqueId(com.documentum.ldap.internal.ldap.IEntry)}
*/
public void setUniqueAttrGroup(String uniqueAttrGroup) {
if (Tracer.getTraceLevel() >= Tracer.TRACE_LEVEL_DEBUG) {
Tracer.logDebug(Utilities.getMessage(KEY_MSG_DEBUG_CONFIG_SET, PARAM_UNIQUE_GROUP, uniqueAttrGroup));
}
/* Store the attribute name */
this.uniqueAttrGroup = uniqueAttrGroup;
}
/**
* Set the attribute name to identify unique user item.
*
* @param uniqueAttrUser The attribute name
* @see {@link com.documentum.ldap.internal.processors.IDirectoryProcessor#getUniqueId(com.documentum.ldap.internal.ldap.IEntry)}
*/
public void setUniqueAttrUser(String uniqueAttrUser) {
if (Tracer.getTraceLevel() >= Tracer.TRACE_LEVEL_DEBUG) {
Tracer.logDebug(Utilities.getMessage(KEY_MSG_DEBUG_CONFIG_SET, PARAM_UNIQUE_USER, uniqueAttrUser));
}
/* Store the attribute name */
this.uniqueAttrUser = uniqueAttrUser;
}
}
Cette classe implémente l'interface DefaultConfig
.
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package fr.amexio.documentum.ldap.config;
/**
* Default configuration manager for LDAP Synchronization.
* Used to define some default attribute name during synchronization.
*
* @author <a href="mailto:ejouvin@amexio.fr">Etienne Jouvin</a>
*
*/
public interface DefaultConfig {
/**
* The configuration key to retrieve the attribute name for group uniqueness
*/
static final String KEY_UNIQUE_ATTR_GROUP = "UNIQUE_ATTR_GROUP";
/**
* The configuration key to retrieve the attribute name for user uniqueness
*/
static final String KEY_UNIQUE_ATTR_USER = "UNIQUE_ATTR_USER";
/**
* @return The attribute name to identify unique group item.
*/
String getUniqueAttrGroup();
/**
* @return The attribute name to identify unique user item.
*/
String getUniqueAttrUser();
}
Deux fichiers de configuration sont donc chargés. Les mécanismes déjà en place, à partir de la classe com.documentum.ldap.internal.utils.LDAPResourceBundle
sont utilisés. Cependant, cette classe ayant une visibilité interne au paquet, elle est difficilement utilisable par l'extension. Il est donc nécessaire de mettre en place une nouvelle classe, dans le même paquet, donnant un accès aux méthodes souhaitées.
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.documentum.ldap.internal.utils;
import java.util.ResourceBundle;
/**
* Give access to add resource in the Documentum class <code>com.documentum.ldap.internal.utils.LDAPResourceBundle</code>
* which is in package visibility only. In EDF extension, it can be necessary to add some resources accessible by class
* <code>com.documentum.ldap.internal.utils.Utilities</code> when tracing, like done in standard.
*
* @author <a href="mailto:ejouvin@amexio.fr">Etienne Jouvin</a>
*
*/
public final class LDAPResourceBundleAccessor {
private static final LDAPResourceBundleAccessor INSTANCE = new LDAPResourceBundleAccessor();
/**
* Add a resources file in the current LDAPResourceBundle singleton.
*
* @param bundleName Resource bundle path.
*/
public static void addResource(String bundleName) {
LDAPResourceBundle ldapResourceBundle = LDAPResourceBundle.getInstance();
ldapResourceBundle.addResource(ResourceBundle.getBundle(bundleName));
}
/**
* @return Default instance.
*/
public static LDAPResourceBundleAccessor getInstance() {
return INSTANCE;
}
/**
* Private constructor.
*/
private LDAPResourceBundleAccessor() {
}
}
Le premier fichier de configuration fr.amexio.documentum.ldap.config.impl.LdapDefaultConfigBundle.properties
est utilisé pour les messages affichés dans la log.
#Specific LDAP Configuration manager for EDF
LDAP_DEFAULT_CONFIG_CLOSE_FAILED=Failed to close the configuration resources file.
LDAP_DEFAULT_CONFIG_LOAD=Load configuration.
LDAP_DEFAULT_CONFIG_LOAD_FAILED=Failed to load the configuration resources file.
LDAP_DEFAULT_CONFIG_SET=Set configuration attribute \"{0}\" with value \"{1}\".
Le second fichier de configuration fr.amexio.documentum.ldap.config.impl.openldap_config.properties
est utilisé pour paramétrer les deux propriétés contenant l'identifiant unique des objets.
UNIQUE_ATTR_GROUP=cn
UNIQUE_ATTR_USER=uid
Le nouveau processeur mis en place, classe SunDirectoryProcessorPatched
, ne fait qu'étendre le code standard. A noter que la méthode dumpConfig
est également surchargée pour annuler le traitement. En effet, celle-ci ne fait qu'afficher dans la log des informations sur le schéma LDAP. Or, celles-ci sont récupérées depuis l'objet cn=config
qui peut ne pas exister.
public void dumpConfig()
throws DmLdapException
{
String configDn = "cn=config";
Tracer.logDebug("------------------------------------------------------------------");
Tracer.logDebug((new StringBuilder()).append("Dumping SunOne LDAP Config: ").append(configDn).toString());
try
{
IEntry entry = m_dapi.getEntry(configDn, (String[])null);
Iterator iter = null;
if(entry != null)
iter = entry.getAttrNames();
while(iter != null && iter.hasNext())
{
String attrName = (String)iter.next();
Tracer.logDebug((new StringBuilder()).append("\t").append(attrName).toString());
Iterator valuesIter = entry.getValues(attrName);
while(valuesIter != null && valuesIter.hasNext())
{
Object value = valuesIter.next();
Tracer.logDebug((new StringBuilder()).append("\t\t").append(value).toString());
}
}
}
catch(DmLdapException ldapEx)
{
Tracer.logDebug((new StringBuilder()).append("Failed to dump SunOne LDAP Config: ").append(Utilities.toDmLdapExceptionMessage(ldapEx)).toString());
}
Tracer.logDebug("------------------------------------------------------------------");
}
Dans le constructeur de l'extension, un chargement de la classe DefaultConfigImpl
est réalisée, entraînant la lecture des configurations. Ainsi, dans la fonction getUniqueId
, il est possible de récupérer la valeur de la propriété souhaitée.
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.documentum.ldap.internal.processors;
import com.documentum.ldap.DmLdapException;
import com.documentum.ldap.internal.ldap.EntryType;
import com.documentum.ldap.internal.ldap.IEntry;
import com.documentum.ldap.internal.sync.RepositoryHelper;
import com.documentum.ldap.internal.sync.SynchronizationContext;
import com.documentum.ldap.internal.trace.Tracer;
import fr.amexio.documentum.ldap.config.DefaultConfig;
import fr.amexio.documentum.ldap.config.impl.DefaultConfigImpl;
/**
* Build a custom Directory Processor for Open LDAP.
* This LDAP implementation is used in the project in order to synchronized users and groups.
*
* But in the standard <code>SunDirectoryProcessor</code>, the method <code>getUniqueId</code> returns an attribute value,
* with an hard coded attribute name.
*
* And this attribute name is not the one defined in open LDAP.
* Moreover, the attribute name is not the same for groups and users.
*
* Use a the new class DefaultConfigImpl in order to read those attributes names from a configuration file.
*
* @author <a href="mailto:ejouvin@amexio.fr">Etienne Jouvin</a>
*
*/
public class SunDirectoryProcessorPatched extends SunDirectoryProcessor {
/** Instance of DefaultConfig used to read attribute name configuration */
private DefaultConfig defaultConfig;
/**
* Build the object.
* Add construction of DefaultConfig instance from standard, use to retrieve attribute name
* for uniqueness attribute name for groups and users.
*
* @param synchronizationContext Instance of SynchronizationContext
* @param repositoryHelper Instance of RepositoryHelper
* @throws DmLdapException Exception fired by parent constructor or during the DefaultConfig instance building
*/
public SunDirectoryProcessorPatched(SynchronizationContext synchronizationContext, RepositoryHelper repositoryHelper) throws DmLdapException {
super(synchronizationContext, repositoryHelper);
defaultConfig = DefaultConfigImpl.getInstance();
}
/** {@inheritDoc} */
@Override
public void dumpConfig() {
Tracer.logDebug("------------------------------------------------------------------");
Tracer.logDebug("Dumping LDAP Config disabled.");
Tracer.logDebug("Use openLDAP and not a real SunOne LDAP, cn=config is not provided.");
Tracer.logDebug("And dumping configuration is not necessary.");
Tracer.logDebug("------------------------------------------------------------------");
}
/** {@inheritDoc} */
@Override
public String getUniqueId(IEntry entry) throws DmLdapException {
/* Get the entry type. */
EntryType entryType = super.getEntryType(entry.getDN());
String key = null;
if (entryType == EntryType.GROUP) {
/* Is a group. */
key = defaultConfig.getUniqueAttrGroup();
} else {
/* Is a user. */
key = defaultConfig.getUniqueAttrUser();
}
/* Return the value from the new key. */
return (String) entry.getValue(key);
}
}
La dernière modification concerne la classe com.documentum.ldap.internal.processors.DirectoryProcessorFactory
. Malheureusement, celle-ci est un singleton et n'offre aucune possibilité de surcharge. Elle est donc réécrite entièrement afin de prendre en compte la nouvelle instance du processeur.
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.documentum.ldap.internal.processors;
import com.documentum.ldap.DmLdapException;
import com.documentum.ldap.internal.ldap.DirectoryType;
import com.documentum.ldap.internal.sync.RepositoryHelper;
import com.documentum.ldap.internal.sync.SynchronizationContext;
import com.documentum.ldap.internal.trace.Tracer;
/**
* A patch is applied on the directory processor for Open LDAP.
* Need to over write the standard class in order to return a instance of class SunDirectoryProcessorPatched in case of
* NETSCAPE configuration on the dm_ldap_config object.
*
* @author <a href="mailto:ejouvin@amexio.fr">Etienne Jouvin</a>
*
*/
public final class DirectoryProcessorFactory {
/** Instance of DirectoryProcessorFactory as singleton */
private static DirectoryProcessorFactory directoryProcessorFactory;
/**
* Build the DirectoryProcessorFactory singleton and return it
*
* @return Instance of DirectoryProcessorFactory
*/
public static synchronized DirectoryProcessorFactory getDirectoryProcessorFactory() {
if (directoryProcessorFactory == null) {
directoryProcessorFactory = new DirectoryProcessorFactory();
}
return directoryProcessorFactory;
}
/**
* Private constructor
*/
private DirectoryProcessorFactory() {
}
/**
* Copy of standard class with changes:
* <ul>
* <li>Change the compare order.
* <li>Change the class instance in case of netscape configuration.
* </ul>
*
* @param synchronizationContext Instance of SynchronizationContext, sent by standard
* @param repoHelper Instance of RepositoryHelper, sent by standard
* @return Instance of IDirectoryProcessor, use the class SunDirectoryProcessorPatched in case of netscape
* @throws DmLdapException Fired by the IDirectoryProcessor constructor
*/
public IDirectoryProcessor createDirectoryProcessor(
SynchronizationContext synchronizationContext,
RepositoryHelper repoHelper) throws DmLdapException {
DirectoryType directoryType = synchronizationContext.getDirectoryType();
if (DirectoryType.NETSCAPE.equals(directoryType)) {
Tracer.logInfo("Directory Type: Sun ONE Directory Server ...");
/* Use a custom processor. */
return new SunDirectoryProcessorPatched(synchronizationContext, repoHelper);
}
if (DirectoryType.MICROSOFT.equals(directoryType)) {
Tracer.logInfo("Directory Type: Microsoft's Active Directory Server ...");
return new ActiveDirectoryProcessor(synchronizationContext, repoHelper);
}
if (DirectoryType.ADAM.equals(directoryType)) {
Tracer.logInfo("Directory Type: Microsoft's ADAM Directory Server ...");
return new ActiveDirectoryProcessor(synchronizationContext, repoHelper);
}
if (DirectoryType.ORACLE.equals(directoryType)) {
Tracer.logInfo("Directory Type: Oracle Internet Directory Server ...");
return new OracleDirectoryProcessor(synchronizationContext, repoHelper);
}
if (DirectoryType.NOVELL.equals(directoryType)) {
Tracer.logInfo("Directory Type: Novell's eDirectory Server ...");
return new NovellDirectoryProcessor(synchronizationContext, repoHelper);
}
if (DirectoryType.IBM.equals(directoryType)) {
Tracer.logInfo("Directory Type: IBM's Tivolli Directory Server ...");
return new IbmDirectoryProcessor(synchronizationContext, repoHelper);
} else {
throw new DmLdapException((new StringBuilder())
.append("Unsupported Directory Type: ")
.append(synchronizationContext.getDirectoryType())
.toString());
}
}
}
Enfin, il faut injecter toutes ces classes dans le fichier dmldap.jar
et relancer le serveur de méthode.