/* AbstractReaderDocument.java created 2007-09-20 * */ package org.signalml.app.document.signal; import static org.signalml.app.util.i18n.SvarogI18n._; import java.beans.IntrospectionException; import java.io.File; import java.util.Arrays; import java.util.HashMap; import java.util.List; import org.signalml.app.document.FileBackedDocument; import org.signalml.app.model.components.LabelledPropertyDescriptor; import org.signalml.app.worker.signal.SignalChecksumWorker; import org.signalml.domain.signal.SignalChecksum; import org.signalml.plugin.export.SignalMLException; import org.signalml.util.Util; /** * Abstract implementation of {@link FileBackedDocument}. * Apart from what can be found in {@link AbstractSignal}, contains * the {@link #getBackingFile() backing file} and implements the calculation * of the {@link SignalChecksum signal checksums} (using the provided * {@link SignalChecksumWorker worker}). * * @author Michal Dobaczewski © 2007-2008 CC Otwarte Systemy Komputerowe Sp. z o.o. */ public abstract class AbstractFileSignal extends AbstractSignal implements FileBackedDocument { /** * the file with which this document is backed */ protected File backingFile = null; /** * {@code HashMap} associating the names of the types of * {@link SignalChecksum checksums} with the calculated checksums * for this signal */ protected HashMap<String,SignalChecksum> checksums = new HashMap<String,SignalChecksum>(); /** * the {@link SignalChecksumWorker worker} responsible for calculating * the {@link SignalChecksum checksums} */ protected volatile SignalChecksumWorker precalculatingWorker; /** * Constructor. */ public AbstractFileSignal() { super(); } @Override public void closeDocument() throws SignalMLException { super.closeDocument(); if (precalculatingWorker != null) { if (!precalculatingWorker.isDone()) { precalculatingWorker.cancel(true); } precalculatingWorker = null; } } @Override public File getBackingFile() { return backingFile; } @Override public void setBackingFile(File backingFile) { this.backingFile = backingFile; } /** * Returns the {@link SignalChecksumWorker worker} responsible for * calculating the {@link SignalChecksum checksums}. * @return the worker responsible for calculating the checksums */ public SignalChecksumWorker getPrecalculatingWorker() { return precalculatingWorker; } /** * Sets the {@link SignalChecksumWorker worker} responsible for * calculating the {@link SignalChecksum checksums}. * @param precalculatingWorker the worker responsible for calculating the * checksums */ public void setPrecalculatingWorker(SignalChecksumWorker precalculatingWorker) { this.precalculatingWorker = precalculatingWorker; } @Override public String getName() { return (backingFile != null ? backingFile.getName() : ""); } @Override public SignalChecksum[] getChecksums(String[] types, SignalChecksumProgressMonitor monitor) throws SignalMLException { synchronized (checksums) { SignalChecksum[] checksumArr = new SignalChecksum[types.length]; int[] missingIdx = new int[types.length]; String[] missing = new String[types.length]; int missingCnt = 0; SignalChecksum checksum; int i; for (i=0; i<types.length; i++) { checksum = checksums.get(types[i]); if (checksum == null) { missing[missingCnt] = types[i]; missingIdx[missingCnt] = i; missingCnt++; } else { checksumArr[i] = checksum; } } if (missingCnt == 0) { return checksumArr; } String[] missingTypes = Arrays.copyOf(missing, missingCnt); SignalChecksum[] results = Util.getSignalChecksums(backingFile, missingTypes, monitor); for (i=0; i<results.length; i++) { checksums.put(results[i].getMethod(), results[i]); checksumArr[missingIdx[i]] = results[i]; } return checksumArr; } } @Override public List<LabelledPropertyDescriptor> getPropertyList() throws IntrospectionException { List<LabelledPropertyDescriptor> list = super.getPropertyList(); list.add(new LabelledPropertyDescriptor(_("backing file"), "backingFile", AbstractFileSignal.class)); return list; } }