/*
* Copyright (c) 2006 Stiftung Deutsches Elektronen-Synchroton,
* Member of the Helmholtz Association, (DESY), HAMBURG, GERMANY.
*
* THIS SOFTWARE IS PROVIDED UNDER THIS LICENSE ON AN "../AS IS" BASIS.
* WITHOUT WARRANTY OF ANY KIND, EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED
* TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR PARTICULAR PURPOSE AND
* NON-INFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE
* FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR
* THE USE OR OTHER DEALINGS IN THE SOFTWARE. SHOULD THE SOFTWARE PROVE DEFECTIVE
* IN ANY RESPECT, THE USER ASSUMES THE COST OF ANY NECESSARY SERVICING, REPAIR OR
* CORRECTION. THIS DISCLAIMER OF WARRANTY CONSTITUTES AN ESSENTIAL PART OF THIS LICENSE.
* NO USE OF ANY SOFTWARE IS AUTHORIZED HEREUNDER EXCEPT UNDER THIS DISCLAIMER.
* DESY HAS NO OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS,
* OR MODIFICATIONS.
* THE FULL LICENSE SPECIFYING FOR THE SOFTWARE THE REDISTRIBUTION, MODIFICATION,
* USAGE AND OTHER RIGHTS AND OBLIGATIONS IS INCLUDED WITH THE DISTRIBUTION OF THIS
* PROJECT IN THE FILE LICENSE.HTML. IF THE LICENSE IS NOT INCLUDED YOU MAY FIND A COPY
* AT HTTP://WWW.DESY.DE/LEGAL/LICENSE.HTM
*/
package org.csstudio.sds.components.ui.internal.editparts;
import java.util.concurrent.ScheduledFuture;
import java.util.concurrent.TimeUnit;
import org.csstudio.sds.components.model.TimerModel;
import org.csstudio.sds.components.ui.internal.figures.RefreshableTimerFigure;
import org.csstudio.sds.internal.model.logic.ScriptEngine;
import org.csstudio.sds.model.AbstractWidgetModel;
import org.csstudio.sds.model.IScript;
import org.csstudio.sds.ui.CheckedUiRunnable;
import org.csstudio.sds.ui.editparts.AbstractWidgetEditPart;
import org.csstudio.sds.ui.editparts.ExecutionMode;
import org.csstudio.sds.ui.editparts.IWidgetPropertyChangeHandler;
import org.csstudio.sds.ui.scripting.RunnableScript;
import org.csstudio.sds.util.ExecutionService;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.IPath;
import org.eclipse.draw2d.IFigure;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* EditPart controller for the Rectangle widget. The controller mediates between
* {@link TimerModel} and {@link RefreshableTimerFigure}.
*
* @author Kai Meyer & Sven Wende
*
*/
public final class TimerEditPart extends AbstractWidgetEditPart {
private static final Logger LOG = LoggerFactory.getLogger(TimerEditPart.class);
private long _lastExecution;
private ScheduledFuture _scheduledFuture1;
private ScheduledFuture _scheduledFuture2;
/**
* The used {@link ScriptEngine}.
*/
private ScriptEngine _scriptEngine;
/**
* {@inheritDoc}
*/
@Override
public void activate() {
super.activate();
startScriptExecution();
}
/**
* {@inheritDoc}
*/
@Override
public void deactivate() {
cancelScriptExecution();
super.deactivate();
}
/**
* {@inheritDoc}
*/
@Override
protected IFigure doCreateFigure() {
TimerModel timerModel = getTimerModel();
RefreshableTimerFigure timerFigure = new RefreshableTimerFigure();
timerFigure.setVisible(timerModel.isVisible());
return timerFigure;
}
/**
* Return the associated {@link TimerModel}.
*
* @return The TimerModel
*/
private TimerModel getTimerModel() {
return (TimerModel) this.getCastedModel();
}
/**
* Configures the internal timer.
*/
private void startScriptExecution() {
final TimerModel model = this.getTimerModel();
if (model.isAccesible() && model.getDelay() > 0
&& model.getScriptPath() != null
&& getExecutionMode().equals(ExecutionMode.RUN_MODE)
&& _scheduledFuture1 == null && _scheduledFuture2 == null) {
IPath path = model.getScriptPath();
if (!path.isEmpty()) {
IFile file = ResourcesPlugin.getWorkspace().getRoot().getFile(
path);
try {
// load the script
IScript script = new RunnableScript(file.getName(), file
.getContents());
_scriptEngine = new ScriptEngine(script);
// runnable for the script execution
Runnable r = new Runnable() {
@Override
public void run() {
if (_scriptEngine != null) {
Thread t = new Thread(new Runnable() {
@Override
public void run() {
_scriptEngine.processScript();
}
});
t.start();
_lastExecution = System.currentTimeMillis();
}
}
};
// runnable for updating the figure to see the progress
Runnable r2 = new Runnable() {
@Override
public void run() {
new CheckedUiRunnable() {
@Override
protected void doRunInUi() {
long t = System.currentTimeMillis()
- _lastExecution;
double p = Math.min(1.0, (double) t
/ model.getDelay());
RefreshableTimerFigure figure = (RefreshableTimerFigure) getFigure();
figure.setPercentage(p);
}
};
}
};
_lastExecution = System.currentTimeMillis();
// schedule the runnables
_scheduledFuture1 = ExecutionService.getInstance()
.getScheduledExecutorService().scheduleAtFixedRate(
r, model.getDelay(), model.getDelay(),
TimeUnit.MILLISECONDS);
_scheduledFuture2 = ExecutionService.getInstance()
.getScheduledExecutorService().scheduleAtFixedRate(
r2, 100, 100, TimeUnit.MILLISECONDS);
} catch (Exception e) {
LOG.error("Could not start timer.");
}
}
}
}
/**
* {@inheritDoc}
*/
@Override
protected void registerPropertyChangeHandlers() {
IWidgetPropertyChangeHandler handler = new IWidgetPropertyChangeHandler() {
@Override
public boolean handleChange(final Object oldValue,
final Object newValue, final IFigure refreshableFigure) {
cancelScriptExecution();
startScriptExecution();
return true;
}
};
setPropertyChangeHandler(AbstractWidgetModel.PROP_ENABLED, handler);
setPropertyChangeHandler(TimerModel.PROP_DELAY, handler);
setPropertyChangeHandler(TimerModel.PROP_SCRIPT, handler);
setPropertyChangeHandler(TimerModel.PROP_ACCESS_GRANTED, handler);
}
private void cancelScriptExecution() {
_scriptEngine = null;
if (_scheduledFuture1 != null) {
_scheduledFuture1.cancel(true);
_scheduledFuture1 = null;
}
if (_scheduledFuture2 != null) {
_scheduledFuture2.cancel(true);
_scheduledFuture2 = null;
}
}
}