/* license-start
*
* Copyright (C) 2008 - 2013 Crispico, <http://www.crispico.com/>.
*
* This program 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 version 3.
*
* 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 General Public License for more details, at <http://www.gnu.org/licenses/>.
*
* Contributors:
* Crispico - Initial API and implementation
*
* license-end
*/
package org.flowerplatform.communication.progress_monitor;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.ScheduledFuture;
import java.util.concurrent.TimeUnit;
import org.eclipse.core.runtime.IProgressMonitor;
import org.flowerplatform.communication.CommunicationPlugin;
import org.flowerplatform.communication.channel.CommunicationChannel;
import org.flowerplatform.communication.progress_monitor.remote.ProgressMonitorStatefulLocalClient;
import org.flowerplatform.communication.progress_monitor.remote.ProgressMonitorStatefulService;
import org.flowerplatform.communication.stateful_service.StatefulServiceInvocationContext;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* @author Sorin
*
*/
public class ProgressMonitor implements IProgressMonitor {
public static final Logger logger = LoggerFactory.getLogger(ProgressMonitor.class);
/**
* Public visibility for ProgressMonitorStatefulService to dispose when server stops.
*
*/
public static final ScheduledExecutorService scheduler = CommunicationPlugin.getInstance().getScheduledExecutorServiceFactory().createScheduledExecutorService();
private static final int UPDATE_CLIENT_PERIOD = 500; // TODO configurabil din properties
/**
*
*/
private static int lastUsedId = 0;
private String title;
/**
*
*/
private String statefulClientId;
/**
* Package visibility for ProgressMonitorStatefulService for client method invocation.
*
*/
private CommunicationChannel channel;
/**
*
*/
private String lastName = "";
/**
*
*/
private double workUntilNow = 0;
/**
*
*/
private boolean canceled = false;
private boolean terminated = false;
/**
* Represents the repetitive task that updates the client.
* Referenced to stop when the operation is done.
*
*/
@SuppressWarnings("rawtypes")
private ScheduledFuture updateProgressMonitorTask;
public ProgressMonitor(CommunicationChannel channel, String title, String statefulClientId, boolean createdByServer) {
this.channel = channel;
this.title = title;
this.statefulClientId = createdByServer ? "ServerProgressMonitor" + (++ lastUsedId) : statefulClientId;
}
/**
* Forces the client to create a ProgressMonitorStatefulClient. It returns the WebProgressMonitor
* associated to that stateful client.
*/
public static ProgressMonitor create(String title, CommunicationChannel channel) {
return getService().createProgressMonitor(title, channel);
}
/**
* Creates a non-cancelable progress monitor (without cancel button displayed).
* @author Cristina
*/
public static ProgressMonitor createNonCancelableProgressMonitor(String title, CommunicationChannel channel) {
return getService().createNonCancelableProgressMonitor(title, channel);
}
/**
*
*/
public void beginTask(String name, int totalWork) {
if (updateProgressMonitorTask != null) {
throw new RuntimeException("Progress monitor already started!");
}
if (logger.isTraceEnabled())
logger.trace("Web Progress Monitor " + statefulClientId + ", Begin name = " + name + " totalWork = " + totalWork);
getService().beginProgressMonitor(channel, statefulClientId, name, totalWork);
updateProgressMonitorTask = scheduler.scheduleWithFixedDelay( // Schedule repetitive task to update client
new Runnable() {
@Override
public void run() {
if (logger.isTraceEnabled())
logger.trace("Web Progress Monitor " + statefulClientId + ", Update Client lastName = " + lastName + " workUntilNow = " + workUntilNow);
getService().updateProgressMonitor(channel, statefulClientId, lastName, workUntilNow);
}
},
UPDATE_CLIENT_PERIOD / 5, UPDATE_CLIENT_PERIOD,TimeUnit.MILLISECONDS);
}
/**
*
*/
public void done() {
if (terminated)
return;
terminated = true;
if (logger.isTraceEnabled())
logger.trace("Web Progress Monitor " + statefulClientId + ", Done");
//cancel the task of the progress monitor only if it started
if (updateProgressMonitorTask != null) {
updateProgressMonitorTask.cancel(true);
}
getService().closeProgressMonitor(channel, statefulClientId);
}
/**
*
*/
public void setTaskName(String name) {
subTask(name);
}
/**
*
*/
public void worked(int work) {
internalWorked(work);
}
/**
*
*/
public void subTask(String name) {
if (name == null || name.trim().equals(""))
return; // Actually nothing to update.
lastName = name;
if (logger.isTraceEnabled())
logger.trace("Web Progress Monitor " + statefulClientId + ", name = " + lastName);
}
/**
*
*/
public void internalWorked(double work) {
workUntilNow += work;
if (logger.isTraceEnabled())
logger.trace("Web Progress Monitor " + statefulClientId + ", workUntilNow = " + workUntilNow + ", added work = " + work);
}
/**
*
*/
public void setCanceled(boolean value) {
canceled = value;
}
/**
*
*/
public boolean isCanceled() {
return canceled;
}
/**
* Package visibility because it's used only by the StatefulService.
*/
public String getStatefulClientId() {
return statefulClientId;
}
public CommunicationChannel getChannel() {
return channel;
}
public void setChannel(CommunicationChannel channel) {
this.channel = channel;
}
private static ProgressMonitorStatefulService getService() {
return (ProgressMonitorStatefulService) CommunicationPlugin.getInstance().getServiceRegistry().getService(ProgressMonitorStatefulService.SERVICE_ID);
}
@Override
public String toString() {
return ProgressMonitor.class.getSimpleName() +
" statefulClientId = " + statefulClientId +
", title = " + title +
", lastName = " + lastName +
", workUntilNow = " + workUntilNow +
", canceled = " + canceled +
", done = " + terminated;
}
}