tikhomirov@520: /* tikhomirov@520: * Copyright (c) 2012 TMate Software Ltd tikhomirov@520: * tikhomirov@520: * This program is free software; you can redistribute it and/or modify tikhomirov@520: * it under the terms of the GNU General Public License as published by tikhomirov@520: * the Free Software Foundation; version 2 of the License. tikhomirov@520: * tikhomirov@520: * This program is distributed in the hope that it will be useful, tikhomirov@520: * but WITHOUT ANY WARRANTY; without even the implied warranty of tikhomirov@520: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the tikhomirov@520: * GNU General Public License for more details. tikhomirov@520: * tikhomirov@520: * For information on how to redistribute this software under tikhomirov@520: * the terms of a license other than GNU General Public License tikhomirov@520: * contact TMate Software at support@hg4j.com tikhomirov@520: */ tikhomirov@520: package org.tmatesoft.hg.internal; tikhomirov@520: tikhomirov@520: import org.tmatesoft.hg.util.CancelSupport; tikhomirov@520: import org.tmatesoft.hg.util.CancelledException; tikhomirov@520: import org.tmatesoft.hg.util.ProgressSupport; tikhomirov@520: tikhomirov@520: /** tikhomirov@520: * Bridge low-level life-cycle ({@link Lifecycle}) API with high-level one ({@link ProgressSupport} and {@link CancelSupport}). tikhomirov@520: * tikhomirov@520: * @author Artem Tikhomirov tikhomirov@520: * @author TMate Software Ltd. tikhomirov@520: */ tikhomirov@520: public class LifecycleBridge implements Lifecycle { tikhomirov@520: private final ProgressSupport progressHelper; tikhomirov@520: private final CancelSupport cancelSupport; tikhomirov@520: // may be null unless #start() is invoked tikhomirov@520: private Callback receiver; tikhomirov@520: private CancelledException cancellation; tikhomirov@520: tikhomirov@520: tikhomirov@520: public LifecycleBridge(ProgressSupport progress, CancelSupport cancel) { tikhomirov@520: progressHelper = progress; tikhomirov@520: cancelSupport = cancel; tikhomirov@520: } tikhomirov@520: tikhomirov@520: public void start(int count, Callback callback, Object token) { tikhomirov@520: receiver = callback; tikhomirov@520: if (progressHelper != null) { tikhomirov@520: progressHelper.start(count); tikhomirov@520: } tikhomirov@520: } tikhomirov@520: tikhomirov@520: public void finish(Object token) { tikhomirov@520: if (progressHelper != null) { tikhomirov@520: progressHelper.done(); tikhomirov@520: } tikhomirov@520: receiver = null; tikhomirov@520: } tikhomirov@520: tikhomirov@520: // XXX SHALL work without start/finish sequence because tikhomirov@520: // HgLogCommand invokes ChangesetTransformer#next directly (i.e. not from tikhomirov@520: // inside a library's #range() or similar) to process changesets in unnatural order. tikhomirov@520: public void nextStep() { tikhomirov@520: if (progressHelper != null) { tikhomirov@520: progressHelper.worked(1); tikhomirov@520: } tikhomirov@520: if (cancelSupport == null) { tikhomirov@520: return; tikhomirov@520: } tikhomirov@520: try { tikhomirov@520: cancelSupport.checkCancelled(); tikhomirov@520: } catch (CancelledException ex) { tikhomirov@520: if (receiver != null) { tikhomirov@520: receiver.stop(); tikhomirov@520: } tikhomirov@520: cancellation = ex; tikhomirov@520: } tikhomirov@520: } tikhomirov@520: tikhomirov@520: public void stop() { tikhomirov@520: if (receiver != null) { tikhomirov@520: receiver.stop(); tikhomirov@520: } tikhomirov@520: } tikhomirov@520: tikhomirov@520: /** tikhomirov@520: * @return true iff {@link CancelledException} was thrown and catched. Forced stop doesn't count tikhomirov@520: */ tikhomirov@520: public boolean isCancelled() { tikhomirov@520: return cancellation != null; tikhomirov@520: } tikhomirov@520: tikhomirov@520: public CancelledException getCancelOrigin() { tikhomirov@520: return cancellation; tikhomirov@520: } tikhomirov@520: }