KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > versant > core > jdbc > JdbcStorageManagerFactory


1
2 /*
3  * Copyright (c) 1998 - 2005 Versant Corporation
4  * All rights reserved. This program and the accompanying materials
5  * are made available under the terms of the Eclipse Public License v1.0
6  * which accompanies this distribution, and is available at
7  * http://www.eclipse.org/legal/epl-v10.html
8  *
9  * Contributors:
10  * Versant Corporation - initial API and implementation
11  */

12 package com.versant.core.jdbc;
13
14 import com.versant.core.storagemanager.*;
15 import com.versant.core.logging.LogEventStore;
16 import com.versant.core.metadata.ModelMetaData;
17 import com.versant.core.metadata.ClassMetaData;
18
19 import com.versant.core.metadata.generator.OIDSrcGenerator;
20 import com.versant.core.metadata.generator.StateSrcGenerator;
21
22 import com.versant.core.common.config.ConfigInfo;
23 import com.versant.core.common.*;
24 import com.versant.core.jdbc.sql.SqlDriver;
25 import com.versant.core.jdbc.conn.JDBCConnectionPool;
26 import com.versant.core.jdbc.metadata.JdbcMetaData;
27 import com.versant.core.jdbc.metadata.JdbcClass;
28 import com.versant.core.server.DataStoreInfo;
29 import com.versant.core.server.CompiledQueryCache;
30 import com.versant.core.metric.HasMetrics;
31
32 import com.versant.core.compiler.ClassSpec;
33
34
35 import java.util.*;
36 import java.sql.Driver JavaDoc;
37 import java.sql.Connection JavaDoc;
38 import java.sql.SQLException JavaDoc;
39 import java.lang.reflect.Constructor JavaDoc;
40 import java.io.IOException JavaDoc;
41
42 /**
43  * Creates JdbcStorageManager's.
44  */

45 public final class JdbcStorageManagerFactory
46         implements StorageManagerFactory, HasMetrics {
47
48     private final LogEventStore pes;
49     private final StorageCache cache;
50     private JdbcConnectionSource conSrc;
51     private final ModelMetaData jmd;
52     private final JdbcConfig jdbcConfig;
53     private final SqlDriver sqlDriver;
54     private final CompiledQueryCache compiledQueryCache;
55     private final boolean hyperdrive;
56     private Driver jdbcDriver;
57
58     public JdbcStorageManagerFactory(StorageManagerFactoryBuilder b) {
59         this.pes = b.getLogEventStore();
60         this.cache = b.getCache();
61         this.compiledQueryCache = b.getCompiledQueryCache();
62         ConfigInfo config = b.getConfig();
63         this.jdbcConfig = new JdbcConfigParser().parse(config.props);
64
65         boolean createPool = !b.isOnlyMetaData();
66         ClassLoader JavaDoc loader = b.getLoader();
67
68         // load JDBC driver, create wrapper and conSrc + customize wrapper
69
if (createPool) {
70             jdbcDriver = SqlDriver.createJdbcDriver(jdbcConfig.driver, loader);
71         } else {
72             jdbcDriver = null;
73         }
74         sqlDriver = SqlDriver.createSqlDriver(jdbcConfig.db, jdbcDriver);
75         if (createPool) {
76             createPool(loader);
77         } else {
78             conSrc = null;
79         }
80
81         // build meta data
82
JdbcMetaDataBuilder mdb = new JdbcMetaDataBuilder(config,
83                 jdbcConfig, loader, sqlDriver, b.isContinueAfterMetaDataError());
84         jmd = mdb.buildMetaData(config.jdoMetaData);
85
86         // generate source for hyperdrive classes if needed
87
hyperdrive = config.hyperdrive;
88
89         if (hyperdrive) {
90             OIDSrcGenerator oidGen = new JdbcOIDGenerator(jmd);
91             StateSrcGenerator stateGen = new JdbcStateGenerator();
92             HashMap classSpecs = b.getClassSpecs();
93             for (int i = jmd.classes.length - 1; i >= 0; i--) {
94                 ClassMetaData cmd = jmd.classes[i];
95                 if (cmd.horizontal) continue;
96                 ClassSpec spec = oidGen.generateOID(cmd);
97                 classSpecs.put(spec.getQName(), spec);
98                 spec = stateGen.generateState(cmd);
99                 classSpecs.put(spec.getQName(), spec);
100             }
101         }
102
103     }
104
105     public void init(boolean full, ClassLoader JavaDoc loader) {
106
107         if (hyperdrive) {
108             if (full) {
109                 installHyperdriveStateAndOIDFactory(loader);
110             }
111         } else { // not using generated hyperdrive classes
112
installGenericStateAndOIDFactory();
113         }
114
115
116         Connection JavaDoc con = null;
117         try {
118             conSrc.init();
119             if (sqlDriver.isCustomizeForServerRequired()) {
120                 con = conSrc.getConnection(false, false);
121                 sqlDriver.customizeForServer(con);
122             }
123             if (full) {
124                 ClassMetaData[] classes = jmd.classes;
125                 for (int j = 0; j < classes.length; j++) {
126                     ClassMetaData cmd = classes[j];
127                     if (cmd.top != cmd) {
128                         continue;
129                     }
130                     JdbcKeyGenerator kg = ((JdbcClass)cmd.storeClass).jdbcKeyGenerator;
131                     if (kg == null) {
132                         continue;
133                     }
134                     if (con == null) {
135                         con = conSrc.getConnection(false, false);
136                     }
137                     kg.init(cmd.qname, ((JdbcClass)cmd.storeClass).table, con);
138                     con.commit();
139                 }
140             }
141         } catch (SQLException JavaDoc e) {
142             throw BindingSupportImpl.getInstance().datastore(e.toString(),
143                     e);
144         } finally {
145             if (con != null) {
146                 try {
147                     conSrc.returnConnection(con);
148                 } catch (SQLException JavaDoc e) {
149                     // ignore
150
}
151             }
152         }
153     }
154
155     /**
156      * Install a single StateAndOIDFactory for all classes that uses hand
157      * written State and OID classes.
158      */

159     private void installGenericStateAndOIDFactory() {
160         StateAndOIDFactory f = new GenericFactory();
161         ClassMetaData[] classes = jmd.classes;
162         for (int i = 0; i < classes.length; i++) {
163             classes[i].stateAndOIDFactory = f;
164         }
165     }
166
167     /**
168      * Install a StateAndOIDFactory for each class that uses the generated
169      * State and OID classes.
170      */

171
172     private void installHyperdriveStateAndOIDFactory(ClassLoader JavaDoc loader) {
173         try {
174             ClassMetaData[] classes = jmd.classes;
175             for (int i = 0; i < classes.length; i++) {
176                 ClassMetaData cmd = classes[i];
177                 if (cmd.horizontal) {
178                     continue;
179                 }
180                 Class JavaDoc oidClass = Class.forName(cmd.oidClassName, true, loader);
181                 Class JavaDoc stateClass = Class.forName(cmd.stateClassName, true, loader);
182                 if (cmd.isInHeirachy()) {
183                     cmd.stateAndOIDFactory =
184                             new HyperdriveFactoryHeirachy(oidClass,
185                                     stateClass);
186                 } else {
187                     cmd.stateAndOIDFactory =
188                             new HyperdriveFactory(oidClass,
189                                     stateClass);
190                 }
191             }
192         } catch (Exception JavaDoc e) {
193             throw BindingSupportImpl.getInstance().internal(e.toString(), e);
194         }
195     }
196
197
198     public void destroy() {
199         if (conSrc != null) {
200             conSrc.destroy();
201         }
202         compiledQueryCache.clear();
203     }
204
205     /**
206      * If we do not have a JdbcConnectionSource then create a connection
207      * pool otherwise do nothing.
208      */

209     public void createPool(ClassLoader JavaDoc loader) {
210         if (conSrc == null) {
211             if (jdbcDriver == null) {
212                 jdbcDriver = SqlDriver.createJdbcDriver(jdbcConfig.driver, loader);
213             }
214             conSrc = new JDBCConnectionPool(jdbcConfig, pes, jdbcDriver,
215                     sqlDriver);
216         }
217     }
218
219     public StorageManager getStorageManager() {
220         return new JdbcStorageManager(jmd, conSrc, sqlDriver, cache,
221                 compiledQueryCache, pes, jdbcConfig);
222     }
223
224     public void returnStorageManager(StorageManager sm) {
225         sm.destroy();
226     }
227
228     public LogEventStore getPerfEventStore() {
229         return pes;
230     }
231
232     public StorageCache getCache() {
233         return cache;
234     }
235
236     public JdbcConnectionSource getConnectionSource() {
237         return conSrc;
238     }
239
240     public ModelMetaData getModelMetaData() {
241         return jmd;
242     }
243
244     public SqlDriver getSqlDriver() {
245         return sqlDriver;
246     }
247
248     public JdbcConfig getJdbcConfig() {
249         return jdbcConfig;
250     }
251
252     public Object JavaDoc getDatastoreConnection() {
253         try {
254             return conSrc.getConnection(false, false);
255         } catch (SQLException JavaDoc e) {
256             throw BindingSupportImpl.getInstance().datastore(e.toString(), e);
257         }
258     }
259
260     public void closeIdleDatastoreConnections() {
261         conSrc.closeIdleConnections();
262     }
263
264     public JdbcMetaData getJdbcMetaData() {
265         return (JdbcMetaData)jmd.jdbcMetaData;
266     }
267
268     public DataStoreInfo getDataStoreInfo() {
269         DataStoreInfo info = new DataStoreInfo();
270         info.setDataStoreType(sqlDriver.getName());
271         info.setName("main");
272         info.setAutoIncSupported(sqlDriver.isAutoIncSupported());
273         info.setJdbc(true);
274         info.setMajorVersion(sqlDriver.getMajorVersion());
275         info.setPreparedStatementPoolingOK(
276                 sqlDriver.isPreparedStatementPoolingOK());
277         info.setScrollableResultSetSupported(
278                 sqlDriver.isScrollableResultSetSupported());
279         info.setSelectForUpdate(sqlDriver.getSelectForUpdate() == null
280                 ? null
281                 : new String JavaDoc(sqlDriver.getSelectForUpdate()));
282         return info;
283     }
284
285     public void addMetrics(List list) {
286         if (conSrc instanceof HasMetrics) {
287             ((HasMetrics)conSrc).addMetrics(list);
288         }
289         if (cache instanceof HasMetrics) {
290             ((HasMetrics)cache).addMetrics(list);
291         }
292     }
293
294     public void sampleMetrics(int[][] buf, int pos) {
295         if (conSrc instanceof HasMetrics) {
296             ((HasMetrics)conSrc).sampleMetrics(buf, pos);
297         }
298         if (cache instanceof HasMetrics) {
299             ((HasMetrics)cache).sampleMetrics(buf, pos);
300         }
301     }
302
303     public StorageManagerFactory getInnerStorageManagerFactory() {
304         return null;
305     }
306
307     public void supportedOptions(Set options) {
308     }
309
310     public CompiledQueryCache getCompiledQueryCache() {
311         return compiledQueryCache;
312     }
313
314     /**
315      * Factory that returns instances of the non-generated State and OID
316      * classes.
317      */

318     private static class GenericFactory
319             implements StateAndOIDFactory {
320
321         public OID createOID(ClassMetaData cmd, boolean resolved) {
322             return new JdbcGenericOID(cmd, resolved);
323         }
324
325         public State createState(ClassMetaData cmd) {
326             return new JdbcGenericState(cmd);
327         }
328
329         public NewObjectOID createNewObjectOID(ClassMetaData cmd) {
330             return new JdbcNewObjectOID(cmd);
331         }
332
333         public OID createUntypedOID() {
334             throw BindingSupportImpl.getInstance().unsupported(
335                 "Untyped OIDs are not supported by the datastore");
336         }
337     }
338
339     /**
340      * Factory for classes not in a hierachy.
341      */

342     private static class HyperdriveFactory implements StateAndOIDFactory {
343
344         protected final Class JavaDoc stateClass;
345         protected final Class JavaDoc oidClass;
346
347         public HyperdriveFactory(Class JavaDoc oidClass, Class JavaDoc stateClass) {
348             this.oidClass = oidClass;
349             this.stateClass = stateClass;
350         }
351
352         public State createState(ClassMetaData cmd) {
353             try {
354                 return (State)stateClass.newInstance();
355             } catch (Exception JavaDoc e) {
356                 throw BindingSupportImpl.getInstance().internal(e.toString(), e);
357             }
358         }
359
360         public OID createOID(ClassMetaData cmd, boolean resolved) {
361             try {
362                 return (OID)oidClass.newInstance();
363             } catch (Exception JavaDoc e) {
364                 throw BindingSupportImpl.getInstance().internal(e.toString(), e);
365             }
366         }
367
368         public NewObjectOID createNewObjectOID(ClassMetaData cmd) {
369             return new JdbcNewObjectOID(cmd);
370         }
371
372         public OID createUntypedOID() {
373             throw BindingSupportImpl.getInstance().unsupported(
374                 "Untyped OIDs are not supported by the datastore");
375         }
376     }
377
378     /**
379      * Factory for classes in a heirachy.
380      */

381     private static class HyperdriveFactoryHeirachy
382             extends HyperdriveFactory {
383
384         private transient Constructor JavaDoc oidCon;
385
386         public HyperdriveFactoryHeirachy(Class JavaDoc oidClass, Class JavaDoc stateClass) {
387             super(oidClass, stateClass);
388             init();
389         }
390
391         private void init() {
392             try {
393                 oidCon = oidClass.getConstructor(new Class JavaDoc[]{ClassMetaData.class,
394                     Boolean.TYPE});
395             } catch (NoSuchMethodException JavaDoc e) {
396                 throw BindingSupportImpl.getInstance().internal(e.toString(), e);
397             }
398         }
399
400         private void writeObject(java.io.ObjectOutputStream JavaDoc out)
401                 throws IOException JavaDoc {
402             out.defaultWriteObject();
403         }
404
405         private void readObject(java.io.ObjectInputStream JavaDoc in)
406             throws IOException JavaDoc, ClassNotFoundException JavaDoc {
407             in.defaultReadObject();
408             init();
409         }
410
411         public OID createOID(ClassMetaData cmd, boolean resolved) {
412             try {
413                 return (OID)oidCon.newInstance(new Object JavaDoc[]{cmd,
414                     resolved ? Boolean.TRUE : Boolean.FALSE});
415             } catch (Exception JavaDoc e) {
416                 throw BindingSupportImpl.getInstance().internal(e.toString(), e);
417             }
418         }
419     }
420
421 }
422
423
Popular Tags