/**
* This program is copyright (c) 2007 Hortis-GRC SA.
*
* This file is part of Sonar.
* Sonar is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* Sonar is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Sonar; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
*/
package ch.hortis.sonar.web.listener;
import java.sql.SQLException;
import ch.hortis.sonar.core.Batch;
import ch.hortis.sonar.jpa.JPAUtil;
import ch.hortis.sonar.model.JdbcData;
import org.quartz.SchedulerException;
import javax.naming.Context;
import javax.naming.InitialContext;
import javax.naming.NameClassPair;
import javax.naming.NameNotFoundException;
import javax.naming.NamingEnumeration;
import javax.naming.NamingException;
import javax.persistence.PersistenceException;
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
import javax.sql.DataSource;
/**
* Servlet context listener to startup/stop sonar core
*/
public class SonarCoreStartupListener implements ServletContextListener {
private Batch batch;
public void contextInitialized( ServletContextEvent ctxEvent ) {
Context ctx;
try {
ctx = new InitialContext();
} catch (NamingException ex) {
ctxEvent.getServletContext().log( "Naming exception occured during JNDI initial context creation", ex );
return;
}
Boolean startBatchProcess = lookup( ctx, "java:comp/env/sonar/enable-batch", Boolean.TRUE );
if ( !startBatchProcess ) return;
String url = lookup( ctx, "java:comp/env/sonar/jdbc-url", null );
String driver = lookup( ctx, "java:comp/env/sonar/jdbc-driver", null );
String password = lookup( ctx, "java:comp/env/sonar/db-password", null );
String username = lookup( ctx, "java:comp/env/sonar/db-username", null );
String datasource = lookup( ctx, "java:comp/env/sonar/ds-jndi-binding", null );
if ( datasource == null ) {
datasource = JdbcData.DEFAULT_SONAR_DS_JNDI_NAME;
SonarContext.getInstance().put( "ds-jndi-binding", datasource );
}
String jdbcDialect = lookup( ctx, "java:comp/env/sonar/jdbc-dialect", null );
if ( jdbcDialect == null ) {
jdbcDialect = autodetectJDBCDialect( ctx, datasource );
SonarContext.getInstance().put( "jdbc-dialect", jdbcDialect );
}
try {
populateSonarContext( ctx );
} catch ( NameNotFoundException ex ) {
// no java:comp/env/sonar found.. not an issue
} catch ( NamingException ex ) {
ctxEvent.getServletContext().log( "Naming exception occured during java:comp/env/sonar lookups", ex );
}
if ( url != null && driver != null && password != null && username != null ) {
batch = new Batch( url, driver, username, password );
} else if ( jdbcDialect != null ) {
batch = new Batch( datasource, jdbcDialect );
} else {
ctxEvent.getServletContext().log( "Missing JDBC settings" );
}
if ( batch != null ) {
Long purgeRepeatInMillis = lookup( ctx, "java:comp/env/sonar/batch-purge-job-mstime", Batch.DEFAULT_PURGE_REPEAT_INTERVAL_MILLIS );
batch.setPurgeRepeatInMillis( purgeRepeatInMillis );
try {
batch.start();
} catch (Exception e) {
ctxEvent.getServletContext().log( "Error occured during scheduler startup", e );
}
}
try {
ctx.close();
} catch (NamingException e) {
// should log a warning
}
}
private void populateSonarContext(Context ctx) throws NamingException{
SonarContext sonarContext = SonarContext.getInstance();
NamingEnumeration<NameClassPair> rorEnv = ctx.list( "java:comp/env/sonar" );
while ( rorEnv.hasMoreElements() ) {
NameClassPair pair = rorEnv.nextElement();
Object val = ctx.lookup( "java:comp/env/sonar/" + pair.getName() );
if ( val == null ) val = "";
sonarContext.put( pair.getName(), val.toString() );
}
}
private String autodetectJDBCDialect(Context ctx, String datasource) {
DataSource ds = lookup( ctx, datasource, null );
if ( ds == null ) return JdbcData.DEFAULT_SONAR_DIALECT;
try {
String jdbcURL = ds.getConnection().getMetaData().getURL();
return JPAUtil.getJDBCDialect( jdbcURL );
} catch ( SQLException ex ) {
return JdbcData.DEFAULT_SONAR_DIALECT;
} catch ( PersistenceException ex ) {
return JdbcData.DEFAULT_SONAR_DIALECT;
}
}
public void contextDestroyed( ServletContextEvent ctxEvent ) {
if ( batch != null ) {
try {
batch.shutdown();
} catch (SchedulerException e) {
ctxEvent.getServletContext().log( "Error occured during scheduler shutdown", e );
}
}
SonarContext.getInstance().destroy();
}
private <T> T lookup( Context ctx, String key, Object defaultValue ) {
Object value;
try {
value = ctx.lookup( key );
} catch ( NamingException e ) {
value = defaultValue;
}
return (T)value;
}
}