/* * Copyright 2001-2009 Terracotta, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); you may not * use this file except in compliance with the License. You may obtain a copy * of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the * License for the specific language governing permissions and limitations * under the License. * */ package org.quartz.impl; import java.text.ParseException; import java.util.Collections; import java.util.Date; import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Set; import javax.management.Attribute; import javax.management.AttributeList; import javax.management.MalformedObjectNameException; import javax.management.ObjectName; import javax.management.openmbean.CompositeData; import org.quartz.Calendar; import org.quartz.JobDataMap; import org.quartz.JobDetail; import org.quartz.JobExecutionContext; import org.quartz.JobKey; import org.quartz.ListenerManager; import org.quartz.Scheduler; import org.quartz.SchedulerContext; import org.quartz.SchedulerException; import org.quartz.SchedulerMetaData; import org.quartz.Trigger; import org.quartz.TriggerKey; import org.quartz.UnableToInterruptJobException; import org.quartz.Trigger.TriggerState; import org.quartz.core.jmx.JobDetailSupport; import org.quartz.core.jmx.TriggerSupport; import org.quartz.impl.matchers.GroupMatcher; import org.quartz.impl.matchers.StringMatcher; import org.quartz.spi.JobFactory; /** * <p> * An implementation of the <code>Scheduler</code> interface that remotely * proxies all method calls to the equivalent call on a given <code>QuartzScheduler</code> * instance, via JMX. * </p> * * <p> * A user must create a subclass to implement the actual connection to the remote * MBeanServer using their application specific connector. * </p> * @see org.quartz.Scheduler * @see org.quartz.core.QuartzScheduler */ public abstract class RemoteMBeanScheduler implements Scheduler { /* * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ * * Data members. * * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ private ObjectName schedulerObjectName; /* * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ * * Constructors. * * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ public RemoteMBeanScheduler() { } /* * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ * * Properties. * * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ /** * Get the name under which the Scheduler MBean is registered on the * remote MBean server. */ protected ObjectName getSchedulerObjectName() { return schedulerObjectName; } /** * Set the name under which the Scheduler MBean is registered on the * remote MBean server. */ public void setSchedulerObjectName(String schedulerObjectName) throws SchedulerException { try { this.schedulerObjectName = new ObjectName(schedulerObjectName); } catch (MalformedObjectNameException e) { throw new SchedulerException("Failed to parse Scheduler MBean name: " + schedulerObjectName, e); } } /** * Set the name under which the Scheduler MBean is registered on the * remote MBean server. */ public void setSchedulerObjectName(ObjectName schedulerObjectName) throws SchedulerException { this.schedulerObjectName = schedulerObjectName; } /* * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ * * Abstract methods. * * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ /** * Initialize this RemoteMBeanScheduler instance, connecting to the * remote MBean server. */ public abstract void initialize() throws SchedulerException; /** * Get the given attribute of the remote Scheduler MBean. */ protected abstract Object getAttribute( String attribute) throws SchedulerException; /** * Get the given attributes of the remote Scheduler MBean. */ protected abstract AttributeList getAttributes(String[] attributes) throws SchedulerException; /** * Invoke the given operation on the remote Scheduler MBean. */ protected abstract Object invoke( String operationName, Object[] params, String[] signature) throws SchedulerException; /* * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ * * Interface. * * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ /** * <p> * Returns the name of the <code>Scheduler</code>. * </p> */ public String getSchedulerName() throws SchedulerException { return (String)getAttribute("SchedulerName"); } /** * <p> * Returns the instance Id of the <code>Scheduler</code>. * </p> */ public String getSchedulerInstanceId() throws SchedulerException { return (String)getAttribute("SchedulerInstanceId"); } public SchedulerMetaData getMetaData() throws SchedulerException { AttributeList attributeList = getAttributes( new String[] { "SchedulerName", "SchedulerInstanceId", "StandbyMode", "Shutdown", "JobStoreClassName", "ThreadPoolClassName", "ThreadPoolSize", "Version", "PerformanceMetrics" }); try { return new SchedulerMetaData( (String)getAttribute(attributeList, 0).getValue(), (String)getAttribute(attributeList, 1).getValue(), getClass(), true, false, (Boolean)getAttribute(attributeList, 2).getValue(), (Boolean)getAttribute(attributeList, 3).getValue(), null, Integer.parseInt(((Map)getAttribute(attributeList, 8).getValue()).get("JobsExecuted").toString()), Class.forName((String)getAttribute(attributeList, 4).getValue()), false, false, Class.forName((String)getAttribute(attributeList, 5).getValue()), (Integer)getAttribute(attributeList, 6).getValue(), (String)getAttribute(attributeList, 7).getValue()); } catch (ClassNotFoundException e) { throw new SchedulerException(e); } } private Attribute getAttribute(AttributeList attributeList, int index) { return (Attribute)attributeList.get(index); } /** * <p> * Returns the <code>SchedulerContext</code> of the <code>Scheduler</code>. * </p> */ public SchedulerContext getContext() throws SchedulerException { throw new SchedulerException("Operation not supported for remote schedulers."); } /////////////////////////////////////////////////////////////////////////// /// /// Schedululer State Management Methods /// /////////////////////////////////////////////////////////////////////////// /** * <p> * Calls the equivalent method on the 'proxied' <code>QuartzScheduler</code>. * </p> */ public void start() throws SchedulerException { invoke("start", new Object[] {}, new String[] {}); } /** * <p> * Calls the equivalent method on the 'proxied' <code>QuartzScheduler</code>. * </p> */ public void startDelayed(int seconds) throws SchedulerException { invoke("startDelayed", new Object[] {seconds}, new String[] {int.class.getName()}); } /** * <p> * Calls the equivalent method on the 'proxied' <code>QuartzScheduler</code>. * </p> */ public void standby() throws SchedulerException { invoke("standby", new Object[] {}, new String[] {}); } /** * Whether the scheduler has been started. * * <p> * Note: This only reflects whether <code>{@link #start()}</code> has ever * been called on this Scheduler, so it will return <code>true</code> even * if the <code>Scheduler</code> is currently in standby mode or has been * since shutdown. * </p> * * @see #start() * @see #isShutdown() * @see #isInStandbyMode() */ public boolean isStarted() throws SchedulerException { return (Boolean) getAttribute("Started"); } /** * <p> * Calls the equivalent method on the 'proxied' <code>QuartzScheduler</code>. * </p> */ public boolean isInStandbyMode() throws SchedulerException { return (Boolean)getAttribute("StandbyMode"); } /** * <p> * Calls the equivalent method on the 'proxied' <code>QuartzScheduler</code>. * </p> */ public void shutdown() throws SchedulerException { // Have to get the scheduler name before we actually call shutdown. String schedulerName = getSchedulerName(); invoke("shutdown", new Object[] {}, new String[] {}); SchedulerRepository.getInstance().remove(schedulerName); } /** * <p> * Calls the equivalent method on the 'proxied' <code>QuartzScheduler</code>. * </p> */ public void shutdown(boolean waitForJobsToComplete) throws SchedulerException { throw new SchedulerException("Operation not supported for remote schedulers."); } /** * <p> * Calls the equivalent method on the 'proxied' <code>QuartzScheduler</code>. * </p> */ public boolean isShutdown() throws SchedulerException { throw new SchedulerException("Operation not supported for remote schedulers."); } /** * <p> * Calls the equivalent method on the 'proxied' <code>QuartzScheduler</code>. * </p> */ @SuppressWarnings("unchecked") public List<JobExecutionContext> getCurrentlyExecutingJobs() throws SchedulerException { throw new SchedulerException("Operation not supported for remote schedulers."); } /////////////////////////////////////////////////////////////////////////// /// /// Scheduling-related Methods /// /////////////////////////////////////////////////////////////////////////// /** * <p> * Calls the equivalent method on the 'proxied' <code>QuartzScheduler</code>, * passing the <code>SchedulingContext</code> associated with this * instance. * </p> */ public Date scheduleJob(JobDetail jobDetail, Trigger trigger) throws SchedulerException { throw new SchedulerException("Operation not supported for remote schedulers."); } /** * <p> * Calls the equivalent method on the 'proxied' <code>QuartzScheduler</code>, * passing the <code>SchedulingContext</code> associated with this * instance. * </p> */ public Date scheduleJob(Trigger trigger) throws SchedulerException { throw new SchedulerException("Operation not supported for remote schedulers."); } /** * <p> * Calls the equivalent method on the 'proxied' <code>QuartzScheduler</code>, * passing the <code>SchedulingContext</code> associated with this * instance. * </p> */ public void addJob(JobDetail jobDetail, boolean replace) throws SchedulerException { invoke( "addJob", new Object[] { JobDetailSupport.toCompositeData(jobDetail), replace }, new String[] { CompositeData.class.getName(), boolean.class.getName() }); } /** * <p> * Calls the equivalent method on the 'proxied' <code>QuartzScheduler</code>, * passing the <code>SchedulingContext</code> associated with this * instance. * </p> */ public void addJob(JobDetail jobDetail, boolean replace, boolean storeNonDurableWhileAwaitingScheduling) throws SchedulerException { invoke( "addJob", new Object[] { JobDetailSupport.toCompositeData(jobDetail), replace , storeNonDurableWhileAwaitingScheduling}, new String[] { CompositeData.class.getName(), boolean.class.getName(), boolean.class.getName() }); } /** * <p> * Calls the equivalent method on the 'proxied' <code>QuartzScheduler</code>, * passing the <code>SchedulingContext</code> associated with this * instance. * </p> */ public boolean deleteJob(JobKey jobKey) throws SchedulerException { return (Boolean)invoke( "deleteJob", new Object[] { jobKey.getName(), jobKey.getGroup() }, new String[] { String.class.getName(), String.class.getName() }); } /** * <p> * Calls the equivalent method on the 'proxied' <code>QuartzScheduler</code>, * passing the <code>SchedulingContext</code> associated with this * instance. * </p> */ public boolean unscheduleJob(TriggerKey triggerKey) throws SchedulerException { return (Boolean)invoke( "unscheduleJob", new Object[] { triggerKey.getName(), triggerKey.getGroup() }, new String[] { String.class.getName(), String.class.getName() }); } public boolean deleteJobs(List<JobKey> jobKeys) throws SchedulerException { throw new SchedulerException("Operation not supported for remote schedulers."); } public void scheduleJobs(Map<JobDetail, Set<? extends Trigger>> triggersAndJobs, boolean replace) throws SchedulerException { throw new SchedulerException("Operation not supported for remote schedulers."); } public void scheduleJob(JobDetail jobDetail, Set<? extends Trigger> triggersForJob, boolean replace) throws SchedulerException { throw new SchedulerException("Operation not supported for remote schedulers."); } public boolean unscheduleJobs(List<TriggerKey> triggerKeys) throws SchedulerException { throw new SchedulerException("Operation not supported for remote schedulers."); } /** * <p> * Calls the equivalent method on the 'proxied' <code>QuartzScheduler</code>, * passing the <code>SchedulingContext</code> associated with this * instance. * </p> */ public Date rescheduleJob(TriggerKey triggerKey, Trigger newTrigger) throws SchedulerException { throw new SchedulerException("Operation not supported for remote schedulers."); } /** * <p> * Calls the equivalent method on the 'proxied' <code>QuartzScheduler</code>, * passing the <code>SchedulingContext</code> associated with this * instance. * </p> */ public void triggerJob(JobKey jobKey) throws SchedulerException { triggerJob(jobKey, null); } /** * <p> * Calls the equivalent method on the 'proxied' <code>QuartzScheduler</code>, * passing the <code>SchedulingContext</code> associated with this * instance. * </p> */ public void triggerJob(JobKey jobKey, JobDataMap data) throws SchedulerException { throw new SchedulerException("Operation not supported for remote schedulers."); } /** * <p> * Calls the equivalent method on the 'proxied' <code>QuartzScheduler</code>, * passing the <code>SchedulingContext</code> associated with this * instance. * </p> */ public void pauseTrigger(TriggerKey triggerKey) throws SchedulerException { invoke( "pauseTrigger", new Object[] { triggerKey.getName(), triggerKey.getGroup() }, new String[] { String.class.getName(), String.class.getName() }); } /** * <p> * Calls the equivalent method on the 'proxied' <code>QuartzScheduler</code>, * passing the <code>SchedulingContext</code> associated with this * instance. * </p> */ public void pauseTriggers(GroupMatcher<TriggerKey> matcher) throws SchedulerException { String operation = null; switch (matcher.getCompareWithOperator()) { case EQUALS: operation = "pauseTriggerGroup"; break; case CONTAINS: operation = "pauseTriggersContaining"; break; case STARTS_WITH: operation = "pauseTriggersStartingWith"; break; case ENDS_WITH: operation = "pauseTriggersEndingWith"; case ANYTHING: operation = "pauseTriggersAll"; } if (operation != null) { invoke( operation, new Object[] { matcher.getCompareToValue() }, new String[] { String.class.getName() }); } else { throw new SchedulerException("Unsupported GroupMatcher kind for pausing triggers: " + matcher.getCompareWithOperator()); } } /** * <p> * Calls the equivalent method on the 'proxied' <code>QuartzScheduler</code>, * passing the <code>SchedulingContext</code> associated with this * instance. * </p> */ public void pauseJob(JobKey jobKey) throws SchedulerException { invoke( "pauseJob", new Object[] { jobKey.getName(), jobKey.getGroup() }, new String[] { String.class.getName(), String.class.getName() }); } /** * <p> * Calls the equivalent method on the 'proxied' <code>QuartzScheduler</code>, * passing the <code>SchedulingContext</code> associated with this * instance. * </p> */ public void pauseJobs(GroupMatcher<JobKey> matcher) throws SchedulerException { String operation = null; switch (matcher.getCompareWithOperator()) { case EQUALS: operation = "pauseJobGroup"; break; case STARTS_WITH: operation = "pauseJobsStartingWith"; break; case ENDS_WITH: operation = "pauseJobsEndingWith"; break; case CONTAINS: operation = "pauseJobsContaining"; case ANYTHING: operation = "pauseJobsAll"; } invoke( operation, new Object[] { matcher.getCompareToValue() }, new String[] { String.class.getName() }); } /** * <p> * Calls the equivalent method on the 'proxied' <code>QuartzScheduler</code>, * passing the <code>SchedulingContext</code> associated with this * instance. * </p> */ public void resumeTrigger(TriggerKey triggerKey) throws SchedulerException { invoke( "resumeTrigger", new Object[] { triggerKey.getName(), triggerKey.getGroup() }, new String[] { String.class.getName(), String.class.getName() }); } /** * <p> * Calls the equivalent method on the 'proxied' <code>QuartzScheduler</code>, * passing the <code>SchedulingContext</code> associated with this * instance. * </p> */ public void resumeTriggers(GroupMatcher<TriggerKey> matcher) throws SchedulerException { String operation = null; switch (matcher.getCompareWithOperator()) { case EQUALS: operation = "resumeTriggerGroup"; break; case CONTAINS: operation = "resumeTriggersContaining"; break; case STARTS_WITH: operation = "resumeTriggersStartingWith"; break; case ENDS_WITH: operation = "resumeTriggersEndingWith"; case ANYTHING: operation = "resumeTriggersAll"; } if (operation != null) { invoke( operation, new Object[] { matcher.getCompareToValue() }, new String[] { String.class.getName() }); } else { throw new SchedulerException("Unsupported GroupMatcher kind for resuming triggers: " + matcher.getCompareWithOperator()); } } /** * <p> * Calls the equivalent method on the 'proxied' <code>QuartzScheduler</code>, * passing the <code>SchedulingContext</code> associated with this * instance. * </p> */ public void resumeJob(JobKey jobKey) throws SchedulerException { invoke( "resumeJob", new Object[] { jobKey.getName(), jobKey.getGroup() }, new String[] { String.class.getName(), String.class.getName() }); } /** * <p> * Calls the equivalent method on the 'proxied' <code>QuartzScheduler</code>, * passing the <code>SchedulingContext</code> associated with this * instance. * </p> */ public void resumeJobs(GroupMatcher<JobKey> matcher) throws SchedulerException { String operation = null; switch (matcher.getCompareWithOperator()) { case EQUALS: operation = "resumeJobGroup"; break; case STARTS_WITH: operation = "resumeJobsStartingWith"; break; case ENDS_WITH: operation = "resumeJobsEndingWith"; break; case CONTAINS: operation = "resumeJobsContaining"; case ANYTHING: operation = "resumeJobsAll"; } invoke( operation, new Object[] { matcher.getCompareToValue() }, new String[] { String.class.getName() }); } /** * <p> * Calls the equivalent method on the 'proxied' <code>QuartzScheduler</code>, * passing the <code>SchedulingContext</code> associated with this * instance. * </p> */ public void pauseAll() throws SchedulerException { invoke( "pauseAllTriggers", new Object[] { }, new String[] { }); } /** * <p> * Calls the equivalent method on the 'proxied' <code>QuartzScheduler</code>, * passing the <code>SchedulingContext</code> associated with this * instance. * </p> */ public void resumeAll() throws SchedulerException { invoke( "resumeAllTriggers", new Object[] { }, new String[] { }); } /** * <p> * Calls the equivalent method on the 'proxied' <code>QuartzScheduler</code>, * passing the <code>SchedulingContext</code> associated with this * instance. * </p> */ @SuppressWarnings("unchecked") public List<String> getJobGroupNames() throws SchedulerException { return (List<String>)getAttribute("JobGroupNames"); } /** * <p> * Calls the equivalent method on the 'proxied' <code>QuartzScheduler</code>, * passing the <code>SchedulingContext</code> associated with this * instance. * </p> */ @SuppressWarnings("unchecked") public Set<JobKey> getJobKeys(GroupMatcher<JobKey> matcher) throws SchedulerException { if (matcher.getCompareWithOperator().equals(StringMatcher.StringOperatorName.EQUALS)) { List<JobKey> keys = (List<JobKey>)invoke( "getJobNames", new Object[] { matcher.getCompareToValue() }, new String[] { String.class.getName() }); return new HashSet<JobKey>(keys); } else { throw new SchedulerException("Only equals matcher are supported for looking up JobKeys"); } } /** * <p> * Calls the equivalent method on the 'proxied' <code>QuartzScheduler</code>, * passing the <code>SchedulingContext</code> associated with this * instance. * </p> */ @SuppressWarnings("unchecked") public List<Trigger> getTriggersOfJob(JobKey jobKey) throws SchedulerException { throw new SchedulerException("Operation not supported for remote schedulers."); } /** * <p> * Calls the equivalent method on the 'proxied' <code>QuartzScheduler</code>, * passing the <code>SchedulingContext</code> associated with this * instance. * </p> */ @SuppressWarnings("unchecked") public List<String> getTriggerGroupNames() throws SchedulerException { return (List<String>)getAttribute("TriggerGroupNames"); } /** * <p> * Calls the equivalent method on the 'proxied' <code>QuartzScheduler</code>, * passing the <code>SchedulingContext</code> associated with this * instance. * </p> */ @SuppressWarnings("unchecked") public Set<TriggerKey> getTriggerKeys(GroupMatcher<TriggerKey> matcher) throws SchedulerException { throw new SchedulerException("Operation not supported for remote schedulers."); } /** * <p> * Calls the equivalent method on the 'proxied' <code>QuartzScheduler</code>, * passing the <code>SchedulingContext</code> associated with this * instance. * </p> */ public JobDetail getJobDetail(JobKey jobKey) throws SchedulerException { try { return JobDetailSupport.newJobDetail((CompositeData)invoke( "getJobDetail", new Object[] { jobKey.getName(), jobKey.getGroup() }, new String[] { String.class.getName(), String.class.getName() })); } catch (ClassNotFoundException e) { throw new SchedulerException("Unable to resolve job class", e); } } /** * <p> * Calls the equivalent method on the 'proxied' <code>QuartzScheduler</code>. * </p> */ public Trigger getTrigger(TriggerKey triggerKey) throws SchedulerException { throw new SchedulerException("Operation not supported for remote schedulers."); } /** * <p> * Calls the equivalent method on the 'proxied' <code>QuartzScheduler</code>. * </p> */ public boolean checkExists(JobKey jobKey) throws SchedulerException { throw new SchedulerException("Operation not supported for remote schedulers."); } /** * <p> * Calls the equivalent method on the 'proxied' <code>QuartzScheduler</code>. * </p> */ public boolean checkExists(TriggerKey triggerKey) throws SchedulerException { return (Boolean)invoke( "checkExists", new Object[] { triggerKey }, new String[] { TriggerKey.class.getName() }); } public void clear() throws SchedulerException { invoke( "clear", new Object[] { }, new String[] { }); } /** * <p> * Calls the equivalent method on the 'proxied' <code>QuartzScheduler</code>, * passing the <code>SchedulingContext</code> associated with this * instance. * </p> */ public TriggerState getTriggerState(TriggerKey triggerKey) throws SchedulerException { return TriggerState.valueOf((String)invoke( "getTriggerState", new Object[] { triggerKey.getName(), triggerKey.getGroup() }, new String[] { String.class.getName(), String.class.getName() })); } /** * <p> * Calls the equivalent method on the 'proxied' <code>QuartzScheduler</code>, * passing the <code>SchedulingContext</code> associated with this * instance. * </p> */ public void addCalendar(String calName, Calendar calendar, boolean replace, boolean updateTriggers) throws SchedulerException { invoke( "addCalendar", new Object[] { calName, calendar, replace, updateTriggers }, new String[] { String.class.getName(), Calendar.class.getName(), boolean.class.getName(), boolean.class.getName() }); } /** * <p> * Calls the equivalent method on the 'proxied' <code>QuartzScheduler</code>, * passing the <code>SchedulingContext</code> associated with this * instance. * </p> */ public boolean deleteCalendar(String calName) throws SchedulerException { invoke("deleteCalendar", new Object[] { calName }, new String[] { String.class.getName() }); return true; } /** * <p> * Calls th0e equivalent method on the 'proxied' <code>QuartzScheduler</code>, * passing the <code>SchedulingContext</code> associated with this * instance. * </p> */ public Calendar getCalendar(String calName) throws SchedulerException { throw new SchedulerException("Operation not supported for remote schedulers."); } /** * <p> * Calls the equivalent method on the 'proxied' <code>QuartzScheduler</code>, * passing the <code>SchedulingContext</code> associated with this * instance. * </p> */ @SuppressWarnings("unchecked") public List<String> getCalendarNames() throws SchedulerException { return (List<String>)getAttribute("CalendarNames"); } /** * @see org.quartz.Scheduler#getPausedTriggerGroups() */ @SuppressWarnings("unchecked") public Set<String> getPausedTriggerGroups() throws SchedulerException { return (Set<String>)getAttribute("PausedTriggerGroups"); } /////////////////////////////////////////////////////////////////////////// /// /// Other Methods /// /////////////////////////////////////////////////////////////////////////// /** * <p> * Calls the equivalent method on the 'proxied' <code>QuartzScheduler</code>. * </p> */ public ListenerManager getListenerManager() throws SchedulerException { throw new SchedulerException( "Operation not supported for remote schedulers."); } /** * @see org.quartz.Scheduler#interrupt(JobKey) */ public boolean interrupt(JobKey jobKey) throws UnableToInterruptJobException { try { return (Boolean)invoke( "interruptJob", new Object[] { jobKey.getName(), jobKey.getGroup() }, new String[] { String.class.getName(), String.class.getName() }); } catch (SchedulerException se) { throw new UnableToInterruptJobException(se); } } public boolean interrupt(String fireInstanceId) throws UnableToInterruptJobException { try { return (Boolean)invoke( "interruptJob", new Object[] { fireInstanceId }, new String[] { String.class.getName() }); } catch (SchedulerException se) { throw new UnableToInterruptJobException(se); } } /** * @see org.quartz.Scheduler#setJobFactory(org.quartz.spi.JobFactory) */ public void setJobFactory(JobFactory factory) throws SchedulerException { throw new SchedulerException("Operation not supported for remote schedulers."); } }