/*
 * Copyright (c) 1998, 2021 Oracle and/or its affiliates. All rights reserved.
 *
 * This program and the accompanying materials are made available under the
 * terms of the Eclipse Public License v. 2.0 which is available at
 * http://www.eclipse.org/legal/epl-2.0,
 * or the Eclipse Distribution License v. 1.0 which is available at
 * http://www.eclipse.org/org/documents/edl-v10.php.
 *
 * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
 */

// Contributors:
//     Oracle - initial API and implementation from Oracle TopLink
//     cdelahun - Bug 214534: changes for JMSPublishingTransportManager configuration via session.xml
package org.eclipse.persistence.internal.sessions.factories;

import java.lang.reflect.Constructor;
import java.security.AccessController;
import java.security.PrivilegedActionException;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import org.eclipse.persistence.config.SessionCustomizer;
import org.eclipse.persistence.eis.EISConnectionSpec;
import org.eclipse.persistence.eis.EISLogin;
import org.eclipse.persistence.exceptions.ExceptionHandler;
import org.eclipse.persistence.exceptions.SessionLoaderException;
import org.eclipse.persistence.exceptions.ValidationException;
import org.eclipse.persistence.internal.databaseaccess.DatabasePlatform;
import org.eclipse.persistence.internal.databaseaccess.DatasourcePlatform;
import org.eclipse.persistence.internal.databaseaccess.Platform;
import org.eclipse.persistence.internal.helper.ConversionManager;
import org.eclipse.persistence.internal.security.PrivilegedAccessHelper;
import org.eclipse.persistence.internal.security.PrivilegedGetConstructorFor;
import org.eclipse.persistence.internal.security.PrivilegedInvokeConstructor;
import org.eclipse.persistence.internal.security.PrivilegedNewInstanceFromClass;
import org.eclipse.persistence.internal.sessions.AbstractSession;
import org.eclipse.persistence.internal.sessions.DatabaseSessionImpl;
import org.eclipse.persistence.internal.sessions.factories.model.SessionConfigs;
import org.eclipse.persistence.internal.sessions.factories.model.event.SessionEventManagerConfig;
import org.eclipse.persistence.internal.sessions.factories.model.log.DefaultSessionLogConfig;
import org.eclipse.persistence.internal.sessions.factories.model.log.JavaLogConfig;
import org.eclipse.persistence.internal.sessions.factories.model.log.LogConfig;
import org.eclipse.persistence.internal.sessions.factories.model.log.ServerLogConfig;
import org.eclipse.persistence.internal.sessions.factories.model.login.DatabaseLoginConfig;
import org.eclipse.persistence.internal.sessions.factories.model.login.EISLoginConfig;
import org.eclipse.persistence.internal.sessions.factories.model.login.LoginConfig;
import org.eclipse.persistence.internal.sessions.factories.model.login.StructConverterConfig;
import org.eclipse.persistence.internal.sessions.factories.model.login.XMLLoginConfig;
import org.eclipse.persistence.internal.sessions.factories.model.platform.CustomServerPlatformConfig;
import org.eclipse.persistence.internal.sessions.factories.model.platform.ServerPlatformConfig;
import org.eclipse.persistence.internal.sessions.factories.model.pool.ConnectionPolicyConfig;
import org.eclipse.persistence.internal.sessions.factories.model.pool.ConnectionPoolConfig;
import org.eclipse.persistence.internal.sessions.factories.model.pool.PoolsConfig;
import org.eclipse.persistence.internal.sessions.factories.model.pool.ReadConnectionPoolConfig;
import org.eclipse.persistence.internal.sessions.factories.model.project.ProjectConfig;
import org.eclipse.persistence.internal.sessions.factories.model.property.PropertyConfig;
import org.eclipse.persistence.internal.sessions.factories.model.rcm.RemoteCommandManagerConfig;
import org.eclipse.persistence.internal.sessions.factories.model.rcm.command.CommandsConfig;
import org.eclipse.persistence.internal.sessions.factories.model.sequencing.DefaultSequenceConfig;
import org.eclipse.persistence.internal.sessions.factories.model.sequencing.NativeSequenceConfig;
import org.eclipse.persistence.internal.sessions.factories.model.sequencing.SequenceConfig;
import org.eclipse.persistence.internal.sessions.factories.model.sequencing.TableSequenceConfig;
import org.eclipse.persistence.internal.sessions.factories.model.sequencing.UnaryTableSequenceConfig;
import org.eclipse.persistence.internal.sessions.factories.model.sequencing.XMLFileSequenceConfig;
import org.eclipse.persistence.internal.sessions.factories.model.session.DatabaseSessionConfig;
import org.eclipse.persistence.internal.sessions.factories.model.session.ServerSessionConfig;
import org.eclipse.persistence.internal.sessions.factories.model.session.SessionBrokerConfig;
import org.eclipse.persistence.internal.sessions.factories.model.session.SessionConfig;
import org.eclipse.persistence.internal.sessions.factories.model.transport.JMSPublishingTransportManagerConfig;
import org.eclipse.persistence.internal.sessions.factories.model.transport.JMSTopicTransportManagerConfig;
import org.eclipse.persistence.internal.sessions.factories.model.transport.Oc4jJGroupsTransportManagerConfig;
import org.eclipse.persistence.internal.sessions.factories.model.transport.RMIIIOPTransportManagerConfig;
import org.eclipse.persistence.internal.sessions.factories.model.transport.RMITransportManagerConfig;
import org.eclipse.persistence.internal.sessions.factories.model.transport.SunCORBATransportManagerConfig;
import org.eclipse.persistence.internal.sessions.factories.model.transport.TransportManagerConfig;
import org.eclipse.persistence.internal.sessions.factories.model.transport.UserDefinedTransportManagerConfig;
import org.eclipse.persistence.internal.sessions.factories.model.transport.discovery.DiscoveryConfig;
import org.eclipse.persistence.internal.sessions.factories.model.transport.naming.JNDINamingServiceConfig;
import org.eclipse.persistence.internal.sessions.factories.model.transport.naming.RMIRegistryNamingServiceConfig;
import org.eclipse.persistence.logging.DefaultSessionLog;
import org.eclipse.persistence.logging.SessionLog;
import org.eclipse.persistence.oxm.XMLLogin;
import org.eclipse.persistence.platform.database.converters.StructConverter;
import org.eclipse.persistence.platform.server.NoServerPlatform;
import org.eclipse.persistence.platform.server.ServerPlatform;
import org.eclipse.persistence.platform.server.ServerPlatformUtils;
import org.eclipse.persistence.sequencing.DefaultSequence;
import org.eclipse.persistence.sequencing.NativeSequence;
import org.eclipse.persistence.sequencing.Sequence;
import org.eclipse.persistence.sequencing.TableSequence;
import org.eclipse.persistence.sequencing.UnaryTableSequence;
import org.eclipse.persistence.sessions.DatabaseLogin;
import org.eclipse.persistence.sessions.DatasourceLogin;
import org.eclipse.persistence.sessions.ExternalTransactionController;
import org.eclipse.persistence.sessions.JNDIConnector;
import org.eclipse.persistence.sessions.Login;
import org.eclipse.persistence.sessions.Project;
import org.eclipse.persistence.sessions.Session;
import org.eclipse.persistence.sessions.SessionEventListener;
import org.eclipse.persistence.sessions.broker.SessionBroker;
import org.eclipse.persistence.sessions.coordination.DiscoveryManager;
import org.eclipse.persistence.sessions.coordination.RemoteCommandManager;
import org.eclipse.persistence.sessions.coordination.TransportManager;
import org.eclipse.persistence.sessions.coordination.jms.JMSPublishingTransportManager;
import org.eclipse.persistence.sessions.coordination.jms.JMSTopicTransportManager;
import org.eclipse.persistence.sessions.coordination.rmi.RMITransportManager;
import org.eclipse.persistence.sessions.factories.XMLProjectReader;
import org.eclipse.persistence.sessions.factories.XMLSessionConfigLoader;
import org.eclipse.persistence.sessions.server.ConnectionPolicy;
import org.eclipse.persistence.sessions.server.ConnectionPool;
import org.eclipse.persistence.sessions.server.ReadConnectionPool;
import org.eclipse.persistence.sessions.server.ServerSession;
import org.eclipse.persistence.tools.profiler.PerformanceProfiler;

/**
 * INTERNAL:
 * Builds EclipseLink Sessions from the XML Session Config model.
 * Model classes that are not built, are processed only.
 *
 * @author Guy Pelletier
 * @version 1.0
 */
public class SessionsFactory {
    protected Map<String, Session> m_sessions;
    protected Map<String, Integer> m_logLevels;
    protected ClassLoader m_classLoader;

    /**
     * INTERNAL:
     */
    public SessionsFactory() {
        m_logLevels = new HashMap<>();
        m_logLevels.put("off", SessionLog.OFF);
        m_logLevels.put("severe", SessionLog.SEVERE);
        m_logLevels.put("warning", SessionLog.WARNING);
        m_logLevels.put("info", SessionLog.INFO);
        m_logLevels.put("config", SessionLog.CONFIG);
        m_logLevels.put("fine", SessionLog.FINE);
        m_logLevels.put("finer", SessionLog.FINER);
        m_logLevels.put("finest", SessionLog.FINEST);
        m_logLevels.put("all", SessionLog.ALL);
    }

    /**
     * INTERNAL:
     * To build EclipseLink sessions, users must call this method with a
     * SessionConfigs object returned from an OX read in the
     * {@link XMLSessionConfigLoader}.
     *
     * @param eclipseLinkSessions object returned from an OX read in the XMLSessionConfigLoader
     * @param classLoader class loader used in the XMLSessionConfigLoader
     * @return EclipseLink sessions
     */
    public Map<String, Session> buildSessionConfigs(SessionConfigs eclipseLinkSessions, ClassLoader classLoader) {
        m_sessions = new HashMap<>();
        m_classLoader = classLoader;
        List<SessionBrokerConfig> sessionBrokerConfigs = new ArrayList<>();
        Enumeration<SessionConfig> e = eclipseLinkSessions.getSessionConfigs().elements();

        while (e.hasMoreElements()) {
            SessionConfig sessionConfig = e.nextElement();

            if (sessionConfig instanceof SessionBrokerConfig) {
                // Hold all the session brokers till all the sessions have been built
                sessionBrokerConfigs.add((SessionBrokerConfig) sessionConfig);
            } else {
                AbstractSession session = buildSession(sessionConfig);
                session.getDatasourcePlatform().getConversionManager().setLoader(classLoader);
                processSessionCustomizer(sessionConfig, session);
                m_sessions.put(session.getName(), session);
            }
        }

        // All the sessions have been built now so we can process the Session Brokers
        for (SessionBrokerConfig sessionBrokerConfig : sessionBrokerConfigs) {
            SessionBroker sessionBroker = buildSessionBrokerConfig(sessionBrokerConfig);
            sessionBroker.getDatasourcePlatform().getConversionManager().setLoader(classLoader);
            processSessionCustomizer(sessionBrokerConfig, sessionBroker);
            m_sessions.put(sessionBroker.getName(), sessionBroker);
        }

        return m_sessions;
    }

    /**
     * INTERNAL:
     * Process the user inputed session customizer class. Will be run at the
     * end of the session build process
     */
    protected void processSessionCustomizer(SessionConfig sessionConfig, AbstractSession session) {
        // Session customizer - MUST BE THE LAST THING TO PROCESS
        String sessionCustomizerClassName = sessionConfig.getSessionCustomizerClass();
        if (sessionCustomizerClassName != null) {
            try {
                @SuppressWarnings({"unchecked"})
                Class<SessionCustomizer> sessionCustomizerClass = (Class<SessionCustomizer>) m_classLoader.loadClass(sessionCustomizerClassName);
                if (PrivilegedAccessHelper.shouldUsePrivilegedAccess()){
                    AccessController.doPrivileged(new PrivilegedNewInstanceFromClass<>(sessionCustomizerClass)).customize(session);
                }else{
                    PrivilegedAccessHelper.newInstanceFromClass(sessionCustomizerClass).customize(session);
                }
            } catch (Exception exception) {
                throw SessionLoaderException.failedToLoadTag("session-customizer-class", sessionCustomizerClassName, exception);
            }
        }
    }

    /**
     * INTERNAL:
     * Build the correct session based on the session config type
     */
    protected AbstractSession buildSession(SessionConfig sessionConfig) {
        if (sessionConfig instanceof ServerSessionConfig) {
            return buildServerSessionConfig((ServerSessionConfig)sessionConfig);
        } else {// if (sessionConfig instanceof DatabaseSessionConfig) {
            return buildDatabaseSessionConfig((DatabaseSessionConfig)sessionConfig);
        }
    }

    /**
     * INTERNAL:
     * Wrapped by the getSession() call, therefore, config can't be null at this
     * point.
     */
    protected AbstractSession buildDatabaseSessionConfig(DatabaseSessionConfig databaseSessionConfig) {
        // Create a new database session (null means use login from deployment xml if there is one)
        DatabaseSessionImpl databaseSession = createSession(databaseSessionConfig, null);

        // Login - may overwrite the previous login (expected behavior)
        Login login = buildLogin(databaseSessionConfig.getLoginConfig());
        if (login != null) {
            databaseSession.setLogin(login);
        }

        // Common processing since ServerSessions inherit from DatabaseSession
        processDatabaseSessionConfig(databaseSessionConfig, databaseSession);

        // Process the common elements in SessionConfig
        processSessionConfig(databaseSessionConfig, databaseSession);

        return databaseSession;
    }

    /**
     * INTERNAL
     * Process a DatabaseSessionConfig object.
     */
    protected void processDatabaseSessionConfig(DatabaseSessionConfig sessionConfig, AbstractSession session) {
    }

    /**
     * INTERNAL:
     * Builds a server server from the given ServerSessionConfig.
     */
    protected AbstractSession buildServerSessionConfig(ServerSessionConfig serverSessionConfig) {
        // For server sessions we should build the login first, that way we can
        // initialize the server session with the login (if there is one)
        Login login = buildLogin(serverSessionConfig.getLoginConfig());

        // Create a new server session
        ServerSession serverSession = (ServerSession)createSession(serverSessionConfig, login);

        // Common processing since ServerSessions inherit from DatabaseSession
        processDatabaseSessionConfig(serverSessionConfig, serverSession);

        // Process pools config
        processPoolsConfig(serverSessionConfig.getPoolsConfig(), serverSession);

        // Process connection policy config
        processConnectionPolicyConfig(serverSessionConfig.getConnectionPolicyConfig(), serverSession);

        // Process the common elements in SessionConfig
        processSessionConfig(serverSessionConfig, serverSession);

        return serverSession;
    }

    /**
     * INTERNAL:
     * Return a DatabaseSession object from it's config object using either
     * the project classes or project XML files.
     */
    protected DatabaseSessionImpl createSession(DatabaseSessionConfig sessionConfig, Login login) {
        Project primaryProject;

        if (sessionConfig.getPrimaryProject() != null) {
            primaryProject = loadProjectConfig(sessionConfig.getPrimaryProject());
        } else {
            primaryProject = new Project();// Build a session from an empty project
        }

        prepareProjectLogin(primaryProject, login);
        DatabaseSessionImpl sessionToReturn = getSession(sessionConfig, primaryProject);

        // Append descriptors from all subsequent project.xml and project classes
        // to the mainProject
        if (sessionConfig.getAdditionalProjects() != null) {
            Enumeration<ProjectConfig> additionalProjects = sessionConfig.getAdditionalProjects().elements();

            while (additionalProjects.hasMoreElements()) {
                Project subProject = loadProjectConfig(additionalProjects.nextElement());
                primaryProject.addDescriptors(subProject, sessionToReturn);
            }
        }

        return sessionToReturn;
    }

    /**
     * INTERNAL:
     * Return the correct session type from the sessionConfig
     */
    protected void prepareProjectLogin(Project project, Login login) {
        if (login != null) {
            project.setLogin(login);
        } else if (project.getDatasourceLogin() == null) {
            // dummy login that needs to be set, otherwise session creation will fail
            project.setLogin(new DatabaseLogin());
        } else {
            // we read a login from the deployment xml of java, don't overwrite
        }
    }

    /**
     * INTERNAL:
     * Return the correct session type from the sessionConfig
     */
    protected DatabaseSessionImpl getSession(SessionConfig sessionConfig, Project project) {
        if (sessionConfig instanceof ServerSessionConfig) {
            return (ServerSession)project.createServerSession();
        } else {
            return (DatabaseSessionImpl)project.createDatabaseSession();
        }
    }

    /**
     * INTERNAL:
     * Load a projectConfig from the session.xml file. This method will determine
     * the proper loading scheme, that is, for a class or xml project.
     */
    @SuppressWarnings({"unchecked"})
    protected Project loadProjectConfig(ProjectConfig projectConfig) {
        Project project = null;
        String projectString = projectConfig.getProjectString().trim();

        if (projectConfig.isProjectClassConfig()) {
            try {
                if (PrivilegedAccessHelper.shouldUsePrivilegedAccess()){
                    project = AccessController.doPrivileged(new PrivilegedNewInstanceFromClass<>((Class<Project>) m_classLoader.loadClass(projectString)));
                }else{
                    project = PrivilegedAccessHelper.newInstanceFromClass((Class<Project>)m_classLoader.loadClass(projectString));
                }
            } catch (Exception exception) {
                throw SessionLoaderException.failedToLoadProjectClass(projectString, exception);
            }
        } else {
            try {
                project = XMLProjectReader.read(projectString, m_classLoader);
            } catch (ValidationException validationException) {
                if (validationException.getErrorCode() == ValidationException.PROJECT_XML_NOT_FOUND) {
                    try {
                        project = XMLProjectReader.read(projectString);
                    } catch (Exception e) {
                        throw SessionLoaderException.failedToLoadProjectXml(projectString, validationException);
                    }
                } else {
                    throw SessionLoaderException.failedToLoadProjectXml(projectString, validationException);
                }
            }
        }

        return project;
    }

    /**
     * INTERNAL:
     * Build the correct login based on the login config type
     */
    protected Login buildLogin(LoginConfig loginConfig) {
        if (loginConfig instanceof EISLoginConfig) {
            return buildEISLoginConfig((EISLoginConfig)loginConfig);
        } else if (loginConfig instanceof XMLLoginConfig) {
            return buildXMLLoginConfig((XMLLoginConfig)loginConfig);
        } else if (loginConfig instanceof DatabaseLoginConfig) {
            return buildDatabaseLoginConfig((DatabaseLoginConfig)loginConfig);
        } else {
            return null;
        }
    }

    /**
     * INTERNAL:
     * Wrapped by the getLogin() call, therefore, config can't be null at this
     * point.
     */
    protected Login buildEISLoginConfig(EISLoginConfig eisLoginConfig) {
        EISLogin eisLogin = new EISLogin();

        // Connection Spec
        String specClassName = eisLoginConfig.getConnectionSpecClass();
        if (specClassName != null) {
            try {
                @SuppressWarnings({"unchecked"})
                Class<EISConnectionSpec> specClass = (Class<EISConnectionSpec>) m_classLoader.loadClass(specClassName);
                EISConnectionSpec spec = null;
                if (PrivilegedAccessHelper.shouldUsePrivilegedAccess()){
                    spec = AccessController.doPrivileged(new PrivilegedNewInstanceFromClass<>(specClass));
                }else{
                    spec = PrivilegedAccessHelper.newInstanceFromClass(specClass);
                }
                eisLogin.setConnectionSpec(spec);
            } catch (Exception exception) {
                throw SessionLoaderException.failedToLoadTag("connection-spec-class", specClassName, exception);
            }
        }

        // Connection Factory URL, setConnectionFactoryURL checks for null
        eisLogin.setConnectionFactoryURL(eisLoginConfig.getConnectionFactoryURL());

        // Process the common elements in LoginConfig
        processLoginConfig(eisLoginConfig, eisLogin);

        // Finally, return the newly created EISLogin
        return eisLogin;
    }

    /**
      * INTERNAL:
      * Wrapped by the getLogin() call, therefore, config can't be null at this
      * point.
      */
    protected Login buildXMLLoginConfig(XMLLoginConfig xmlLoginConfig) {
        XMLLogin xmlLogin = new XMLLogin();

        // Process the common elements in LoginConfig
        processLoginConfig(xmlLoginConfig, xmlLogin);

        // Finally, return the newly created XMLLogin
        return xmlLogin;
    }

    /**
     * INTERNAL:
     * Build a DatabaseLogin for the given Session
     * Wrapped by the getLogin() call, therefore, config can't be null at this
     * point.
     */
    protected Login buildDatabaseLoginConfig(DatabaseLoginConfig databaseLoginConfig) {
        DatabaseLogin databaseLogin = new DatabaseLogin();

        // Driver class
        String driverClassName = databaseLoginConfig.getDriverClass();
        if (driverClassName != null) {
            try {
                Class<?> driverClass = m_classLoader.loadClass(driverClassName);
                databaseLogin.setDriverClass(driverClass);
            } catch (Exception exception) {
                throw SessionLoaderException.failedToLoadTag("driver-class", driverClassName, exception);
            }
        }

        // Connection URL
        String connectionString = databaseLoginConfig.getConnectionURL();
        if (connectionString != null) {
            databaseLogin.setConnectionString(connectionString);
        }

        // Datasource
        String datasourceName = databaseLoginConfig.getDatasource();
        if (datasourceName != null) {
            try {
                JNDIConnector jndiConnector = new JNDIConnector(new javax.naming.InitialContext(), datasourceName);
                jndiConnector.setLookupType(databaseLoginConfig.getLookupType());
                databaseLogin.setConnector(jndiConnector);
            } catch (Exception exception) {
                throw SessionLoaderException.failedToLoadTag("datasource", datasourceName, exception);
            }
        }

        // Bind all parameters - XML Schema default is false
        databaseLogin.setShouldBindAllParameters(databaseLoginConfig.getBindAllParameters());

        // Cache all statements - XML Schema default is false
        databaseLogin.setShouldCacheAllStatements(databaseLoginConfig.getCacheAllStatements());

        // Byte array binding - XML Schema default is true
        databaseLogin.setUsesByteArrayBinding(databaseLoginConfig.getByteArrayBinding());

        // String binding - XML Schema default is false
        databaseLogin.setUsesStringBinding(databaseLoginConfig.getStringBinding());

        // Stream binding - XML Schema default is false
        databaseLogin.setUsesStreamsForBinding(databaseLoginConfig.getStreamsForBinding());

        // Force field to uppper case - XML Schema default is false
        databaseLogin.setShouldForceFieldNamesToUpperCase(databaseLoginConfig.getForceFieldNamesToUppercase());

        // Optimize data conversion - XML Schema default is true
        databaseLogin.setShouldOptimizeDataConversion(databaseLoginConfig.getOptimizeDataConversion());

        // Trim strings - XML Schema default is true
        databaseLogin.setShouldTrimStrings(databaseLoginConfig.getTrimStrings());

        // Batch writing - XML Schema default is false
        databaseLogin.setUsesBatchWriting(databaseLoginConfig.getBatchWriting());

        // JDBC 2.0 batch writing - XML Schema default is true
        databaseLogin.setUsesJDBCBatchWriting(databaseLoginConfig.getJdbcBatchWriting());

        // Max batch writing size - XML Schema default is 32000
        Integer maxBatchWritingSize = databaseLoginConfig.getMaxBatchWritingSize();
        if (maxBatchWritingSize != null) {
            databaseLogin.setMaxBatchWritingSize(maxBatchWritingSize);
        }

        // Native SQL - XML Schema default is false
        databaseLogin.setUsesNativeSQL(databaseLoginConfig.getNativeSQL());

        // Process the common elements in LoginConfig
        processLoginConfig(databaseLoginConfig, databaseLogin);

        processStructConverterConfig(databaseLoginConfig.getStructConverterConfig(), databaseLogin);

        if (databaseLoginConfig.isConnectionHealthValidatedOnError() != null){
            databaseLogin.setConnectionHealthValidatedOnError(databaseLoginConfig.isConnectionHealthValidatedOnError());
        }
        if (databaseLoginConfig.getQueryRetryAttemptCount() != null){
            databaseLogin.setQueryRetryAttemptCount(databaseLoginConfig.getQueryRetryAttemptCount());
        }
        if (databaseLoginConfig.getDelayBetweenConnectionAttempts() != null){
            databaseLogin.setDelayBetweenConnectionAttempts(databaseLoginConfig.getDelayBetweenConnectionAttempts());
        }
        if (databaseLoginConfig.getPingSQL() != null){
            databaseLogin.setPingSQL(databaseLoginConfig.getPingSQL());
        }

        // Finally, return the newly created DatabaseLogin
        return databaseLogin;
    }

    /**
     * INTERNAL:
     */
    @SuppressWarnings({"unchecked"})
    protected void processStructConverterConfig(StructConverterConfig converterClassConfig, DatabaseLogin login) {
        if (converterClassConfig != null) {
            Platform platform = login.getDatasourcePlatform();
            if (platform instanceof DatabasePlatform){
                Iterator<String> i = converterClassConfig.getStructConverterClasses().iterator();

                while (i.hasNext()) {
                    String converterClassName = i.next();
                    try {
                        Class<StructConverter> converterClass = (Class<StructConverter>) m_classLoader.loadClass(converterClassName);
                        StructConverter converter = null;
                        if (PrivilegedAccessHelper.shouldUsePrivilegedAccess()){
                            try{
                                converter = AccessController.doPrivileged(new PrivilegedNewInstanceFromClass<>(converterClass));
                            }catch (PrivilegedActionException ex){
                                throw (Exception)ex.getCause();
                            }
                        }else{
                            converter = PrivilegedAccessHelper.newInstanceFromClass(converterClass);
                        }
                        ((DatabasePlatform)platform).addStructConverter(converter);
                    } catch (Exception exception) {
                        throw SessionLoaderException.failedToLoadTag("struct-converter", converterClassName, exception);
                    }
                }
            }
        }
    }

    /**
     * INTERNAL:
     * Process the common elements of a Login.
     */
    protected void processLoginConfig(LoginConfig loginConfig, DatasourceLogin login) {
        // Platform class
        String platformClassName = loginConfig.getPlatformClass();
        if (platformClassName != null) {
            try {
                @SuppressWarnings({"unchecked"})
                Class<DatasourcePlatform> platformClass = (Class<DatasourcePlatform>) m_classLoader.loadClass(platformClassName);
                if (PrivilegedAccessHelper.shouldUsePrivilegedAccess()){
                    login.usePlatform(AccessController.doPrivileged(new PrivilegedNewInstanceFromClass<>(platformClass)));
                }else{
                    login.usePlatform(PrivilegedAccessHelper.newInstanceFromClass(platformClass));
                }
            } catch (Exception exception) {
                throw SessionLoaderException.failedToLoadTag("platform-class", platformClassName, exception);
            }
        }

        // Table qualifier
        String tableQualifier = loginConfig.getTableQualifier();
        if (tableQualifier != null) {
            login.setTableQualifier(tableQualifier);
        }

        // Username - setUserName checks for null
        login.setUserName(loginConfig.getUsername());

        // Encryption class (must be set before the password)
        // XML Schema default is org.eclipse.persistence.internal.security.JCEEncryptor
        login.setEncryptionClassName(loginConfig.getEncryptionClass());

        // Password is encrypted on the model - setEncryptedPassword checks for null
        login.setEncryptedPassword(loginConfig.getEncryptedPassword());

        // External connection pool - XML Schema default is false
        login.setUsesExternalConnectionPooling(loginConfig.getExternalConnectionPooling());

        // External transaction controller - XML Schema default is false
        login.setUsesExternalTransactionController(loginConfig.getExternalTransactionController());

        // Sequencing - XML Schema default is null
        if (loginConfig.getSequencingConfig() != null) {
            if (loginConfig.getSequencingConfig().getDefaultSequenceConfig() != null) {
                Sequence sequence = buildSequence(loginConfig.getSequencingConfig().getDefaultSequenceConfig());
                login.setDefaultSequence(sequence);
            }

            if ((loginConfig.getSequencingConfig().getSequenceConfigs() != null) && !loginConfig.getSequencingConfig().getSequenceConfigs().isEmpty()) {
                Enumeration<SequenceConfig> eSequenceConfigs = loginConfig.getSequencingConfig().getSequenceConfigs().elements();

                while (eSequenceConfigs.hasMoreElements()) {
                    Sequence sequence = buildSequence(eSequenceConfigs.nextElement());
                    login.addSequence(sequence);
                }
            }
        }

        // Properties (assumes they are all valid)
        if (loginConfig.getPropertyConfigs() != null) {
            Enumeration<PropertyConfig> e = loginConfig.getPropertyConfigs().elements();

            while (e.hasMoreElements()) {
                PropertyConfig propertyConfig = e.nextElement();
                login.getProperties().put(propertyConfig.getName(), propertyConfig.getValue());
            }
        }
    }

    /**
     * INTERNAL:
     * Process the PoolsConfig object.
     */
    protected void processPoolsConfig(PoolsConfig poolsConfig, ServerSession serverSession) {
        if (poolsConfig != null) {
            // Read connection pool
            ReadConnectionPoolConfig readConnectionPoolConfig = poolsConfig.getReadConnectionPoolConfig();
            if (readConnectionPoolConfig != null) {
                serverSession.setReadConnectionPool(buildReadConnectionPoolConfig(readConnectionPoolConfig, serverSession));
            }

            // Write connection pool
            ConnectionPoolConfig writeConnectionPoolConfig = poolsConfig.getWriteConnectionPoolConfig();
            if (writeConnectionPoolConfig != null) {
                serverSession.addConnectionPool(buildConnectionPoolConfig(writeConnectionPoolConfig, serverSession));
            }

            // Sequence connection pool
            ConnectionPoolConfig sequenceConnectionPoolConfig = poolsConfig.getSequenceConnectionPoolConfig();
            if (sequenceConnectionPoolConfig != null) {
                processSequenceConnectionPoolConfig(sequenceConnectionPoolConfig, serverSession);
            }

            // Connection pools
            Enumeration<ConnectionPoolConfig> e = poolsConfig.getConnectionPoolConfigs().elements();
            while (e.hasMoreElements()) {
                ConnectionPoolConfig connectionPoolConfig = e.nextElement();
                serverSession.addConnectionPool(buildConnectionPoolConfig(connectionPoolConfig, serverSession));
            }
        }
    }

    /**
     * INTERNAL:
     * Process a SequenceConnectionPoolConfig object.
     */
    protected void processSequenceConnectionPoolConfig(ConnectionPoolConfig poolConfig, ServerSession serverSession) {
        // Set the Sequence connection pool flag to true
        serverSession.getSequencingControl().setShouldUseSeparateConnection(true);

        // Max connections
        Integer maxConnections = poolConfig.getMaxConnections();
        if (maxConnections != null) {
            serverSession.getSequencingControl().setMaxPoolSize(maxConnections);
        }

        // Min connections
        Integer minConnections = poolConfig.getMinConnections();
        if (minConnections != null) {
            serverSession.getSequencingControl().setMinPoolSize(minConnections);
        }

        // Name - no need to process
    }

    /**
     * INTERNAL:
     * Process a ServerPlatformConfig object.
     */
    protected void processServerPlatformConfig(ServerPlatformConfig platformConfig, ServerPlatform platform) {
        // Enable runtime services - XML schema default is true
        if (!platformConfig.getEnableRuntimeServices()) {
            platform.disableRuntimeServices();
        }

        // Enable JTA - XML schema default is true
        if (!platformConfig.getEnableJTA()) {
            platform.disableJTA();
        }
    }

    /**
     * INTERNAL:
     * Build a connection pool from the config to store on the server session.
     */
    protected ConnectionPool buildConnectionPoolConfig(ConnectionPoolConfig poolConfig, ServerSession serverSession) {
        ConnectionPool connectionPool = new ConnectionPool();

        // Process the common elements in ConnectionPool
        processConnectionPoolConfig(poolConfig, connectionPool, serverSession);

        return connectionPool;
    }

    /**
     * INTERNAL:
     */
    @SuppressWarnings({"unchecked", "rawtypes"})
    protected ServerPlatform buildCustomServerPlatformConfig(CustomServerPlatformConfig platformConfig, DatabaseSessionImpl session) {
        ServerPlatform platform;

        // Server class - XML schema default is org.eclipse.persistence.platform.server.CustomServerPlatform
        String serverClassName = platformConfig.getServerClassName();
        try {
            Class<ServerPlatform> serverClass = (Class<ServerPlatform>) m_classLoader.loadClass(serverClassName);
            if (PrivilegedAccessHelper.shouldUsePrivilegedAccess()){
                Constructor<ServerPlatform> constructor = AccessController.doPrivileged(new PrivilegedGetConstructorFor<>(serverClass, new Class[] { org.eclipse.persistence.sessions.DatabaseSession.class }, false));
                platform = AccessController.doPrivileged(new PrivilegedInvokeConstructor<>(constructor, new Object[] { session }));
            }else{
                Constructor<ServerPlatform> constructor = PrivilegedAccessHelper.getConstructorFor(serverClass, new Class[] { org.eclipse.persistence.sessions.DatabaseSession.class }, false);
                platform = PrivilegedAccessHelper.invokeConstructor(constructor, new Object[] { session });
            }
        } catch (Exception e) {
            throw SessionLoaderException.failedToLoadTag("server-class", serverClassName, e);
        }

        // External transaction controller class
        String externalTransactionControllerClass = platformConfig.getExternalTransactionControllerClass();
        if (externalTransactionControllerClass != null) {
            try {
                platform.setExternalTransactionControllerClass((Class<ExternalTransactionController>) m_classLoader.loadClass(externalTransactionControllerClass));
            } catch (Exception exception) {
                throw SessionLoaderException.failedToLoadTag("external-transaction-controller-class", externalTransactionControllerClass, exception);
            }
        }

        return platform;
    }

    /**
     * INTERNAL:
     * Build a read connection pool from the config to store on the server session.
     */
    protected ConnectionPool buildReadConnectionPoolConfig(ReadConnectionPoolConfig poolConfig, ServerSession serverSession) {
        // Exclusive tag - XML Schema default is false
        ConnectionPool connectionPool = (poolConfig.getExclusive()) ? new ConnectionPool() : new ReadConnectionPool();

        // Process the common elements in ConnectionPool
        processConnectionPoolConfig(poolConfig, connectionPool, serverSession);

        return connectionPool;
    }

    /**
     * INTERNAL:
     * Process the common elements from a ConnectionPoolConfig
     */
    protected void processConnectionPolicyConfig(ConnectionPolicyConfig connectionPolicyConfig, ServerSession serverSession) {
        if (connectionPolicyConfig != null) {
            ConnectionPolicy connectionPolicy = serverSession.getDefaultConnectionPolicy();
            if(connectionPolicyConfig.getUseExclusiveConnection()) {
                connectionPolicy.setExclusiveMode(ConnectionPolicy.ExclusiveMode.Isolated);
            } else {
                connectionPolicy.setExclusiveMode(ConnectionPolicy.ExclusiveMode.Transactional);
            }
            connectionPolicy.setIsLazy(connectionPolicyConfig.getLazy());
        }
    }

    /**
     * INTERNAL:
     * Process the common elements from a ConnectionPoolConfig
     */
    protected void processConnectionPoolConfig(ConnectionPoolConfig poolConfig, ConnectionPool connectionPool, AbstractSession session) {
        // Login - if null, set it to the same as the session login
        Login login = buildLogin(poolConfig.getLoginConfig());
        if (login != null) {
            connectionPool.setLogin(login);
        } else {
            connectionPool.setLogin(session.getDatasourceLogin());
        }

        // Name
        connectionPool.setName(poolConfig.getName());

        // Max connections
        Integer maxConnections = poolConfig.getMaxConnections();
        if (maxConnections != null) {
            connectionPool.setMaxNumberOfConnections(maxConnections);
        }

        // Min connections
        Integer minConnections = poolConfig.getMinConnections();
        if (minConnections != null) {
            connectionPool.setMinNumberOfConnections(minConnections);
        }
    }

    /**
     * INTERNAL:
     * Process the common elements from a SessionConfig.
     */
    protected void processSessionConfig(SessionConfig sessionConfig, AbstractSession session) {
        // Name
        session.setName(sessionConfig.getName().trim());

        // Session Event Manager
        processSessionEventManagerConfig(sessionConfig.getSessionEventManagerConfig(), session);

        //server platform
        ((DatabaseSessionImpl)session).setServerPlatform(buildServerPlatformConfig(sessionConfig.getServerPlatformConfig(), (DatabaseSessionImpl)session));

        // Session Log - BUG# 3442865, don't set the log if it is null
        SessionLog log = buildSessionLog(sessionConfig.getLogConfig(), session);
        if (log != null) {
            session.setSessionLog(log);
        }

        // Remote command manager
        buildRemoteCommandManagerConfig(sessionConfig.getRemoteCommandManagerConfig(), session);

        // Profiler - XML Schema default is null
        if (sessionConfig.getProfiler() != null) {
            if (sessionConfig.getProfiler().equals("eclipselink")) {
                session.setProfiler(new PerformanceProfiler());
            }
        }

        // Exception handler
        String exceptionHandlerClassName = sessionConfig.getExceptionHandlerClass();
        if (exceptionHandlerClassName != null) {
            try {
                @SuppressWarnings({"unchecked"})
                Class<ExceptionHandler> exceptionHandlerClass = (Class<ExceptionHandler>) m_classLoader.loadClass(exceptionHandlerClassName);
                if (PrivilegedAccessHelper.shouldUsePrivilegedAccess()){
                    session.setExceptionHandler(AccessController.doPrivileged(new PrivilegedNewInstanceFromClass<>(exceptionHandlerClass)));
                }else{
                    session.setExceptionHandler(PrivilegedAccessHelper.newInstanceFromClass(exceptionHandlerClass));
                }
            } catch (Exception e) {
                throw SessionLoaderException.failedToLoadTag("exception-handler-class", exceptionHandlerClassName, e);
            }
        }

        // Session customizer will be processed in the buildSessions method.
        // Ensures it is run last.
    }

    /**
     * INTERNAL: Build the appropriate server platform
     */
    protected ServerPlatform buildServerPlatformConfig(ServerPlatformConfig platformConfig, DatabaseSessionImpl session) {
        if (platformConfig == null) {
            return new NoServerPlatform(session);
        }

        // Build the server platform, the config model knows which to build.
        ServerPlatform platform;

        if (platformConfig instanceof CustomServerPlatformConfig) {
            platform = buildCustomServerPlatformConfig((CustomServerPlatformConfig)platformConfig, session);
        } else {
            // A supported platform so instantiate an object of its type.
            String serverClassName = platformConfig.getServerClassName();
            if (platformConfig.isSupported()) {
                platform = ServerPlatformUtils.createServerPlatform(session, serverClassName, m_classLoader);
            } else {
                throw SessionLoaderException.serverPlatformNoLongerSupported(serverClassName);
            }
        }

        // Process the common elements in ServerPlatformConfig
        processServerPlatformConfig(platformConfig, platform);
        return platform;
    }

    /**
     * INTERNAL:
     */
    protected void buildRemoteCommandManagerConfig(RemoteCommandManagerConfig rcmConfig, AbstractSession session) {
        if (rcmConfig != null) {
            RemoteCommandManager rcm = new RemoteCommandManager(session);

            // Commands
            processCommandsConfig(rcmConfig.getCommandsConfig(), rcm);

            // Transport Manager - will set the built TransportManager on the given
            // Remote command manager that is passed in
            buildTransportManager(rcmConfig.getTransportManagerConfig(), rcm);

            // Channel - XML Schema default is TopLinkCommandChannel
            rcm.setChannel(rcmConfig.getChannel());
        }
    }

    /**
     * INTERNAL:
     */
    protected void buildTransportManager(TransportManagerConfig tmConfig, RemoteCommandManager rcm) {
        if (tmConfig instanceof RMIIIOPTransportManagerConfig) {
            buildRMIIIOPTransportManagerConfig((RMIIIOPTransportManagerConfig)tmConfig, rcm);
        }  else if (tmConfig instanceof RMITransportManagerConfig) {
            buildRMITransportManagerConfig((RMITransportManagerConfig)tmConfig, rcm);
        } else if (tmConfig instanceof JMSTopicTransportManagerConfig) {
            buildJMSTopicTransportManagerConfig((JMSTopicTransportManagerConfig)tmConfig, rcm);
        } else if (tmConfig instanceof JMSPublishingTransportManagerConfig) {
            buildJMSPublishingTransportManagerConfig((JMSPublishingTransportManagerConfig)tmConfig, rcm);
        } else if (tmConfig instanceof Oc4jJGroupsTransportManagerConfig) {
            buildOc4jJGroupsTransportManagerConfig((Oc4jJGroupsTransportManagerConfig)tmConfig, rcm);
        } else if (tmConfig instanceof SunCORBATransportManagerConfig) {
            buildSunCORBATransportManagerConfig((SunCORBATransportManagerConfig)tmConfig, rcm);
        } else if (tmConfig instanceof UserDefinedTransportManagerConfig) {
            buildUserDefinedTransportManagerConfig((UserDefinedTransportManagerConfig)tmConfig, rcm);
        }
    }

    /**
     * INTERNAL:
     */
    protected void buildRMITransportManagerConfig(RMITransportManagerConfig tmConfig, RemoteCommandManager rcm) {
        RMITransportManager tm = new RMITransportManager(rcm);

        // Set the transport manager. This will initialize the DiscoveryManager
        // This needs to be done before we process the DiscoveryConfig.
        rcm.setTransportManager(tm);

        // Discovery
        DiscoveryConfig discoveryConfig = tmConfig.getDiscoveryConfig();
        if (discoveryConfig != null) {
            processDiscoveryConfig(discoveryConfig, rcm.getDiscoveryManager());
        }

        if (tmConfig.getJNDINamingServiceConfig() != null) {
            // JNDI naming service
            tm.setNamingServiceType(TransportManager.JNDI_NAMING_SERVICE);
            processJNDINamingServiceConfig(tmConfig.getJNDINamingServiceConfig(), tm);
        } else if (tmConfig.getRMIRegistryNamingServiceConfig() != null) {
            // RMI registry naming service
            tm.setNamingServiceType(TransportManager.REGISTRY_NAMING_SERVICE);
            processRMIRegistryNamingServiceConfig(tmConfig.getRMIRegistryNamingServiceConfig(), tm);
        }

        tm.setIsRMIOverIIOP(tmConfig instanceof RMIIIOPTransportManagerConfig);

        // Send mode - Can only be Asynchronous (true) or Synchronous (false), validated by the schema
        // XML Schema default is Asynchronous
        rcm.setShouldPropagateAsynchronously(tmConfig.getSendMode().equals("Asynchronous"));

        // Process the common elements in TransportManagerConfig
        processTransportManagerConfig(tmConfig, tm);
    }

    /**
     * INTERNAL:
     * Builds a Sequence from the given SequenceConfig.
     */
    protected Sequence buildSequence(SequenceConfig sequenceConfig) {
        if (sequenceConfig == null) {
            return null;
        }

        String name = sequenceConfig.getName();
        int size = sequenceConfig.getPreallocationSize();

        if (sequenceConfig instanceof DefaultSequenceConfig) {
            return new DefaultSequence(name, size);
        } else if (sequenceConfig instanceof NativeSequenceConfig) {
            return new NativeSequence(name, size);
        } else if (sequenceConfig instanceof TableSequenceConfig) {
            TableSequenceConfig tsc = (TableSequenceConfig)sequenceConfig;
            return new TableSequence(name, size, tsc.getTable(), tsc.getNameField(), tsc.getCounterField());
        } else if (sequenceConfig instanceof UnaryTableSequenceConfig) {
            UnaryTableSequenceConfig utsc = (UnaryTableSequenceConfig)sequenceConfig;
            return new UnaryTableSequence(name, size, utsc.getCounterField());
        } else if (sequenceConfig instanceof XMLFileSequenceConfig) {
            try {
                // Can no longer reference class directly as in a different project.
                @SuppressWarnings({"unchecked"})
                Class<Sequence> xmlClass = (Class<Sequence>) Class.forName("org.eclipse.persistence.eis.adapters.xmlfile.XMLFileSequence");
                Sequence sequence = xmlClass.getConstructor().newInstance();
                sequence.setName(name);
                sequence.setInitialValue(size);
                return sequence;
            } catch (Exception missing) {
                return null;
            }
        } else {
            // Unknown SequenceConfig subclass - should never happen
            return null;
        }
    }

    /**
     * INTERNAL:
     * Left this in for now since in the future we may add more IIOP specific
     * configurations?
     */
    protected void buildRMIIIOPTransportManagerConfig(RMIIIOPTransportManagerConfig tmConfig, RemoteCommandManager rcm) {
        buildRMITransportManagerConfig(tmConfig, rcm);
    }

    /**
     * INTERNAL:
     */
    protected void buildJMSTopicTransportManagerConfig(JMSTopicTransportManagerConfig tmConfig, RemoteCommandManager rcm) {
        JMSTopicTransportManager tm = new JMSTopicTransportManager(rcm);

        // Set the transport manager. This will initialize the DiscoveryManager
        rcm.setTransportManager(tm);

        processJMSTransportManagerConfig(tmConfig, tm);
    }

    /**
     * INTERNAL:
     */
    protected void buildJMSPublishingTransportManagerConfig(JMSPublishingTransportManagerConfig tmConfig, RemoteCommandManager rcm) {
        JMSPublishingTransportManager tm = new JMSPublishingTransportManager(rcm);

        // Set the transport manager. This will initialize the DiscoveryManager
        rcm.setTransportManager(tm);
        processJMSTransportManagerConfig(tmConfig, tm);
    }

    /**
     * INTERNAL:
     * Common JMS configuration
     */
    protected void processJMSTransportManagerConfig(JMSPublishingTransportManagerConfig tmConfig, JMSPublishingTransportManager tm ){
        // JNDI naming service
        if (tmConfig.getJNDINamingServiceConfig() != null) {
            tm.setNamingServiceType(TransportManager.JNDI_NAMING_SERVICE);
            processJNDINamingServiceConfig(tmConfig.getJNDINamingServiceConfig(), tm);
        }

        // Topic host URL
        String topicHostURL = tmConfig.getTopicHostURL();
        if (topicHostURL != null) {
            tm.setTopicHostUrl(topicHostURL);
        }

        // Topic connection factory name - XML Schema default is jms/TopLinkTopicConnectionFactory
        tm.setTopicConnectionFactoryName(tmConfig.getTopicConnectionFactoryName());

        // Topic name - XML Schema default is jms/TopLinkTopic
        tm.setTopicName(tmConfig.getTopicName());

        // Process the common elements in TransportManagerConfig
        processTransportManagerConfig(tmConfig, tm);
    }

    /**
     * INTERNAL:
     */
    @SuppressWarnings({"unchecked", "rawtypes"})
    protected void buildOc4jJGroupsTransportManagerConfig(Oc4jJGroupsTransportManagerConfig tmConfig, RemoteCommandManager rcm) {
        TransportManager tm = null;
        try {
            Class<TransportManager> tmClass = (Class<TransportManager>) m_classLoader.loadClass(tmConfig.getTransportManagerClassName());
            if (PrivilegedAccessHelper.shouldUsePrivilegedAccess()){
                Constructor<TransportManager> constructor = AccessController.doPrivileged(new PrivilegedGetConstructorFor<>(tmClass, new Class[] { RemoteCommandManager.class, boolean.class, String.class }, false));
                tm = AccessController.doPrivileged(new PrivilegedInvokeConstructor<>(constructor, new Object[] { rcm, tmConfig.useSingleThreadedNotification(), tmConfig.getTopicName() }));
            }else{
                Constructor<TransportManager> constructor = PrivilegedAccessHelper.getConstructorFor(tmClass, new Class[] { RemoteCommandManager.class, boolean.class, String.class }, false);
                tm = PrivilegedAccessHelper.invokeConstructor(constructor, new Object[] { rcm, tmConfig.useSingleThreadedNotification(), tmConfig.getTopicName() });
            }
        } catch (Exception e) {
            throw SessionLoaderException.failedToParseXML("Oc4jJGroupsTransportManager class is invalid: " + tmConfig.getTransportManagerClassName(), e);
        }

        // Set the transport manager. This will initialize the DiscoveryManager
        rcm.setTransportManager(tm);

        // Process the common elements in TransportManagerConfig
        processTransportManagerConfig(tmConfig, tm);
    }

    /**
     * INTERNAL:
     */
    protected void buildUserDefinedTransportManagerConfig(UserDefinedTransportManagerConfig tmConfig, RemoteCommandManager rcm) {
        TransportManager tm = null;

        // Transport class
        String transportManagerClassName = tmConfig.getTransportClass();
        if (transportManagerClassName != null) {
            try {
                @SuppressWarnings({"unchecked"})
                Class<TransportManager> transportManagerClass = (Class<TransportManager>) m_classLoader.loadClass(transportManagerClassName);
                if (PrivilegedAccessHelper.shouldUsePrivilegedAccess()){
                    tm = AccessController.doPrivileged(new PrivilegedNewInstanceFromClass<>(transportManagerClass));
                }else{
                    tm = PrivilegedAccessHelper.newInstanceFromClass(transportManagerClass);
                }
            } catch (Exception exception) {
                throw SessionLoaderException.failedToLoadTag("transport-class", transportManagerClassName, exception);
            }

            // Set the transport manager. This will initialize the DiscoveryManager
            rcm.setTransportManager(tm);

            // Process the common elements in TransportManagerConfig
            processTransportManagerConfig(tmConfig, tm);
        }
    }

    /**
     * INTERNAL:
     */
    protected void processJNDINamingServiceConfig(JNDINamingServiceConfig namingConfig, TransportManager tm) {
        // URL
        String url = namingConfig.getURL();
        if (url != null) {
            tm.getRemoteCommandManager().setUrl(url);
        }

        // Username - XML Schema default is admin
        tm.setUserName(namingConfig.getUsername());

        // Encryption class - XML Schema default is org.eclipse.persistence.internal.security.JCEEncryptor
        tm.setEncryptionClassName(namingConfig.getEncryptionClass());

        // Password - XML Schema default is password
        tm.setEncryptedPassword(namingConfig.getEncryptedPassword());

        // Initial context factory name - XML Schema is weblogic.jndi.WLInitialContextFactory
        tm.setInitialContextFactoryName(namingConfig.getInitialContextFactoryName());

        // Properties (assumes they are all valid)
        Enumeration<PropertyConfig> e = namingConfig.getPropertyConfigs().elements();

        while (e.hasMoreElements()) {
            PropertyConfig propertyConfig = e.nextElement();
            tm.getRemoteContextProperties().put(propertyConfig.getName(), propertyConfig.getValue());
        }
    }

    /**
     * INTERNAL:
     */
    protected void processRMIRegistryNamingServiceConfig(RMIRegistryNamingServiceConfig namingConfig, TransportManager tm) {
        // URL
        tm.getRemoteCommandManager().setUrl(namingConfig.getURL());
    }

    /**
     * INTERNAL:
     */
    protected void processDiscoveryConfig(DiscoveryConfig discoveryConfig, DiscoveryManager discoveryManager) {
        // Multicast group address - XML Schema default is 226.10.12.64
        discoveryManager.setMulticastGroupAddress(discoveryConfig.getMulticastGroupAddress());

        // Mutlicast port - XML Schema default is 3121
        discoveryManager.setMulticastPort(discoveryConfig.getMulticastPort());

        // Announcement delay - XML Schema default is 1000
        discoveryManager.setAnnouncementDelay(discoveryConfig.getAnnouncementDelay());

        //Packet time-to-live - XML Schema default is 2
        discoveryManager.setPacketTimeToLive(discoveryConfig.getPacketTimeToLive());
    }

    /**
     * INTERNAL:
     */
    protected void processTransportManagerConfig(TransportManagerConfig tmConfig, TransportManager tm) {
        // On connection error - Can only be DiscardConnection (true) or
        // KeepConnection (false), validated by the schema
        // XML Schema default is DiscardConnection
        tm.setShouldRemoveConnectionOnError(tmConfig.getOnConnectionError().equals("DiscardConnection"));
    }

    /**
     * INTERNAL:
     */
    protected void processSessionEventManagerConfig(SessionEventManagerConfig sessionEventManagerConfig, AbstractSession session) {
        if (sessionEventManagerConfig != null) {
            Enumeration<String> e = sessionEventManagerConfig.getSessionEventListeners().elements();

            while (e.hasMoreElements()) {
                String listenerClassName = e.nextElement();

                try {
                    @SuppressWarnings({"unchecked"})
                    Class<SessionEventListener> listenerClass = (Class<SessionEventListener>) m_classLoader.loadClass(listenerClassName);
                    if (PrivilegedAccessHelper.shouldUsePrivilegedAccess()){
                        session.getEventManager().addListener(AccessController.doPrivileged(new PrivilegedNewInstanceFromClass<>(listenerClass)));
                    }else{

                    }
                    session.getEventManager().addListener(PrivilegedAccessHelper.newInstanceFromClass(listenerClass));
                } catch (Exception exception) {
                    throw SessionLoaderException.failedToLoadTag("event-listener-class", listenerClassName, exception);
                }
            }
        }
    }

    /**
     * INTERNAL:
     */
    protected SessionLog buildSessionLog(LogConfig logConfig, AbstractSession session) {
        if (logConfig instanceof JavaLogConfig) {
            return buildJavaLogConfig((JavaLogConfig)logConfig, session);
        } else if (logConfig instanceof DefaultSessionLogConfig) {
            return buildDefaultSessionLogConfig((DefaultSessionLogConfig)logConfig);
        } else if (logConfig instanceof ServerLogConfig) {
            return buildServerLogConfig((ServerLogConfig)logConfig, session);
        } else {
            return null;
        }
    }

    /**
     * INTERNAL:
     */
    @SuppressWarnings({"unchecked"})
    protected SessionLog buildJavaLogConfig(JavaLogConfig javaLogConfig, AbstractSession session) {
        SessionLog javaLog = null;
        try {
            // use ConversionManager to avoid loading the JDK 1.4 class unless it is needed.
            ConversionManager conversionManager = new ConversionManager();
            conversionManager.setLoader(getClass().getClassLoader());
            javaLog = ((Class<SessionLog>)conversionManager.convertObject("org.eclipse.persistence.logging.JavaLog", Class.class)).getConstructor().newInstance();
            javaLog.setSession(session);
        } catch (Exception exception) {
            throw ValidationException.unableToLoadClass("org.eclipse.persistence.logging.JavaLog", exception);
        }

        // Process the common elements from LogConfig
        processLogConfig(javaLogConfig, javaLog);

        return javaLog;
    }

    /**
     * INTERNAL:
     * Wrapped by the getSessionLog() call, therefore, config can't be null at
     * this point.
     */
    protected SessionLog buildDefaultSessionLogConfig(DefaultSessionLogConfig defaultSessionLogConfig) {
        DefaultSessionLog defaultSessionLog = new DefaultSessionLog();

        // Log level - XML Schema default is info
        defaultSessionLog.setLevel(m_logLevels.get(defaultSessionLogConfig.getLogLevel()));

        // Filename - setWriter will handle nulls
        defaultSessionLog.setWriter(defaultSessionLogConfig.getFilename());

        // Process the common elements from LogConfig
        processLogConfig(defaultSessionLogConfig, defaultSessionLog);

        return defaultSessionLog;
    }

    /**
     * INTERNAL:
     */
    protected SessionLog buildServerLogConfig(ServerLogConfig serverLogConfig, AbstractSession session) {
        SessionLog serverLog = session.getServerPlatform().getServerLog();

        return serverLog;
    }

    /**
     * INTERNAL:
     */
    protected void processLogConfig(LogConfig logConfig, SessionLog log) {
        if (logConfig.getLoggingOptions() != null) {
            if (logConfig.getLoggingOptions().getShouldLogExceptionStackTrace() != null) {
                log.setShouldLogExceptionStackTrace(logConfig.getLoggingOptions().getShouldLogExceptionStackTrace());
            }
            if (logConfig.getLoggingOptions().getShouldPrintConnection() != null) {
                log.setShouldPrintConnection(logConfig.getLoggingOptions().getShouldPrintConnection());
            }
            if (logConfig.getLoggingOptions().getShouldPrintDate() != null) {
                log.setShouldPrintDate(logConfig.getLoggingOptions().getShouldPrintDate());
            }
            if (logConfig.getLoggingOptions().getShouldPrintSession() != null) {
                log.setShouldPrintSession(logConfig.getLoggingOptions().getShouldPrintSession());
            }
            if (logConfig.getLoggingOptions().getShouldPrintThread() != null) {
                log.setShouldPrintThread(logConfig.getLoggingOptions().getShouldPrintThread());
            }
        }
    }

    /**
     * INTERNAL:
     * Builds a Sun CORBA transport manager with the given remote command manager
     */
    protected void buildSunCORBATransportManagerConfig(SunCORBATransportManagerConfig tmConfig, RemoteCommandManager rcm) {
        TransportManager tm = TransportManager.newSunCORBATransportManager(rcm);

        // Set the transport manager. This will initialize the DiscoveryManager
        rcm.setTransportManager(tm);

        // Process the common elements in TransportManagerConfig
        processTransportManagerConfig(tmConfig, tm);
    }

    /**
     * INTERNAL:
     */
    protected void processCommandsConfig(CommandsConfig commandsConfig, RemoteCommandManager rcm) {
        if (commandsConfig != null) {
            // cache-sync - XML Schema default is false
            ((AbstractSession)rcm.getCommandProcessor()).setShouldPropagateChanges(commandsConfig.getCacheSync());
        }
    }

    /**
     * INTERNAL:
     * Builds a session broker from the given SessionBrokerConfig.
     */
    protected SessionBroker buildSessionBrokerConfig(SessionBrokerConfig sessionBrokerConfig) {
        SessionBroker sessionBroker = new SessionBroker();

        // Session names
        Enumeration<String> sessionNames = sessionBrokerConfig.getSessionNames().elements();

        while (sessionNames.hasMoreElements()) {
            // Register the sessions
            String sessionName = sessionNames.nextElement();
            sessionBroker.registerSession(sessionName, (AbstractSession)m_sessions.get(sessionName));
        }

        // Process the common elements in SessionConfig
        processSessionConfig(sessionBrokerConfig, sessionBroker);

        return sessionBroker;
    }
}
