001: /*
002: * Copyright 2007 The Kuali Foundation
003: *
004: * Licensed under the Educational Community License, Version 1.0 (the "License");
005: * you may not use this file except in compliance with the License.
006: * You may obtain a copy of the License at
007: *
008: * http://www.opensource.org/licenses/ecl1.php
009: *
010: * Unless required by applicable law or agreed to in writing, software
011: * distributed under the License is distributed on an "AS IS" BASIS,
012: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013: * See the License for the specific language governing permissions and
014: * limitations under the License.
015: */
016: package org.kuali.rice.ojb;
017:
018: import java.sql.Connection;
019: import java.util.ArrayList;
020: import java.util.HashMap;
021: import java.util.List;
022: import java.util.Map;
023:
024: import javax.sql.DataSource;
025:
026: import org.apache.ojb.broker.accesslayer.ConnectionFactoryNotPooledImpl;
027: import org.apache.ojb.broker.accesslayer.LookupException;
028: import org.apache.ojb.broker.metadata.JdbcConnectionDescriptor;
029: import org.springframework.beans.factory.BeanFactory;
030: import org.springframework.jdbc.datasource.TransactionAwareDataSourceProxy;
031:
032: public class RiceDataSourceConnectionFactory extends
033: ConnectionFactoryNotPooledImpl {
034:
035: /**
036: * BeanFactories to retrieve DataSource beans from.
037: */
038: private static List<BeanFactory> beanFactories = new ArrayList<BeanFactory>();
039:
040: public static void addBeanFactory(BeanFactory beanFactory) {
041: beanFactories.add(beanFactory);
042: }
043:
044: /**
045: * Map that holds already retrieved DataSources,
046: * with JCD alias Strings as keys and DataSources as values.
047: */
048: private Map<String, DataSource> dataSources = new HashMap<String, DataSource>();
049:
050: public RiceDataSourceConnectionFactory() {
051: if (beanFactories.isEmpty()) {
052: throw new IllegalStateException(
053: "No BeanFactories found for configuration - must specify RiceOjbConfigurer as a Spring bean.");
054: }
055: }
056:
057: public Connection lookupConnection(JdbcConnectionDescriptor jcd)
058: throws LookupException {
059: try {
060: DataSource dataSource = null;
061: synchronized (this .dataSources) {
062: dataSource = this .dataSources.get(jcd.getJcdAlias());
063: if (dataSource == null) {
064: dataSource = getDataSource(jcd.getJcdAlias());
065: this .dataSources.put(jcd.getJcdAlias(), dataSource);
066: }
067: }
068: return dataSource.getConnection();
069: } catch (Exception ex) {
070: throw new LookupException(
071: "Could not obtain connection from data source", ex);
072: }
073: }
074:
075: /**
076: * Return the DataSource to use for the given JCD alias.
077: * <p>This implementation fetches looks for a bean with the
078: * JCD alias name in the provided Spring BeanFactory.
079: * @param jcdAlias the JCD alias to retrieve a DataSource for
080: * @return the DataSource to use
081: */
082:
083: protected DataSource getDataSource(String jcdAlias)
084: throws LookupException {
085: DataSource dataSource = null;
086: for (BeanFactory beanFactory : beanFactories) {
087: if (beanFactory.containsBean(jcdAlias)) {
088: dataSource = (DataSource) beanFactory.getBean(jcdAlias,
089: DataSource.class);
090: break;
091: }
092: }
093: if (dataSource == null) {
094: throw new LookupException(
095: "Could not lookup datasource with alias "
096: + jcdAlias);
097: } else if (dataSource instanceof TransactionAwareDataSourceProxy) {
098: return dataSource;
099: } else {
100: return new TransactionAwareDataSourceProxy(dataSource);
101: }
102: }
103:
104: }
|