KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > cayenne > dba > AutoAdapter


1 /*****************************************************************
2  * Licensed to the Apache Software Foundation (ASF) under one
3  * or more contributor license agreements. See the NOTICE file
4  * distributed with this work for additional information
5  * regarding copyright ownership. The ASF licenses this file
6  * to you under the Apache License, Version 2.0 (the
7  * "License"); you may not use this file except in compliance
8  * with the License. You may obtain a copy of the License at
9  *
10  * http://www.apache.org/licenses/LICENSE-2.0
11  *
12  * Unless required by applicable law or agreed to in writing,
13  * software distributed under the License is distributed on an
14  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15  * KIND, either express or implied. See the License for the
16  * specific language governing permissions and limitations
17  * under the License.
18  ****************************************************************/

19
20 package org.apache.cayenne.dba;
21
22 import java.sql.Connection JavaDoc;
23 import java.sql.PreparedStatement JavaDoc;
24 import java.sql.SQLException JavaDoc;
25 import java.util.Arrays JavaDoc;
26 import java.util.Collection JavaDoc;
27
28 import javax.sql.DataSource JavaDoc;
29
30 import org.apache.cayenne.CayenneRuntimeException;
31 import org.apache.cayenne.access.DataNode;
32 import org.apache.cayenne.access.QueryLogger;
33 import org.apache.cayenne.access.trans.QualifierTranslator;
34 import org.apache.cayenne.access.trans.QueryAssembler;
35 import org.apache.cayenne.access.types.ExtendedTypeMap;
36 import org.apache.cayenne.dba.db2.DB2Sniffer;
37 import org.apache.cayenne.dba.derby.DerbySniffer;
38 import org.apache.cayenne.dba.frontbase.FrontBaseSniffer;
39 import org.apache.cayenne.dba.hsqldb.HSQLDBSniffer;
40 import org.apache.cayenne.dba.ingres.IngresSniffer;
41 import org.apache.cayenne.dba.mysql.MySQLSniffer;
42 import org.apache.cayenne.dba.openbase.OpenBaseSniffer;
43 import org.apache.cayenne.dba.oracle.OracleSniffer;
44 import org.apache.cayenne.dba.postgres.PostgresSniffer;
45 import org.apache.cayenne.dba.sqlserver.SQLServerSniffer;
46 import org.apache.cayenne.dba.sybase.SybaseSniffer;
47 import org.apache.cayenne.map.DbAttribute;
48 import org.apache.cayenne.map.DbEntity;
49 import org.apache.cayenne.map.DbRelationship;
50 import org.apache.cayenne.query.Query;
51 import org.apache.cayenne.query.SQLAction;
52
53 /**
54  * A DbAdapter that automatically detects the kind of database it is running on and
55  * instantiates an appropriate DB-specific adapter, delegating all subsequent method calls
56  * to this adapter.
57  *
58  * @since 1.2
59  * @author Andrus Adamchik
60  */

61 public class AutoAdapter implements DbAdapter {
62
63     // hardcoded factories for adapters that we know how to auto-detect
64
static final DbAdapterFactory[] DEFAULT_FACTORIES = new DbAdapterFactory[] {
65             new MySQLSniffer(), new PostgresSniffer(), new OracleSniffer(),
66             new SQLServerSniffer(), new HSQLDBSniffer(), new DB2Sniffer(),
67             new SybaseSniffer(), new DerbySniffer(), new OpenBaseSniffer(),
68             new FrontBaseSniffer(), new IngresSniffer()
69     };
70
71     /**
72      * Returns a DbAdapterFactory configured to detect all databases officially supported
73      * by Cayenne.
74      */

75     public static DbAdapterFactory getDefaultFactory() {
76         return new DbAdapterFactoryChain(Arrays.asList(DEFAULT_FACTORIES));
77     }
78
79     protected DbAdapterFactory adapterFactory;
80     protected DataSource JavaDoc dataSource;
81     protected PkGenerator pkGenerator;
82
83     /**
84      * The actual adapter that is delegated method execution.
85      */

86     DbAdapter adapter;
87
88     /**
89      * Creates an AutoAdapter that can detect adapters known to Cayenne.
90      */

91     public AutoAdapter(DataSource JavaDoc dataSource) {
92         this(null, dataSource);
93     }
94
95     /**
96      * Creates an AutoAdapter with specified adapter factory and DataSource. If
97      * adapterFactory is null, default factory is used.
98      */

99     public AutoAdapter(DbAdapterFactory adapterFactory, DataSource JavaDoc dataSource) {
100         // sanity check
101
if (dataSource == null) {
102             throw new CayenneRuntimeException("Null dataSource");
103         }
104
105         this.adapterFactory = adapterFactory != null
106                 ? adapterFactory
107                 : createDefaultFactory();
108         this.dataSource = dataSource;
109     }
110
111     /**
112      * Called from constructor to initialize factory in case no factory was specified by
113      * the object creator.
114      */

115     protected DbAdapterFactory createDefaultFactory() {
116         return getDefaultFactory();
117     }
118
119     /**
120      * Returns a proxied DbAdapter, lazily creating it on first invocation.
121      */

122     protected DbAdapter getAdapter() {
123         if (adapter == null) {
124             synchronized (this) {
125                 if (adapter == null) {
126                     this.adapter = loadAdapter();
127                 }
128             }
129         }
130
131         return adapter;
132     }
133
134     /**
135      * Opens a connection, retrieves JDBC metadata and attempts to guess adapter form it.
136      */

137     protected DbAdapter loadAdapter() {
138         DbAdapter adapter = null;
139
140         try {
141             Connection JavaDoc c = dataSource.getConnection();
142
143             try {
144                 adapter = adapterFactory.createAdapter(c.getMetaData());
145             }
146             finally {
147                 try {
148                     c.close();
149                 }
150                 catch (SQLException JavaDoc e) {
151                     // ignore...
152
}
153             }
154         }
155         catch (SQLException JavaDoc e) {
156             throw new CayenneRuntimeException("Error detecting database type", e);
157         }
158
159         if (adapter == null) {
160             QueryLogger.log("Failed to detect database type, using default adapter");
161             adapter = new JdbcAdapter();
162         }
163         else {
164             QueryLogger.log("Detected and installed adapter: "
165                     + adapter.getClass().getName());
166         }
167
168         return adapter;
169     }
170
171     // ---- DbAdapter methods ----
172

173     public String JavaDoc getBatchTerminator() {
174         return getAdapter().getBatchTerminator();
175     }
176
177     public QualifierTranslator getQualifierTranslator(QueryAssembler queryAssembler) {
178         return getAdapter().getQualifierTranslator(queryAssembler);
179     }
180
181     public SQLAction getAction(Query query, DataNode node) {
182         return getAdapter().getAction(query, node);
183     }
184
185     /**
186      * @deprecated since 3.0 - almost all DB's support FK's now and also this flag is less
187      * relevant for Cayenne now.
188      */

189     public boolean supportsFkConstraints() {
190         return getAdapter().supportsFkConstraints();
191     }
192
193     public boolean supportsUniqueConstraints() {
194         return getAdapter().supportsUniqueConstraints();
195     }
196
197     public boolean supportsGeneratedKeys() {
198         return getAdapter().supportsGeneratedKeys();
199     }
200
201     public boolean supportsBatchUpdates() {
202         return getAdapter().supportsBatchUpdates();
203     }
204
205     public String JavaDoc dropTable(DbEntity entity) {
206         return getAdapter().dropTable(entity);
207     }
208
209     public String JavaDoc createTable(DbEntity entity) {
210         return getAdapter().createTable(entity);
211     }
212
213     public String JavaDoc createUniqueConstraint(DbEntity source, Collection JavaDoc columns) {
214         return getAdapter().createUniqueConstraint(source, columns);
215     }
216
217     public String JavaDoc createFkConstraint(DbRelationship rel) {
218         return getAdapter().createFkConstraint(rel);
219     }
220
221     public String JavaDoc[] externalTypesForJdbcType(int type) {
222         return getAdapter().externalTypesForJdbcType(type);
223     }
224
225     public ExtendedTypeMap getExtendedTypes() {
226         return getAdapter().getExtendedTypes();
227     }
228
229     /**
230      * Returns a primary key generator.
231      */

232     public PkGenerator getPkGenerator() {
233         return (pkGenerator != null) ? pkGenerator : getAdapter().getPkGenerator();
234     }
235
236     /**
237      * Sets a PK generator override. If set to non-null value, such PK generator will be
238      * used instead of the one provided by wrapped adapter.
239      */

240     public void setPkGenerator(PkGenerator pkGenerator) {
241         this.pkGenerator = pkGenerator;
242     }
243
244     public DbAttribute buildAttribute(
245             String JavaDoc name,
246             String JavaDoc typeName,
247             int type,
248             int size,
249             int precision,
250             boolean allowNulls) {
251
252         return getAdapter().buildAttribute(
253                 name,
254                 typeName,
255                 type,
256                 size,
257                 precision,
258                 allowNulls);
259     }
260
261     public void bindParameter(
262             PreparedStatement JavaDoc statement,
263             Object JavaDoc object,
264             int pos,
265             int sqlType,
266             int precision) throws SQLException JavaDoc, Exception JavaDoc {
267         getAdapter().bindParameter(statement, object, pos, sqlType, precision);
268     }
269
270     public String JavaDoc tableTypeForTable() {
271         return getAdapter().tableTypeForTable();
272     }
273
274     public String JavaDoc tableTypeForView() {
275         return getAdapter().tableTypeForView();
276     }
277 }
278
Popular Tags