001: /*
002: * Copyright Aduna (http://www.aduna-software.com/) (c) 2008.
003: *
004: * Licensed under the Aduna BSD-style license.
005: */
006: package org.openrdf.sail.rdbms;
007:
008: import java.sql.Connection;
009: import java.sql.DatabaseMetaData;
010: import java.sql.SQLException;
011: import java.util.Iterator;
012:
013: import javax.imageio.spi.ServiceRegistry;
014: import javax.naming.InitialContext;
015: import javax.naming.NamingException;
016: import javax.sql.DataSource;
017:
018: import org.apache.commons.dbcp.BasicDataSource;
019:
020: import org.openrdf.sail.SailConnection;
021: import org.openrdf.sail.SailException;
022: import org.openrdf.sail.helpers.SailBase;
023: import org.openrdf.sail.rdbms.exceptions.RdbmsException;
024:
025: /**
026: * The RDBMS SAIL for relational database storage in Sesame. This class acts
027: * both as a base class for database specific stores as well as a generic store
028: * that can infer the type of database through the JDBC connection.
029: *
030: * @author James Leigh
031: *
032: */
033: public class RdbmsStore extends SailBase {
034: private RdbmsConnectionFactory factory;
035: private String jdbcDriver;
036: private String url;
037: private String user;
038: private String password;
039: private int maxTripleTables;
040: private boolean triplesIndexed = true;
041: private boolean sequenced = false;
042:
043: public RdbmsStore() {
044: super ();
045: }
046:
047: public RdbmsStore(String url) {
048: this .url = url;
049: }
050:
051: public RdbmsStore(String url, String user, String password) {
052: this .url = url;
053: this .user = user;
054: this .password = password;
055: }
056:
057: public RdbmsStore(String jdbcDriver, String jdbcUrl) {
058: this .jdbcDriver = jdbcDriver;
059: this .url = jdbcUrl;
060: }
061:
062: public RdbmsStore(String jdbcDriver, String jdbcUrl, String user,
063: String password) {
064: this .jdbcDriver = jdbcDriver;
065: this .url = jdbcUrl;
066: this .user = user;
067: this .password = password;
068: }
069:
070: public int getMaxNumberOfTripleTables() {
071: return maxTripleTables;
072: }
073:
074: public void setMaxNumberOfTripleTables(int max) {
075: maxTripleTables = max;
076: }
077:
078: public boolean isIndexed() {
079: return triplesIndexed;
080: }
081:
082: public void setIndexed(boolean indexed) throws SailException {
083: triplesIndexed = indexed;
084: if (factory != null) {
085: factory.setTriplesIndexed(triplesIndexed);
086: }
087: }
088:
089: public boolean isSequenced() {
090: return sequenced;
091: }
092:
093: public void setSequenced(boolean useSequence) {
094: this .sequenced = useSequence;
095: }
096:
097: public void initialize() throws SailException {
098: if (factory == null) {
099: try {
100: factory = createFactory(jdbcDriver, url, user, password);
101: } catch (SailException e) {
102: throw e;
103: } catch (Exception e) {
104: throw new RdbmsException(e);
105: }
106: }
107: factory.setMaxNumberOfTripleTables(maxTripleTables);
108: factory.setTriplesIndexed(triplesIndexed);
109: factory.setSequenced(sequenced);
110: factory.init();
111: }
112:
113: public boolean isWritable() throws SailException {
114: return factory.isWritable();
115: }
116:
117: public RdbmsValueFactory getValueFactory() {
118: return factory.getValueFactory();
119: }
120:
121: @Override
122: protected SailConnection getConnectionInternal()
123: throws SailException {
124: return factory.createConnection();
125: }
126:
127: @Override
128: protected void shutDownInternal() throws SailException {
129: DataSource ds = factory.getDataSource();
130: factory.shutDown();
131: if (ds instanceof BasicDataSource) {
132: try {
133: ((BasicDataSource) ds).close();
134: } catch (SQLException e) {
135: throw new RdbmsException(e);
136: }
137: }
138: }
139:
140: protected void setConnectionFactory(RdbmsConnectionFactory factory) {
141: this .factory = factory;
142: }
143:
144: private RdbmsConnectionFactory createFactory(String jdbcDriver,
145: String url, String user, String password) throws Exception {
146: if (jdbcDriver != null) {
147: Class.forName(jdbcDriver);
148: }
149: DataSource ds = lookupDataSource(url, user, password);
150: Connection con;
151: if (user == null || url.startsWith("jdbc:")) {
152: con = ds.getConnection();
153: } else {
154: con = ds.getConnection(user, password);
155: }
156: try {
157: DatabaseMetaData metaData = con.getMetaData();
158: RdbmsConnectionFactory factory = newFactory(metaData);
159: factory.setSail(this );
160: if (user == null || url.startsWith("jdbc:")) {
161: factory.setDataSource(ds);
162: } else {
163: factory.setDataSource(ds, user, password);
164: }
165: return factory;
166: } finally {
167: con.close();
168: }
169: }
170:
171: private DataSource lookupDataSource(String url, String user,
172: String password) throws NamingException {
173: if (url.startsWith("jdbc:")) {
174: BasicDataSource ds = new BasicDataSource();
175: ds.setUrl(url);
176: ds.setUsername(user);
177: ds.setPassword(password);
178: return ds;
179: }
180: return (DataSource) new InitialContext().lookup(url);
181: }
182:
183: private RdbmsConnectionFactory newFactory(DatabaseMetaData metaData)
184: throws SQLException {
185: String dbn = metaData.getDatabaseProductName();
186: String dbv = metaData.getDatabaseProductVersion();
187: RdbmsConnectionFactory factory;
188: Iterator<RdbmsProvider> providers;
189: providers = ServiceRegistry
190: .lookupProviders(RdbmsProvider.class);
191: while (providers.hasNext()) {
192: RdbmsProvider provider = providers.next();
193: factory = provider.createRdbmsConnectionFactory(dbn, dbv);
194: if (factory != null)
195: return factory;
196: }
197: return new RdbmsConnectionFactory();
198: }
199:
200: }
|