blob: 18e0cd275d87f12ccb9b315ba9b46b5ae0bd9e41 [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2003, 2017 IBM Corporation and others.
*
* This program and the accompanying materials
* are made available under the terms of the Eclipse Public License 2.0
* which accompanies this distribution, and is available at
* https://www.eclipse.org/legal/epl-2.0/
*
* SPDX-License-Identifier: EPL-2.0
*
* Contributors:
* IBM Corporation - initial API and implementation
* Trevor S. Kaufman <endante@gmail.com> - bug 156152
*******************************************************************************/
package org.eclipse.team.internal.ui.synchronize;
import java.util.Date;
import org.eclipse.core.runtime.Adapters;
import org.eclipse.core.runtime.jobs.Job;
import org.eclipse.osgi.util.NLS;
import org.eclipse.team.internal.ui.TeamUIMessages;
import org.eclipse.team.internal.ui.TeamUIPlugin;
import org.eclipse.team.ui.synchronize.ISynchronizeParticipant;
import org.eclipse.ui.IMemento;
import org.eclipse.ui.actions.ActionFactory;
import com.ibm.icu.text.DateFormat;
import com.ibm.icu.util.Calendar;
/**
* Schedule to refresh a subscriber at a specified interval. The schedule can be disabled or enabled
* and will create the refresh job.
*
* @since 3.0
*/
public class SubscriberRefreshSchedule {
private long refreshInterval = 3600; // 1 hour default
private Date refreshStart;
private boolean runOnce = false;
private boolean enabled = false;
private RefreshParticipantJob job;
private IRefreshable refreshable;
private IRefreshEvent lastRefreshEvent;
/**
* Key for settings in memento
*/
private static final String CTX_REFRESHSCHEDULE_INTERVAL = TeamUIPlugin.ID + ".CTX_REFRESHSCHEDULE_INTERVAL"; //$NON-NLS-1$
/**
* Key for schedule in memento
*/
private static final String CTX_REFRESHSCHEDULE_ENABLED = TeamUIPlugin.ID + ".CTX_REFRESHSCHEDULE_ENABLED"; //$NON-NLS-1$
/**
* Key for start date in memento
*/
private static final String CTX_REFRESHSCHEDULE_START = TeamUIPlugin.ID + ".CTX_REFRESHSCHEDULE_START"; //$NON-NLS-1$
/**
* Key for run once in memento
*/
private static final String CTX_REFRESHSCHEDULE_RUNONCE = TeamUIPlugin.ID + ".CTX_REFRESHSCHEDULE_RUNONCE"; //$NON-NLS-1$
private IRefreshSubscriberListener refreshSubscriberListener = new IRefreshSubscriberListener() {
@Override
public void refreshStarted(IRefreshEvent event) {
}
@Override
public ActionFactory.IWorkbenchAction refreshDone(final IRefreshEvent event) {
if (getRefreshable(event.getParticipant()) == refreshable) {
lastRefreshEvent = event;
if(enabled && event.getRefreshType() == IRefreshEvent.SCHEDULED_REFRESH) {
RefreshUserNotificationPolicy policy = new RefreshUserNotificationPolicy(refreshable.getParticipant());
policy.refreshDone(event);
}
}
return null;
}
private IRefreshable getRefreshable(ISynchronizeParticipant participant) {
return Adapters.adapt(participant, IRefreshable.class);
}
};
public SubscriberRefreshSchedule(IRefreshable refreshable) {
this.refreshable = refreshable;
RefreshParticipantJob.addRefreshListener(refreshSubscriberListener);
// Calendar cal = Calendar.getInstance();
// cal.clear();
// refreshStart = cal.getTime();
}
/**
* @return Returns the enabled.
*/
public boolean isEnabled() {
return enabled;
}
/**
* @param enabled The enabled to set.
* @param allowedToStart Is the job allowed to start.
*/
public void setEnabled(boolean enabled, boolean allowedToStart) {
boolean wasEnabled = isEnabled();
this.enabled = enabled;
if(enabled && ! wasEnabled) {
if(allowedToStart) {
startJob();
}
} else {
stopJob();
}
}
/**
* @return Returns the refreshInterval in seconds.
*/
public long getRefreshInterval() {
return refreshInterval;
}
public ISynchronizeParticipant getParticipant() {
return refreshable.getParticipant();
}
/**
* @param refreshInterval The refreshInterval to set.
*/
public void setRefreshInterval(long refreshInterval) {
if(refreshInterval != getRefreshInterval()) {
stopJob();
this.refreshInterval = refreshInterval;
runOnce = false;
if(isEnabled()) {
startJob();
}
}
}
public void startJob() {
if(job == null) {
job = refreshable.createJob(getRefreshIntervalAsString());
job.setUser(false);
} else if(job.getState() != Job.NONE){
stopJob();
}
job.setRefreshInterval(getRefreshInterval());
job.setRestartOnCancel(true);
job.setReschedule(!runOnce);
if (refreshStart != null) {
job.schedule(getJobDelay());
} else {
job.schedule();
}
}
/**
* @return schedule delay in milliseconds
*/
private long getJobDelay() {
Calendar now = Calendar.getInstance();
Calendar start = Calendar.getInstance();
start.setTime(refreshStart);
while (now.after(start)) {
start.add(Calendar.DATE, 1); // tomorrow
}
return start.getTimeInMillis() - now.getTimeInMillis();
}
protected void stopJob() {
if(job != null) {
job.setRestartOnCancel(false /* don't restart the job */);
job.setReschedule(false);
job.cancel();
job = null;
}
}
public void dispose() {
stopJob();
RefreshParticipantJob.removeRefreshListener(refreshSubscriberListener);
}
public void saveState(IMemento memento) {
memento.putString(CTX_REFRESHSCHEDULE_ENABLED, Boolean.toString(enabled));
memento.putInteger(CTX_REFRESHSCHEDULE_INTERVAL, (int)refreshInterval);
if (refreshStart != null)
memento.putString(CTX_REFRESHSCHEDULE_START, Long.toString(refreshStart.getTime()));
memento.putString(CTX_REFRESHSCHEDULE_RUNONCE, Boolean.toString(runOnce));
}
public static SubscriberRefreshSchedule init(IMemento memento, IRefreshable refreshable) {
SubscriberRefreshSchedule schedule = new SubscriberRefreshSchedule(refreshable);
if(memento != null) {
String enabled = memento.getString(CTX_REFRESHSCHEDULE_ENABLED);
int interval = memento.getInteger(CTX_REFRESHSCHEDULE_INTERVAL).intValue();
String startString = memento.getString(CTX_REFRESHSCHEDULE_START);
String runOnce = memento.getString(CTX_REFRESHSCHEDULE_RUNONCE);
if (startString != null) {
long start = Long.parseLong(startString);
schedule.setRefreshStartTime(new Date(start));
}
schedule.setRefreshInterval(interval);
schedule.setRunOnce("true".equals(runOnce) ? true : false); //$NON-NLS-1$
schedule.setEnabled("true".equals(enabled) ? true : false, false /* don't start job */); //$NON-NLS-1$
}
// Use the defaults if a schedule hasn't been saved or can't be found.
return schedule;
}
public static String refreshEventAsString(IRefreshEvent event) {
if(event == null) {
return TeamUIMessages.SyncViewPreferencePage_lastRefreshRunNever;
}
long stopMills = event.getStopTime();
StringBuilder text = new StringBuilder();
if(stopMills <= 0) {
text.append(TeamUIMessages.SyncViewPreferencePage_lastRefreshRunNever);
} else {
Date lastTimeRun = new Date(stopMills);
text.append(DateFormat.getDateTimeInstance(DateFormat.SHORT, DateFormat.SHORT).format(lastTimeRun));
}
int changeCount = event.getChangeDescription().getChangeCount();
if (changeCount == 0) {
text.append(TeamUIMessages.RefreshSchedule_7);
} else if (changeCount == 1) {
text.append(NLS.bind(TeamUIMessages.RefreshSchedule_changesSingular, new String[] { Integer.toString(changeCount) }));
} else {
text.append(NLS.bind(TeamUIMessages.RefreshSchedule_changesPlural, new String[] { Integer.toString(changeCount) }));
}
return text.toString();
}
public IRefreshEvent getLastRefreshEvent() {
return lastRefreshEvent;
}
private String getRefreshIntervalAsString() {
if (runOnce)
return TeamUIMessages.RefreshSchedule_16;
boolean hours = false;
long seconds = getRefreshInterval();
if(seconds <= 60) {
seconds = 60;
}
long minutes = seconds / 60;
if(minutes >= 60) {
minutes = minutes / 60;
hours = true;
}
String unit;
if(minutes >= 1) {
unit = (hours ? TeamUIMessages.RefreshSchedule_9 : TeamUIMessages.RefreshSchedule_10);
} else {
unit = (hours ? TeamUIMessages.RefreshSchedule_11 : TeamUIMessages.RefreshSchedule_12);
}
return NLS.bind(TeamUIMessages.RefreshSchedule_13, new String[] { Long.toString(minutes), unit });
}
public IRefreshable getRefreshable() {
return refreshable;
}
/**
* @return The time when the job should start or <code>null</code> when it
* should be run immediately.
*/
public Date getRefreshStartTime() {
return refreshStart;
}
public void setRefreshStartTime(Date refreshStart) {
if(refreshStart==null || refreshStart != getRefreshStartTime()) {
stopJob();
this.refreshStart = refreshStart;
if(isEnabled()) {
startJob();
}
}
}
/**
* @return Return <code>false</code> if the job should be run again when
* finished, or <code>true</code> otherwise.
*/
public boolean getRunOnce() {
return runOnce;
}
public void setRunOnce(boolean runOnce) {
if (runOnce != getRunOnce()) {
stopJob();
this.runOnce = runOnce;
if (isEnabled()) {
startJob();
}
}
}
}