package jalview.workers; import java.util.ArrayList; import java.util.HashSet; import java.util.Hashtable; import java.util.List; import java.util.Map; import jalview.api.AlignCalcManagerI; import jalview.api.AlignCalcWorkerI; import jalview.datamodel.AlignmentAnnotation; public class AlignCalcManager implements AlignCalcManagerI { private volatile List restartable = new ArrayList(); private List blackList = new ArrayList(); /** * global record of calculations in progress */ private static Hashtable inProgress = new Hashtable(); /** * record of calculations pending or in progress in the current context */ private Map> updating = new Hashtable>(); @Override public void notifyStart(AlignCalcWorkerI worker) { List upd = updating.get(worker.getClass()); if (upd == null) { updating.put(worker.getClass(), upd = new ArrayList()); } upd.add(worker); } @Override public synchronized boolean alreadyDoing(AlignCalcWorkerI worker) { return inProgress.containsKey(worker.getClass()); } @Override public synchronized boolean notifyWorking(AlignCalcWorkerI worker) { // synchronized (inProgress) { // TODO: decide if we should throw exceptions here if multiple workers // start to work if (inProgress.get(worker.getClass()) != null) { if (false) { System.err .println("Warning: Multiple workers are running of type " + worker.getClass()); } return false; } inProgress.put(worker.getClass(), worker); } return true; } private HashSet canUpdate=new HashSet(); @Override public synchronized void workerComplete(AlignCalcWorkerI worker) { inProgress.remove(worker.getClass()); List upd = updating.get(worker.getClass()); if (upd != null) { upd.remove(worker); canUpdate.add(worker); } } @Override public void workerCannotRun(AlignCalcWorkerI worker) { blackList.add(worker.getClass()); } public boolean isBlackListed(Class workerType) { return blackList.contains(workerType); } @Override public void startWorker(AlignCalcWorkerI worker) { new Thread(worker).start(); } @Override public synchronized boolean isWorking(AlignCalcWorkerI worker) { // System.err.println("isWorking : worker "+(worker!=null ? // worker.getClass():"null")+ " "+hashCode()); return worker != null && inProgress.get(worker.getClass()) == worker; } @Override public boolean isWorking() { // System.err.println("isWorking "+hashCode()); return inProgress.size() > 0; } @Override public void registerWorker(AlignCalcWorkerI worker) { if (!restartable.contains(worker)) { restartable.add(worker); } startWorker(worker); } @Override public void restartWorkers() { for (AlignCalcWorkerI worker : restartable) { startWorker(worker); } } @Override public boolean workingInvolvedWith(AlignmentAnnotation alignmentAnnotation) { if (isWorking()) { for (List workers: updating.values()) { for (AlignCalcWorkerI worker:workers) if (worker.involves(alignmentAnnotation)) { return true; } } } return false; } @Override public void updateAnnotationFor(Class workerClass) { for (AlignCalcWorkerI worker:canUpdate.toArray(new AlignCalcWorkerI[0])) { if (workerClass.equals(worker.getClass())) { worker.updateAnnotation(); } } } @Override public List getRegisteredWorkersOfClass( Class workerClass) { List workingClass=new ArrayList(); for (AlignCalcWorkerI worker:canUpdate.toArray(new AlignCalcWorkerI[0])) { if (workerClass.equals(worker.getClass())) { workingClass.add(worker); } } return (workingClass.size()==0) ? null : workingClass; } @Override public boolean startRegisteredWorkersOfClass(Class workerClass) { List workers=getRegisteredWorkersOfClass(workerClass); if (workers==null) { return false; } for (AlignCalcWorkerI worker: workers) { startWorker(worker); } return true; } @Override public void workerMayRun(AlignCalcWorkerI worker) { if (blackList.contains(worker.getClass())) { blackList.remove(worker.getClass()); } } }