/*
* ARX: Powerful Data Anonymization
* Copyright 2012 - 2017 Fabian Prasser, Florian Kohlmayer and contributors
*
* 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.deidentifier.arx.gui.view.impl.common.async;
import org.eclipse.swt.widgets.Display;
/**
* This class manages the execution of asynchronous analyses.
*
* @author Fabian Prasser
*/
public class AnalysisManager {
/**
* A worker for analyses.
*
* @author Fabian Prasser
*/
private class AnalysisWorker implements Runnable {
/** Stop flag. */
private volatile boolean stopped = false;
/** Analysis to perform. */
private final Analysis analysis;
/** The thread. */
private Thread thread;
/**
* Creates a new instance.
*
* @param analysis
*/
private AnalysisWorker(Analysis analysis){
this.analysis = analysis;
}
/**
* Returns the progress, if any
* @return
*/
public synchronized int getProgress() {
return this.analysis.getProgress();
}
/**
* Returns the thread.
*
* @return
*/
public Thread getThread(){
return this.thread;
}
/**
* Is this analysis stopped.
*
* @return
*/
public synchronized boolean isStopped(){
return this.stopped;
}
@Override
public void run() {
try {
this.analysis.run();
synchronized(this){
if (this.isStopped()) {
onInterrupt();
}
else {
onFinish();
}
}
} catch (InterruptedException e){
onInterrupt();
} catch (Exception e){
onError();
}
}
/**
* Starts this analysis.
*/
public void start(){
this.thread = new Thread(this);
this.thread.setName("StatisticsBuilder"); //$NON-NLS-1$
this.thread.setDaemon(true);
this.thread.start();
}
/**
* Stops this analysis.
*/
public synchronized void stop(){
this.stopped = true;
this.analysis.stop();
}
/**
* Trigger.
*/
private void onError() {
display.asyncExec(new Runnable(){
public void run(){
analysis.onError();
}
});
}
/**
* Trigger.
*/
private void onFinish() {
display.asyncExec(new Runnable(){
public void run(){
analysis.onFinish();
}
});
}
/**
* Trigger.
*/
private void onInterrupt() {
display.asyncExec(new Runnable(){
public void run(){
analysis.onInterrupt();
}
});
}
}
/** The current worker. */
private AnalysisWorker worker = null;
/** The current worker. */
private Display display = null;
/**
* Creates a new instance.
*
* @param display
*/
public AnalysisManager(Display display){
this.display = display;
}
/**
* Returns the progress, if any
* @return
*/
public int getProgress() {
if (worker != null) {
return worker.getProgress();
} else {
return 0;
}
}
/**
* Returns whether a process is running
* @return
*/
public boolean isRunning() {
return worker != null;
}
/**
* Start a new analysis. Analyses already executing
* will be canceled.
*
* @param analysis
*/
public synchronized void start(Analysis analysis) {
// Stop
stop();
// Start new work
worker = new AnalysisWorker(analysis);
worker.start();
}
/**
* Stops all running analysis threads.
*/
public void stop() {
// Stop old work
if (worker != null && !worker.isStopped()) {
worker.stop();
try {
try {
worker.getThread().interrupt();
} catch (SecurityException e) {
/* Ignore*/
}
if (worker.getThread().isAlive()) {
worker.getThread().join();
}
} catch (InterruptedException e) {
/* Ignore*/
}
worker = null;
}
}
}