blob: 69401b72f5e1ab81a273f8eef18e8cd08b5c65ba [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2000, 2007 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* IBM Corporation - initial API and implementation
*******************************************************************************/
package org.eclipse.update.internal.scheduler;
import java.lang.reflect.Constructor;
import java.util.Calendar;
import org.eclipse.core.runtime.Preferences;
import org.eclipse.core.runtime.jobs.IJobChangeListener;
import org.eclipse.core.runtime.jobs.Job;
import org.eclipse.ui.IStartup;
/**
* This plug-in is loaded on startup to fork a job that searches for new
* plug-ins.
*/
public class SchedulerStartup implements IStartup {
// Preferences
public static final String P_ENABLED = "enabled"; //$NON-NLS-1$
public static final String P_SCHEDULE = "schedule"; //$NON-NLS-1$
public static final String VALUE_ON_STARTUP = "on-startup"; //$NON-NLS-1$
public static final String VALUE_ON_SCHEDULE = "on-schedule"; //$NON-NLS-1$
public static final String P_DOWNLOAD = "download"; // value is true or false, default isfalse //$NON-NLS-1$
// values are to be picked up from the arryas DAYS and HOURS
public static final String P_DAY = "day"; //$NON-NLS-1$
public static final String P_HOUR = "hour"; //$NON-NLS-1$
// Keeps track of the running job
private Job job;
static final Object automaticJobFamily = new Object();
// Listener for job changes
private IJobChangeListener jobListener;
public static final String[] DAYS = {
UpdateSchedulerMessages.SchedulerStartup_day,
UpdateSchedulerMessages.SchedulerStartup_Monday,
UpdateSchedulerMessages.SchedulerStartup_Tuesday,
UpdateSchedulerMessages.SchedulerStartup_Wednesday,
UpdateSchedulerMessages.SchedulerStartup_Thursday,
UpdateSchedulerMessages.SchedulerStartup_Friday,
UpdateSchedulerMessages.SchedulerStartup_Saturday,
UpdateSchedulerMessages.SchedulerStartup_Sunday };
public static final String[] HOURS = {
UpdateSchedulerMessages.SchedulerStartup_1AM,
UpdateSchedulerMessages.SchedulerStartup_2AM,
UpdateSchedulerMessages.SchedulerStartup_3AM,
UpdateSchedulerMessages.SchedulerStartup_4AM,
UpdateSchedulerMessages.SchedulerStartup_5AM,
UpdateSchedulerMessages.SchedulerStartup_6AM,
UpdateSchedulerMessages.SchedulerStartup_7AM,
UpdateSchedulerMessages.SchedulerStartup_8AM,
UpdateSchedulerMessages.SchedulerStartup_9AM,
UpdateSchedulerMessages.SchedulerStartup_10AM,
UpdateSchedulerMessages.SchedulerStartup_11AM,
UpdateSchedulerMessages.SchedulerStartup_12PM,
UpdateSchedulerMessages.SchedulerStartup_1PM,
UpdateSchedulerMessages.SchedulerStartup_2PM,
UpdateSchedulerMessages.SchedulerStartup_3PM,
UpdateSchedulerMessages.SchedulerStartup_4PM,
UpdateSchedulerMessages.SchedulerStartup_5PM,
UpdateSchedulerMessages.SchedulerStartup_6PM,
UpdateSchedulerMessages.SchedulerStartup_7PM,
UpdateSchedulerMessages.SchedulerStartup_8PM,
UpdateSchedulerMessages.SchedulerStartup_9PM,
UpdateSchedulerMessages.SchedulerStartup_10PM,
UpdateSchedulerMessages.SchedulerStartup_11PM,
UpdateSchedulerMessages.SchedulerStartup_12AM, };
/**
* The constructor.
*/
public SchedulerStartup() {
UpdateSchedulerPlugin.setScheduler(this);
}
public void earlyStartup() {
scheduleUpdateJob();
}
public void scheduleUpdateJob() {
Preferences pref = UpdateSchedulerPlugin.getDefault()
.getPluginPreferences();
// See if automatic search is enabled at all
if (pref.getBoolean(P_ENABLED) == false)
return;
String schedule = pref.getString(P_SCHEDULE);
long delay = -1L;
if (schedule.equals(VALUE_ON_STARTUP))
// have we already started a job ?
if (job == null)
delay = 0L;
else
delay = -1L;
else
delay = computeDelay(pref);
if (delay == -1L)
return;
startSearch(delay);
}
private int getDay(Preferences pref) {
String day = pref.getString(P_DAY);
for (int d = 0; d < DAYS.length; d++)
if (DAYS[d].equals(day))
switch (d) {
case 0:
return -1;
case 1:
return Calendar.MONDAY;
case 2:
return Calendar.TUESDAY;
case 3:
return Calendar.WEDNESDAY;
case 4:
return Calendar.THURSDAY;
case 5:
return Calendar.FRIDAY;
case 6:
return Calendar.SATURDAY;
case 7:
return Calendar.SUNDAY;
}
return -1;
}
private int getHour(Preferences pref) {
String hour = pref.getString(P_HOUR);
for (int h = 0; h < HOURS.length; h++)
if (HOURS[h].equals(hour))
return h + 1;
return 1;
}
/*
* Computes the number of milliseconds from this moment to the next
* scheduled search. If that moment has already passed, returns 0L (start
* immediately).
*/
private long computeDelay(Preferences pref) {
int target_d = getDay(pref);
int target_h = getHour(pref);
Calendar calendar = Calendar.getInstance();
// may need to use the BootLoader locale
int current_d = calendar.get(Calendar.DAY_OF_WEEK);
// starts with SUNDAY
int current_h = calendar.get(Calendar.HOUR_OF_DAY);
int current_m = calendar.get(Calendar.MINUTE);
int current_s = calendar.get(Calendar.SECOND);
int current_ms = calendar.get(Calendar.MILLISECOND);
long delay = 0L; // milliseconds
if (target_d == -1) {
// Compute the delay for "every day at x o'clock"
// Is it now ?
if (target_h == current_h && current_m == 0 && current_s == 0)
return delay;
int delta_h = target_h - current_h;
if (target_h <= current_h)
delta_h += 24;
delay = ((delta_h * 60 - current_m) * 60 - current_s) * 1000
- current_ms;
return delay;
} else {
// Compute the delay for "every Xday at x o'clock"
// Is it now ?
if (target_d == current_d && target_h == current_h
&& current_m == 0 && current_s == 0)
return delay;
int delta_d = target_d - current_d;
if (target_d < current_d
|| target_d == current_d
&& (target_h < current_h || target_h == current_h
&& current_m > 0))
delta_d += 7;
delay = (((delta_d * 24 + target_h - current_h) * 60 - current_m) * 60 - current_s)
* 1000 - current_ms;
return delay;
}
// return -1L;
}
private void startSearch(long delay) {
if (job != null) {
// cancel old job.
// We need to deregister the listener first,so we won't
// automatically start another job
if (jobListener != null)
Job.getJobManager().removeJobChangeListener(jobListener);
Job.getJobManager().cancel(automaticJobFamily);
}
if (jobListener == null) {
// using reflection to avoid premature class loading
jobListener = createJobChangeAdapter();
if (jobListener == null)
return;
}
Job.getJobManager().addJobChangeListener(jobListener);
String jobName = UpdateSchedulerMessages.AutomaticUpdatesJob_AutomaticUpdateSearch; //);
boolean download = UpdateSchedulerPlugin.getDefault()
.getPluginPreferences().getBoolean(
UpdateSchedulerPlugin.P_DOWNLOAD);
job = createUpdateJob(jobName, download);
if (job != null)
job.schedule(delay);
}
/*
* Loads the update job using reflection to avoid premature startup of the
* Update UI plug-in.
*/
private Job createUpdateJob(String name, boolean download) {
try {
Class theClass = Class
.forName("org.eclipse.update.internal.scheduler.AutomaticUpdateJob"); //$NON-NLS-1$
Constructor constructor = theClass.getConstructor(new Class[] {
String.class, Boolean.TYPE, Boolean.TYPE });
return (Job) constructor.newInstance(new Object[] { name,
Boolean.TRUE, new Boolean(download) });
} catch (Exception e) {
UpdateSchedulerPlugin.logException(e, false);
return null;
}
}
/*
* Loads the job listener using reflection to avoid premature startup of the
* Update UI plug-in.
*/
private IJobChangeListener createJobChangeAdapter() {
try {
Class theClass = Class
.forName("org.eclipse.update.internal.scheduler.UpdateJobChangeAdapter"); //$NON-NLS-1$
Constructor constructor = theClass
.getConstructor(new Class[] { SchedulerStartup.class });
return (IJobChangeListener) constructor
.newInstance(new Object[] { this });
} catch (Exception e) {
UpdateSchedulerPlugin.logException(e, false);
return null;
}
}
Job getJob() {
return job;
}
}