001: /*
002: * (c) Copyright 2003, 2004, 2005, 2006, 2007, 2008 Hewlett-Packard Development Company, LP
003: * [See end of file]
004: */
005:
006: package jena.util;
007:
008: import jena.cmdline.*;
009: import com.hp.hpl.jena.db.*;
010: import com.hp.hpl.jena.enhanced.BuiltinPersonalities;
011: import com.hp.hpl.jena.rdf.model.Model; //import com.hp.hpl.jena.rdf.model.* ;
012: import java.sql.SQLException;
013: import java.util.*;
014:
015: /** Framework for the database commands.
016: *
017: * @author Andy Seaborne
018: * @version $Id: DBcmd.java,v 1.9 2008/01/02 12:11:27 andy_seaborne Exp $
019: */
020:
021: public abstract class DBcmd {
022: // Standardised names.
023: protected final ArgDecl argDeclDbURL = new ArgDecl(true, "db");
024: protected final ArgDecl argDeclDbType = new ArgDecl(true, "dbType");
025: protected final ArgDecl argDeclDbUser = new ArgDecl(true, "dbUser",
026: "user");
027: protected final ArgDecl argDeclDbPassword = new ArgDecl(true,
028: "dbPassword", "password", "pw");
029: protected final ArgDecl argDeclModelName = new ArgDecl(true,
030: "model");
031: protected final ArgDecl argDeclDbDriver = new ArgDecl(true,
032: "driver");
033:
034: protected final ArgDecl argDeclVerbose = new ArgDecl(false, "v",
035: "verbose");
036: protected boolean verbose = false;
037:
038: protected final ArgDecl argDeclDebug = new ArgDecl(false, "debug");
039: protected boolean debug = false;
040:
041: protected final ArgDecl argDeclHelp = new ArgDecl(false, "help",
042: "h");
043:
044: // The values of these arguments
045: protected String argDbURL = null;
046: protected String argDbType = null; // Lower-cased name - key into tables
047: protected String argDriverName = null; // JDBC class name
048: protected String argDriverTypeName = null; // Jena driver name
049: protected String argDbUser = null;
050: protected String argDbPassword = null;
051: protected String argModelName = null;
052:
053: // DB types to JDBC driver name (some common choices)
054: private static Map jdbcDrivers = new HashMap();
055: static {
056: jdbcDrivers.put("mysql", "com.mysql.jdbc.Driver");
057: jdbcDrivers.put("mssql",
058: "com.microsoft.jdbc.sqlserver.SQLServerDriver");
059: jdbcDrivers.put("postgres", "org.postgresql.Driver");
060: jdbcDrivers.put("postgresql", "org.postgresql.Driver");
061: jdbcDrivers.put("hsqldb", "org.hsqldb.jdbcDriver");
062: }
063:
064: // DB types to name Jena uses internally
065: private static Map jenaDriverName = new HashMap();
066: static {
067: jenaDriverName.put("mssql", "MsSQL");
068: jenaDriverName.put("mysql", "MySQL");
069: jenaDriverName.put("postgresql", "PostgreSQL");
070: jenaDriverName.put("postgres", "PostgreSQL");
071: jenaDriverName.put("oracle", "Oracle");
072: jenaDriverName.put("hsqldb", "HSQLDB");
073: }
074:
075: boolean takesPositionalArgs = false;
076: String cmdName = "DB";
077: CommandLine cmdLine = new CommandLine();
078: private IDBConnection jdbcConnection = null;
079: private ModelRDB dbModel = null;
080:
081: private String[] usage = new String[] { "Complain to jena-dev: someone forgot the usage string" };
082:
083: protected DBcmd(String n, boolean posArgs) {
084: cmdName = n;
085: takesPositionalArgs = posArgs;
086: cmdLine.add(argDeclDbURL);
087: cmdLine.add(argDeclDbType);
088: cmdLine.add(argDeclDbUser);
089: cmdLine.add(argDeclDbPassword);
090: cmdLine.add(argDeclModelName);
091: cmdLine.add(argDeclVerbose);
092: cmdLine.add(argDeclDebug);
093: cmdLine.add(argDeclHelp);
094: }
095:
096: protected CommandLine getCommandLine() {
097: return cmdLine;
098: }
099:
100: protected void init(String[] args) {
101: try {
102: cmdLine.process(args);
103: } catch (IllegalArgumentException ex) {
104: usage();
105: System.exit(1);
106: }
107:
108: if (cmdLine.contains(argDeclHelp)) {
109: usage();
110: System.exit(0);
111: }
112:
113: verbose = cmdLine.contains(argDeclVerbose);
114: debug = cmdLine.contains(argDeclDebug);
115: if (debug)
116: verbose = true;
117:
118: if (cmdLine.contains(argDeclDbURL))
119: argDbURL = cmdLine.getArg(argDeclDbURL).getValue();
120:
121: if (cmdLine.contains(argDeclDbType))
122: argDbType = cmdLine.getArg(argDeclDbType).getValue();
123:
124: if (cmdLine.contains(argDeclDbUser))
125: argDbUser = cmdLine.getArg(argDeclDbUser).getValue();
126:
127: if (cmdLine.contains(argDeclDbPassword))
128: argDbPassword = cmdLine.getArg(argDeclDbPassword)
129: .getValue();
130:
131: if (cmdLine.contains(argDeclModelName))
132: argModelName = cmdLine.getArg(argDeclModelName).getValue();
133:
134: if (verbose) {
135: System.out.println("URL = " + argDbURL);
136: System.out.println("User = " + argDbUser);
137: System.out.println("Password = " + argDbPassword);
138: System.out.println("Type = " + argDbType);
139: System.out.println("Name = " + argModelName);
140: }
141:
142: // Mandatory arguments
143: if (argDbURL == null || argDbType == null || argDbUser == null
144: || argDbPassword == null) {
145: System.err
146: .println("Missing a required argument (need JDBC URL, user, password and DB type)");
147: System.exit(9);
148: }
149:
150: if (!takesPositionalArgs && cmdLine.numItems() != 0) {
151: System.err.println(cmdName
152: + ": No positional arguments allowed");
153: usage();
154: System.exit(9);
155: }
156:
157: if (takesPositionalArgs && cmdLine.numItems() == 0) {
158: System.err.println(cmdName
159: + ": Positional argument required");
160: usage();
161: System.exit(9);
162: }
163:
164: // Canonical form (for DBcmd)
165: argDbType = argDbType.toLowerCase();
166: argDriverName = (String) jdbcDrivers.get(argDbType);
167: argDriverTypeName = (String) jenaDriverName.get(argDbType);
168:
169: if (cmdLine.contains(argDeclDbDriver))
170: argDriverName = cmdLine.getArg(argDeclDbDriver).getValue();
171:
172: if (argDriverName == null) {
173: System.err
174: .println("No driver: please say which JDBC driver to use");
175: System.exit(9);
176: }
177:
178: try {
179: Class.forName(argDriverName);
180: } catch (Exception ex) {
181: System.err.println("Couldn't load the driver class: "
182: + argDriverName);
183: System.err.println("" + ex);
184: System.exit(9);
185: }
186:
187: }
188:
189: protected ModelRDB getRDBModel() {
190: if (dbModel == null) {
191: Model m = makeModel();
192: if (m instanceof ModelRDB)
193: dbModel = (ModelRDB) m;
194: else {
195: System.out
196: .println("Model maker didn't return a ModleRDB: ("
197: + m.getClass() + ")");
198: System.exit(9);
199: }
200: }
201: return dbModel;
202: }
203:
204: private ModelRDB makeModel() {
205: try {
206: // Want a ModelRDB and not the default reificiation mode.
207: if (argModelName != null && argModelName.equals("DEFAULT"))
208: argModelName = null;
209: GraphRDB graph = new GraphRDB(
210: getConnection(),
211: argModelName,
212: null,
213: GraphRDB.OPTIMIZE_AND_HIDE_FULL_AND_PARTIAL_REIFICATIONS,
214: false);
215: return new ModelRDB(BuiltinPersonalities.model, graph);
216: } catch (com.hp.hpl.jena.db.RDFRDBException dbEx) {
217: Throwable t = dbEx.getCause();
218: if (t == null)
219: t = dbEx;
220: System.out.println("Failed to connect to the database: "
221: + t.getMessage());
222: System.exit(9);
223: return null;
224: }
225: }
226:
227: protected void closeModel() {
228: if (dbModel != null)
229: dbModel.close();
230: dbModel = null;
231: }
232:
233: protected void closeConnection() {
234: try {
235: if (jdbcConnection != null)
236: jdbcConnection.close();
237: } catch (SQLException ex) {
238: System.err.println("Exception closing connection: "
239: + ex.getMessage());
240: System.exit(9);
241: }
242: }
243:
244: protected IDBConnection getConnection() {
245: if (jdbcConnection == null) {
246: try {
247: jdbcConnection = new DBConnection(argDbURL, argDbUser,
248: argDbPassword, argDriverTypeName);
249: } catch (Exception ex) {
250: System.out.println("Exception making connection: "
251: + ex.getMessage());
252: System.exit(9);
253: }
254: }
255: return jdbcConnection;
256: }
257:
258: protected void exec() {
259: try { // Close down
260: if (cmdLine.numItems() == 0) {
261: exec0();
262: return;
263: }
264:
265: boolean inTransaction = false;
266: try {
267: for (int i = 0; i < cmdLine.numItems(); i++) {
268: if (getRDBModel().supportsTransactions()) {
269: if (!inTransaction) {
270: inTransaction = true;
271: getRDBModel().begin();
272: }
273: }
274:
275: String arg = cmdLine.getItem(i);
276: boolean contTrans = false;
277: try {
278: contTrans = exec1(arg);
279: } catch (Exception ex) {
280: System.out.println(ex.getMessage());
281: ex.printStackTrace(System.out);
282: if (inTransaction) {
283: getRDBModel().abort();
284: inTransaction = false;
285: }
286: closeModel();
287: closeConnection();
288: System.exit(9);
289: }
290:
291: if (!contTrans && inTransaction)
292: getRDBModel().commit();
293: }
294: } finally {
295: if (inTransaction)
296: getRDBModel().commit();
297: }
298: } finally {
299: closeModel();
300: closeConnection();
301: }
302: }
303:
304: /** Called if there are no positional arguments
305: */
306: protected abstract void exec0();
307:
308: /** Called for each postional argument, inside a transaction.
309: * Return true to continue this transaction, false to end it and start a new
310: * one if there are any more args
311: */
312: protected abstract boolean exec1(String arg);
313:
314: protected void setUsage(String a) {
315: String[] aa = new String[] { a };
316: setUsage(aa);
317: }
318:
319: /** Usage message: one line per entry*/
320:
321: protected void setUsage(String[] a) {
322: usage = a;
323: }
324:
325: protected void usage() {
326: for (int i = 0; i < usage.length; i++) {
327: System.err.println(usage[i]);
328: }
329: }
330: }
331:
332: /*
333: * (c) Copyright 2003, 2004, 2005, 2006, 2007, 2008 Hewlett-Packard Development Company, LP
334: * All rights reserved.
335: *
336: * Redistribution and use in source and binary forms, with or without
337: * modification, are permitted provided that the following conditions
338: * are met:
339: * 1. Redistributions of source code must retain the above copyright
340: * notice, this list of conditions and the following disclaimer.
341: * 2. Redistributions in binary form must reproduce the above copyright
342: * notice, this list of conditions and the following disclaimer in the
343: * documentation and/or other materials provided with the distribution.
344: * 3. The name of the author may not be used to endorse or promote products
345: * derived from this software without specific prior written permission.
346: *
347: * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
348: * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
349: * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
350: * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
351: * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
352: * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
353: * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
354: * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
355: * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
356: * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
357: */
|