Package org.apache.tuscany.das.rdb.impl

Source Code of org.apache.tuscany.das.rdb.impl.DASImpl

/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements.  See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership.  The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License.  You may obtain a copy of the License at
*
*   http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied.  See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.apache.tuscany.das.rdb.impl;

import java.io.InputStream;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.util.Collections;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;

import javax.naming.InitialContext;
import javax.naming.NamingException;
import javax.sql.DataSource;

import org.apache.tuscany.das.rdb.Command;
import org.apache.tuscany.das.rdb.DAS;
import org.apache.tuscany.das.rdb.config.Config;
import org.apache.tuscany.das.rdb.config.ConfigFactory;
import org.apache.tuscany.das.rdb.config.ConnectionInfo;
import org.apache.tuscany.das.rdb.config.wrapper.MappingWrapper;
import org.apache.tuscany.das.rdb.exception.DataSourceInitializationException;
import org.apache.tuscany.das.rdb.util.ConfigUtil;

import commonj.sdo.DataObject;

/**
* An ConfiguredCommandFactory produces instances of Command and ApplyChangesCommand. This
* factory is initialized with a configuration that defines
* the commands it produces.
*
*/
public class DASImpl implements DAS {

    private MappingWrapper configWrapper;

    private Connection connection;

    private Map commands = new HashMap();

    public DASImpl(InputStream stream) {
        this(ConfigUtil.loadConfig(stream));

    }

    public DASImpl(Config inConfig) {
        Config cfg = inConfig;
        if (cfg == null) {
            cfg = ConfigFactory.INSTANCE.createConfig();
        }
        this.configWrapper = new MappingWrapper(cfg);

        Iterator i = configWrapper.getConfig().getCommand().iterator();
        while (i.hasNext()) {
            org.apache.tuscany.das.rdb.config.Command commandConfig =
                (org.apache.tuscany.das.rdb.config.Command) i.next();
            String kind = commandConfig.getKind();
            if (kind.equalsIgnoreCase("select")) {
                commands.put(commandConfig.getName(), new ReadCommandImpl(commandConfig, configWrapper, commandConfig.getResultDescriptor()));
            } else if (kind.equalsIgnoreCase("update")) {
                commands.put(commandConfig.getName(), new UpdateCommandImpl(commandConfig));
            } else if (kind.equalsIgnoreCase("insert")) {
                commands.put(commandConfig.getName(), new InsertCommandImpl(commandConfig, new String[0]));
            } else if (kind.equalsIgnoreCase("delete")) {
                commands.put(commandConfig.getName(), new DeleteCommandImpl(commandConfig));
            } else if (kind.equalsIgnoreCase("procedure")) {
                commands.put(commandConfig.getName(), new SPCommandImpl(commandConfig.getSQL(), configWrapper, commandConfig.getParameter()));
            } else {
                throw new RuntimeException("Invalid kind of command: " + kind);
            }

        }

    }

    public DASImpl(Config inConfig, Connection inConnection) {
        this(inConfig);
        setConnection(inConnection);
    }

    public DASImpl(InputStream configStream, Connection inConnection) {
        this(ConfigUtil.loadConfig(configStream), inConnection);
    }

    public DASImpl(Connection inConnection) {
        this(ConfigFactory.INSTANCE.createConfig());
        setConnection(inConnection);
    }

    /*
     * (non-Javadoc)
     *
     * @see org.apache.tuscany.das.rdb.CommandGroup#getApplyChangesCommand()
     */
    public ApplyChangesCommandImpl getApplyChangesCommand() {
        ApplyChangesCommandImpl cmd = new ApplyChangesCommandImpl(configWrapper, getConnection());
        return cmd;
    }

    /*
     * (non-Javadoc)
     *
     * @see org.apache.tuscany.das.rdb.CommandGroup#getCommand(java.lang.String)
     */
    public Command getCommand(String name) {
        if (!commands.containsKey(name)) {
            throw new RuntimeException("CommandGroup has no command named: " + name);
        }
        CommandImpl cmd = (CommandImpl) commands.get(name);
        cmd.setConnection(getConnection(), configWrapper.getConfig());
        return cmd;
    }

    public void setConnection(Connection connection) {
        this.connection = connection;
    }

    public Connection getConnection() {
        if (connection == null) {
            initializeConnection();
        }
        return connection;
    }

    private void initializeConnection() {
        Config config = configWrapper.getConfig();
        if (config == null || config.getConnectionInfo() == null ||
            (config.getConnectionInfo().getDataSource() == null && config.getConnectionInfo().getConnectionProperties() == null)) {
            throw new RuntimeException("No connection has been provided and no data source has been specified");
        }

        if(config.getConnectionInfo().getDataSource() != null && config.getConnectionInfo().getConnectionProperties() != null){
            throw new RuntimeException("Use either dataSource or ConnectionProperties. Can't use both !");
        }

        ConnectionInfo connectionInfo = configWrapper.getConfig().getConnectionInfo();
        if(config.getConnectionInfo().getConnectionProperties() != null){
            initializeDriverManagerConnection(connectionInfo);
        }else{
            initializeDatasourceConnection(connectionInfo);
        }

    }

    /**
     * Initializes a DB connection on a managed environmet (e.g inside Tomcat)
     */
    private void initializeDatasourceConnection(ConnectionInfo connectionInfo){
        Connection connection = null;

        InitialContext ctx;
        try {
            ctx = new InitialContext();
        } catch (NamingException e) {
            throw new RuntimeException(e);
        }
        try {
            DataSource ds = (DataSource) ctx.lookup(connectionInfo.getDataSource());
            try {
                connection = ds.getConnection();
                if (connection == null) {
                    throw new RuntimeException("Could not obtain a Connection from DataSource");
                }
                connection.setAutoCommit(false);
                setConnection(connection);
            } catch (SQLException e) {
                throw new RuntimeException(e);
            }
        } catch (NamingException e) {
            throw new RuntimeException(e);
        }
    }

    /**
     * Initialize a DB connection on a J2SE environment
     * For more info, see http://java.sun.com/j2se/1.3/docs/guide/jdbc/getstart/drivermanager.html
     */
    private void initializeDriverManagerConnection(ConnectionInfo connectionInfo) {

        Connection connection = null;

        if (connectionInfo.getConnectionProperties() == null) {
            throw new DataSourceInitializationException("No existing context and no connection properties");
        }

        if (connectionInfo.getConnectionProperties().getDriverClass() == null) {
            throw new DataSourceInitializationException("No jdbc driver class specified!");
        }

        try {
            //initialize driver and register it with DriverManager
            Class.forName(connectionInfo.getConnectionProperties().getDriverClass());

            //prepare to initialize connection
            String databaseUrl = connectionInfo.getConnectionProperties().getDatabaseURL();
            String userName = connectionInfo.getConnectionProperties().getUserName();
            String userPassword = connectionInfo.getConnectionProperties().getPassword();
            int loginTimeout = connectionInfo.getConnectionProperties().getLoginTimeout();

            DriverManager.setLoginTimeout(loginTimeout);
            if( (userName == null || userName.length() ==0) && (userPassword == null || userPassword.length()==0) ){
                //no username or password suplied
                connection = DriverManager.getConnection(databaseUrl);
            }else{
                connection = DriverManager.getConnection(databaseUrl, userName, userPassword);
            }

            if(connection == null){
                throw new DataSourceInitializationException("Error initializing connection : null");
            }

            connection.setAutoCommit(false);
            setConnection(connection);


        }catch(ClassNotFoundException cnf){
            throw new DataSourceInitializationException("JDBC Driver '" + connectionInfo.getConnectionProperties().getDriverClass() + "' not found", cnf);
        }catch(SQLException sqle){
            throw new DataSourceInitializationException(sqle.getMessage(), sqle);
        }

    }

    public void releaseResources() {

        if (managingConnections()) {
            closeConnection();
        }
    }

    private void closeConnection() {
        if (connection != null) {
            try {
                connection.close();
                connection = null;
            } catch (SQLException e) {
                throw new RuntimeException(e);
            }
        }
    }

    /**
     * If the config has connection properties then we are "managing" the connection via DataSource
     */
    private boolean managingConnections() {

        if (configWrapper.getConfig().getConnectionInfo().getDataSource() == null) {
            return false;
        }

        return true;

    }

    public Command createCommand(String sql) {
        return baseCreateCommand(sql, this.configWrapper);
    }

    public Command createCommand(String sql, Config config) {
        return baseCreateCommand(sql, new MappingWrapper(config));
    }

    private Command baseCreateCommand(String inSql, MappingWrapper config) {
        CommandImpl returnCmd = null;
        String sql = inSql.trim(); // Remove leading white space
        char firstChar = Character.toUpperCase(sql.charAt(0));
        switch (firstChar) {
            case 'S':
                returnCmd = new ReadCommandImpl(sql, config, null);
                break;
            case 'I':
                returnCmd = new InsertCommandImpl(sql, new String[0]);
                break;
            case 'U':
                returnCmd = new UpdateCommandImpl(sql);
                break;
            case 'D':
                returnCmd = new DeleteCommandImpl(sql);
                break;
            case '{':
                returnCmd = new SPCommandImpl(sql, config, Collections.EMPTY_LIST);
                break;
            default:
                throw new RuntimeException("SQL => " + sql + " is not valid");
        }

        returnCmd.setConnection(getConnection(), config.getConfig());
        return returnCmd;
    }

    public void applyChanges(DataObject root) {
        getApplyChangesCommand().execute(root);
    }

}
TOP

Related Classes of org.apache.tuscany.das.rdb.impl.DASImpl

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.