/* * This program is free software; you can redistribute it and/or modify it under the * terms of the GNU Lesser General Public License, version 2.1 as published by the Free Software * Foundation. * * You should have received a copy of the GNU Lesser General Public License along with this * program; if not, you can obtain a copy at http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html * or from the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * * This program 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 Lesser General Public License for more details. * * Copyright 2005 - 2009 Pentaho Corporation. All rights reserved. * * * @created Jul 22, 2005 * @author William Seyler * */ package org.pentaho.platform.scheduler; import java.io.BufferedInputStream; import java.io.File; import java.io.FileInputStream; import java.io.IOException; import java.io.InputStream; import java.util.Properties; import org.pentaho.platform.api.data.DatasourceServiceException; import org.pentaho.platform.api.data.IDatasourceService; import org.pentaho.platform.api.engine.IPentahoSession; import org.pentaho.platform.api.engine.IPentahoSystemListener; import org.pentaho.platform.api.engine.ObjectFactoryException; import org.pentaho.platform.engine.core.system.PentahoSystem; import org.pentaho.platform.engine.services.connection.datasource.dbcp.JndiDatasourceService; import org.pentaho.platform.scheduler.messages.Messages; import org.pentaho.platform.util.logging.Logger; import org.quartz.Scheduler; import org.quartz.SchedulerException; import org.quartz.SchedulerFactory; public class QuartzSystemListener implements IPentahoSystemListener { protected static Scheduler schedulerInstance = null; private final static boolean debug = PentahoSystem.debug; private static boolean useNewDatasourceService = false; public synchronized void setUseNewDatasourceService(boolean useNewService) { // // The platform should not be calling this method. But, in case someone really // really wants to use the new datasource service features to talk to // a core service like Quartz, this is now toggle-able. // useNewDatasourceService = useNewService; } /* * (non-Javadoc) * * @see org.pentaho.core.system.IPentahoSystemListener#startup() */ private static final String DEFAULT_QUARTZ_PROPERTIES_FILE = "quartz/quartz.properties"; //$NON-NLS-1$ Properties quartzProperties; String quartzPropertiesFile = DEFAULT_QUARTZ_PROPERTIES_FILE; public boolean startup(final IPentahoSession session) { Properties quartzProps = null; if (quartzPropertiesFile != null) { quartzProps = PentahoSystem.getSystemSettings().getSystemSettingsProperties(quartzPropertiesFile); } else { quartzProps = quartzProperties; } if (quartzProps == null) { try { quartzProps = findPropertiesInClasspath(); } catch (IOException ex) { Logger.error(QuartzSystemListener.class.getName(), Messages.getInstance() .getErrorString("QuartzSystemListener.ERROR_0004_LOAD_PROPERTIES_FROM_CLASSPATH"), ex); //$NON-NLS-1$ } } if (quartzProps == null) { return false; } String dsName = quartzProps.getProperty("org.quartz.dataSource.myDS.jndiURL"); //$NON-NLS-1$ if (dsName != null) { try { IDatasourceService datasourceService = getQuartzDatasourceService(session); String boundDsName = datasourceService.getDSBoundName(dsName); if (boundDsName != null) { quartzProps.setProperty("org.quartz.dataSource.myDS.jndiURL", boundDsName); //$NON-NLS-1$ } } catch (ObjectFactoryException objface) { Logger.error(this, Messages.getInstance().getErrorString( "QuartzSystemListener.ERROR_0005_UNABLE_TO_INSTANTIATE_OBJECT",QuartzSystemListener.class.getName()), objface); //$NON-NLS-1$ return false; } catch (DatasourceServiceException dse) { Logger.error(this, Messages.getInstance().getErrorString( "QuartzSystemListener.ERROR_0006_UNABLE_TO_GET_DATASOURCE",QuartzSystemListener.class.getName()), dse); //$NON-NLS-1$ return false; } } try { SchedulerFactory schedFact = new org.quartz.impl.StdSchedulerFactory(quartzProps); QuartzSystemListener.schedulerInstance = schedFact.getScheduler(); if (QuartzSystemListener.debug) { Logger.debug(QuartzSystemListener.class.getName(), QuartzSystemListener.schedulerInstance.getSchedulerName()); } QuartzSystemListener.schedulerInstance.start(); } catch (SchedulerException e) { Logger.error(this, Messages.getInstance().getErrorString( "QuartzSystemListener.ERROR_0001_Scheduler_Not_Initialized",QuartzSystemListener.class.getName()), e); //$NON-NLS-1$ return false; } return true; } private IDatasourceService getQuartzDatasourceService(IPentahoSession session) throws ObjectFactoryException { // // Our new datasource stuff is provided for running queries and acquiring data. It is // NOT there for the inner workings of the platform. So, the Quartz datasource should ALWAYS // be provided by JNDI. However, the class could be twiddled so that it will use the factory. // // And, since the default shipping condition should be to NOT use the factory (and force JNDI), // I've reversed the logic in the class to have the negative condition first (the default execution // path). // // Marc - BISERVER-2004 // if (!useNewDatasourceService) { return new JndiDatasourceService(); } else { IDatasourceService datasourceService = PentahoSystem.getObjectFactory().get(IDatasourceService.class,session); return datasourceService; } } private Properties findPropertiesInClasspath() throws IOException { // Do my best to find the properties file... File propFile = new File("quartz.properties"); //$NON-NLS-1$ if (!propFile.canRead()) { InputStream in = Thread.currentThread().getContextClassLoader().getResourceAsStream("quartz.properties"); //$NON-NLS-1$ if (in != null) { try { Properties props = new Properties(); props.load(in); return props; } finally { in.close(); } } return null; // Couldn't find properties file. } else { InputStream iStream = new BufferedInputStream(new FileInputStream(propFile)); try { Properties props = new Properties(); props.load(iStream); return props; } finally { try { iStream.close(); } catch (IOException ignored) { // close quietly } } } } /* * (non-Javadoc) * * @see org.pentaho.core.system.IPentahoSystemListener#shutdown() */ public void shutdown() { try { QuartzSystemListener.schedulerInstance.shutdown(true); QuartzSystemListener.schedulerInstance = null; } catch (SchedulerException e) { // TODO Auto-generated catch block e.printStackTrace(); } } /** * @return Returns the schedulerInstance. * @throws Exception */ public static Scheduler getSchedulerInstance() throws SchedulerInitializationException { if (QuartzSystemListener.schedulerInstance == null) { throw new SchedulerInitializationException(Messages.getInstance() .getErrorString("QuartzSystemListener.ERROR_0001_Scheduler_Not_Initialized")); //$NON-NLS-1$ } return QuartzSystemListener.schedulerInstance; } public Properties getQuartzProperties() { return quartzProperties; } public void setQuartzProperties(Properties quartzProperties) { this.quartzProperties = quartzProperties; if (quartzProperties != null) { quartzPropertiesFile = null; } } public String getQuartzPropertiesFile() { return quartzPropertiesFile; } public void setQuartzPropertiesFile(String quartzPropertiesFile) { this.quartzPropertiesFile = quartzPropertiesFile; if (quartzPropertiesFile != null) { quartzProperties = null; } } }