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 }