/******************************************************************************* * 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(); } }; } }