blob: f428b81a5c699f8c755dce3ecf5da6796b3da392 [file] [log] [blame]
/*
* 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.cocoon.ojb.components;
import org.apache.avalon.excalibur.datasource.DataSourceComponent;
import org.apache.avalon.framework.CascadingRuntimeException;
import org.apache.avalon.framework.activity.Disposable;
import org.apache.avalon.framework.component.Component;
import org.apache.avalon.framework.service.ServiceException;
import org.apache.avalon.framework.service.ServiceManager;
import org.apache.avalon.framework.service.ServiceSelector;
import org.apache.avalon.framework.service.Serviceable;
import org.apache.avalon.framework.thread.ThreadSafe;
import org.apache.ojb.broker.accesslayer.ConnectionFactory;
import org.apache.ojb.broker.accesslayer.LookupException;
import org.apache.ojb.broker.metadata.JdbcConnectionDescriptor;
import java.sql.Connection;
import java.sql.SQLException;
/**
* OJB ConnectionFactory implemenation to bridge into the Avalon DataSource
* connection pooling component defined in the Cocoon configuration.
*
* <p>This class has two faces to it:
* <dl>
* <dt>Avalon Component</dt>
* <dd>Instance of the class created and managed by Avalon container.
* When instance is initialized, it looks up datasource components
* service selector.</dd>
* <dt>OJB Managed Class</dt>
* <dd>Instances of the class are created and managed by OJB, as defined
* in the OJB <code>repository.xml</code> file. Each OJB managed instance
* of the class will have access to the datasource components service
* selector initialized by Avalon managed instance of the class.</dd>
* </dl>
*
* It is important that Avalon component is initialized before any access
* to OJB API is made.</p>
*
* @author giacomo at apache.org
* @author <a href="mailto:vgritsenko@apache.org">Vadim Gritsenko</a>
* @version $Id$
*/
public class ConnectionFactoryImpl implements Component, ThreadSafe, Serviceable, Disposable,
ConnectionFactory {
/** The <code>ServiceManager</code> to be used */
private static ServiceManager manager;
/** The <code>ServiceSelector</code> to be used */
private static ServiceSelector datasources;
/** The <code>JdbcConnectionDescriptor</code> */
private JdbcConnectionDescriptor conDesc;
/**
* Default constructor
*/
public ConnectionFactoryImpl() {
}
/**
* OJB 1.1 constructor
*/
public ConnectionFactoryImpl(JdbcConnectionDescriptor conDesc) {
this.conDesc = conDesc;
}
public void service(ServiceManager manager) throws ServiceException {
ConnectionFactoryImpl.manager = manager;
ConnectionFactoryImpl.datasources = (ServiceSelector) manager.lookup(DataSourceComponent.ROLE + "Selector");
}
public void dispose() {
if (ConnectionFactoryImpl.manager != null) {
ConnectionFactoryImpl.manager.release(ConnectionFactoryImpl.datasources);
ConnectionFactoryImpl.datasources = null;
ConnectionFactoryImpl.manager = null;
}
}
//
// OJB 1.1 ConnectionFactory Implementation
//
public Connection lookupConnection()
throws LookupException {
return lookupConnection(this.conDesc);
}
public void releaseConnection(Connection connection) {
releaseConnection(this.conDesc, connection);
}
public int getActiveConnections() {
return 0;
}
public int getIdleConnections() {
return 0;
}
//
// OJB 1.0 ConnectionFactory Implementation
//
public Connection lookupConnection(final JdbcConnectionDescriptor conDesc)
throws LookupException {
if (ConnectionFactoryImpl.manager == null) {
throw new LookupException("ConnectionFactoryImpl is not initialized! Please check your cocoon.xconf");
}
try {
return ((DataSourceComponent) ConnectionFactoryImpl.datasources.select(conDesc.getJcdAlias())).getConnection();
} catch (final ServiceException e) {
throw new LookupException("Cannot lookup DataSource " +
conDesc.getJcdAlias(), e);
} catch (final SQLException e) {
throw new LookupException("Cannot get connection from DataSource " +
conDesc.getJcdAlias(), e);
}
}
public void releaseConnection(JdbcConnectionDescriptor conDesc, Connection connection) {
try {
// The DataSource of this connection will take care of pooling
connection.close();
} catch (final SQLException e) {
// This should not happen, but in case
throw new CascadingRuntimeException("Cannot release SQL Connection to DataSource", e);
}
}
public void releaseAllResources() {
// Nothing to do here
}
}