1 22 23 package org.xquark.bridge; 24 25 import java.io.*; 26 import java.net.MalformedURLException ; 27 import java.net.URL ; 28 import java.net.URLClassLoader ; 29 import java.sql.SQLException ; 30 import java.util.*; 31 32 import javax.sql.DataSource ; 33 import javax.xml.parsers.ParserConfigurationException ; 34 import javax.xml.parsers.SAXParserFactory ; 35 36 import org.apache.log4j.Level; 37 import org.apache.log4j.Logger; 38 import org.xml.sax.SAXException ; 39 import org.xml.sax.XMLReader ; 40 import org.xquark.jdbc.datasource.JDBCDataSourceFactory; 41 import org.xquark.serialize.XMLSerializer; 42 import org.xquark.xml.xdbc.*; 43 44 49 public class Main { 50 51 private static final String RCSRevision = "$Revision: 1.2 $"; 52 private static final String RCSName = "$Name: $"; 53 54 private static final String HELP_OPT1 = "-help"; 55 private static final String HELP_OPT2 = "-?"; 56 private static final String CONF_OPT = "-conf"; 57 private static final String PROP_OPT1 = "-p"; 58 private static final String PROP_OPT2 = "-properties"; 59 private static final String DRIVER_OPT = "-driver"; 60 private static final String JDBC_OPT = "-db"; 61 private static final String JDBC_OPT2 = "-url"; 62 private static final String USER_OPT = "-user"; 63 private static final String PASSWORD_OPT = "-password"; 64 private static final String QUERY_OPT1 = "-query"; 65 private static final String QUERY_OPT2 = "-q"; 66 private static final String INSERT_OPT1 = "-insert"; 67 private static final String INSERT_OPT2 = "-i"; 68 private static final String FILE_OPT1 = "-file"; 69 private static final String FILE_OPT2 = "-f"; 70 private static final String DEBUG_OPT = "-debug"; 71 private static final String CLASSPATH_OPT1 = "-cp"; 72 private static final String CLASSPATH_OPT2 = "-classpath"; 73 74 private static SAXParserFactory parserFactory; 75 76 static { 77 parserFactory = SAXParserFactory.newInstance(); 78 parserFactory.setNamespaceAware(true); 79 } 80 81 82 83 88 public static void main(String [] args) { 89 String propFile = "XQBridge.properties"; 90 boolean defaultPropFile = true; 91 String configFile = null; 92 String batchFile = null; 93 String driver = null; 94 String url = null; 95 String user = null; 96 String password = null; 97 String classpath = null; 98 ClassLoader classloader = XQBridge.class.getClassLoader(); 99 boolean isQuery = false; 100 boolean isInsert = false; 101 ArrayList parameters = new ArrayList(); 102 103 for (int i = 0; i < args.length; i++) { 104 if (!args[i].startsWith("-")) { 105 parameters.add(args[i]); 107 } else { 108 if (parameters.size() > 0) { 110 usage(); 111 System.err.println("Options must appear before the command parameters."); 112 System.exit(-1); 113 } 114 if (HELP_OPT1.equals(args[i]) || HELP_OPT2.equals(args[i])) { 116 usage(); 117 System.exit(0); 118 } else if (QUERY_OPT1.equals(args[i]) || QUERY_OPT2.equals(args[i])) { 119 isQuery = true; 120 } else if (INSERT_OPT1.equals(args[i]) || INSERT_OPT2.equals(args[i])) { 121 isInsert = true; 122 } else { 123 if (i + 1 == args.length) { 125 System.err.println("Missing value for option " + args[i]); 126 usage(); 127 System.exit(-1); 128 } 129 if (CONF_OPT.equals(args[i])) { 130 configFile = args[++i]; 131 } else if (PROP_OPT1.equals(args[i]) || PROP_OPT2.equals(args[i])) { 132 propFile = args[++i]; 133 defaultPropFile = false; 134 } else if (DEBUG_OPT.equals(args[i])) { 135 Logger.getRootLogger().setLevel(Level.DEBUG); 136 } else if (FILE_OPT1.equals(args[i]) || FILE_OPT2.equals(args[i])) { 137 batchFile = args[++i]; 138 } else if (DRIVER_OPT.equals(args[i])) { 139 driver = args[++i]; 140 } else if (JDBC_OPT.equals(args[i]) || JDBC_OPT2.equals(args[i])) { 141 url = args[++i]; 142 } else if (USER_OPT.equals(args[i])) { 143 user = args[++i]; 144 } else if (PASSWORD_OPT.equals(args[i])) { 145 password = args[++i]; 146 } else if (CLASSPATH_OPT1.equals(args[i]) || CLASSPATH_OPT2.equals(args[i])) { 147 classpath = args[++i]; 148 } else { 149 System.err.println("Invalid option " + args[i]); 151 usage(); 152 System.exit(-1); 153 } 154 } 155 } 156 } 157 if (isQuery == isInsert) { 158 System.err.println("One and only one of -q(uery) and -i(nsert) must be specified"); 159 System.exit(-1); 160 } 161 162 Properties props = new Properties(); 163 try { 164 props.load(new FileInputStream(propFile)); 165 } catch (IOException e) { 166 InputStream inStream = null; 167 try { 168 inStream = XQBridge.class.getResourceAsStream("/" + propFile); 169 if (inStream != null) 170 props.load(inStream); 171 } catch (IOException ex) { 172 inStream = null; 173 } 174 if (configFile == null && inStream == null && (url == null || user == null || password == null)) { 175 System.err.println("error : configuration file " + propFile + " couldn't be found."); 176 System.err.println("(neither using file name nor in CLASSPATH root)"); 177 System.exit(-1); 178 } 179 } 180 181 if (configFile == null || !defaultPropFile) { 182 if (driver == null) 183 driver = props.getProperty("database.driver"); 184 if (url == null) 185 url = props.getProperty("database.url"); 186 if (user == null) 187 user = props.getProperty("database.user"); 188 if (password == null) 189 password = props.getProperty("database.password"); 190 } 191 192 if (classpath == null) 193 classpath = props.getProperty("xqbridge.classpath"); 194 195 if (classpath != null) { 196 classloader = new URLClassLoader (parseClassPath(classpath), classloader); 197 } 198 199 DataSource ds = null; 200 if (url != null && user != null && password != null) { 201 try { 202 JDBCDataSourceFactory dsf = JDBCDataSourceFactory.newInstance(classloader); 203 ds = dsf.newDataSource(driver, url, user, password); 204 } catch (SQLException ex) { 205 ds = null; 206 } 207 } 208 209 XQBridge bridge = null; 210 if (ds == null) { 211 if (configFile == null) { 212 System.err.println("Could not connect to database " + url + ". Check your JDBC parameters."); 213 System.exit(-1); 214 } 215 bridge = new XQBridge(new File(configFile)); 216 } else { 217 if (configFile == null) { 218 bridge = new XQBridge(ds); 219 } else { 220 bridge = new XQBridge(ds, new File(configFile)); 221 } 222 } 223 224 bridge.setClassLoader(classloader); 225 226 List parametersList = null; 227 if (batchFile != null) { 228 parametersList = parseBatchFile(batchFile, isQuery); 229 } else { 230 checkParameters(parameters, isQuery); 231 parametersList = new ArrayList(1); 232 parametersList.add(parameters); 233 } 234 int result = 0; 235 if (isQuery) { 236 result = executeQuery(bridge, parametersList); 237 } else { 238 result = executeInsert(bridge, parametersList); 239 } 240 System.exit(result); 241 } 242 243 private static void checkParameters(List params, boolean isQuery) { 244 int size = params.size(); 245 if (isQuery) { 246 if ((isQuery && (size < 1 || size > 2)) || (!isQuery && size < 2)) { 247 System.err.println("Wrong number of parameters."); 248 System.exit(-1); 249 } 250 } 251 } 252 253 private static List parseBatchFile(String batchFile, boolean isQuery) { 254 ArrayList result = new ArrayList(); 255 BufferedReader reader = null; 256 try { 257 File f = new File(batchFile); 258 reader = new BufferedReader(new FileReader(f)); 259 } catch (IOException ex) { 260 System.err.println("Could not find specified batch file"); 261 System.exit(-1); 262 } 263 try { 264 while (true) { 265 String line = reader.readLine(); 266 if (line == null) 267 break; 268 if (line.startsWith("#") || line.trim().length() == 0) 269 continue; 270 java.util.StringTokenizer it = new java.util.StringTokenizer (line); 271 ArrayList params = new ArrayList(); 272 while (it.hasMoreTokens()) { 273 params.add(it.nextToken()); 274 } 275 checkParameters(params, isQuery); 276 result.add(params); 277 } 278 } catch (IOException e) { 279 System.err.println("Error while reading specified batch file"); 280 System.exit(-1); 281 } 282 return result; 283 } 284 285 private static String readQueryFile(String fileName) { 286 try { 287 StringBuffer retVal = new StringBuffer (); 288 String tmpStr; 289 BufferedReader in = new BufferedReader(new FileReader(fileName)); 290 while ((tmpStr = in.readLine()) != null) { 291 if (retVal.length() > 0) 292 retVal.append('\n'); 293 retVal.append(tmpStr); 294 } 295 in.close(); 296 return retVal.toString(); 297 } catch (FileNotFoundException ex) { 298 System.err.println("Could not find query file " + fileName); 299 } catch (IOException ex) { 300 System.err.println("Error while reading query file " + fileName); 301 } 302 return null; 303 } 304 305 private static int executeQuery(XQBridge bridge, List parametersList) { 306 int result = 0; 307 XMLConnection connection = null; 308 XMLStatement stat = null; 309 try { 310 connection = bridge.getXMLConnection(); 311 stat = connection.createStatement(); 312 } catch (XMLDBCException ex) { 313 System.err.println("Error while creating XQuery statement"); 314 printError(ex); 315 result = -1; 316 } 317 Iterator it = parametersList.iterator(); 318 while (it.hasNext()) { 319 List params = (List) it.next(); 320 String queryFile = (String ) params.get(0); 321 String resultFile = null; 322 if (params.size() > 1) 323 resultFile = (String ) params.get(1); 324 String query = readQueryFile(queryFile); 325 if (query != null) { 326 OutputStream out = System.out; 327 try { 328 if (resultFile != null) { 329 out = new BufferedOutputStream(new FileOutputStream(new File(resultFile))); 330 } 331 } catch (IOException ex) { 332 out = null; 333 System.err.println("Could not open result file " + resultFile); 334 result = -1; 335 } 336 if (out != null) { 337 try { 338 stat.setBaseURI(new File(queryFile).toURL().toString()); 339 XMLResultSet rs = stat.executeQuery(query); 340 XMLSerializer handler = new XMLSerializer(out); 341 rs.setContentHandler(handler); 342 handler.startDocument(); 343 long rtime = System.currentTimeMillis(); 344 while (rs.hasNext()) 345 rs.nextAsSAX(); 346 handler.endDocument(); 347 rs.close(); 348 if (out != System.out) 349 out.close(); 350 } catch (MalformedURLException e) { 351 System.err.println("Error while accessing query file " + queryFile); 352 printError(e); 353 result = -1; 354 } catch (XMLDBCException e) { 355 System.err.println("Error while processing query file " + queryFile); 356 printError(e); 357 result = -1; 358 } catch (UnsupportedEncodingException e) { 359 System.err.println("Illegal encoding for query result for " + queryFile); 360 printError(e); 361 result = -1; 362 } catch (SAXException e) { 363 System.err.println("Error while processing query result for " + queryFile); 364 printError(e); 365 result = -1; 366 } catch (IOException e) { 367 System.err.println("Error while closing result stream"); 368 printError(e); 369 result = -1; 370 } 371 } 372 } else { 373 result = -1; 374 } 375 } 376 try { 377 if (stat != null) 378 stat.close(); 379 } catch (XMLDBCException ex) { 380 System.err.println("Error while closing XQuery statement"); 381 printError(ex); 382 result = -1; 383 } 384 return result; 385 } 386 387 private static int executeInsert(XQBridge bridge, List parametersList) { 388 int result = 0; 389 Iterator it = parametersList.iterator(); 390 while (it.hasNext()) { 391 List params = (List) it.next(); 392 String mapFile = (String ) params.get(0); 393 Mapping mapping = null; 394 try { 395 mapping = bridge.getMapping(mapFile); 396 } catch (XMLDBCException ex) { 397 System.err.println("Error while loading mapping file " + mapFile); 398 printError(ex); 399 result = -1; 400 } 401 if (mapping != null) { 402 String xmlFile = null; 403 try { 404 Mapper mapper = mapping.getMapper(); 405 XMLReader reader = parserFactory.newSAXParser().getXMLReader(); 406 reader.setContentHandler(mapper); 407 for (int i = 1; i < params.size(); i++) { 408 xmlFile = (String ) params.get(i); 409 reader.parse(xmlFile); 410 } 411 mapper.close(); 412 mapping.close(); 413 } catch (XMLDBCException ex) { 414 System.err.println("Error while accessing mapping information for " + xmlFile); 415 printError(ex); 416 result = -1; 417 } catch (SAXException ex) { 418 System.err.println("Error while processing XML file " + xmlFile); 419 printError(ex); 420 result = -1; 421 } catch (ParserConfigurationException ex) { 422 System.err.println("Cannot create XML parser for " + xmlFile); 423 printError(ex); 424 result = -1; 425 } catch (IOException ex) { 426 System.err.println("Error while accessing XML file " + xmlFile); 427 printError(ex); 428 result = -1; 429 } 430 } 431 } 432 return result; 433 } 434 435 438 private static void printError(Throwable e) { 439 XMLDBCException.printError(e, Logger.getRootLogger().isDebugEnabled()); 440 } 441 442 private static URL [] parseClassPath(String classpath) { 443 String pathSeparator = System.getProperty("path.separator"); 444 ArrayList urls = new ArrayList(); 445 if (classpath != null) { 446 StringTokenizer tokenizer = new StringTokenizer(classpath, pathSeparator); 447 while (tokenizer.hasMoreTokens()) { 448 File file = new File(tokenizer.nextToken()); 449 try { 450 urls.add(file.getCanonicalFile().toURL()); 451 } catch (MalformedURLException e) { 452 } catch (IOException e) { 453 } 454 } 455 } 456 return (URL []) urls.toArray(new URL [0]); 457 } 458 459 private static void usage() { 460 System.out.println("Usage: java org.xquark.bridge.XQBridge -q(uery) <common options> <file1> [<file2>]"); 461 System.out.println(" java org.xquark.bridge.XQBridge -i(nsert) <common options> <file1> <file2> [filei]*"); 462 System.out.println(); 463 System.out.println("-q, -query: query mode"); 464 System.out.println("file1: XQuery file"); 465 System.out.println("file2: optional output file, output to stdout by default"); 466 System.out.println(); 467 System.out.println("-i, -insert: mapping mode"); 468 System.out.println("file1: mapping file"); 469 System.out.println("file2: XML document to be inserted according to the mapping"); 470 System.out.println("filei: optional additional XML documents to be inserted according to the mapping"); 471 System.out.println(); 472 System.out.println("Common options:"); 473 System.out.println("-?, -help: this message"); 474 System.out.println("-conf: XQBridge configuration file (see manual for details)."); 475 System.out.println("-p, properties: properties file containing database connection information."); 476 System.out.println("-driver: JDBC driver."); 477 System.out.println("-db, -url: JDBC database URL."); 478 System.out.println("-user: database user name."); 479 System.out.println("-password: database user password."); 480 System.out.println("-cp, -classpath: classpath used to load JDBC drivers and user generators."); 481 System.out.println("-f, file: file containing a list of files to be processed."); 482 System.out.println(" Each line of the file has the number of files described above, according to the mode."); 483 System.out.println(" Lines starting with # are comments"); 484 } 485 486 487 488 } 489 | Popular Tags |