JNDIDataSourceProvider.java 3.91 KB
Newer Older
1
/*
2
 * Copyright (C) 2004-2008 Jive Software. All rights reserved.
Matt Tucker's avatar
Matt Tucker committed
3
 *
4 5 6 7 8 9 10 11 12 13 14
 * Licensed 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.
Matt Tucker's avatar
Matt Tucker committed
15 16 17 18
 */

package org.jivesoftware.database;

19 20 21
import java.sql.Connection;
import java.sql.SQLException;
import java.util.Properties;
Matt Tucker's avatar
Matt Tucker committed
22 23 24 25

import javax.naming.Context;
import javax.naming.InitialContext;
import javax.sql.DataSource;
26 27 28 29

import org.jivesoftware.util.JiveGlobals;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
Matt Tucker's avatar
Matt Tucker committed
30 31 32 33 34

/**
 * An implementation of ConnectionProvider that utilizes a JDBC 2.0 DataSource
 * made available via JNDI. This is useful for application servers where a pooled
 * data connection is already provided so Jive can share the pool with the
35 36
 * other applications.
 * <p>
Matt Tucker's avatar
Matt Tucker committed
37 38
 * The JNDI location of the DataSource stored as the Jive property
 * <code>database.JNDIProvider.name</code>. This can be overridden by setting
39
 * the provider's <code>name</code> property if required.</p>
Matt Tucker's avatar
Matt Tucker committed
40 41 42 43 44 45
 *
 * @author <a href="mailto:joe@truemesh.com">Joe Walnes</a>
 * @see ConnectionProvider
 */
public class JNDIDataSourceProvider implements ConnectionProvider {

46 47
	private static final Logger Log = LoggerFactory.getLogger(JNDIDataSourceProvider.class);

Matt Tucker's avatar
Matt Tucker committed
48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72
    private String dataSourceName;
    private DataSource dataSource;

    /**
     * Keys of JNDI properties to query PropertyManager for.
     */
    private static final String[] jndiPropertyKeys = {
        Context.APPLET,
        Context.AUTHORITATIVE,
        Context.BATCHSIZE,
        Context.DNS_URL,
        Context.INITIAL_CONTEXT_FACTORY,
        Context.LANGUAGE,
        Context.OBJECT_FACTORIES,
        Context.PROVIDER_URL,
        Context.REFERRAL,
        Context.SECURITY_AUTHENTICATION,
        Context.SECURITY_CREDENTIALS,
        Context.SECURITY_PRINCIPAL,
        Context.SECURITY_PROTOCOL,
        Context.STATE_FACTORIES,
        Context.URL_PKG_PREFIXES
    };

    /**
73
     * Constructs a new JNDI pool.
Matt Tucker's avatar
Matt Tucker committed
74 75
     */
    public JNDIDataSourceProvider() {
76
        dataSourceName = JiveGlobals.getXMLProperty("database.JNDIProvider.name");
Matt Tucker's avatar
Matt Tucker committed
77 78
    }

79
    @Override
Matt Tucker's avatar
Matt Tucker committed
80 81 82 83
    public boolean isPooled() {
        return true;
    }

84
    @Override
Matt Tucker's avatar
Matt Tucker committed
85 86
    public void start() {
        if (dataSourceName == null || dataSourceName.equals("")) {
87
            Log.error("No name specified for DataSource. JNDI lookup will fail", new Throwable());
Matt Tucker's avatar
Matt Tucker committed
88 89 90 91
            return;
        }
        try {
            Properties contextProperties = new Properties();
92 93 94 95
            for (String key: jndiPropertyKeys) {
                String value = JiveGlobals.getXMLProperty(key);
                if (value != null) {
                    contextProperties.setProperty(key, value);
Matt Tucker's avatar
Matt Tucker committed
96 97
                }
            }
98
            Context context;
Matt Tucker's avatar
Matt Tucker committed
99 100 101 102 103 104 105 106 107
            if (contextProperties.size() > 0) {
                context = new InitialContext(contextProperties);
            }
            else {
                context = new InitialContext();
            }
            dataSource = (DataSource)context.lookup(dataSourceName);
        }
        catch (Exception e) {
108
            Log.error("Could not lookup DataSource at '" + dataSourceName + "'", e);
Matt Tucker's avatar
Matt Tucker committed
109 110 111
        }
    }

112
    @Override
Matt Tucker's avatar
Matt Tucker committed
113 114 115 116 117
    public void restart() {
        destroy();
        start();
    }

118
    @Override
Matt Tucker's avatar
Matt Tucker committed
119 120 121 122
    public void destroy() {

    }

123
    @Override
124
    public Connection getConnection() throws SQLException {
Matt Tucker's avatar
Matt Tucker committed
125
        if (dataSource == null) {
126
            throw new SQLException("DataSource has not been initialized.");
Matt Tucker's avatar
Matt Tucker committed
127
        }
128
        return dataSource.getConnection();
Matt Tucker's avatar
Matt Tucker committed
129
    }
130
}