KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > xquark > bridge > XQBridge


1 /*
2  * This file belongs to the XQuark distribution.
3  * Copyright (C) 2003 Universite de Versailles Saint-Quentin.
4  *
5  * This program is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU Lesser General Public
7  * License as published by the Free Software Foundation; either
8  * version 2.1 of the License, or (at your option) any later version.
9  *
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13  * Lesser General Public License for more details.
14  *
15  * You should have received a copy of the GNU Lesser General Public
16  * License along with this program; if not, write to the Free Software
17  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307.
18  * You can also get it at http://www.gnu.org/licenses/lgpl.html
19  *
20  * For more information on this software, see http://www.xquark.org.
21  */

22
23 package org.xquark.bridge;
24
25 import java.io.File JavaDoc;
26 import java.io.PrintStream JavaDoc;
27 import java.net.MalformedURLException JavaDoc;
28 import java.sql.Connection JavaDoc;
29 import java.sql.SQLException JavaDoc;
30 import java.util.HashMap JavaDoc;
31
32 import javax.sql.DataSource JavaDoc;
33
34 import org.xml.sax.InputSource JavaDoc;
35 import org.xml.sax.SAXException JavaDoc;
36 import org.xquark.extractor.Extractor;
37 import org.xquark.extractor.ExtractorConnection;
38 import org.xquark.schema.SchemaManager;
39 import org.xquark.xml.xdbc.XMLDBCException;
40
41 /**
42  * Objects of this class encapsulate a JDBC connection and provide access to both
43  * the XQuery and insertion capabilities of the XQBridge.<BR>
44  * Objects of this class are thread-safe and can be reused multiple times.
45  * However, as they encapsulate a JDBC connection, it is recommended to use
46  * different objects with different JDBC connections for different threads.
47  */

48 public class XQBridge {
49     private static final String JavaDoc RCSRevision = "$Revision: 1.22 $";
50     private static final String JavaDoc RCSName = "$Name: $";
51
52     // Initialisation parameters (initialisation is delayed, so that the class loader can be specified)
53
private Connection JavaDoc jdbcConnection;
54     private DataSource JavaDoc dataSource;
55     private String JavaDoc configURI;
56     private File JavaDoc configFile;
57     private String JavaDoc jdbcURL;
58     private String JavaDoc userName;
59     private String JavaDoc password;
60
61     private Extractor extractor;
62     private HashMap JavaDoc mappingMetadata = new HashMap JavaDoc();
63     private SchemaManager schemaManager = null;
64     private PrintStream JavaDoc log = null;
65     private ClassLoader JavaDoc classLoader = null;
66
67     /**
68      * Constructor to use with a configuration file URL or a JNDI name
69      * referencing a JDBC datasource instance. The configuration file is
70      * expected to contain JDBC connection parameters or a JNDI name. Choose
71      * this last solution if you both need to specify a configuration file and a
72      * JNDI name. See the <em>XQuery Language Reference Guide"</em> for more
73      * information about configuration files.
74      *
75      * @param URI
76      * either the configuration file URL, or a JNDI reference that
77      * MUST be prefixed with the "jndi:" string to be recognized as
78      * this.
79      */

80     public XQBridge(String JavaDoc URI) {
81         if (URI == null)
82             throw new NullPointerException JavaDoc("Illegal null value for configuration file URI");
83         configURI = URI;
84     }
85
86     /**
87      * Constructor to use with an extractor configuration file. See the
88      * <em>XQuery Language Reference Guide</em> for more information about
89      * configuration files.
90      *
91      * @param configFile
92      * a Java symbolic file.
93      */

94     public XQBridge(File JavaDoc confFile) {
95         if (confFile == null)
96             throw new NullPointerException JavaDoc("Illegal null value for configuration file");
97         configFile = confFile;
98     }
99
100     /**
101      * Constructor to use with a JDBC data source.
102      *
103      * @param ds
104      * a JDBC data source.
105      * @throws XMLDBCException
106      * API exception
107      */

108     public XQBridge(DataSource JavaDoc dataSource) {
109         if (dataSource == null)
110             throw new NullPointerException JavaDoc("Illegal null value for data source");
111         this.dataSource = dataSource;
112     }
113
114     /**
115      * Constructor to use with a JDBC data source and an extractor configuration
116      * file. See the <em>XQuery Language Reference Guide</em> for more
117      * information about configuration files.
118      *
119      * @param ds
120      * a JDBC data source.
121      * @param configFile
122      * a Java symbolic file
123      * @throws XMLDBCException
124      * API exception
125      */

126     public XQBridge(DataSource JavaDoc dataSource, File JavaDoc confFile) {
127         if (dataSource == null)
128             throw new NullPointerException JavaDoc("Illegal null value for data source");
129         if (confFile == null)
130             throw new NullPointerException JavaDoc("Illegal null value for configuration file");
131         this.dataSource = dataSource;
132         this.configFile = confFile;
133     }
134
135     /**
136      * Construction to use when JDBC connection parameters are available.
137      *
138      * @param jdbcURL
139      * the JDBC URL of the JDBC data source.
140      * @param username
141      * the login name for the JDBC data source.
142      * @param password
143      * the password for the login name.
144      * @throws XMLDBCException
145      * API exception
146      */

147     public XQBridge(String JavaDoc url, String JavaDoc userName, String JavaDoc password) {
148         if (url == null)
149             throw new NullPointerException JavaDoc("Illegal null value for URL");
150         if (userName == null)
151             throw new NullPointerException JavaDoc("Illegal null value for user name");
152         if (password == null)
153             throw new NullPointerException JavaDoc("Illegal null value for user password");
154         this.jdbcURL = url;
155         this.userName = userName;
156         this.password = password;
157     }
158
159     /**
160      * Constructs an Extractor using a single JDBC connection. This connection
161      * should not be used while the XQBridge object is active.
162      *
163      * @param jdbcConnection
164      * a jdbc connection.
165      * @throws XMLDBCException
166      * API exception
167      * @deprecated prevents the use of an external or internal data source.
168      */

169     public XQBridge(Connection JavaDoc jdbcConn) {
170         if (jdbcConn == null)
171             throw new NullPointerException JavaDoc("Illegal null value for connection");
172         jdbcConnection = jdbcConn;
173     }
174
175     /**
176      * Constructs an Extractor using a single JDBC connection and a
177      * configuration file. The connection should not be used while the
178      * XQBridge object is active.
179      *
180      * @param jdbcConnection
181      * a jdbc connection.
182      * @param configURL
183      * the URL of the configuration file.
184      * @throws XMLDBCException
185      * API exception
186      * @deprecated prevents the use of an external or internal data source.
187      */

188     public XQBridge(Connection JavaDoc jdbcConn, String JavaDoc confURI) {
189         if (jdbcConn == null)
190             throw new NullPointerException JavaDoc("Illegal null value for connection");
191         if (confURI == null)
192             throw new NullPointerException JavaDoc("Illegal null value for configuration file URI");
193         jdbcConnection = jdbcConn;
194         configURI = confURI;
195     }
196
197     private Extractor getExtractor() throws XMLDBCException {
198         if (extractor == null) {
199             if (configURI == null && configFile != null) {
200                 try {
201                     configURI = configFile.toURL().toString();
202                 } catch (MalformedURLException JavaDoc ex) {
203                     throw new XMLDBCException("Invalid configuration file name " + configFile, ex);
204                 }
205             }
206             if (dataSource != null) {
207                 extractor = new Extractor(dataSource, configURI);
208             } else if (jdbcConnection != null) {
209                 extractor = new Extractor(jdbcConnection, configURI);
210             } else if (jdbcURL != null) {
211                 extractor = new Extractor(jdbcURL, userName, password);
212             } else {
213                 extractor = new Extractor(configURI, getClassLoader());
214             }
215         }
216         return extractor;
217     }
218
219     /**
220      * Returns a JDBC connection used to access the underlying database.
221      *
222      * @return a JDBC connection. Null when no connection to the database is
223      * available.
224      * @deprecated This method is linked to the deprecated constructor
225      * {@link #XQBridge(Connection, String)}.
226      */

227     public Connection JavaDoc getConnection() throws XMLDBCException {
228         Connection JavaDoc conn = null;
229         try {
230             conn = getExtractor().getJdbcDataSource().getConnection();
231         } catch (SQLException JavaDoc ex) {
232             throw new XMLDBCException("Could not create connection", ex);
233         }
234         return conn;
235     }
236
237     /**
238      * Returns an extractor XML/DBC connection that can be used to execute
239      * XQuery statements over the database.
240      *
241      * @return an XMLConnection object
242      */

243     public ExtractorConnection getXMLConnection() throws XMLDBCException {
244         return getExtractor().getExtractorConnection();
245     }
246
247     /**
248      * Closes the extractor and the underlying resources among which the internal
249      * JDBC data source except if it was passed at construction time.
250      * @throws XMLDBCException
251      * API exception
252      */

253     public void close() throws XMLDBCException {
254         if (extractor != null)
255             extractor.close();
256     }
257
258     /**
259      * Set the class loader used for loading drivers, mappings and user generators.
260      * @param loader ClassLoader
261      */

262     public void setClassLoader(ClassLoader JavaDoc loader) {
263         classLoader = loader;
264     }
265
266     /**
267      * Returns the class loader used for loading drivers, mappings and user generators.
268      */

269     public ClassLoader JavaDoc getClassLoader() {
270         return classLoader != null ? classLoader : this.getClass().getClassLoader();
271     }
272
273     /**
274      * Creates a mapping object containing the processed version of the specified mapping file.
275      * This object can subsequently be used to store XML documents in the database, according
276      * to the specified mapping.<BR>
277      * The mapping file is specified as a SAX input source. If the systemId property of the input source is set,
278      * the object will first be looked up, based on this property, in the mapping cache, and only be created if
279      * not found.
280      * @deprecated Prefer the string methods because they do not create a problem
281      * for resolving relative URIs in mapping file schemaLocation attribute.
282      * @param source a SAX input source encapsulating the mapping file.
283      * @return a Mapping object
284      * @throws XMLDBCException if an error occured while loading the mapping file. The underlying exception provides the
285      * root cause for the exception
286      */

287     public Mapping getMapping(InputSource JavaDoc source) throws XMLDBCException {
288         return loadMapping(source, false);
289     }
290
291     /**
292      * Creates a mapping object containing the processed version of the specified mapping file.
293      * This object can subsequently be used to store XML documents in the database, according
294      * to the specified mapping.<BR>
295      * The mapping file is specified as a SAX input source. If the systemId property of the input source is set,
296      * and the reload flag is false, the object will first be looked up, based on this property,
297      * in the mapping cache, and only be created if not found.
298      * @deprecated Prefer the string methods because they do not create a problem
299      * for resolving relative URIs in mapping file schemaLocation attribute.
300      * @param source a SAX input source encapsulating the mapping file.
301      * @param reload true if the mapping file must be reloaded even if found in the cache.
302      * @throws XMLDBCException if an error occured while loading the mapping file. The underlying exception provides the
303      * root cause for the exception
304      * @return a Mapping object
305      */

306     public Mapping getMapping(InputSource JavaDoc source, boolean reload) throws XMLDBCException {
307         return loadMapping(source, reload);
308     }
309
310     /**
311      * Creates a mapping object containing the processed version of the specified mapping file.
312      * This object can subsequently be used to store XML documents in the database, according
313      * to the specified mapping.<BR>
314      * the object will first be looked up, based on the file URI, in the mapping cache,
315      * and only be created if not found.
316      * @param fileURI the URI of the mapping file.
317      * @return a Mapping object
318      * @throws XMLDBCException if an error occured while loading the mapping file. The underlying exception provides the
319      * root cause for the exception
320      */

321     public Mapping getMapping(String JavaDoc fileURI) throws XMLDBCException {
322         return loadMapping(new InputSource JavaDoc(fileURI), false);
323     }
324
325     /**
326      * Creates a mapping object containing the processed version of the specified mapping file.
327      * This object can subsequently be used to store XML documents in the database, according
328      * to the specified mapping.<BR>
329      * If the reload flag is false, the object will first be looked up, based on the file URI,
330      * in the mapping cache, and only be created if not found.
331      * @param fileURI the URI of the mapping file.
332      * @param reload true if the mapping file must be reloaded even if found in the cache.
333      * @return a Mapping object
334      * @throws XMLDBCException if an error occured while loading the mapping file. The underlying exception provides the
335      * root cause for the exception
336      */

337     public Mapping getMapping(String JavaDoc fileURI, boolean reload) throws XMLDBCException {
338         return loadMapping(new InputSource JavaDoc(fileURI), reload);
339     }
340
341     private Mapping loadMapping(InputSource JavaDoc source, boolean reload) throws XMLDBCException {
342         return new Mapping(getExtractor().getJdbcDataSource(), source, reload, getClassLoader(), getSchemaManager(), mappingMetadata);
343     }
344
345     private SchemaManager getSchemaManager() {
346         if (schemaManager == null)
347             resetSchemas();
348         return schemaManager;
349     }
350
351     private void resetSchemas() {
352         schemaManager = new SchemaManager();
353         String JavaDoc resourceLegacy = getClass().getResource("/org/xquark/bridge/resources/mapping_1_0.xsd").toString();
354         String JavaDoc resource = getClass().getResource("/org/xquark/bridge/resources/mapping.xsd").toString();
355
356         try {
357             schemaManager.loadSchema(new InputSource JavaDoc(resourceLegacy));
358             schemaManager.loadSchema(new InputSource JavaDoc(resource));
359         } catch (SAXException JavaDoc e) {
360             // Should not occur
361
}
362     }
363
364     /**
365      * Loads an XML schema in memory. This is useful for bypassing the automatic schema loading based
366      * upon the schemaLocation attribute (e.g. if there is no such attribute).
367      */

368     public void loadSchema(InputSource JavaDoc source) throws SAXException JavaDoc {
369         getSchemaManager().loadSchema(source);
370     }
371
372     /**
373      * Empties the mappings cache. All Mapping objects that were not closed will continue
374      * working with the old metadata.
375      * @param resetSchemas if the schema cache must be cleared as well
376      */

377     public void resetMappings(boolean resetSchemas) {
378         mappingMetadata.clear();
379         if (resetSchemas)
380             resetSchemas();
381     }
382
383 }
384
Popular Tags