    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    }