/*******************************************************************************
* Copyright (c) 2016 Pivotal, Inc.
* 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:
* Pivotal, Inc. - initial API and implementation
*******************************************************************************/
package org.springframework.ide.eclipse.boot.dash.util;
import org.eclipse.core.runtime.IProgressMonitor;
import org.springframework.ide.eclipse.boot.dash.util.CancelationTokens.CancelationToken;
/**
* Manages a set of CancelationTokens.
*
* @author Kris De Volder
*/
public class CancelationTokens {
private String DEBUG = null;
//Note: we don't actually have to keep a set of tokens explicitly.
// The tokens use a 'id' which is incremented on each new token.
//So it is easy to cancel all existing tokens based on a their
//id simply by remembering the 'id' where the cancelation
//occurred. All ids 'older' than the current id are 'canceled'.
/**
* An uncancelable token that can be used by operations that don't
* need cancelation support.
*/
public static final CancelationToken NULL = new CancelationToken() {
@Override
public boolean isCanceled() {
return false;
}
};
private final Object SYNC = CancelationTokens.this;
private int canceledAllBefore = 0;
private int nextId = 0;
public CancelationTokens() {
}
public CancelationTokens(String debug) {
this.DEBUG = debug;
}
public interface CancelationToken {
boolean isCanceled();
}
public synchronized CancelationToken create() {
CancelationToken token = new ManagedToken();
debug("creating cancelation token: "+token);
return token;
}
private class ManagedToken implements CancelationToken {
private int id;
private ManagedToken() {
synchronized (SYNC) {
this.id = nextId++;
}
}
public boolean isCanceled() {
synchronized (SYNC) {
boolean isCanceled = id < canceledAllBefore;
debug("isCanceled? ["+id+"] => "+isCanceled);
return isCanceled;
}
}
@Override
public String toString() {
return "CancelToken("+id+")";
}
}
public synchronized void cancelAll() {
canceledAllBefore = nextId;
debug("CancelationTokens < "+canceledAllBefore+" are Canceled");
}
private void debug(String string) {
if (DEBUG!=null) {
System.out.println(DEBUG+": "+string);
}
}
public static CancelationToken merge(CancelationToken cancelationToken, IProgressMonitor monitor) {
return new CancelationToken() {
@Override
public boolean isCanceled() {
return cancelationToken.isCanceled() || monitor.isCanceled();
}
};
}
}