/*
 * 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
package org.eclipse.persistence.sessions;

import java.io.PrintWriter;
import java.io.Serializable;
import java.io.StringWriter;
import java.security.AccessController;
import java.security.PrivilegedActionException;
import java.text.MessageFormat;
import java.util.Map;
import java.util.Properties;

import org.eclipse.persistence.Version;
import org.eclipse.persistence.exceptions.DatabaseException;
import org.eclipse.persistence.exceptions.ValidationException;
import org.eclipse.persistence.internal.databaseaccess.Accessor;
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.helper.Helper;
import org.eclipse.persistence.internal.helper.NonSynchronizedProperties;
import org.eclipse.persistence.internal.localization.ToStringLocalization;
import org.eclipse.persistence.internal.security.PrivilegedAccessHelper;
import org.eclipse.persistence.internal.security.PrivilegedNewInstanceFromClass;
import org.eclipse.persistence.internal.security.SecurableObjectHolder;
import org.eclipse.persistence.platform.database.DatabasePlatform;
import org.eclipse.persistence.queries.ValueReadQuery;
import org.eclipse.persistence.sequencing.Sequence;

/**
 * <p>
 * <b>Purpose</b>:
 * Hold the configuration information necessary to connect to a datasource.
 * <p>
 * <b>Description</b>:
 * This is an abstract class that defines the common datasource independent connection configuration.
 * It is extended to support specific datasources such as JDBC, JCA, XML, etc.
 */
public abstract class DatasourceLogin implements org.eclipse.persistence.sessions.Login, Serializable, Cloneable {

    /** Version info */
    private static final String versionStringTemplate = "{0} - {1}";
    public static String versionString = null;

    /** Connection properties (e.g. user, password, and driver-specific settings) */
    protected Properties properties;

    /** Implementation of platform-specific behaviors. */
    protected Platform platform;

    /** findbugs: removed the encrypted String that holds the expiry key */

    /** The securable object holder and flag*/
    private boolean isEncryptedPasswordSet;
    private transient SecurableObjectHolder securableObjectHolder;

    /** Provide a little flexibility for connecting to a database */
    protected Connector connector;

    /** True if we use an external connection pool such as WebLogic's JTS driver */
    protected boolean usesExternalConnectionPooling;

    /** True if we should use some external transaction service such as JTS. */
    protected boolean usesExternalTransactionController;

    /**
     * By default concurrency is optimized and the cache is not locked during reads or writes,
     * This allows for concurrent reading and writing and should never cause any problems.  If the application
     * uses no form of locking the last unit of work to merge changes will win, with no locking it is possible
     * only under this scenario for two unit of works to merge changes different than the database although highly unlikely
     * and if occurred is the entire purpose of locking.  This property allows for the isolation level of changes to the
     * cache to be configured for sever situation and it is not suggest that this be changed.
     */
    protected int cacheTransactionIsolation = SYNCRONIZED_OBJECT_LEVEL_READ_WRITE_DATABASE;

    /** Reads and unit of work merges can occur concurrently. */
    public static final int CONCURRENT_READ_WRITE = 1;

    /** Reads can occur concurrently but unit of work merges will be serialized. */
    public static final int SYNCHRONIZED_WRITE = 2;

    /** Reads and unit of work merges will be serialized. */
    public static final int SYNCHRONIZED_READ_ON_WRITE = 3;

    /** Writes to the cache (merge, object build/refresh will be synchronized
     * as will cache access (cloning) based on when access is required.
     */
    public static final int SYNCRONIZED_OBJECT_LEVEL_READ_WRITE = 4;

    /** Writes to the cache (merge, object build/refresh will be synchronized
     * as will cache access (cloning) based on database transaction.
     */
    public static final int SYNCRONIZED_OBJECT_LEVEL_READ_WRITE_DATABASE = 5;

    /**
     * PUBLIC:
     * Create a new login.
     */
    protected DatasourceLogin() {
        this(new DatasourcePlatform());
    }

    /**
     * ADVANCED:
     * Create a new login for the given platform.
     */
    protected DatasourceLogin(Platform databasePlatform) {
        this.platform = databasePlatform;

        this.dontUseExternalConnectionPooling();
        this.dontUseExternalTransactionController();

        this.properties = new NonSynchronizedProperties(4);
        this.properties.put("user", "");
        this.isEncryptedPasswordSet = false;
        this.securableObjectHolder = new SecurableObjectHolder();
    }

    /**
     * INTERNAL:
     * Return the encryption securable holder.
     * Lazy initialize to handle serialization.
     */
    protected SecurableObjectHolder getSecurableObjectHolder() {
        if (securableObjectHolder == null) {
            securableObjectHolder = new SecurableObjectHolder();
            securableObjectHolder.getSecurableObject();
        }
        return securableObjectHolder;
    }

    /**
     * INTERNAL:
     * Clone the login.
     * This also clones the platform as it is internal to the login.
     */
    @Override
    public DatasourceLogin clone() {
        DatasourceLogin clone = null;
        try {
            clone = (DatasourceLogin)super.clone();
        } catch (Exception exception) {
            throw new AssertionError(exception);
        }
        if (getConnector() != null) {
            clone.setConnector((Connector)getConnector().clone());
        }
        clone.setDatasourcePlatform((Platform)getDatasourcePlatform().clone());
        clone.setProperties((Properties)properties.clone());
        return clone;
    }

    /**
     * INTERNAL:
     * Connect to the datasource, and return the driver level connection object.
     */
    @Override
    public Object connectToDatasource(Accessor accessor, Session session) throws DatabaseException {
        return getConnector().connect(prepareProperties(properties), session);
    }

    /**
     * ADVANCED:
     * By default concurrency is optimized and the cache is not locked more than required during reads or writes,
     * This allows for virtual concurrent reading and writing and should never cause any problems.  If the application
     * uses no form of locking the last unit of work to merge changes will win, with no locking it is possible
     * only under this scenario for two unit of works to merge changes different than the database although highly unlikely
     * and if occurred is the entire purpose of locking and locking is the suggested solution if this is a problem.
     * This property allows for the isolation level of changes to the
     * cache to be configured for sever situations and it is not suggest that this be changed.
     * <p>Setting are:<ul>
     * <li>ConcurrentReadWrite - default
     * <li>SynchronizedWrite - only allow a single writer (i.e. unit of work merge) to the cache at once
     * <li>SynchronizedReadOnWrite - do not allow reading or other unit of work merge while a unit of work is in merge</ul>
     */
    public int getCacheTransactionIsolation() {
        return cacheTransactionIsolation;
    }

    /**
     * ADVANCED:
     * Return the connector that will instantiate the connection.
     */
    public Connector getConnector() {
        return connector;
    }

    /**
     * INTERNAL:
     * Return the database platform specific information.
     * This allows EclipseLink to configure certain advanced features for the database desired.
     * NOTE: this must only be used for relational specific usage and will not work for
     * non-relational datasources.
     */
    @Override
    public DatabasePlatform getPlatform() {
        try {
            return (DatabasePlatform)getDatasourcePlatform();
        } catch (ClassCastException wrongType) {
            throw ValidationException.notSupportedForDatasource();
        }
    }

    /**
     * PUBLIC:
     * Return the datasource platform specific information.
     * This allows EclipseLink to configure certain advanced features for the datasource desired.
     */
    @Override
    public Platform getDatasourcePlatform() {
        if (this.platform == null) {
            this.platform = new DatasourcePlatform();
        }
        return platform;
    }

    /**
     * INTERNAL:
     * The properties are additional, driver-specific, connection information
     * to be passed to the driver.<p>
     * NOTE: Do not set the password directly by getting the properties and
     * setting the "password" property directly. Use the method DatabaseLogin.setPassword(String).
     */
    public Properties getProperties() {
        return properties;
    }

    /**
     * PUBLIC:
     * The properties are additional, driver-specific, connection information
     * to be passed to the driver.<p>
     * NOTE: Do not set the password directly by getting the properties and
     * setting the "password" property directly. Use the method DatabaseLogin.setPassword(String).
     */
    @Override
    public Object getProperty(String name) {
        return getProperties().get(name);
    }

    /**
     * PUBLIC:
     * Return the qualifier for the all of the tables referenced by EclipseLink.
     * This can be the creator of the table or database name the table exists on.
     * This is required by some databases such as Oracle and DB2.
     * This should only be used if all of the tables have the same qualifier.
     * It can also be set on each descriptor when the table name is specified.
     */
    @Override
    public String getTableQualifier() {
        return getDatasourcePlatform().getTableQualifier();
    }

    /**
     * PUBLIC:
     * The user name is the database login name.
     * Some databases do not require a user name or the user is obtained from the OS,
     * in this case the user name not be specified.
     */
    @Override
    public String getUserName() {
        return properties.getProperty("user");
    }


    /**
     * PUBLIC:
     * This value defaults to false when not on a DatabaseLogin as the functionality has not been implemented
     * for other datasource type.  On an SQL Exception EclipseLink will ping the database to determine
     * if the connection used can continue to be used for queries.  This should have no impact on applications
     * unless the user is using pessimistic locking queries with 'no wait' or are using a query timeout feature.
     * If that is the case and the application is experiencing a performance impact from the health check then
     * this feature can be turned off. Turning this feature off will prevent EclipseLink from being able to
     * retry queries in the case of database failure.
     */
    @Override
    public boolean isConnectionHealthValidatedOnError(){
        return false;
    }

    /**
     * PUBLIC:
     * Return the EclipseLink version.
     * @return version of EclipseLink
     */
    public static String getVersion() {
        if (versionString == null) {
            Object[] args = { Version.getProduct(), Version.getVersionString() };
            versionString = MessageFormat.format(versionStringTemplate, args);
        }
        return versionString;
    }

    /**
     * SECURE:
     * The password in the login properties is encrypted. Return a clone
     * of the properties with the password decrypted.
     */
    private Properties prepareProperties(Properties properties) {
        Properties result = properties;
        Object passwordObject = result.get("password");
        if (passwordObject != null) {
            // Fix for bug # 2700529
            // The securable object is initialized on first call of
            // getSecurableObject. When setting an encrypted password
            // we don't make this call since it is already encrypted, hence,
            // we do not initialize the securable object on the holder.
            //
            // If neither setPassword or setEncryptedPassword is called
            // (example, user sets properties via the setProperties method),
            // when the user tries to connect they  will get a null pointer
            // exception. So if the holder does not hold
            // a securable object or the setEncryptedPassword flag is not true,
            // don't bother trying to decrypt.
            if (getSecurableObjectHolder().hasSecurableObject() || isEncryptedPasswordSet) {
                result = (Properties)properties.clone();
                // Bug 4117441 - Secure programming practices, store password in char[]
                // If isEncryptedPasswordSet is true, or we have a SecurableObject then we stored
                // the password as a char[], and we need to convert it into a String for the
                // prepared Properties object.
                if (passwordObject instanceof char[]) {
                    result.put("password", getSecurableObjectHolder().getSecurableObject().decryptPassword(new String((char[])passwordObject)));
                } else if (passwordObject instanceof String) {
                    result.put("password", getSecurableObjectHolder().getSecurableObject().decryptPassword((String)passwordObject));
                } else {
                    //properties cannot store null
                    result.remove("password");
                }
            } else if ((passwordObject instanceof char[]) && (((char[])passwordObject).length == 0)) {
                // Bug 236726 - deal with empty string for passwords
                result.put("password", "");
            }
        }

        return result;
    }

    /**
     * PUBLIC:
     * Some drivers don't like the "user" and "password" properties.
     * They can be removed with this method, or by using setUserName(null) / setPassword(null)
     */
    public void removeProperty(String propertyName) {
        properties.remove(propertyName);
    }

    /**
     * ADVANCED:
     * By default concurrency is optimized and the cache is not locked more than required during reads or writes,
     * This allows for virtual concurrent reading and writing and should never cause any problems.  If the application
     * uses no form of locking the last unit of work to merge changes will win, with no locking it is possible
     * only under this scenario for two unit of works to merge changes different than the database although highly unlikely
     * and if occurred is the entire purpose of locking and locking is the suggested solution if this is a problem.
     * This property allows for the isolation level of changes to the
     * cache to be configured for sever situations and it is not suggest that this be changed.
     * <p>Setting are:<ul>
     * <li>ConcurrentReadWrite - default
     * <li>SynchronizedWrite - only allow a single writer (i.e. unit of work merge) to the cache at once
     * <li>SynchronizedReadOnWrite - do not allow reading or other unit of work merge while a unit of work is in merge</ul>
     */
    public void setCacheTransactionIsolation(int cacheTransactionIsolation) {
        this.cacheTransactionIsolation = cacheTransactionIsolation;
    }

    /**
     * PUBLIC:
     * Set the connector that will instantiate the connection.
     * As an example, to use a JNDI-supplied <code>DataSource</code>, use code
     * something like the following:
     * <blockquote><code>
     * session.getLogin().setConnector(new JNDIConnector(context, dataSourceName));<br>
     * session.login();
     * </code></blockquote>
     * where the <code>context</code> is an instance of a <code>javax.naming.Context</code> and
     * the <code>dataSourceName</code> refers to the name of the <code>DataSource</code>
     * within the context.
     */
    public void setConnector(Connector connector) {
        this.connector = connector;
    }

    /**
     * PUBLIC:
     * The default value to substitute for database NULLs can be configured
     * on a per-class basis.
     * Example: login.setDefaultNullValue(long.class, Long.valueOf(0))
     */
    public void setDefaultNullValue(Class type, Object value) {
        getDatasourcePlatform().getConversionManager().setDefaultNullValue(type, value);
    }

    /**
     * Set the password.
     */
    @Override
    public void setPassword(String password) {
        if (password != null) {
            // PERF: Do not encrypt empty string.
            if (password.isEmpty()) {
                setProperty("password", "");
            } else {
                // first call to get will initialize the securable object
                 // Bug 4117441 - Secure programming practices, store password in char[]
                String encryptedPassword = getSecurableObjectHolder().getSecurableObject().encryptPassword(password);
                setProperty("password", encryptedPassword.toCharArray());
            }
        } else {
            // is null so remove the property
            removeProperty("password");
        }
    }

    /**
     * Return the password. It will be encrypted.
     */
    @Override
    public String getPassword() {
        // Bug 4117441 - Secure programming practices, store password in char[]
        Object password = properties.get("password");
        if (password instanceof String) {
            return (String)password;
        }
        char[] passwordObject = (char[]) password;
        if (passwordObject != null) {
            return new String(passwordObject);
        } else {
             // respect explicit de-referencing of password
            return null;
        }
    }

    /**
     * Set the encrypted password.
     */
    public void setEncryptedPassword(String password) {
        // remember that we set an encrypted password
        // flag will be needed in prepareProperties.
        isEncryptedPasswordSet = true;

        if (password != null) {
            // Bug 4117441 - Secure programming practices, store password in char[]
            setProperty("password", password.toCharArray());
        } else {// is null so remove the property
            removeProperty("password");
        }
    }

    /**
     * Sets the encryption class name
     */
    public void setEncryptionClassName(String encryptionClassName) {
        getSecurableObjectHolder().setEncryptionClassName(encryptionClassName);
    }

    /**
     * INTERNAL:
     * Set the database platform specific information.
     * This allows EclipseLink to configure certain advanced features for the database desired.
     */
    @Override
    public void setPlatform(Platform platform) {
        setDatasourcePlatform(platform);
    }

    /**
     * PUBLIC:
     * Set the database platform specific information.
     * This allows EclipseLink to configure certain advanced features for the database desired.
     */
    @Override
    public void setDatasourcePlatform(Platform platform) {
        this.platform = platform;
    }

    /**
     * INTERNAL:
     * Return the name of the database platform class.
     */
    public String getPlatformClassName() {
        return getDatasourcePlatform().getClass().getName();
    }
    /**
     * INTERNAL:
     * Set the name of the Platform to be used.
     * Creates a new instance of the specified Class.
     */
    public void setPlatformClassName(String platformClassName) throws ValidationException {
        // Handle old Oracle platform conversion.
        if (platformClassName.equals("org.eclipse.persistence.platform.database.oracle.OraclePlatform")) {
            platformClassName = "org.eclipse.persistence.platform.database.OraclePlatform";
        }

        Class platformClass = null;
        try {
            //First try loading with the Login's class loader
            platformClass = this.getClass().getClassLoader().loadClass(platformClassName);
        } catch(Throwable cne) {
            //next try using ConversionManager
            try {
                platformClass = ConversionManager.loadClass(platformClassName);
            } catch(Throwable cne2) {
                //set the original exception
                cne2.addSuppressed(cne);
                //if still not found, throw exception
                throw ValidationException.platformClassNotFound(cne2, platformClassName);
            }
        }

        Platform platform = null;
        try {
            if (PrivilegedAccessHelper.shouldUsePrivilegedAccess()){
                platform = (Platform)AccessController.doPrivileged(new PrivilegedNewInstanceFromClass(platformClass));
            } else {
                platform = (Platform)PrivilegedAccessHelper.newInstanceFromClass(platformClass);
            }
        } catch (PrivilegedActionException exception) {
            throw ValidationException.platformClassNotFound(exception.getException(), platformClassName);
        } catch(Throwable cne) {
            throw ValidationException.platformClassNotFound(cne, platformClassName);
        }
        usePlatform(platform);
    }
    /**
     * INTERNAL:
     * Set the name of the Platform to be created using the
     * passed in class loader.  If no class loader is passed
     * in, of if an exception is thrown, call the
     * setPlatformClassName method with no classloader.
     * @see #setPlatformClassName(String platformClassName)
     */
    public void setPlatformClassName(String platformClassName, ClassLoader loader) throws ValidationException {
        boolean exceptionCaught = false;
        Class platformClass = null;
        try {
            Platform platform = null;
            if (loader != null) {
                platformClass = loader.loadClass(platformClassName);
                if (PrivilegedAccessHelper.shouldUsePrivilegedAccess()){
                    try {
                       platform = (Platform)AccessController.doPrivileged(new PrivilegedNewInstanceFromClass(platformClass));
                  } catch (PrivilegedActionException exception) {
                      throw ValidationException.platformClassNotFound(exception.getException(), platformClassName);
                  }
                } else {
                    platform = (Platform)PrivilegedAccessHelper.newInstanceFromClass(platformClass);
                }
            }
            usePlatform(platform);
        } catch(Exception cne) {
            exceptionCaught = true;
        }
        if (exceptionCaught || (loader == null))
        {
            //attempt to load with default classloader
            this.setPlatformClassName(platformClassName);
        }
    }


    /**
     * ADVANCED:
     * Set the database platform to be custom platform.
     */
    public void usePlatform(Platform platform) {
        if (getDatasourcePlatform() != null) {
            getDatasourcePlatform().copyInto(platform);
        }
        setPlatform(platform);
    }

    /**
     * PUBLIC:
     * The properties are additional, driver-specific, connection information
     * to be passed to the JDBC driver.
     */
    @Override
    public void setProperties(Properties properties) {
        this.properties = properties;
    }

    /**
     * PUBLIC:
     * Some JDBC drivers require additional, driver-specific, properties.
     * Add the specified property to those to be passed to the JDBC driver.
     */
    @Override
    public void setProperty(String propertyName, Object propertyValue) {
        properties.put(propertyName, propertyValue);
    }

    /**
     * PUBLIC:
     * Set the default qualifier for all tables.
     * This can be the creator of the table or database name the table exists on.
     * This is required by some databases such as Oracle and DB2.
     */
    public void setTableQualifier(String qualifier) {
        getDatasourcePlatform().setTableQualifier(qualifier);
    }

    /**
     * PUBLIC:
     * Override the default query for returning a timestamp from the server.
     */
    public void setTimestampQuery(ValueReadQuery timestampQuery) {
        getDatasourcePlatform().setTimestampQuery(timestampQuery);
    }


    /**
     * PUBLIC:
     * The user name is the database login name.
     * Some databases do not require a user name or the user is obtained from the OS,
     * in this case this should not be specified.
     */
    @Override
    public void setUserName(String name) {
        if (name != null) {
            setProperty("user", name);
        } else {
            removeProperty("user");
        }
    }

    /**
     * PUBLIC:
     * Return whether EclipseLink uses some external connection pooling service such as a JDBC 2.0 driver.
     */
    public void setUsesExternalConnectionPooling(boolean usesExternalConnectionPooling) {
        this.usesExternalConnectionPooling = usesExternalConnectionPooling;
    }

    /**
     * PUBLIC:
     * Return whether EclipseLink uses some external transaction service such as JTS.
     */
    public void setUsesExternalTransactionController(boolean usesExternalTransactionController) {
        this.usesExternalTransactionController = usesExternalTransactionController;
    }

    /**
     * PUBLIC:
     * Do not use external connection pooling. This is appropriate if using regular
     * EclipseLink connection pooling and regular JDBC drivers.
     *
     * @see #useExternalConnectionPooling()
     */
    public void dontUseExternalConnectionPooling() {
        setUsesExternalConnectionPooling(false);
    }

    /**
     * PUBLIC:
     * Let EclipseLink control transactions instead of some external transaction
     * service such as JTS.
     *
     * @see #useExternalTransactionController()
     */
    public void dontUseExternalTransactionController() {
        setUsesExternalTransactionController(false);
    }

    /**
     * INTERNAL:
     * Used for cache isolation.
     */
    @Override
    public boolean shouldAllowConcurrentReadWrite() {
        return this.cacheTransactionIsolation == CONCURRENT_READ_WRITE;
    }

    /**
     * INTERNAL:
     * Used for cache isolation.
     */
    @Override
    public boolean shouldSynchronizedReadOnWrite() {
        return this.cacheTransactionIsolation == SYNCHRONIZED_READ_ON_WRITE;
    }

    /**
     * INTERNAL:
     * Used for Cache Isolation.  Causes EclipseLink to lock at the class level on
     * cache updates.
     */
    @Override
    public boolean shouldSynchronizeWrites() {
        return this.cacheTransactionIsolation == SYNCHRONIZED_WRITE;
    }

    /**
     * INTERNAL:
     * Used for Cache Isolation.  Causes EclipseLink to lock at the object level on
     * cache updates and cache access.
     */
    @Override
    public boolean shouldSynchronizeObjectLevelReadWrite(){
        return this.cacheTransactionIsolation == SYNCRONIZED_OBJECT_LEVEL_READ_WRITE;
    }

    /**
     * INTERNAL:
     * Used for Cache Isolation.  Causes EclipseLink to lock at the object level on
     * cache updates and cache access, based on database transaction.
     */
    @Override
    public boolean shouldSynchronizeObjectLevelReadWriteDatabase(){
        return this.cacheTransactionIsolation == SYNCRONIZED_OBJECT_LEVEL_READ_WRITE_DATABASE;
    }

    /**
     * PUBLIC:
     * Return whether EclipseLink uses some external connection pooling
     * (e.g. WebLogic's JTS driver).
     *
     * @see #useExternalConnectionPooling()
     * @see #dontUseExternalConnectionPooling()
     */
    @Override
    public boolean shouldUseExternalConnectionPooling() {
        return usesExternalConnectionPooling;
    }

    /**
     * PUBLIC:
     * Return whether EclipseLink uses some external transaction service such as JTS.
     *
     * @see #useExternalTransactionController()
     * @see #dontUseExternalTransactionController()
     */
    @Override
    public boolean shouldUseExternalTransactionController() {
        return usesExternalTransactionController;
    }

    /**
     * PUBLIC:
     * Use external connection pooling.
     *
     * @see #dontUseExternalConnectionPooling()
     * @see #shouldUseExternalConnectionPooling()
     */
    public void useExternalConnectionPooling() {
        setUsesExternalConnectionPooling(true);
    }

    /**
     * PUBLIC:
     * Use an external transaction controller such as a JTS service
     *
     * @see #dontUseExternalTransactionController()
     * @see #shouldUseExternalTransactionController()
     */
    public void useExternalTransactionController() {
        setUsesExternalTransactionController(true);
    }

    /**
     * PUBLIC:
     * Print all of the connection information.
     */
    @Override
    public String toString() {
        StringWriter stringWriter = new StringWriter();
        PrintWriter writer = new PrintWriter(stringWriter);
        writer.write(Helper.getShortClassName(getClass()));
        writer.println("(");
        writer.println("\t" + ToStringLocalization.buildMessage("platform", null) + "=> " + getDatasourcePlatform());
        if (!shouldUseExternalConnectionPooling()) {
            writer.println("\t" + ToStringLocalization.buildMessage("user_name", null) + "=> \"" + getUserName() + "\"");
        }
        writer.print("\t");
        getConnector().toString(writer);
        writer.write(")");
        return stringWriter.toString();
    }

    /**
     * Get default sequence
     */
    public Sequence getDefaultSequence() {
        return getDatasourcePlatform().getDefaultSequence();
    }

    /**
     * Set default sequence
     */
    public void setDefaultSequence(Sequence sequence) {
        getDatasourcePlatform().setDefaultSequence(sequence);
    }

    /**
     * Add sequence corresponding to the name
     * Don't use if the session is connected.
     */
    public void addSequence(Sequence sequence) {
        getDatasourcePlatform().addSequence(sequence);
    }

    /**
     * Get sequence corresponding to the name
     */
    public Sequence getSequence(String seqName) {
        return getDatasourcePlatform().getSequence(seqName);
    }

    /**
     * Returns a map of sequence names to Sequences (may be null).
     */
    public Map getSequences() {
        return getDatasourcePlatform().getSequences();
    }

    /**
     * Remove sequence corresponding to name.
     * Doesn't remove default sequence.
     * Don't use if the session is connected.
     */
    public Sequence removeSequence(String seqName) {
        return getDatasourcePlatform().removeSequence(seqName);
    }

    /**
     * Remove all sequences but the default one.
     */
    public void removeAllSequences() {
        getDatasourcePlatform().removeAllSequences();
    }

    /**
     * INTERNAL:
     * Used only for writing the login into XML or Java.
     */
    public Sequence getDefaultSequenceToWrite() {
        return getDatasourcePlatform().getDefaultSequenceToWrite();
    }

    /**
     * INTERNAL:
     * Used only for writing the login into XML or Java.
     */
    public Map getSequencesToWrite() {
        return getDatasourcePlatform().getSequencesToWrite();
    }

    /**
     * INTERNAL:
     * Used only for reading the login from XML.
     */
    public void setSequences(Map sequences) {
        getDatasourcePlatform().setSequences(sequences);
    }
}
