/* * $Id$ * * Copyright 2007 Glencoe Software, Inc. All rights reserved. * Use is subject to license terms supplied in LICENSE.txt */ package ome.services.procs; import java.util.HashSet; import java.util.Set; import ome.conditions.ApiUsageException; import org.slf4j.Logger; import org.slf4j.LoggerFactory; /** * * @author Josh Moore, josh at glencoesoftware.com * @since 3.0-Beta3 */ public class ProcessSkeleton implements Process { private final Logger log; private final Set<ProcessCallback> cbs = new HashSet<ProcessCallback>(); private final Processor processor; private boolean cancelled, finished; public ProcessSkeleton(Processor p) { this.processor = p; this.log = LoggerFactory.getLogger(this.getClass()); } public Processor processor() { return this.processor; } public void registerCallback(ProcessCallback cb) { synchronized (cbs) { checkState(); boolean added = cbs.add(cb); debug("Added", cb, added); } } public void unregisterCallback(ProcessCallback cb) { synchronized (cbs) { checkState(); boolean removed = cbs.remove(cb); debug("removed", cb, removed); } } public void cancel() { synchronized (cbs) { checkState(); for (ProcessCallback cb : cbs) { try { cb.processCancelled(this); } catch (Exception e) { log .warn(String.format("Exception thrown by %s while " + "cancelling %s. Removing callback.", cb, this), e); cbs.remove(cb); } } cbs.clear(); cancelled = true; if (log.isDebugEnabled()) { log.debug("Process cancelled: " + this); } } } public void finish() { synchronized (cbs) { checkState(); for (ProcessCallback cb : cbs) { try { cb.processFinished(this); } catch (Exception e) { log.warn(String.format("Exception throw by %s while " + "finished %s. Removing callback.", cb, this), e); cbs.remove(cb); } } cbs.clear(); finished = true; if (log.isDebugEnabled()) { log.debug("Process finished: " + this); } } } public boolean isActive() { return !cancelled && !finished; } protected void checkState() { if (!isActive()) { String state = cancelled ? "cancelled" : "finished"; throw new ApiUsageException(String.format("Process already %s: %s", state, this)); } } private void debug(String action, ProcessCallback cb, boolean added) { if (log.isDebugEnabled()) { if (added) { log.debug(String.format("%s %s to %s", cb, action, this)); } else { log.debug(String .format("%s already %s to %s", cb, action, this)); } } } }