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 + " " + rsmd.getPrecision( i + 1 ) + " " + rsmd.getScale( i + 1 ) );
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 ), rsmd.getScale( 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, -9999, sb );
288
289 String[] props = shp.getProperties();
290 for ( int i = 0; i < props.length; i++ ) {
291 int sqlCode = toSQLCode( dataTypes[i] ), precision, scale;
292 printProperty( tables[0], props[i], sqlCode, Types.getTypeNameForSQLTypeCode( sqlCode ),
293 1, toScale( dataTypes[i] ), sb );
294 }
295
296 printComplexFooter( sb );
297
298 shp.close();
299 }
300
301 /**
302 * @return scale for a dBase numerical type
303 *
304 * @param dbfType
305 */
306 private int toScale( String dbfType ) {
307 int precision = 0;
308
309 if ( dbfType.equalsIgnoreCase( "I" ) ) {
310 precision = 1;
311 }
312
313 return precision;
314 }
315
316 /**
317 * @return the SQL type code for a dBase type char
318 *
319 * @param dbfType
320 */
321 private int toSQLCode( String dbfType ) {
322
323 int type = -9999;
324
325 if ( dbfType.equalsIgnoreCase( "C" ) ) {
326 type = Types.VARCHAR;
327 } else if ( dbfType.equalsIgnoreCase( "F" ) || dbfType.equalsIgnoreCase( "N" )
328 || dbfType.equalsIgnoreCase( "I" ) ) {
329 type = Types.NUMERIC;
330 } else if ( dbfType.equalsIgnoreCase( "D" ) || dbfType.equalsIgnoreCase( "M" ) ) {
331 type = Types.DATE;
332 } else if ( dbfType.equalsIgnoreCase( "L" ) ) {
333 type = Types.BOOLEAN;
334 } else if ( dbfType.equalsIgnoreCase( "B" ) ) {
335 type = Types.BLOB;
336 }
337
338 if ( type == -9999 ) {
339 throw new RuntimeException( "Type '" + dbfType + "' is not suported." );
340 }
341
342 return type;
343 }
344
345 /**
346 * adds the header of the configuration/schema for a database datastore
347 *
348 * @param sb
349 */
350 private void printHeader( StringBuffer sb ) {
351
352 String s = DBSchemaToDatastoreConfSQLXSDAccess.getXSDFragment( "HEADER", backend, srs, driver, logon, user, pw );
353 sb.append( s );
354
355 }
356
357 /**
358 * adds the header of the configuration/schema for a shapefile datastore
359 *
360 * @param sb
361 * @param filename
362 * path to the shapefile
363 */
364 private void printShapeHeader( StringBuffer sb, String filename ) {
365
366 String s = DBSchemaToDatastoreConfSQLXSDAccess.getXSDFragment( "SHAPEHEADER", filename, srs );
367 sb.append( s );
368
369 }
370
371 /**
372 * adds a header for a feature type to the schema
373 *
374 * @param sb
375 * @param table
376 * name of the table the feature type is assigned to
377 * @throws Exception
378 */
379 private void printComplexHeader( StringBuffer sb, String table )
380 throws Exception {
381 String idField = getPKeyName( table );
382 String tp = "INTEGER";
383 if ( backend.equals( "GENERICSQL" ) ) {
384 tp = "VARCHAR";
385 }
386 String idg = "";
387 if ( "DB_MAX".equalsIgnoreCase( idGenerator ) ) {
388 idg = DBSchemaToDatastoreConfSQLXSDAccess.getXSDFragment( "DB_MAX_IDGENERATOR", table, idField );
389 } else if ( "DB_SEQ".equalsIgnoreCase( idGenerator ) && sequence != null ) {
390 idg = DBSchemaToDatastoreConfSQLXSDAccess.getXSDFragment( "DB_SEQ_IDGENERATOR", sequence );
391 }
392 String s = DBSchemaToDatastoreConfSQLXSDAccess.getXSDFragment( "COMPLEXHEADER", table, table, table, idField,
393 tp, table, update, delete, insert, idg );
394 sb.append( s );
395
396 }
397
398 /**
399 * adds the footer of a feature type definition
400 *
401 * @param sb
402 */
403 private void printComplexFooter( StringBuffer sb ) {
404 sb.append( DBSchemaToDatastoreConfSQLXSDAccess.getXSDFragment( "COMPLEXFOOTER" ) );
405 }
406
407 /**
408 * prints XSD footer
409 *
410 * @param sb
411 */
412 private void printFooter( StringBuffer sb ) {
413 sb.append( DBSchemaToDatastoreConfSQLXSDAccess.getXSDFragment( "FOOTER" ) );
414 }
415
416 /**
417 * adds a property assigned to a database table field to the schema
418 *
419 * @param tableName
420 * table name
421 * @param name
422 * property name
423 * @param type
424 * xsd type name
425 * @param typeName
426 * SQL type name
427 * @param precision
428 * number precision if type is a number
429 * @param sb
430 * @throws SQLException
431 * @throws DBPoolException
432 * @throws IOException
433 */
434 private void printProperty( String tableName, String name, int type, String typeName, int precision, int scale, StringBuffer sb )
435 throws DBPoolException, SQLException, IOException {
436
437 String tp = Types.getXSDTypeForSQLType( type, precision, scale );
438 if ( !tp.startsWith( "gml:" ) ) {
439 tp = "xsd:" + tp;
440 }
441
442 if ( tp.equals( "gml:GeometryPropertyType" ) ) {
443 int srid = getSRID( tableName, name );
444 String s = DBSchemaToDatastoreConfSQLXSDAccess.getXSDFragment( "GEOMPROPERTY", name.toLowerCase(), tp,
445 name, "" + srid );
446 sb.append( s );
447 } else {
448 String s = DBSchemaToDatastoreConfSQLXSDAccess.getXSDFragment( "PROPERTY", name.toLowerCase(), tp, name,
449 typeName.toUpperCase() );
450 sb.append( s );
451 }
452 }
453
454 private int getSRID( String tableName, String columnName )
455 throws SQLException, DBPoolException, IOException {
456
457 if ( defaultSRID != null ) {
458 return defaultSRID;
459 }
460
461 int srid = -1;
462 String query = DBSchemaToDatastoreConfSQLSQLAccess.getSQLStatement( vendor + "_SRID", tableName.toUpperCase(),
463 columnName.toUpperCase() );
464 LOG.logInfo( query );
465 Connection con = null;
466 Statement stmt = null;
467 ResultSet rs = null;
468 if ( query != null && query.indexOf( "not found$" ) < 0 ) {
469 try {
470 con = DBConnectionPool.getInstance().acquireConnection( driver, logon, user, pw );
471 stmt = con.createStatement();
472 rs = stmt.executeQuery( query );
473
474 while ( rs.next() ) {
475 srid = rs.getInt( 1 );
476 }
477
478 if ( srid == 0 ) {
479 srid = -1;
480 }
481
482 } catch ( SQLException e ) {
483 System.out.println( DBSchemaToDatastoreConfSQLMSGAccess.getMessage( "ERRORSRID" ) + e.getMessage() );
484 System.out.println( DBSchemaToDatastoreConfSQLMSGAccess.getMessage( "ENTERFIELD" ) );
485 } finally {
486 rs.close();
487 stmt.close();
488 DBConnectionPool.getInstance().releaseConnection( con, driver, logon, user, pw );
489 }
490 } else {
491 System.out.println( DBSchemaToDatastoreConfSQLMSGAccess.getMessage( "NOSRIDQUERY" ) );
492 }
493 if ( srid == -1 ) {
494 String tmp = DBSchemaToDatastoreConfSQLMSGAccess.getMessage( "ENTERSRID" );
495 srid = Integer.parseInt( readUserInput( tmp, false ) );
496 }
497 return srid;
498 }
499
500 /**
501 * returns the name of the primary key of the passed table
502 *
503 * @param table
504 * @return the name of the primary key of the passed table
505 * @throws DBPoolException
506 * @throws SQLException
507 * @throws IOException
508 */
509 private String getPKeyName( String table )
510 throws DBPoolException, SQLException, IOException {
511
512 if ( defaultPKey != null ) {
513 return defaultPKey;
514 }
515
516 String query = DBSchemaToDatastoreConfSQLSQLAccess.getSQLStatement( vendor + "_ID", table.toUpperCase() );
517 LOG.logInfo( query );
518 Object id = null;
519 Statement stmt = null;
520 ResultSet rs = null;
521 if ( query != null && query.indexOf( "not found$" ) < 0 ) {
522 Connection con = DBConnectionPool.getInstance().acquireConnection( driver, logon, user, pw );
523 try {
524 stmt = con.createStatement();
525 rs = stmt.executeQuery( query );
526
527 if ( rs.next() ) {
528 id = rs.getObject( 1 );
529 }
530 } catch ( Exception e ) {
531 System.out.println( DBSchemaToDatastoreConfSQLMSGAccess.getMessage( "ERRORPK" ) + e.getMessage() );
532 System.out.println( DBSchemaToDatastoreConfSQLMSGAccess.getMessage( "ENTERFIELD" ) );
533 } finally {
534 rs.close();
535 stmt.close();
536 DBConnectionPool.getInstance().releaseConnection( con, driver, logon, user, pw );
537 }
538 } else {
539 System.out.println( DBSchemaToDatastoreConfSQLMSGAccess.getMessage( "NOPKQUERY" ) );
540 }
541 if ( id == null ) {
542 id = readUserInput( DBSchemaToDatastoreConfSQLMSGAccess.getMessage( "ENTERPK" ), false );
543 }
544 return id.toString();
545 }
546
547 private static void validate( Map<String, String> map )
548 throws InvalidParameterException, IOException {
549 if ( map.get( "-?" ) != null || map.get( "-h" ) != null || map.get( "-help" ) != null ) {
550 printHelp();
551 System.exit( 1 );
552 }
553 if ( map.get( "-tables" ) == null ) {
554 String s = readUserInput( DBSchemaToDatastoreConfSQLMSGAccess.getMessage( "ENTERTABLES" ), false );
555 map.put( "-tables", s );
556 }
557
558 if ( map.get( "-driver" ) == null ) {
559 String s = readUserInput( DBSchemaToDatastoreConfSQLMSGAccess.getMessage( "ENTERDRIVER" ), false );
560 map.put( "-driver", s );
561 }
562
563 if ( map.get( "-user" ) == null ) {
564 if ( !"SHAPE".equals( map.get( "-driver" ) ) ) {
565 String s = readUserInput( DBSchemaToDatastoreConfSQLMSGAccess.getMessage( "ENTERUSER" ), false );
566 map.put( "-user", s );
567 }
568 }
569
570 if ( map.get( "-password" ) == null ) {
571 if ( !"SHAPE".equals( map.get( "-driver" ) ) ) {
572 String s = readUserInput( DBSchemaToDatastoreConfSQLMSGAccess.getMessage( "ENTERPASSWORD" ), false );
573 map.put( "-password", s );
574 } else {
575 map.put( "-password", " " );
576 }
577 }
578
579 if ( map.get( "-url" ) == null && !"SHAPE".equalsIgnoreCase( (String) map.get( "-driver" ) ) ) {
580 String s = readUserInput( DBSchemaToDatastoreConfSQLMSGAccess.getMessage( "ENTERURL" ), false );
581 map.put( "-url", s );
582 }
583 if ( map.get( "-output" ) == null ) {
584 String s = readUserInput( DBSchemaToDatastoreConfSQLMSGAccess.getMessage( "ENTEROUTPUT" ), false );
585 map.put( "-output", s );
586 }
587 }
588
589 private static void printHelp()
590 throws IOException {
591 URL url = DBSchemaToDatastoreConf.class.getResource( "DBSchemaToDatastoreConfHelp.txt" );
592 System.out.println( FileUtils.readTextFile( url ) );
593 }
594
595 /**
596 * @param args
597 * @throws IOException
598 * @throws SAXException
599 * @throws TransformerException
600 * @throws Exception
601 */
602 public static void main( String[] args )
603 throws Exception {
604
605 Map<String, String> map = new HashMap<String, String>();
606 for ( int i = 0; i < args.length; ) {
607 String first = args[i++];
608 if ( "?".equals( first ) || "-h".equals( first ) || "-help".equals( first ) ) {
609 printHelp();
610 System.exit( 0 );
611 }
612 map.put( first, args[i++] );
613 }
614
615 try {
616 validate( map );
617 } catch ( InvalidParameterException ipe ) {
618 LOG.logError( ipe.getMessage() );
619 printHelp();
620 System.exit( 1 );
621 }
622 LOG.logDebug( "Resulting commandline arguments and their values {argument=value, ...}: " + map );
623 String tmp = (String) map.get( "-tables" );
624 String[] tables = StringTools.toArray( tmp, ",;|", true );
625 String user = (String) map.get( "-user" );
626 String pw = (String) map.get( "-password" );
627 String driver = (String) map.get( "-driver" );
628 String url = (String) map.get( "-url" );
629 String output = (String) map.get( "-output" );
630 String srs = (String) map.get( "-srs" );
631 String insert = "false";
632 if ( "true".equalsIgnoreCase( map.get( "-insert" ) ) ) {
633 insert = "true";
634 }
635 String delete = "false";
636 if ( "true".equalsIgnoreCase( map.get( "-delete" ) ) ) {
637 delete = "true";
638 }
639 String update = "false";
640 if ( "true".equalsIgnoreCase( map.get( "-update" ) ) ) {
641 update = "true";
642 }
643 String idGenerator = (String) map.get( "-idGenerator" );
644 String sequence = (String) map.get( "-sequence" );
645
646 String omitFidAsProperty = "false";
647 if ( "true".equalsIgnoreCase( map.get( "-omitFidAsProperty" ) ) ) {
648 omitFidAsProperty = "true";
649 }
650
651 // hidden parameters to ease bulk processing, if provided, these values determine
652 // primary key column name and srid for all tables
653 String pkey = (String) map.get( "-pkey" );
654 String sridString = (String) map.get( "-srid" );
655 Integer srid = null;
656 if ( sridString != null ) {
657 srid = Integer.parseInt( sridString );
658 }
659
660 DBSchemaToDatastoreConf stc = new DBSchemaToDatastoreConf( tables, user, pw, driver, url, srs, pkey, srid,
661 insert, update, delete, idGenerator, sequence,
662 omitFidAsProperty );
663 String conf = null;
664 try {
665 conf = stc.run();
666 } catch ( Exception e ) {
667 LOG.logError( e.getMessage(), e );
668 System.exit( 1 );
669 }
670 storeSchema( output, conf );
671 System.exit( 0 );
672 }
673
674 /**
675 *
676 * @param output
677 * @param conf
678 * @throws IOException
679 * @throws SAXException
680 * @throws TransformerException
681 */
682 private static void storeSchema( String output, String conf )
683 throws SAXException, IOException, TransformerException {
684 if ( conf != null ) {
685 XMLFragment xml = new XMLFragment();
686 xml.load( new StringReader( conf ), XMLFragment.DEFAULT_URL );
687 FileOutputStream fos = new FileOutputStream( output );
688 xml.prettyPrint( fos );
689 fos.close();
690 }
691 }
692
693 /**
694 * This function prints a message on the command line and asks the user for an input, returns
695 * the text the User has typed, null otherwise
696 *
697 * @param describtion
698 * The message to be displayed to the user asking for a certain text to type
699 * @return the read text, or null if nothing was read
700 * @throws IOException
701 */
702 private static String readUserInput( String describtion, boolean acceptNull )
703 throws IOException {
704
705 String result = null;
706 do {
707 System.out.print( describtion );
708 System.out.println( ':' );
709 BufferedReader reader = new BufferedReader( new InputStreamReader( System.in ) );
710 result = reader.readLine();
711 } while ( !acceptNull && ( result == null || result.trim().length() == 0 ) );
712 return result;
713
714 }
715 }