001 //$HeadURL: svn+ssh://developername@svn.wald.intevation.org/deegree/base/trunk/src/org/deegree/tools/datastore/DBSchemaToDatastoreConf.java $ 002 /*---------------------------------------------------------------------------- 003 This file is part of deegree, http://deegree.org/ 004 Copyright (C) 2001-2009 by: 005 Department of Geography, University of Bonn 006 and 007 lat/lon GmbH 008 009 This library is free software; you can redistribute it and/or modify it under 010 the terms of the GNU Lesser General Public License as published by the Free 011 Software Foundation; either version 2.1 of the License, or (at your option) 012 any later version. 013 This library is distributed in the hope that it will be useful, but WITHOUT 014 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS 015 FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more 016 details. 017 You should have received a copy of the GNU Lesser General Public License 018 along with this library; if not, write to the Free Software Foundation, Inc., 019 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 020 021 Contact information: 022 023 lat/lon GmbH 024 Aennchenstr. 19, 53177 Bonn 025 Germany 026 http://lat-lon.de/ 027 028 Department of Geography, University of Bonn 029 Prof. Dr. Klaus Greve 030 Postfach 1147, 53001 Bonn 031 Germany 032 http://www.geographie.uni-bonn.de/deegree/ 033 034 e-mail: info@deegree.org 035 ----------------------------------------------------------------------------*/ 036 package org.deegree.tools.datastore; 037 038 import java.io.BufferedReader; 039 import java.io.File; 040 import java.io.FileOutputStream; 041 import java.io.IOException; 042 import java.io.InputStreamReader; 043 import java.io.StringReader; 044 import java.net.URL; 045 import java.security.InvalidParameterException; 046 import java.sql.Connection; 047 import java.sql.ResultSet; 048 import java.sql.ResultSetMetaData; 049 import java.sql.SQLException; 050 import java.sql.Statement; 051 import java.util.HashMap; 052 import java.util.Map; 053 054 import javax.xml.transform.TransformerException; 055 056 import org.deegree.datatypes.Types; 057 import org.deegree.datatypes.UnknownTypeException; 058 import org.deegree.framework.log.ILogger; 059 import org.deegree.framework.log.LoggerFactory; 060 import org.deegree.framework.util.FileUtils; 061 import org.deegree.framework.util.StringTools; 062 import org.deegree.framework.xml.XMLFragment; 063 import org.deegree.io.DBConnectionPool; 064 import org.deegree.io.DBPoolException; 065 import org.deegree.io.dbaseapi.DBaseException; 066 import org.deegree.io.shpapi.HasNoDBaseFileException; 067 import org.deegree.io.shpapi.ShapeFile; 068 import org.xml.sax.SAXException; 069 070 /** 071 * Example: java -classpath .;deegree.jar;$databasedriver.jar 072 * org.deegree.tools.datastore.DBSchemaToDatastoreConf -tables mytable,myothertable -user dev 073 * -password dev -driver oracle.jdbc.OracleDriver -url jdbc:oracle:thin:@localhost:1521:devs -output 074 * e:/temp/schema.xsd<br> 075 * or for shapefile:<br> 076 * java -classpath .;deegree.jar org.deegree.tools.datastore.DBSchemaToDatastoreConf -url 077 * c:/data/myshape -driver SHAPE -output e:/temp/schema.xsd<br> 078 * 079 * @author <a href="mailto:poth@lat-lon.de">Andreas Poth</a> 080 * @author last edited by: $Author: apoth $ 081 * 082 * @version $Revision: 8049 $, $Date: 2007-08-23 10:19:28 +0200 (Do, 23 Aug 2007) $ 083 */ 084 public class DBSchemaToDatastoreConf { 085 086 private static final ILogger LOG = LoggerFactory.getLogger( DBSchemaToDatastoreConf.class ); 087 088 private String[] tables; 089 090 private String user; 091 092 private String pw; 093 094 private String driver; 095 096 private String logon; 097 098 private String backend; 099 100 private String vendor; 101 102 private String srs; 103 104 private String defaultPKey; 105 106 private String insert; 107 108 private String update; 109 110 private String delete; 111 112 private String idGenerator; 113 114 private String sequence; 115 116 private Integer defaultSRID; 117 118 private String omitFidAsProperty; 119 120 /** 121 * 122 * @param tables 123 * list of table names used for one featuretype 124 * @param user 125 * database user 126 * @param pw 127 * users password 128 * @param driver 129 * database driver 130 * @param logon 131 * database URL/logon 132 * @param srs 133 * @throws IOException 134 */ 135 public DBSchemaToDatastoreConf( String[] tables, String user, String pw, String driver, String logon, String srs, 136 String pkey, Integer srid, String insert, String update, String delete, 137 String idGenerator, String sequence, String omitFidAsProperty ) throws IOException { 138 this.driver = driver; 139 this.logon = logon; 140 this.pw = pw; 141 this.user = user; 142 this.tables = tables; 143 if ( srs != null ) { 144 this.srs = srs; 145 } else { 146 this.srs = readUserInput( DBSchemaToDatastoreConfSQLMSGAccess.getMessage( "ENTERSRS" ), false ); 147 } 148 149 if ( driver.toUpperCase().indexOf( "ORACLE" ) > -1 ) { 150 backend = "ORACLE"; 151 vendor = backend; 152 } else if ( driver.toUpperCase().indexOf( "POSTGRES" ) > -1 ) { 153 backend = "POSTGIS"; 154 vendor = backend; 155 } else if ( driver.toUpperCase().contains( "SHAPE" ) ) { 156 backend = "SHAPE"; 157 vendor = backend; 158 } else { 159 backend = "GENERICSQL"; 160 vendor = getVendor( driver ); 161 } 162 this.defaultPKey = pkey; 163 this.defaultSRID = srid; 164 this.insert = insert; 165 this.delete = delete; 166 this.update = update; 167 this.idGenerator = idGenerator; 168 this.sequence = sequence; 169 this.omitFidAsProperty = omitFidAsProperty; 170 } 171 172 private String getVendor( String driver ) { 173 // find out which database is used 174 String vendor = null; 175 if ( driver.toUpperCase().contains( "POSTGRES" ) ) { 176 backend = "POSTGRES"; 177 } else if ( driver.toUpperCase().contains( "SQLSERVER" ) ) { 178 backend = "SQLSERVER"; 179 } else if ( driver.toUpperCase().contains( "INGRES" ) || driver.equals( "ca.edbc.jdbc.EdbcDriver" ) ) { 180 backend = "INGRES"; 181 } else if ( driver.toUpperCase().contains( "HSQLDB" ) ) { 182 backend = "HSQLDB"; 183 } else { 184 backend = "SHAPE"; 185 } 186 return vendor; 187 } 188 189 /** 190 * creates a schema/datastore configuration for accessin database table through deegree WFS 191 * 192 * @return a schema/datastore configuration for accessin database table through deegree WFS 193 * @throws Exception 194 */ 195 public String run() 196 throws Exception { 197 StringBuffer sb = new StringBuffer( 5000 ); 198 199 if ( backend.equals( "SHAPE" ) ) { 200 handleShape( sb ); 201 } else { 202 handleDatabase( sb ); 203 } 204 printFooter( sb ); 205 206 return sb.toString(); 207 } 208 209 /** 210 * creates a datastore configuration for a database backend 211 * 212 * @param sb 213 * @throws DBPoolException 214 * @throws SQLException 215 * @throws Exception 216 * @throws UnknownTypeException 217 * @throws IOException 218 */ 219 private void handleDatabase( StringBuffer sb ) 220 throws DBPoolException, SQLException, Exception, UnknownTypeException, IOException { 221 printHeader( sb ); 222 223 for ( int k = 0; k < tables.length; k++ ) { 224 LOG.logInfo( "Opening JDBC connection with driver: " + driver ); 225 LOG.logInfo( "Opening JDBC connection to database : " + logon ); 226 227 Connection con = DBConnectionPool.getInstance().acquireConnection( driver, logon, user, pw ); 228 Statement stmt = con.createStatement(); 229 // ensure that we do not get a filled resultset because we just 230 // need the metainformation 231 LOG.logDebug( "read table: ", tables[k] ); 232 ResultSet rs = stmt.executeQuery( "select * from " + tables[k] + " where 1 = 2" ); 233 234 ResultSetMetaData rsmd = rs.getMetaData(); 235 int cols = rsmd.getColumnCount(); 236 237 printComplexHeader( sb, tables[k] ); 238 for ( int i = 0; i < cols; i++ ) { 239 if ( rsmd.getColumnType( i + 1 ) != 2004 ) { 240 int tp = rsmd.getColumnType( i + 1 ); 241 String tpn = Types.getTypeNameForSQLTypeCode( tp ); 242 LOG.logDebug( tables[k] + '.' + rsmd.getColumnName( i + 1 ) + ": " + tpn ); 243 // add property just if type != BLOB 244 if ( !"true".equals( omitFidAsProperty ) 245 || !getPKeyName( tables[k] ).equalsIgnoreCase( rsmd.getColumnName( i + 1 ) ) ) { 246 printProperty( tables[k], rsmd.getColumnName( i + 1 ), rsmd.getColumnType( i + 1 ), tpn, 247 rsmd.getPrecision( i + 1 ), sb ); 248 } 249 } else { 250 String msg = StringTools.concat( 200, "skiped: ", tables[k], '.', rsmd.getColumnName( i + 1 ), 251 ": ", rsmd.getColumnTypeName( i + 1 ) ); 252 LOG.logDebug( msg ); 253 } 254 } 255 256 DBConnectionPool.getInstance().releaseConnection( con, driver, logon, user, pw ); 257 printComplexFooter( sb ); 258 } 259 } 260 261 /** 262 * creates a datastore configuration for a shapefile backend 263 * 264 * @param sb 265 * @throws IOException 266 * @throws Exception 267 * @throws HasNoDBaseFileException 268 * @throws DBaseException 269 * @throws DBPoolException 270 * @throws SQLException 271 * @throws UnknownTypeException 272 */ 273 private void handleShape( StringBuffer sb ) 274 throws IOException, Exception, HasNoDBaseFileException, DBaseException, DBPoolException, 275 SQLException, UnknownTypeException { 276 // TODO throw RE if tbl.len != 1 277 278 printShapeHeader( sb, tables[0] ); 279 280 File f = new File( tables[0] ); 281 ShapeFile shp = new ShapeFile( f.getAbsolutePath() ); 282 283 printComplexHeader( sb, f.getName() ); 284 285 String[] dataTypes = shp.getDataTypes(); 286 287 printProperty( f.getName(), "GEOM", 2002, "GEOM", -9999, sb ); 288 289 String[] props = shp.getProperties(); 290 for ( int i = 0; i < props.length; i++ ) { 291 int sqlCode = toSQLCode( dataTypes[i] ); 292 printProperty( tables[0], props[i], sqlCode, Types.getTypeNameForSQLTypeCode( sqlCode ), 293 toPrecision( dataTypes[i] ), sb ); 294 } 295 296 printComplexFooter( sb ); 297 298 shp.close(); 299 } 300 301 /** 302 * @return precision for a dBase numerical type 303 * 304 * @param dbfType 305 */ 306 private int toPrecision( String dbfType ) { 307 int precision = 0; 308 309 if ( dbfType.equalsIgnoreCase( "N" ) ) { 310 precision = 1; 311 } else if ( dbfType.equalsIgnoreCase( "F" ) ) { 312 precision = 2; 313 } 314 315 return precision; 316 } 317 318 /** 319 * @return the SQL type code for a dBase type char 320 * 321 * @param dbfType 322 */ 323 private int toSQLCode( String dbfType ) { 324 325 int type = -9999; 326 327 if ( dbfType.equalsIgnoreCase( "C" ) ) { 328 type = Types.VARCHAR; 329 } else if ( dbfType.equalsIgnoreCase( "F" ) || dbfType.equalsIgnoreCase( "N" ) ) { 330 type = Types.NUMERIC; 331 } else if ( dbfType.equalsIgnoreCase( "D" ) || dbfType.equalsIgnoreCase( "M" ) ) { 332 type = Types.DATE; 333 } else if ( dbfType.equalsIgnoreCase( "L" ) ) { 334 type = Types.BOOLEAN; 335 } else if ( dbfType.equalsIgnoreCase( "B" ) ) { 336 type = Types.BLOB; 337 } 338 339 if ( type == -9999 ) { 340 throw new RuntimeException( "Type '" + dbfType + "' is not suported." ); 341 } 342 343 return type; 344 } 345 346 /** 347 * adds the header of the configuration/schema for a database datastore 348 * 349 * @param sb 350 */ 351 private void printHeader( StringBuffer sb ) { 352 353 String s = DBSchemaToDatastoreConfSQLXSDAccess.getXSDFragment( "HEADER", backend, srs, driver, logon, user, pw ); 354 sb.append( s ); 355 356 } 357 358 /** 359 * adds the header of the configuration/schema for a shapefile datastore 360 * 361 * @param sb 362 * @param filename 363 * path to the shapefile 364 */ 365 private void printShapeHeader( StringBuffer sb, String filename ) { 366 367 String s = DBSchemaToDatastoreConfSQLXSDAccess.getXSDFragment( "SHAPEHEADER", filename, srs ); 368 sb.append( s ); 369 370 } 371 372 /** 373 * adds a header for a feature type to the schema 374 * 375 * @param sb 376 * @param table 377 * name of the table the feature type is assigned to 378 * @throws Exception 379 */ 380 private void printComplexHeader( StringBuffer sb, String table ) 381 throws Exception { 382 String idField = getPKeyName( table ); 383 String tp = "INTEGER"; 384 if ( backend.equals( "GENERICSQL" ) ) { 385 tp = "VARCHAR"; 386 } 387 String idg = ""; 388 if ( "DB_MAX".equalsIgnoreCase( idGenerator ) ) { 389 idg = DBSchemaToDatastoreConfSQLXSDAccess.getXSDFragment( "DB_MAX_IDGENERATOR", table, idField ); 390 } else if ( "DB_SEQ".equalsIgnoreCase( idGenerator ) && sequence != null ) { 391 idg = DBSchemaToDatastoreConfSQLXSDAccess.getXSDFragment( "DB_SEQ_IDGENERATOR", sequence ); 392 } 393 String s = DBSchemaToDatastoreConfSQLXSDAccess.getXSDFragment( "COMPLEXHEADER", table, table, table, idField, 394 tp, table, update, delete, insert, idg ); 395 sb.append( s ); 396 397 } 398 399 /** 400 * adds the footer of a feature type definition 401 * 402 * @param sb 403 */ 404 private void printComplexFooter( StringBuffer sb ) { 405 sb.append( DBSchemaToDatastoreConfSQLXSDAccess.getXSDFragment( "COMPLEXFOOTER" ) ); 406 } 407 408 /** 409 * prints XSD footer 410 * 411 * @param sb 412 */ 413 private void printFooter( StringBuffer sb ) { 414 sb.append( DBSchemaToDatastoreConfSQLXSDAccess.getXSDFragment( "FOOTER" ) ); 415 } 416 417 /** 418 * adds a property assigned to a database table field to the schema 419 * 420 * @param tableName 421 * table name 422 * @param name 423 * property name 424 * @param type 425 * xsd type name 426 * @param typeName 427 * SQL type name 428 * @param precision 429 * number precision if type is a number 430 * @param sb 431 * @throws SQLException 432 * @throws DBPoolException 433 * @throws IOException 434 */ 435 private void printProperty( String tableName, String name, int type, String typeName, int precision, StringBuffer sb ) 436 throws DBPoolException, SQLException, IOException { 437 438 String tp = Types.getXSDTypeForSQLType( type, precision ); 439 if ( !tp.startsWith( "gml:" ) ) { 440 tp = "xsd:" + tp; 441 } 442 443 if ( tp.equals( "gml:GeometryPropertyType" ) ) { 444 int srid = getSRID( tableName, name ); 445 String s = DBSchemaToDatastoreConfSQLXSDAccess.getXSDFragment( "GEOMPROPERTY", name.toLowerCase(), tp, 446 name, "" + srid ); 447 sb.append( s ); 448 } else { 449 String s = DBSchemaToDatastoreConfSQLXSDAccess.getXSDFragment( "PROPERTY", name.toLowerCase(), tp, name, 450 typeName.toUpperCase() ); 451 sb.append( s ); 452 } 453 } 454 455 private int getSRID( String tableName, String columnName ) 456 throws SQLException, DBPoolException, IOException { 457 458 if ( defaultSRID != null ) { 459 return defaultSRID; 460 } 461 462 int srid = -1; 463 String query = DBSchemaToDatastoreConfSQLSQLAccess.getSQLStatement( vendor + "_SRID", tableName.toUpperCase(), 464 columnName.toUpperCase() ); 465 LOG.logInfo( query ); 466 Connection con = null; 467 Statement stmt = null; 468 ResultSet rs = null; 469 if ( query != null && query.indexOf( "not found$" ) < 0 ) { 470 try { 471 con = DBConnectionPool.getInstance().acquireConnection( driver, logon, user, pw ); 472 stmt = con.createStatement(); 473 rs = stmt.executeQuery( query ); 474 475 while ( rs.next() ) { 476 srid = rs.getInt( 1 ); 477 } 478 479 if ( srid == 0 ) { 480 srid = -1; 481 } 482 483 } catch ( SQLException e ) { 484 System.out.println( DBSchemaToDatastoreConfSQLMSGAccess.getMessage( "ERRORSRID" ) + e.getMessage() ); 485 System.out.println( DBSchemaToDatastoreConfSQLMSGAccess.getMessage( "ENTERFIELD" ) ); 486 } finally { 487 rs.close(); 488 stmt.close(); 489 DBConnectionPool.getInstance().releaseConnection( con, driver, logon, user, pw ); 490 } 491 } else { 492 System.out.println( DBSchemaToDatastoreConfSQLMSGAccess.getMessage( "NOSRIDQUERY" ) ); 493 } 494 if ( srid == -1 ) { 495 String tmp = DBSchemaToDatastoreConfSQLMSGAccess.getMessage( "ENTERSRID" ); 496 srid = Integer.parseInt( readUserInput( tmp, false ) ); 497 } 498 return srid; 499 } 500 501 /** 502 * returns the name of the primary key of the passed table 503 * 504 * @param table 505 * @return the name of the primary key of the passed table 506 * @throws DBPoolException 507 * @throws SQLException 508 * @throws IOException 509 */ 510 private String getPKeyName( String table ) 511 throws DBPoolException, SQLException, IOException { 512 513 if ( defaultPKey != null ) { 514 return defaultPKey; 515 } 516 517 String query = DBSchemaToDatastoreConfSQLSQLAccess.getSQLStatement( vendor + "_ID", table.toUpperCase() ); 518 LOG.logInfo( query ); 519 Object id = null; 520 Statement stmt = null; 521 ResultSet rs = null; 522 if ( query != null && query.indexOf( "not found$" ) < 0 ) { 523 Connection con = DBConnectionPool.getInstance().acquireConnection( driver, logon, user, pw ); 524 try { 525 stmt = con.createStatement(); 526 rs = stmt.executeQuery( query ); 527 528 if ( rs.next() ) { 529 id = rs.getObject( 1 ); 530 } 531 } catch ( Exception e ) { 532 System.out.println( DBSchemaToDatastoreConfSQLMSGAccess.getMessage( "ERRORPK" ) + e.getMessage() ); 533 System.out.println( DBSchemaToDatastoreConfSQLMSGAccess.getMessage( "ENTERFIELD" ) ); 534 } finally { 535 rs.close(); 536 stmt.close(); 537 DBConnectionPool.getInstance().releaseConnection( con, driver, logon, user, pw ); 538 } 539 } else { 540 System.out.println( DBSchemaToDatastoreConfSQLMSGAccess.getMessage( "NOPKQUERY" ) ); 541 } 542 if ( id == null ) { 543 id = readUserInput( DBSchemaToDatastoreConfSQLMSGAccess.getMessage( "ENTERPK" ), false ); 544 } 545 return id.toString(); 546 } 547 548 private static void validate( Map<String, String> map ) 549 throws InvalidParameterException, IOException { 550 if ( map.get( "-?" ) != null || map.get( "-h" ) != null || map.get( "-help" ) != null ) { 551 printHelp(); 552 System.exit( 1 ); 553 } 554 if ( map.get( "-tables" ) == null ) { 555 String s = readUserInput( DBSchemaToDatastoreConfSQLMSGAccess.getMessage( "ENTERTABLES" ), false ); 556 map.put( "-tables", s ); 557 } 558 559 if ( map.get( "-driver" ) == null ) { 560 String s = readUserInput( DBSchemaToDatastoreConfSQLMSGAccess.getMessage( "ENTERDRIVER" ), false ); 561 map.put( "-driver", s ); 562 } 563 564 if ( map.get( "-user" ) == null ) { 565 if ( !"SHAPE".equals( map.get( "-driver" ) ) ) { 566 String s = readUserInput( DBSchemaToDatastoreConfSQLMSGAccess.getMessage( "ENTERUSER" ), false ); 567 map.put( "-user", s ); 568 } 569 } 570 571 if ( map.get( "-password" ) == null ) { 572 if ( !"SHAPE".equals( map.get( "-driver" ) ) ) { 573 String s = readUserInput( DBSchemaToDatastoreConfSQLMSGAccess.getMessage( "ENTERPASSWORD" ), false ); 574 map.put( "-password", s ); 575 } else { 576 map.put( "-password", " " ); 577 } 578 } 579 580 if ( map.get( "-url" ) == null && !"SHAPE".equalsIgnoreCase( (String) map.get( "-driver" ) ) ) { 581 String s = readUserInput( DBSchemaToDatastoreConfSQLMSGAccess.getMessage( "ENTERURL" ), false ); 582 map.put( "-url", s ); 583 } 584 if ( map.get( "-output" ) == null ) { 585 String s = readUserInput( DBSchemaToDatastoreConfSQLMSGAccess.getMessage( "ENTEROUTPUT" ), false ); 586 map.put( "-output", s ); 587 } 588 } 589 590 private static void printHelp() 591 throws IOException { 592 URL url = DBSchemaToDatastoreConf.class.getResource( "DBSchemaToDatastoreConfHelp.txt" ); 593 System.out.println( FileUtils.readTextFile( url ) ); 594 } 595 596 /** 597 * @param args 598 * @throws IOException 599 * @throws SAXException 600 * @throws TransformerException 601 * @throws Exception 602 */ 603 public static void main( String[] args ) 604 throws Exception { 605 606 Map<String, String> map = new HashMap<String, String>(); 607 for ( int i = 0; i < args.length; ) { 608 String first = args[i++]; 609 if ( "?".equals( first ) || "-h".equals( first ) || "-help".equals( first ) ) { 610 printHelp(); 611 System.exit( 0 ); 612 } 613 map.put( first, args[i++] ); 614 } 615 616 try { 617 validate( map ); 618 } catch ( InvalidParameterException ipe ) { 619 LOG.logError( ipe.getMessage() ); 620 printHelp(); 621 System.exit( 1 ); 622 } 623 LOG.logDebug( "Resulting commandline arguments and their values {argument=value, ...}: " + map ); 624 String tmp = (String) map.get( "-tables" ); 625 String[] tables = StringTools.toArray( tmp, ",;|", true ); 626 String user = (String) map.get( "-user" ); 627 String pw = (String) map.get( "-password" ); 628 String driver = (String) map.get( "-driver" ); 629 String url = (String) map.get( "-url" ); 630 String output = (String) map.get( "-output" ); 631 String srs = (String) map.get( "-srs" ); 632 String insert = "false"; 633 if ( "true".equalsIgnoreCase( map.get( "-insert" ) ) ) { 634 insert = "true"; 635 } 636 String delete = "false"; 637 if ( "true".equalsIgnoreCase( map.get( "-delete" ) ) ) { 638 delete = "true"; 639 } 640 String update = "false"; 641 if ( "true".equalsIgnoreCase( map.get( "-update" ) ) ) { 642 update = "true"; 643 } 644 String idGenerator = (String) map.get( "-idGenerator" ); 645 String sequence = (String) map.get( "-sequence" ); 646 647 String omitFidAsProperty = "false"; 648 if ( "true".equalsIgnoreCase( map.get( "-omitFidAsProperty" ) ) ) { 649 omitFidAsProperty = "true"; 650 } 651 652 // hidden parameters to ease bulk processing, if provided, these values determine 653 // primary key column name and srid for all tables 654 String pkey = (String) map.get( "-pkey" ); 655 String sridString = (String) map.get( "-srid" ); 656 Integer srid = null; 657 if ( sridString != null ) { 658 srid = Integer.parseInt( sridString ); 659 } 660 661 DBSchemaToDatastoreConf stc = new DBSchemaToDatastoreConf( tables, user, pw, driver, url, srs, pkey, srid, 662 insert, update, delete, idGenerator, sequence, 663 omitFidAsProperty ); 664 String conf = null; 665 try { 666 conf = stc.run(); 667 } catch ( Exception e ) { 668 LOG.logError( e.getMessage(), e ); 669 System.exit( 1 ); 670 } 671 storeSchema( output, conf ); 672 System.exit( 0 ); 673 } 674 675 /** 676 * 677 * @param output 678 * @param conf 679 * @throws IOException 680 * @throws SAXException 681 * @throws TransformerException 682 */ 683 private static void storeSchema( String output, String conf ) 684 throws SAXException, IOException, TransformerException { 685 if ( conf != null ) { 686 XMLFragment xml = new XMLFragment(); 687 xml.load( new StringReader( conf ), XMLFragment.DEFAULT_URL ); 688 FileOutputStream fos = new FileOutputStream( output ); 689 xml.prettyPrint( fos ); 690 fos.close(); 691 } 692 } 693 694 /** 695 * This function prints a message on the command line and asks the user for an input, returns 696 * the text the User has typed, null otherwise 697 * 698 * @param describtion 699 * The message to be displayed to the user asking for a certain text to type 700 * @return the read text, or null if nothing was read 701 * @throws IOException 702 */ 703 private static String readUserInput( String describtion, boolean acceptNull ) 704 throws IOException { 705 706 String result = null; 707 do { 708 System.out.print( describtion ); 709 System.out.println( ':' ); 710 BufferedReader reader = new BufferedReader( new InputStreamReader( System.in ) ); 711 result = reader.readLine(); 712 } while ( !acceptNull && ( result == null || result.trim().length() == 0 ) ); 713 return result; 714 715 } 716 }