db-torque-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Christoph Engelbert <c.engelb...@u-form.de>
Subject Re: Antwort: Torque and OSGi
Date Tue, 23 Nov 2010 18:40:45 GMT
 I missed a thing I had to do to make Torque 3 run "in" OSGi
environments. I had to reimplement the SharedPoolDataSourceFactory
since the original one used CPDS which isn't capable of using the
OSGi-classloaders.

Here's a snapshot of what I had done:
import java.io.PrintWriter;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.sql.Connection;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.Iterator;
import java.util.Properties;

import javax.sql.DataSource;

import org.apache.commons.configuration.Configuration;
import org.apache.commons.dbcp.BasicDataSource;
import org.apache.commons.dbcp.BasicDataSourceFactory;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.torque.TorqueException;
import org.apache.torque.dsfactory.AbstractDataSourceFactory;

public class OsgiPoolDataSourceFactory extends
AbstractDataSourceFactory {

    /** The log. */
    private static Log log =
LogFactory.getLog(OsgiPoolDataSourceFactory.class);

    private DataSourceAdapter ds = null;

    @Override
    @SuppressWarnings("unchecked")
    public void initialize(Configuration configuration) throws
TorqueException {
        super.initialize(configuration);

        System.out.println("Initialize Torque DataSource...");

        Properties properties = new Properties();
        Iterator<String> iterator = configuration.getKeys();
        while (iterator.hasNext()) {
            String key = iterator.next();

            String value = configuration.getProperty(key).toString();

            System.out
                    .println("Found property " + key + " with value
" + value);

            String property = null;
            for (String[] k : mappings) {
                if (k[0].equals(key))
                    property = k[1];
            }

            if (property != null) {
                System.out.println("Found mapping for key " + key +
" to "
                        + property);
                properties.setProperty(property, value);
            } else {
                properties.setProperty(key, value);
            }
        }

        try {
            ds = new DataSourceAdapter((BasicDataSource)
BasicDataSourceFactory
                    .createDataSource(properties));

            System.out
                    .println("Testing datasource for successful
connection...");
            Connection connection = getDataSource().getConnection();
            Statement statement = connection.createStatement();
            statement.execute("SELECT 1");
            System.out.println("Connection established...");
        } catch (Exception e) {
            e.printStackTrace();
            throw new TorqueException(e);
        }
    }

    @Override
    public DataSource getDataSource() throws TorqueException {
        return ds;
    }

    @Override
    public void close() throws TorqueException {
        try {
            ds.close();
        } catch (Exception e) {
            log.error("Exception caught during close()", e);
            throw new TorqueException(e);
        }
        ds = null;
    }

    private static final String[][] mappings = {
            new String[] { "connection.driver", "driverClassName" },
            new String[] { "connection.url", "url" },
            new String[] { "connection.user", "username" },
            new String[] { "connection.password", "password" } };

    private static final class DataSourceAdapter implements DataSource {
        private final int retry;
        private final BasicDataSource dataSource;

        public DataSourceAdapter(BasicDataSource basicDataSource) {
            this(3, basicDataSource);
        }

        public DataSourceAdapter(int retry, BasicDataSource
basicDataSource) {
            this.retry = retry;
            this.dataSource = basicDataSource;
        }

        @Override
        public Connection getConnection() throws SQLException {
            for (int i = 0; i < retry; i++) {
                try {
                    Connection connection = dataSource.getConnection();
                    Statement statement = connection.createStatement();
                    statement.execute("SELECT 1;");
                    return connection;
                } catch (Exception e) {
                    log
                            .info("Caught
com.mysql.jdbc.exceptions.jdbc4.CommunicationsException - try again");
                    // just ignore this one and try again
                }
            }
            throw new SQLException("MySQL database link could not be
restored.");
        }

        @Override
        public Connection getConnection(String username, String
password)
                throws SQLException {
            return dataSource.getConnection(username, password);
        }

        @Override
        public PrintWriter getLogWriter() throws SQLException {
            return dataSource.getLogWriter();
        }

        @Override
        public int getLoginTimeout() throws SQLException {
            return dataSource.getLoginTimeout();
        }

        @Override
        public void setLogWriter(PrintWriter out) throws SQLException {
            dataSource.setLogWriter(out);
        }

        @Override
        public void setLoginTimeout(int seconds) throws SQLException {
            dataSource.setLoginTimeout(seconds);
        }

        public void close() throws SQLException {
            dataSource.close();
        }

        @Override
        public boolean isWrapperFor(Class<?> iface) throws
SQLException {
            try {
                if (iface.isAssignableFrom(dataSource.getClass())) {
                    return true;
                }
                Method method =
dataSource.getClass().getMethod("isWrapperFor",
                        new Class[] { Class.class });
                return Boolean.TRUE.equals(method.invoke(dataSource,
                        new Object[] { iface }));
            } catch (NoSuchMethodException e) {
                throw new UnsupportedOperationException();
            } catch (IllegalAccessException e) {
                throw new SQLException(e);
            } catch (InvocationTargetException e) {
                throw new SQLException(e);
            }
        }

        @Override
        @SuppressWarnings("unchecked")
        public <T> T unwrap(Class<T> iface) throws SQLException {
            try {
                if (iface.isAssignableFrom(dataSource.getClass())) {
                    return (T) dataSource;
                }

                Method method =
dataSource.getClass().getMethod("unwrap",
                        new Class[] { Class.class });
                return (T) method.invoke(dataSource, new Object[] {
iface });
            } catch (NoSuchMethodException e) {
                throw new UnsupportedOperationException();
            } catch (IllegalAccessException e) {
                throw new SQLException(e);
            } catch (InvocationTargetException e) {
                throw new SQLException(e);
            }
        }
    }
}


Am 23.11.2010 19:03, schrieb Christoph Engelbert:
>  At the moment there's some static way to initialize, shutdown
> torque by using the Torque-Class.
> The next problem would be some Buddy-Behaviour to make it possible
> for a Torque-Service-Bundle to persist the classes from other
> bundles (a woldcard-import would be possible but isn't really nice).
> I guess for a real Torque bundle that exports services the way
> EclipseLink, Hibernate and other peristance engine does there'll be
> more problems that does not recognized yet.
>
> At the moment we're using Torque in an OSGi environment but in a
> very ugly hacking way. It is bundled to the OSGi-Bundle that uses it
> and is initialized for every single os that bundles.
>
> Since there were some discussions about using interfaces and this
> possibly means bigger internal changes it could be a good reason to
> think about more changes that could help using Torque in OSGi
> environments.
>
> Am 23.11.2010 18:24, schrieb Thomas Fox:
>>> are there any plans to support OSGi runtime environments in Torque 4?
>> Not yet. I have not even thought about what it might mean. Do you have any
>> idea whether it means more than adding a manifest.mf to the runtime ?
>>
>>    Thomas
>>
>>
>> ---------------------------------------------------------------------
>> To unsubscribe, e-mail: torque-dev-unsubscribe@db.apache.org
>> For additional commands, e-mail: torque-dev-help@db.apache.org
>>
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: torque-dev-unsubscribe@db.apache.org
> For additional commands, e-mail: torque-dev-help@db.apache.org
>


---------------------------------------------------------------------
To unsubscribe, e-mail: torque-dev-unsubscribe@db.apache.org
For additional commands, e-mail: torque-dev-help@db.apache.org


Mime
View raw message