001: package net.sf.saxon.sql;
002:
003: import net.sf.saxon.expr.Expression;
004: import net.sf.saxon.expr.SimpleExpression;
005: import net.sf.saxon.expr.StaticProperty;
006: import net.sf.saxon.expr.XPathContext;
007: import net.sf.saxon.instruct.Executable;
008: import net.sf.saxon.om.Item;
009: import net.sf.saxon.style.ExtensionInstruction;
010: import net.sf.saxon.trans.XPathException;
011: import net.sf.saxon.value.ObjectValue;
012: import net.sf.saxon.value.StringValue;
013:
014: import java.sql.Connection;
015: import java.sql.DriverManager;
016:
017: /**
018: * An sql:connect element in the stylesheet.
019: */
020:
021: public class SQLConnect extends ExtensionInstruction {
022:
023: Expression database;
024: Expression driver;
025: Expression user;
026: Expression password;
027:
028: public boolean mayContainSequenceConstructor() {
029: return false;
030: }
031:
032: public void prepareAttributes() throws XPathException {
033:
034: // Get mandatory database attribute
035:
036: String dbAtt = attributeList.getValue("", "database");
037: if (dbAtt == null) {
038: reportAbsence("database");
039: dbAtt = ""; // for error recovery
040: }
041: database = makeAttributeValueTemplate(dbAtt);
042:
043: // Get driver attribute
044:
045: String dbDriver = attributeList.getValue("", "driver");
046: if (dbDriver == null) {
047: if (dbAtt.length() > 9
048: && dbAtt.substring(0, 9).equals("jdbc:odbc")) {
049: dbDriver = "sun.jdbc.odbc.JdbcOdbcDriver";
050: } else {
051: reportAbsence("driver");
052: }
053: }
054: driver = makeAttributeValueTemplate(dbDriver);
055:
056: // Get and expand user attribute, which defaults to empty string
057:
058: String userAtt = attributeList.getValue("", "user");
059: if (userAtt == null) {
060: user = StringValue.EMPTY_STRING;
061: } else {
062: user = makeAttributeValueTemplate(userAtt);
063: }
064:
065: // Get and expand password attribute, which defaults to empty string
066:
067: String pwdAtt = attributeList.getValue("", "password");
068: if (pwdAtt == null) {
069: password = StringValue.EMPTY_STRING;
070: } else {
071: password = makeAttributeValueTemplate(pwdAtt);
072: }
073: }
074:
075: public void validate() throws XPathException {
076: super .validate();
077: database = typeCheck("database", database);
078: driver = typeCheck("driver", driver);
079: user = typeCheck("user", user);
080: password = typeCheck("password", password);
081: }
082:
083: public Expression compile(Executable exec) throws XPathException {
084: return new ConnectInstruction(database, driver, user, password);
085: }
086:
087: private static class ConnectInstruction extends SimpleExpression {
088:
089: public static final int DATABASE = 0;
090: public static final int DRIVER = 1;
091: public static final int USER = 2;
092: public static final int PASSWORD = 3;
093:
094: public ConnectInstruction(Expression database,
095: Expression driver, Expression user, Expression password) {
096:
097: Expression[] subs = { database, driver, user, password };
098: setArguments(subs);
099: };
100:
101: /**
102: * A subclass must provide one of the methods evaluateItem(), iterate(), or process().
103: * This method indicates which of the three is provided.
104: */
105:
106: public int getImplementationMethod() {
107: return Expression.EVALUATE_METHOD;
108: }
109:
110: public int computeCardinality() {
111: return StaticProperty.EXACTLY_ONE;
112: }
113:
114: public String getExpressionType() {
115: return "sql:connect";
116: }
117:
118: public Item evaluateItem(XPathContext context)
119: throws XPathException {
120:
121: // Establish the JDBC connection
122:
123: Connection connection = null; // JDBC Database Connection
124:
125: String dbString = arguments[DATABASE]
126: .evaluateAsString(context);
127: String dbDriverString = arguments[DRIVER]
128: .evaluateAsString(context);
129: String userString = arguments[USER]
130: .evaluateAsString(context);
131: String pwdString = arguments[PASSWORD]
132: .evaluateAsString(context);
133:
134: try {
135: // the following hack is necessary to load JDBC drivers
136: Class.forName(dbDriverString);
137: connection = DriverManager.getConnection(dbString,
138: userString, pwdString);
139: } catch (Exception ex) {
140: dynamicError("JDBC Connection Failure: "
141: + ex.getMessage(), context);
142: }
143:
144: return new ObjectValue(connection);
145:
146: }
147: }
148: }
149:
150: //
151: // The contents of this file are subject to the Mozilla Public License Version 1.0 (the "License");
152: // you may not use this file except in compliance with the License. You may obtain a copy of the
153: // License at http://www.mozilla.org/MPL/
154: //
155: // Software distributed under the License is distributed on an "AS IS" basis,
156: // WITHOUT WARRANTY OF ANY KIND, either express or implied.
157: // See the License for the specific language governing rights and limitations under the License.
158: //
159: // The Original Code is: all this file.
160: //
161: // The Initial Developer of the Original Code is Michael H. Kay.
162: //
163: // Portions created by (your name) are Copyright (C) (your legal entity). All Rights Reserved.
164: //
165: // Additional Contributor(s): Rick Bonnett [rbonnett@acadia.net]
166: //
|