KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > ejen > ext > db > BasicMetaDataConnection


1 //
2
// Ejen (code generation system)
3
// Copyright (C) 2001, 2002 François Wolff (ejen@noos.fr).
4
//
5
// This file is part of Ejen.
6
//
7
// Ejen is free software; you can redistribute it and/or modify
8
// it under the terms of the GNU General Public License as published by
9
// the Free Software Foundation; either version 2 of the License, or
10
// (at your option) any later version.
11
//
12
// Ejen is distributed in the hope that it will be useful,
13
// but WITHOUT ANY WARRANTY; without even the implied warranty of
14
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15
// GNU General Public License for more details.
16
//
17
// You should have received a copy of the GNU General Public License
18
// along with Ejen; if not, write to the Free Software
19
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20
//
21
package org.ejen.ext.db;
22
23 import org.ejen.util.XSLUtil;
24 import org.ejen.util.DOMUtil;
25 import java.util.Hashtable JavaDoc;
26 import java.util.Enumeration JavaDoc;
27 import java.util.Properties JavaDoc;
28 import java.sql.Connection JavaDoc;
29 import java.sql.DriverManager JavaDoc;
30 import org.w3c.dom.Node JavaDoc;
31 import org.w3c.dom.traversal.NodeIterator;
32 import org.apache.xalan.extensions.XSLProcessorContext;
33 import org.apache.xalan.extensions.ExpressionContext;
34 import org.apache.xalan.templates.ElemExtensionCall;
35 import org.apache.xml.utils.WrappedRuntimeException;
36 import org.apache.xpath.objects.XObject;
37 import org.apache.xpath.objects.XNodeSet;
38
39 /**
40  * JDBC connections utility (static methods).
41  * <p>
42  * <table class="usage">
43  * <tr><th class="usage">Usage (XSL stylesheet)</th></tr>
44  * <tr><td class="usage"><pre>
45  *
46  * &lt;?xml version="1.0" encoding="iso-8859-1"?&gt;
47  *
48  * &lt;xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
49  * ...
50  * <b>xmlns:mta="org.ejen.ext.db.BasicMetaDataConnection"
51  * extension-element-prefixes="mta ..."
52  * exclude-result-prefixes="mta ..."</b>
53  * version="1.0"&gt;
54  *
55  * &lt;xsl:output method="xml" encoding="iso-8859-1"/&gt;
56  *
57  * &lt;xsl:template match="ejen"&gt;
58  *
59  * &lt;mta:{@link #open(XSLProcessorContext,ElemExtensionCall) open} name="connection1" select="connections/connection[1]"/&gt;
60  * &lt;xsl:if test="not(mta:{@link #open(ExpressionContext,String,NodeIterator) open}('connection3',connections/connection[3]))"&gt;
61  * ...
62  * &lt;/xsl:if&gt;
63  * &lt;mta:{@link #setActive(XSLProcessorContext,ElemExtensionCall) setActive} name="connection1"/&gt;
64  * &lt;mta:{@link #close(XSLProcessorContext,ElemExtensionCall) close} name="connection1"/&gt;
65  * &lt;xsl:if test="not(mta:{@link #close(ExpressionContext,String) close}('connection3'))"&gt;
66  * ...
67  * &lt;/xsl:if&gt;
68  * &lt;mta:{@link #closeAll(XSLProcessorContext,ElemExtensionCall) closeAll}/&gt;
69  * &lt;xsl:if test="not(mta:{@link #closeAll(ExpressionContext) closeAll}())"&gt;
70  * ...
71  * &lt;/xsl:if&gt;
72  *
73  * &lt;xsl:copy-of select="mta:{@link TableMetaDataNodeBuilder#getTableMetaData(ExpressionContext,String) getTableMetaData}('ADDRESS')"/&gt;
74  * &lt;xsl:copy-of select="mta:{@link TableMetaDataNodeBuilder#getTableMetaData(ExpressionContext,String,String,String) getTableMetaData}('CAT','SCH','ADDRESS')"/&gt;
75  *
76  * &lt;xsl:variable name="errors" select="mta:{@link MetaDataNodeBuilder#getErrors(ExpressionContext) getErrors()}"/&gt;
77  * &lt;xsl:copy-of select="mta:{@link MetaDataNodeBuilder#getDatabaseInformation(ExpressionContext) getDatabaseInformation}()/@*"/&gt;
78  * &lt;xsl:copy-of select="mta:{@link MetaDataNodeBuilder#getResultSetMetaData(ExpressionContext,String) getResultSetMetaData}('ADDRESS')"/&gt;
79  * &lt;xsl:copy-of select="mta:{@link MetaDataNodeBuilder#getResultSetMetaData(ExpressionContext,String,String) getResultSetMetaData}('ADDRESS','COL1,COL2')"/&gt;
80  * &lt;xsl:copy-of select="mta:{@link MetaDataNodeBuilder#getPrimaryKeys(ExpressionContext,String) getPrimaryKeys}('ADDRESS')"/&gt;
81  * &lt;xsl:copy-of select="mta:{@link MetaDataNodeBuilder#getPrimaryKeys(ExpressionContext,String,String,String) getPrimaryKeys}('CAT','SCH','ADDRESS')"/&gt;
82  * &lt;xsl:copy-of select="mta:{@link MetaDataNodeBuilder#getImportedKeys(ExpressionContext,String) getImportedKeys}('ADDRESS')"/&gt;
83  * &lt;xsl:copy-of select="mta:{@link MetaDataNodeBuilder#getImportedKeys(ExpressionContext,String,String,String) getImportedKeys}('CAT','SCH','ADDRESS')"/&gt;
84  * &lt;xsl:copy-of select="mta:{@link MetaDataNodeBuilder#getExportedKeys(ExpressionContext,String) getExportedKeys}('ADDRESS')"/&gt;
85  * &lt;xsl:copy-of select="mta:{@link MetaDataNodeBuilder#getExportedKeys(ExpressionContext,String,String,String) getExportedKeys}('CAT','SCH','ADDRESS')"/&gt;
86  * &lt;xsl:copy-of select="mta:{@link MetaDataNodeBuilder#getIndexInfo(ExpressionContext,String) getIndexInfo}('ADDRESS')"/&gt;
87  * &lt;xsl:copy-of select="mta:{@link MetaDataNodeBuilder#getIndexInfo(ExpressionContext,String,String,String) getIndexInfo}('CAT','SCH','ADDRESS')"/&gt;
88  *
89  * &lt;/xsl:template&gt;
90  *
91  * &lt;/xsl:stylesheet&gt;
92  * </pre></td></tr></table>
93  * @author F. Wolff
94  * @version 1.0
95  */

96 public class BasicMetaDataConnection extends TableMetaDataNodeBuilder {
97     public static final String JavaDoc S_CI_CONNECTION_NODE_NAME = "connection";
98     public static final String JavaDoc S_CI_DRIVER = "driver";
99     public static final String JavaDoc S_CI_URL = "url";
100
101     /** Connections table */
102     protected static Hashtable JavaDoc _conns = new Hashtable JavaDoc();
103
104     /**
105      * Prevents instanciation.
106      */

107     protected BasicMetaDataConnection() {}
108
109     /**
110      * Opens a JDBC connection and puts it in the connections table. If a
111      * connection is already registered with the same name, closes it before.
112      * <p>
113      * <table class="usage"><tr><td class="usage"><pre>
114      *
115      * &lt;mta:open name="connection1" select="connections/connection[1]"/&gt;
116      * </pre></td></tr></table>
117      * <p>
118      * The selected connection <code>Node</code> must have the following format:
119      * <p>
120      * <table class="usage"><tr><td class="usage"><pre>
121      *
122      * &lt;connection url="jdbc:hsqldb:hsql://localhost:1476"
123      * driver="org.hsqldb.jdbcDriver"&gt;
124      * &lt;property name="user" value="sa"/&gt;
125      * &lt;property name="password" value=""/&gt;
126      * [...any number of other JDBC properties]
127      * &lt;/connection&gt;
128      * </pre></td></tr></table>
129      * <p>
130      * The <code>&lt;property...&gt;</code> nodes are all passed to the
131      * {@link java.sql.DriverManager#getConnection(String,Properties)} method.
132      * <p>
133      * Connections errors (SQLException) are not thrown. Instead, an errors
134      * <code>NodeSet</code> is built that can be retreived by the
135      * {@link MetaDataNodeBuilder#getErrors(ExpressionContext)} method.
136      * <p>
137      * <dd><dl><dt><b>XSLT Attributes:</b>
138      * <dd>name <b>[Mantatory/AVT]</b> name of the connection to be opened.
139      * <dd>name <b>[Mantatory]</b> connection Node to use.
140      * </dl></dd>
141      * <p>
142      * @param context automatically passed by the xalan extension mechanism.
143      * @param elem automatically passed by the xalan extension mechanism.
144      * @return <code>true</code> if connection succeed, <code>false</code> otherwise.
145      * @throws java.lang.RuntimeException
146      * if the 'name' or 'select' attribute is missing or incorrect.
147      * @throws org.apache.xml.utils.WrappedRuntimeException
148      * if the 'select' result is not a <code>NodeIterator</code>.
149      */

150     public static void open(XSLProcessorContext context, ElemExtensionCall elem) {
151         String JavaDoc name = XSLUtil.getAttribute(context, elem, "name", true);
152         String JavaDoc select = XSLUtil.getAttribute(context, elem, "select", true);
153         XObject xo = XSLUtil.evaluate(context, elem, select);
154
155         if (xo == null || !(xo instanceof XNodeSet)) {
156             throw new RuntimeException JavaDoc("illegal 'select' attribute in 'connection' node");
157         }
158         NodeIterator ni = null;
159
160         try {
161             ni = xo.nodeset();
162         } catch (Exception JavaDoc e) {
163             throw new WrappedRuntimeException(e);
164         }
165         open(null, name, ni);
166     }
167
168     /**
169      * Opens a JDBC connection and puts it in the connections table. If a
170      * connection is already registered with the same name, closes it before.
171      * <p>
172      * <table class="usage"><tr><td class="usage"><pre>
173      *
174      * &lt;xsl:if test="not(mta:open('connection3',connections/connection[3]))"&gt;
175      * ...
176      * &lt;/xsl:if&gt;
177      * </pre></td></tr></table>
178      * <p>
179      * See {@link #open(XSLProcessorContext,ElemExtensionCall)}.
180      * <p>
181      * <dd><dl><dt><b>XSLT parameters:</b>
182      * <dd><b>[Mandatory/AVT]</b> name of the connection to be opened.
183      * <dd><b>[Mandatory]</b> connection Node to use.
184      * </dl></dd>
185      * <p>
186      * @param context automatically passed by the xalan extension mechanism.
187      * @param name name of the connection.
188      * @param connectionNi connection <code>Node</code>.
189      * @return <code>true</code> if connection succeed, <code>false</code>
190      * otherwise.
191      * @throws java.lang.RuntimeException
192      * if the connection <code>Node</code> incorrect.
193      */

194     public static boolean open(ExpressionContext context, String JavaDoc name, NodeIterator connectionNi) {
195         name = XSLUtil.evaluate(context, name);
196         if (!close(null, name)) {
197             return false;
198         }
199         try {
200             boolean badNode = false;
201             Properties JavaDoc props = null;
202             String JavaDoc driver = null;
203             String JavaDoc url = null;
204             Node JavaDoc elt = connectionNi.nextNode();
205
206             if (elt == null
207                     || !S_CI_CONNECTION_NODE_NAME.equals(elt.getNodeName())) {
208                 badNode = true;
209             } else {
210                 driver = DOMUtil.getAttribute(elt, S_CI_DRIVER);
211                 url = DOMUtil.getAttribute(elt, S_CI_URL);
212                 if (driver == null || url == null) {
213                     badNode = true;
214                 } else {
215                     props = DOMUtil.getChildProperties(elt);
216                 }
217             }
218             if (badNode) {
219                 throw new RuntimeException JavaDoc("Illegal jdbc 'connection' node");
220             }
221             Class.forName(driver);
222             _activeConn = DriverManager.getConnection(url, props);
223             _conns.put(name, _activeConn);
224         } catch (Exception JavaDoc e) {
225             appendErrorNode(e);
226         }
227         return _errors == null;
228     }
229
230     /**
231      * Closes a JDBC connection and removes it from the connections table.
232      * <p>
233      * <table class="usage"><tr><td class="usage"><pre>
234      *
235      * &lt;mta:close name="connection1"/&gt;
236      * </pre></td></tr></table>
237      * <p>
238      * Connections errors (SQLException) are not thrown. Instead, an errors
239      * <code>NodeSet</code> is built that can be retreived by the
240      * {@link MetaDataNodeBuilder#getErrors(ExpressionContext)} method.
241      * <p>
242      * <dd><dl><dt><b>XSLT Attributes:</b>
243      * <dd>name <b>[Mantatory/AVT]</b> name of the connection to be closed.
244      * </dl></dd>
245      * <p>
246      * @param context automatically passed by the xalan extension mechanism.
247      * @param elem automatically passed by the xalan extension mechanism.
248      * @return <code>true</code> if closing connection succeed, <code>false</code>
249      * otherwise.
250      * @throws java.lang.RuntimeException if the 'name' attribute is missing or
251      * does not match a registered connection.
252      */

253     public static void close(XSLProcessorContext context, ElemExtensionCall elem) {
254         close(null, XSLUtil.getAttribute(context, elem, "name", true));
255     }
256
257     /**
258      * Closes a JDBC connection and removes it from the connections table.
259      * <p>
260      * <table class="usage"><tr><td class="usage"><pre>
261      *
262      * &lt;xsl:if test="not(mta:close('connection3'))"&gt;
263      * ...
264      * &lt;/xsl:if&gt;
265      * </pre></td></tr></table>
266      * <p>
267      * Connections errors (SQLException) are not thrown. Instead, an errors
268      * <code>NodeSet</code> is built that can be retreived by the
269      * {@link MetaDataNodeBuilder#getErrors(ExpressionContext)} method.
270      * <p>
271      * <dd><dl><dt><b>XSLT parameters:</b>
272      * <dd><b>[Mandatory/AVT]</b> name of the connection to be closed.
273      * </dl></dd>
274      * <p>
275      * @param context automatically passed by the xalan extension mechanism.
276      * @param name connection name.
277      * @return <code>true</code> if closing connection succeed, <code>false</code>
278      * otherwise.
279      * @throws java.lang.RuntimeException
280      * if the 'name' parameter does not match a registered connection.
281      */

282     public static boolean close(ExpressionContext context, String JavaDoc name) {
283         if (context != null) {
284             name = XSLUtil.evaluate(context, name);
285         }
286         _errors = null;
287         if (context != null) {
288             Connection JavaDoc conn = (Connection JavaDoc) (_conns.get(name));
289
290             if (conn != null) {
291                 if (_activeConn == conn) {
292                     _activeConn = null;
293                 }
294                 try {
295                     conn.close();
296                 } catch (Exception JavaDoc e) {
297                     appendErrorNode(e);
298                 }
299                 finally {
300                     _conns.remove(name);
301                 }
302             } else {
303                 throw new RuntimeException JavaDoc("No jdbc connection with this name: "
304                         + name);
305             }
306         }
307         return _errors == null;
308     }
309
310     /**
311      * Sets the current active JDBC connection.
312      * <p>
313      * <table class="usage"><tr><td class="usage"><pre>
314      *
315      * &lt;mta:setActive name="connection1"/&gt;
316      * </pre></td></tr></table>
317      * <p>
318      * <dd><dl><dt><b>XSLT Attributes:</b>
319      * <dd>name <b>[Mantatory/AVT]</b> name of the connection to be activated.
320      * </dl></dd>
321      * <p>
322      * @param context automatically passed by the xalan extension mechanism.
323      * @param elem automatically passed by the xalan extension mechanism.
324      * @throws java.lang.RuntimeException if the 'name' attribute is missing or
325      * does not match a registered connection.
326      */

327     public static void setActive(XSLProcessorContext context, ElemExtensionCall elem) {
328         String JavaDoc name = XSLUtil.getAttribute(context, elem, "name", true);
329         Connection JavaDoc conn = (Connection JavaDoc) (_conns.get(name));
330
331         if (conn != null) {
332             _activeConn = conn;
333         } else {
334             throw new RuntimeException JavaDoc("No jdbc connection with this name: "
335                     + name);
336         }
337     }
338
339     /**
340      * Closes all JDBC connections.
341      * <p>
342      * <table class="usage"><tr><td class="usage"><pre>
343      *
344      * &lt;mta:closeAll/&gt;
345      * </pre></td></tr></table>
346      * <p>
347      * Connections errors (SQLException) are not thrown. Instead, an errors
348      * <code>NodeSet</code> is built that can be retreived by the
349      * {@link MetaDataNodeBuilder#getErrors(ExpressionContext)} method.
350      * <p>
351      * @param context automatically passed by the xalan extension mechanism.
352      * @param elem automatically passed by the xalan extension mechanism.
353      * @return <code>true</code> if closing all connections succeed, <code>false</code>
354      * otherwise.
355      */

356     public static void closeAll(XSLProcessorContext context, ElemExtensionCall elem) {
357         closeAll(null);
358     }
359
360     /**
361      * Closes all JDBC connections.
362      * <p>
363      * <table class="usage"><tr><td class="usage"><pre>
364      *
365      * &lt;xsl:if test="not(mta:closeAll())"&gt;
366      * ...
367      * &lt;/xsl:if&gt;
368      * </pre></td></tr></table>
369      * <p>
370      * Connections errors (SQLException) are not thrown. Instead, an errors
371      * <code>NodeSet</code> is built that can be retreived by the
372      * {@link MetaDataNodeBuilder#getErrors(ExpressionContext)} method.
373      * <p>
374      * @param context automatically passed by the xalan extension mechanism.
375      * @return <code>true</code> if closing all connections succeed, <code>false</code>
376      * otherwise.
377      */

378     public static boolean closeAll(ExpressionContext context) {
379         _errors = null;
380         for (Enumeration JavaDoc e = _conns.elements(); e.hasMoreElements();) {
381             Connection JavaDoc conn = (Connection JavaDoc) (e.nextElement());
382
383             try {
384                 conn.close();
385             } catch (Exception JavaDoc f) {
386                 appendErrorNode(f);
387             }
388         }
389         _conns.clear();
390         return _errors == null;
391     }
392 }
393
Popular Tags