001    //$HeadURL: svn+ssh://developername@svn.wald.intevation.org/deegree/base/trunk/resources/eclipse/files_template.xml $
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.portal.cataloguemanager.control;
037    
038    import java.io.BufferedReader;
039    import java.io.File;
040    import java.io.FileInputStream;
041    import java.io.FileOutputStream;
042    import java.io.FileReader;
043    import java.io.IOException;
044    import java.net.URI;
045    import java.nio.charset.Charset;
046    import java.sql.Connection;
047    import java.sql.Statement;
048    import java.util.List;
049    import java.util.Properties;
050    
051    import org.deegree.enterprise.control.ajax.AbstractListener;
052    import org.deegree.enterprise.control.ajax.ResponseHandler;
053    import org.deegree.enterprise.control.ajax.WebEvent;
054    import org.deegree.framework.log.ILogger;
055    import org.deegree.framework.log.LoggerFactory;
056    import org.deegree.framework.util.FileUtils;
057    import org.deegree.framework.xml.NamespaceContext;
058    import org.deegree.framework.xml.XMLFragment;
059    import org.deegree.framework.xml.XMLParsingException;
060    import org.deegree.framework.xml.XMLTools;
061    import org.deegree.io.DBConnectionPool;
062    import org.deegree.ogcbase.CommonNamespaces;
063    import org.w3c.dom.Element;
064    import org.xml.sax.SAXException;
065    
066    /**
067     * TODO add class documentation here
068     * 
069     * @author <a href="mailto:name@deegree.org">Andreas Poth</a>
070     * @author last edited by: $Author: admin $
071     * 
072     * @version $Revision: $, $Date: $
073     */
074    public class DoConfigurationListener extends AbstractListener {
075    
076        private static final ILogger LOG = LoggerFactory.getLogger( DoConfigurationListener.class );
077    
078        private static final String[] sqlOracle = new String[] { "oracle/drop_harvester.sql",
079                                                                "oracle/drop_searchTables.sql", 
080                                                                "oracle/drop_database.sql",
081                                                                "oracle/create_database.sql",
082                                                                "oracle/create_harvester.sql",
083                                                                "oracle/create_searchTables.sql",
084                                                                "oracle/create_spatial_index.sql",
085                                                                "oracle/create_spatial_index.sql"};    
086    
087        private static final String[] sqlPostgis = new String[] { "postgis/drop_normal_index.sql",
088                                                                 "postgis/drop_spatial_index.sql",
089                                                                 "postgis/drop_harvester.sql",
090                                                                 "postgis/drop_searchTables.sql",
091                                                                 "postgis/drop_database.sql",
092                                                                 "postgis/create_database.sql",
093                                                                 "postgis/create_harvester.sql",
094                                                                 "postgis/create_searchTables.sql",
095                                                                 "postgis/create_normal_index.sql",
096                                                                 "postgis/create_spatial_index.sql" };
097           
098        private XMLFragment xml = null;
099         
100        private String dbVendor;
101    
102        private static NamespaceContext nsc = null;
103        static {
104            if ( nsc == null ) {
105                nsc = CommonNamespaces.getNamespaceContext();
106                nsc.addNamespace( "md", URI.create( "http://www.deegree.org/cataloguemanager" ) );
107            }
108        }
109    
110        private WebEvent event;
111    
112        /*
113         * (non-Javadoc)
114         * 
115         * @see
116         * org.deegree.enterprise.control.ajax.AbstractListener#actionPerformed(org.deegree.enterprise.control.ajax.WebEvent
117         * , org.deegree.enterprise.control.ajax.ResponseHandler)
118         */
119        public void actionPerformed( WebEvent event, ResponseHandler resp )
120                                throws IOException {
121            this.event = event;
122            String cswurl = (String) event.getParameter().get( "cswurl" );
123            String url = (String) event.getParameter().get( "url" );
124            String db = (String) event.getParameter().get( "db" );
125            String user = (String) event.getParameter().get( "user" );
126            String password = (String) event.getParameter().get( "pw" );
127            String sid = (String) event.getParameter().get( "sid" );
128            String driver = null;
129            String database = null;
130            String[] sql = null;
131            if ( db.equalsIgnoreCase( "postgres" ) ) {
132                driver = "org.postgresql.Driver";
133                database = "jdbc:postgresql://" + url + '/' + sid;
134                sql = sqlPostgis;
135                dbVendor = "postgres";
136            } else if ( db.equalsIgnoreCase( "oracle" ) ) {
137                driver = "oracle.jdbc.OracleDriver";
138                database = "jdbc:oracle:thin:@" + url + ':' + sid;
139                sql = sqlOracle;
140                dbVendor = "oracle";
141            } else {
142                resp.writeAndClose( "ERROR: not supported database type" );
143                return;
144            }
145            boolean newTables = (Boolean) event.getParameter().get( "newTables" );
146            boolean transactions = (Boolean) event.getParameter().get( "transactions" );
147            boolean searchClient = (Boolean) event.getParameter().get( "searchClient" );
148            boolean editor = (Boolean) event.getParameter().get( "editor" );
149            if ( newTables ) {
150                try {
151                    createTables( driver, database, user, password, sql );
152                } catch ( Exception e ) {
153                    resp.writeAndClose( "ERROR: can not create database: " + e.getMessage() );
154                    return;
155                }
156            }
157    
158            xml = new XMLFragment();
159            try {
160                xml.load( new File( event.getAbsolutePath( "./WEB-INF/web.xml" ) ).toURI().toURL() );
161            } catch ( SAXException e ) {
162                // should never happen
163                e.printStackTrace();
164            }
165    
166            try {
167                doCSWConfiguration( driver, database, user, password, cswurl, db, transactions );
168            } catch ( Exception e ) {
169                resp.writeAndClose( "ERROR: can not do CSW configuration: " + e.getMessage() );
170                return;
171            }
172    
173            doSearchClientConfiguration( searchClient, cswurl );
174    
175            doMetadataEditorConfiguration( cswurl );
176    
177            markAsConfigured( searchClient, editor );
178    
179            resp.writeAndClose( "success" );
180        }
181    
182        /**
183         * 
184         * @param searchClient
185         * @param editor
186         * @throws IOException
187         */
188        private void markAsConfigured( boolean searchClient, boolean editor )
189                                throws IOException {
190            String s = event.getAbsolutePath( "WEB-INF/conf/setup/catalogueManager_config.properties" );
191            Properties p = new Properties();
192            FileInputStream fis = new FileInputStream( s ); 
193            p.load( fis );
194            fis.close();
195            p.put( "configured", "true" );
196            p.put( "searchClient", "" + searchClient );
197            p.put( "editor", "" + editor );
198            FileOutputStream fos = new FileOutputStream( s );
199            p.store( fos, null );
200            fos.close();
201    
202        }
203    
204        /**
205         * @param searchClient
206         * @param cswurl
207         */
208        private void doSearchClientConfiguration( boolean searchClient, String cswurl ) {
209            // TODO Auto-generated method stub
210    
211        }
212    
213        /**
214         * @param cswurl
215         * @throws IOException 
216         */
217        private void doMetadataEditorConfiguration( String cswurl ) throws IOException {
218            String s = event.getAbsolutePath( "WEB-INF/conf/cataloguemanager/cataloguemanager.xml" );
219            XMLFragment cm = new XMLFragment();
220            try {
221                cm.load( new File( s ).toURI().toURL() );
222                String xpath = "md:CatalogueService/md:onlineResource";
223                Element elem = XMLTools.getRequiredElement( cm.getRootElement(), xpath, nsc );
224                elem.setAttribute( "xlink:href", cswurl );
225                //XMLTools.setNodeValue( elem, cswurl );
226                FileUtils.writeToFile( s, cm.getAsPrettyString() );
227            } catch ( Exception e ) {
228                // should never happen
229                e.printStackTrace();
230                throw new IOException( e.getMessage() );
231            }        
232        }
233    
234        /**
235         * 
236         * @param driver
237         * @param url
238         * @param user
239         * @param password
240         * @param cswurl
241         * @param db
242         * @param transactions
243         * @throws XMLParsingException
244         */
245        private void doCSWConfiguration( String driver, String url, String user, String password, String cswurl, String db,
246                                         boolean transactions )
247                                throws Exception {
248            // update CSW capabilities/configuration with desired URL
249            String xpath = "./servlet[servlet-name ='owservice']/init-param[param-name ='csw.config']/param-value";
250            String configFile = XMLTools.getRequiredNodeAsString( xml.getRootElement(), xpath, nsc );
251            configFile = event.getAbsolutePath( configFile );
252            XMLFragment csw = new XMLFragment( new File( configFile ).toURI().toURL() );
253            xpath = "ows:OperationsMetadata/ows:Operation/ows:DCP/ows:HTTP/ows:Get";
254            List<Element> elements = XMLTools.getElements( csw.getRootElement(), xpath, nsc );
255            for ( Element element : elements ) {
256                element.setAttributeNS( CommonNamespaces.XLNNS.toASCIIString(), "xlink:href", cswurl );
257            }
258            xpath = "ows:OperationsMetadata/ows:Operation/ows:DCP/ows:HTTP/ows:Post";
259            elements = XMLTools.getElements( csw.getRootElement(), xpath, nsc );
260            for ( Element element : elements ) {
261                element.setAttributeNS( CommonNamespaces.XLNNS.toASCIIString(), "xlink:href", cswurl );
262            }
263            
264            // delete already existing feature type configurations
265            FileUtils.writeToFile( configFile, csw.getAsPrettyString(), Charset.defaultCharset().displayName() );
266            String ftFile = "WEB-INF/conf/csw/featuretypes/csw_postgres.xsd";
267            ftFile = event.getAbsolutePath( ftFile );
268            File tmp = new File(ftFile);
269            if ( tmp.exists() ) {
270                tmp.delete();
271            }
272            ftFile = "WEB-INF/conf/csw/featuretypes/csw_oracle.xsd";
273            ftFile = event.getAbsolutePath( ftFile );
274            tmp = new File(ftFile);
275            if ( tmp.exists() ) {
276                tmp.delete();
277            }
278            
279            // set database connection informations and feature type configurations
280            if ( db.equalsIgnoreCase( "postgres" ) ) {
281                ftFile = "WEB-INF/conf/csw/featuretypes/csw_postgres.xsd.ignore";
282            } else if ( db.equalsIgnoreCase( "oracle" ) ) {
283                ftFile = "WEB-INF/conf/csw/featuretypes/csw_oracle.xsd.ignore";
284            }
285            
286            ftFile = event.getAbsolutePath( ftFile );
287            XMLFragment ftXML = new XMLFragment( new File( ftFile ).toURI().toURL() );
288            xpath = "xs:annotation/xs:appinfo/dgjdbc:JDBCConnection/dgjdbc:Driver";
289            Element element = (Element) XMLTools.getRequiredNode( ftXML.getRootElement(), xpath, nsc );
290            XMLTools.setNodeValue( element, driver );
291            xpath = "xs:annotation/xs:appinfo/dgjdbc:JDBCConnection/dgjdbc:Url";
292            element = (Element) XMLTools.getRequiredNode( ftXML.getRootElement(), xpath, nsc );
293            XMLTools.setNodeValue( element, url );
294            xpath = "xs:annotation/xs:appinfo/dgjdbc:JDBCConnection/dgjdbc:User";
295            element = (Element) XMLTools.getRequiredNode( ftXML.getRootElement(), xpath, nsc );
296            XMLTools.setNodeValue( element, user );
297            xpath = "xs:annotation/xs:appinfo/dgjdbc:JDBCConnection/dgjdbc:Password";
298            element = (Element) XMLTools.getRequiredNode( ftXML.getRootElement(), xpath, nsc );
299            XMLTools.setNodeValue( element, password );
300            FileUtils.writeToFile( ftFile.substring( 0, ftFile.length() - 7 ), ftXML.getAsPrettyString(),
301                                   Charset.defaultCharset().displayName() );
302            
303            adaptProperties( driver, url, user, password, cswurl );
304    
305        }
306    
307        /**
308         * @param driver
309         * @param url
310         * @param user
311         * @param password
312         * @param cswurl
313         * @throws IOException 
314         */
315        private void adaptProperties( String driver, String url, String user, String password, String cswurl ) throws IOException {
316            File file = new File( event.getAbsolutePath( "./WEB-INF/classes/org/deegree/ogcwebservices/csw/csw202.properties" ) );
317            try {            
318                FileInputStream fis = new FileInputStream( file );
319                Properties prop = new Properties();
320                prop.load( fis );
321                fis.close();
322                
323                prop.put( "db.driver", driver );
324                prop.put( "db.url", url );
325                prop.put( "db.user", user );
326                prop.put( "db.password", password );
327                prop.put( "csw.url", cswurl );
328                
329                FileOutputStream fos = new FileOutputStream( file );
330                prop.store( fos, null );
331                fos.close();
332            } catch ( Exception e ) {
333                LOG.logWarning( file + ": " + e.getMessage() );
334            }
335            file = new File( event.getAbsolutePath( "./WEB-INF/classes/harvestrepository.properties" ) );
336            try {            
337                FileInputStream fis = new FileInputStream( file );
338                Properties prop = new Properties();
339                prop.load( fis );
340                fis.close();
341                
342                prop.put( "harvester.Driver", driver );
343                prop.put( "harvester.Url", url );
344                prop.put( "harvester.User", user );
345                prop.put( "harvester.Password", password );
346                
347                FileOutputStream fos = new FileOutputStream( file );
348                prop.store( fos, null );
349                fos.close();
350            } catch ( Exception e ) {
351                LOG.logWarning( file + ": " + e.getMessage() );
352            }
353            
354        }
355    
356        private void createTables( String driver, String url, String user, String password, String[] sql )
357                                throws Exception {
358    
359            for ( String script : sql ) {
360                BufferedReader br = null;
361                try {
362                    String s = event.getAbsolutePath( "WEB-INF/scripts/sql/" + script );   
363                    LOG.logDebug( "load ", s );
364                    br = new BufferedReader( new FileReader( s ) );
365                } catch ( Exception e ) {
366                    throw new Exception( "can not open database creation script: " + script );
367                }
368                String thisLine, sqlQuery;
369                Statement stmt = null;
370                DBConnectionPool pool = DBConnectionPool.getInstance();
371                Connection conn = null;
372                try {
373                    conn = pool.acquireConnection( driver, url, user, password );
374                    stmt = conn.createStatement();
375                    sqlQuery = "";
376                    while ( ( thisLine = br.readLine() ) != null ) {
377    
378                        // Skip comments and empty lines
379                        if ( thisLine.length() > 0 && thisLine.charAt( 0 ) == '-' || thisLine.length() == 0 ) {
380                            continue;
381                        }
382                        sqlQuery = sqlQuery + " " + thisLine.trim();
383                        // If one command complete
384                        if ( sqlQuery.charAt( sqlQuery.length() - 1 ) == ';' ) {
385                            sqlQuery = sqlQuery.replace( ';', ' ' ); // Remove the ; since jdbc complains
386                            LOG.logDebug( "execute ", sqlQuery );
387                            try {
388                                stmt.execute( sqlQuery );
389                            } catch ( Exception ex ) {
390                                LOG.logInfo( "executed: ", sqlQuery );
391                                LOG.logError( ex.getMessage() );
392                            }
393                            sqlQuery = "";
394                        }
395                    }
396                } catch ( Exception ex ) {
397                    br.close();
398                    throw ex;
399                } finally {
400                    try {
401                        if ( conn != null ) {
402                            pool.releaseConnection( conn, driver, url, user, password );
403                        }
404                    } catch ( Exception e ) {
405                        // do nothing
406                    }
407                }
408                br.close();
409            }
410            if ( "oracle".equalsIgnoreCase( dbVendor ) ) {
411                // special for creating oracle trigger
412                createOracleTrigger( driver, url, user, password );
413            }
414        }
415    
416        private void createOracleTrigger( String driver, String url, String user, String password )
417                                throws Exception, IOException {
418            BufferedReader br = null;
419            try {
420                String s = event.getAbsolutePath( "WEB-INF/scripts/sql/oracle/create_trigger.sql"  );   
421                LOG.logDebug( "load ", s );
422                br = new BufferedReader( new FileReader( s ) );
423            } catch ( Exception e ) {
424                throw new Exception( "can not open database creation script: create_trigger.sql" );
425            }
426            String thisLine, sqlQuery;
427            Statement stmt = null;
428            DBConnectionPool pool = DBConnectionPool.getInstance();
429            Connection conn = null;
430            try {
431                conn = pool.acquireConnection( driver, url, user, password );
432                stmt = conn.createStatement();
433                sqlQuery = "";
434                while ( ( thisLine = br.readLine() ) != null ) {
435    
436                    // Skip comments and empty lines
437                    if ( (thisLine.length() > 0 && thisLine.charAt( 0 ) == '-') || thisLine.length() == 0 ) {
438                        continue;
439                    }
440                    sqlQuery = sqlQuery + " " + thisLine.trim();
441                    // If one command complete
442                    if ( sqlQuery.indexOf( "END;" ) > -1 ) {
443                        LOG.logDebug( "execute ", sqlQuery );
444                        try {  
445                            stmt.execute( sqlQuery );
446                        } catch ( Exception ex ) {
447                            LOG.logInfo( "executed: ", sqlQuery );
448                            LOG.logError( ex.getMessage() );
449                        }
450                        sqlQuery = "";
451                    }
452                }
453            } catch ( Exception ex ) {
454                br.close();
455                throw ex;
456            } finally {
457                try {
458                    if ( conn != null ) {
459                        pool.releaseConnection( conn, driver, url, user, password );
460                    }
461                } catch ( Exception e ) {
462                    // do nothing
463                }
464            }
465            br.close();
466        }
467    
468    }