/*
 * Copyright (c) 1998, 2020 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.eis;

import jakarta.resource.cci.*;
import org.eclipse.persistence.internal.databaseaccess.Accessor;
import org.eclipse.persistence.internal.databaseaccess.Platform;
import org.eclipse.persistence.sessions.DatasourceLogin;
import org.eclipse.persistence.sessions.Session;

/**
 * <p>An <code>EISLogin</code> defines connection information and datasource
 * properties.  There are three ways to connect to an EIS datasource through
 * EclipseLink EIS:
 * <ul>
 * <li>Provide a JNDI name to the ConnectionFactory and use the default
 * getConnection
 * <li>Provide a JNDI name to the ConnectionFactory and a driver specific
 * ConnectionSpec to pass to the getConnection
 * <li>Connect in a non-managed way directly to the driver specific
 * ConnectionFactory
 * </ul>
 *
 * <p> A <code>EISConnectionSpec</code> must be provided to define how to
 * connect to the EIS adapter.
 *
 * <p> The EIS platform can be used to provide datasource/driver specific
 * behavior such as InteractionSpec and Record conversion.
 *
 * @see EISConnectionSpec
 *
 * @author James
 * @since OracleAS TopLink 10<i>g</i> (10.0.3)
 */
public class EISLogin extends DatasourceLogin {

    /**
     * Default constructor.
     */
    public EISLogin() {
        this(new EISPlatform());
    }

    /**
     * Constructor.
     */
    public EISLogin(Platform platform) {
        super(platform);
        this.connector = new EISConnectionSpec();
    }

    /**
     * Build and return the EIS accessorr.
     */
    @Override
    public Accessor buildAccessor() {
        return new EISAccessor();
    }

    /**
     * Connect to the EIS adapter and return the Connection.
     */
    @Override
    public Object connectToDatasource(Accessor accessor, Session session) {
        return getConnectionSpec().connectToDataSource((EISAccessor)accessor, getProperties());
    }

    /**
     * PUBLIC:
     * Set the password.
     */
    @Override
    public void setPassword(String password) {
        // Avoid encryption
        // Bug 4117441 - Secure programming practices, store password in char[]
        if (password != null) {
            setProperty("password", password.toCharArray());
        } else {
            // is null so remove the property
            // respect explicit de-referencing of password
            removeProperty("password");
        }
    }

    /**
     * PUBLIC:
     * Return the JNDI URL for the managed connection factory for the JCA adapter connecting to.
     */
    public String getConnectionFactoryURL() {
        if ((getConnectionSpec().getName() == null) || (getConnectionSpec().getName().size() == 0)) {
            return null;
        }
        return getConnectionSpec().getName().get(0);
    }

    /**
     * PUBLIC:
     * Set the JNDI URL for the managed connection factory for the JCA adapter connecting to.
     */
    public void setConnectionFactoryURL(String url) {
        if ((url == null) || (url.length() == 0)) {
            return;
        }
        getConnectionSpec().setName(url);
    }

    /**
     * Return the connector.
     * The connector defines how the connection is created.
     */
    public EISConnectionSpec getConnectionSpec() {
        return (EISConnectionSpec)getConnector();
    }

    /**
     * PUBLIC:
     * Set the EclipseLink connection spec.
     * The connection spec defines how to connect to the EIS adapter.
     */
    public void setConnectionSpec(EISConnectionSpec connectionSpec) {
        setConnector(connectionSpec);
    }

    /**
     * PUBLIC:
     * Configure the login to connect through a JDNI managed connection factory and the default getConnection().
     */
    public void configureConnectionSpec(String jndiName) {
        setConnectionSpec(new EISConnectionSpec(jndiName));
    }

    /**
     * PUBLIC:
     * Configure the login to connect through a non-managed connection factory and the default getConnection().
     */
    public void configureConnectionSpec(ConnectionFactory connectionFactory) {
        EISConnectionSpec spec = new EISConnectionSpec();
        spec.setConnectionFactory(connectionFactory);
        setConnectionSpec(spec);
    }

    /**
     * PUBLIC:
     * Configure the login to connect through a JDNI managed connection factory and adapter connection spec.
     */
    public void configureConnectionSpec(String jndiName, ConnectionSpec connectionSpec) {
        EISConnectionSpec spec = new EISConnectionSpec(jndiName);
        spec.setConnectionSpec(connectionSpec);
        setConnectionSpec(spec);
    }

    /**
     * PUBLIC:
     * Configure the login to connect through a non-managed connection factory and adapter connection spec.
     */
    public void configureConnectionSpec(ConnectionFactory connectionFactory, ConnectionSpec connectionSpec) {
        EISConnectionSpec spec = new EISConnectionSpec();
        spec.setConnectionFactory(connectionFactory);
        spec.setConnectionSpec(connectionSpec);
        setConnectionSpec(spec);
    }
}
