diff --git a/common/source/java/ch/systemsx/cisd/common/filesystem/DirectoryScannedStore.java b/common/source/java/ch/systemsx/cisd/common/filesystem/DirectoryScannedStore.java index 52b68764ebde37491395deaf1a58d3118a6c94bd..099df325dd0014ea97221656b25d86d1e69dfacd 100644 --- a/common/source/java/ch/systemsx/cisd/common/filesystem/DirectoryScannedStore.java +++ b/common/source/java/ch/systemsx/cisd/common/filesystem/DirectoryScannedStore.java @@ -20,6 +20,7 @@ import java.io.FileFilter; import java.util.ArrayList; import java.util.List; +import org.apache.commons.io.FilenameUtils; import org.apache.commons.lang.StringUtils; import ch.systemsx.cisd.common.filesystem.DirectoryScanningTimerTask.IScannedStore; @@ -54,6 +55,11 @@ public final class DirectoryScannedStore implements IScannedStore return StoreItem.asFile(directory, item).getPath(); } + public StoreItem asStoreItem(String locationDescription) + { + return new StoreItem(FilenameUtils.getName(locationDescription)); + } + public final boolean existsOrError(final StoreItem item) { return StoreItem.asFile(directory, item).exists(); diff --git a/common/source/java/ch/systemsx/cisd/common/filesystem/DirectoryScanningHandlerInterceptor.java b/common/source/java/ch/systemsx/cisd/common/filesystem/DirectoryScanningHandlerInterceptor.java index 381c439c1da4a952a4ed2829ba1a7e70ec51a142..19cae99460dffd2a9c3cf85c3ce343e4c75eb168 100644 --- a/common/source/java/ch/systemsx/cisd/common/filesystem/DirectoryScanningHandlerInterceptor.java +++ b/common/source/java/ch/systemsx/cisd/common/filesystem/DirectoryScanningHandlerInterceptor.java @@ -40,9 +40,14 @@ public class DirectoryScanningHandlerInterceptor implements IDirectoryScanningHa // IDirectoryScanningHandler // - public void beforeHandle() + public void init(IScannedStore scannedStore) { - directoryScanningHandler.beforeHandle(); + directoryScanningHandler.init(scannedStore); + } + + public void beforeHandle(IScannedStore scannedStore) + { + directoryScanningHandler.beforeHandle(scannedStore); } public HandleInstruction mayHandle(final IScannedStore scannedStore, final StoreItem storeItem) diff --git a/common/source/java/ch/systemsx/cisd/common/filesystem/DirectoryScanningTimerTask.java b/common/source/java/ch/systemsx/cisd/common/filesystem/DirectoryScanningTimerTask.java index ffac6f3b64ba0926f18fa5562c746ca18c779980..bc69916863b578b1dc1ebd8b2496ae5457bda0a0 100644 --- a/common/source/java/ch/systemsx/cisd/common/filesystem/DirectoryScanningTimerTask.java +++ b/common/source/java/ch/systemsx/cisd/common/filesystem/DirectoryScanningTimerTask.java @@ -230,6 +230,7 @@ public final class DirectoryScanningTimerTask extends TimerTask implements ITime { didSomeWork = false; int numberOfItemsProcessedInLastRound; + directoryScanningHandler.init(sourceDirectory); do { numberOfItemsProcessedInLastRound = 0; @@ -258,7 +259,7 @@ public final class DirectoryScanningTimerTask extends TimerTask implements ITime break; } final int numberOfItems = storeItemsOrNull.length; - directoryScanningHandler.beforeHandle(); + directoryScanningHandler.beforeHandle(sourceDirectory); if (operationLog.isTraceEnabled()) { operationLog.trace("beforeHandle() completed."); @@ -447,6 +448,12 @@ public final class DirectoryScanningTimerTask extends TimerTask implements ITime * assumed that the result is the path which could be used in java.io.File constructor. */ String getLocationDescription(StoreItem item); + + /** + * Constructs a {@link StoreItem} from a location description as created by + * {@link #getLocationDescription(StoreItem)}. + */ + StoreItem asStoreItem(String locationDescription); } } diff --git a/common/source/java/ch/systemsx/cisd/common/filesystem/FaultyPathDirectoryScanningHandler.java b/common/source/java/ch/systemsx/cisd/common/filesystem/FaultyPathDirectoryScanningHandler.java index 2ddd91f9abe69af112417d8501fdad49ed490457..724fc60582cfc9bd51d14dc49518638740e7c050 100644 --- a/common/source/java/ch/systemsx/cisd/common/filesystem/FaultyPathDirectoryScanningHandler.java +++ b/common/source/java/ch/systemsx/cisd/common/filesystem/FaultyPathDirectoryScanningHandler.java @@ -18,6 +18,7 @@ package ch.systemsx.cisd.common.filesystem; import java.io.File; import java.util.HashSet; +import java.util.Iterator; import java.util.Set; import org.apache.log4j.Logger; @@ -46,7 +47,7 @@ public final class FaultyPathDirectoryScanningHandler implements IDirectoryScann private static final Logger operationLog = LogFactory.getLogger(LogCategory.OPERATION, FaultyPathDirectoryScanningHandler.class); - private final Set<String> faultyPaths; + private final Set<StoreItem> faultyPaths; private final File faultyPathsFile; @@ -57,12 +58,31 @@ public final class FaultyPathDirectoryScanningHandler implements IDirectoryScann public FaultyPathDirectoryScanningHandler(final File faultyPathDirectory, final IStopSignaler stopSignaler) { - this.faultyPaths = new HashSet<String>(); + this.faultyPaths = new HashSet<StoreItem>(); this.faultyPathsFile = new File(faultyPathDirectory, Constants.FAULTY_PATH_FILENAME); this.stopSignaler = stopSignaler; } + + private Set<String> faultyPathsAsStrings(IScannedStore scannedStore) + { + final Set<String> faultyPathStrings = new HashSet<String>(faultyPaths.size()); + for (StoreItem item : faultyPaths) + { + faultyPathStrings.add(scannedStore.getLocationDescription(item)); + } + return faultyPathStrings; + } + + private void setFaultyPathsFromStrings(IScannedStore scannedStore, Set<String> faultyPathStrings) + { + faultyPaths.clear(); + for (String faultyPath : faultyPathStrings) + { + faultyPaths.add(scannedStore.asStoreItem(faultyPath)); + } + } - private final void checkForFaultyPathsFileChanged() + private final void checkForFaultyPathsFileChanged(IScannedStore scannedStore) { if (faultyPathsFile.exists()) { @@ -70,7 +90,9 @@ public final class FaultyPathDirectoryScanningHandler implements IDirectoryScann if (faultyPathsFile.lastModified() > faultyPathsLastChanged) { faultyPaths.clear(); - CollectionIO.readCollection(faultyPathsFile, faultyPaths); + final Set<String> faultyPathStrings = new HashSet<String>(); + CollectionIO.readCollection(faultyPathsFile, faultyPathStrings); + setFaultyPathsFromStrings(scannedStore, faultyPathStrings); faultyPathsLastChanged = faultyPathsFile.lastModified(); if (operationLog.isInfoEnabled()) { @@ -92,12 +114,6 @@ public final class FaultyPathDirectoryScanningHandler implements IDirectoryScann return file.getPath(); } - private final boolean isFaultyPath(final IScannedStore scannedStore, final StoreItem storeItem) - { - final String path = scannedStore.getLocationDescription(storeItem); - return faultyPaths.contains(path); - } - private final boolean isFaultyPathsFile(final IScannedStore scannedStore, final StoreItem storeItem) { @@ -108,20 +124,20 @@ public final class FaultyPathDirectoryScanningHandler implements IDirectoryScann private final void addToFaultyPaths(final IScannedStore scannedStore, final StoreItem item) { - final String path = scannedStore.getLocationDescription(item); if (operationLog.isDebugEnabled()) { + final String path = scannedStore.getLocationDescription(item); operationLog.debug(String.format( - "Following path '%s' has been added to faulty paths file '%s'", path, + "Path '%s' has been added to faulty paths file '%s'", path, faultyPathsFile.getAbsolutePath())); } - faultyPaths.add(path); - refreshFaultyPathsFile(); + faultyPaths.add(item); + refreshFaultyPathsFile(scannedStore); } - private final void refreshFaultyPathsFile() + private final void refreshFaultyPathsFile(IScannedStore scannedStore) { - CollectionIO.writeIterable(faultyPathsFile, faultyPaths); + CollectionIO.writeIterable(faultyPathsFile, faultyPathsAsStrings(scannedStore)); faultyPathsLastChanged = faultyPathsFile.lastModified(); } @@ -129,9 +145,28 @@ public final class FaultyPathDirectoryScanningHandler implements IDirectoryScann // IDirectoryScanningHandler // - public final void beforeHandle() + public void init(IScannedStore scannedStore) + { + final Iterator<StoreItem> it = faultyPaths.iterator(); + boolean changedFaultyPaths = false; + while (it.hasNext()) + { + final StoreItem item = it.next(); + if (scannedStore.existsOrError(item) == false) + { + it.remove(); + changedFaultyPaths = true; + } + } + if (changedFaultyPaths) + { + refreshFaultyPathsFile(scannedStore); + } + } + + public final void beforeHandle(IScannedStore scannedStore) { - checkForFaultyPathsFileChanged(); + checkForFaultyPathsFileChanged(scannedStore); } public final HandleInstruction mayHandle(final IScannedStore scannedStore, @@ -140,7 +175,7 @@ public final class FaultyPathDirectoryScanningHandler implements IDirectoryScann if (isFaultyPathsFile(scannedStore, storeItem)) { return HandleInstruction.IGNORE; - } else if (isFaultyPath(scannedStore, storeItem)) + } else if (faultyPaths.contains(storeItem)) { return HandleInstruction.createError("Known bad item '%s'.", storeItem); } else diff --git a/common/source/java/ch/systemsx/cisd/common/filesystem/IDirectoryScanningHandler.java b/common/source/java/ch/systemsx/cisd/common/filesystem/IDirectoryScanningHandler.java index c9ee9e9000995b5f2ad258fa26f0a395a3441118..3f8c4f264d3b5ac79f5e9eaaed6a149b44b45845 100644 --- a/common/source/java/ch/systemsx/cisd/common/filesystem/IDirectoryScanningHandler.java +++ b/common/source/java/ch/systemsx/cisd/common/filesystem/IDirectoryScanningHandler.java @@ -94,10 +94,15 @@ public interface IDirectoryScanningHandler } } + /** + * Run once before the handler is used. + */ + public void init(IScannedStore scannedStore); + /** * Is performed just before handling all the items contained in the store. */ - public void beforeHandle(); + public void beforeHandle(IScannedStore scannedStore); /** * Whether given <code>storeItem</code> found in given <var>scannedStore</var> should be diff --git a/datamover/source/java/ch/systemsx/cisd/datamover/FileScannedStore.java b/datamover/source/java/ch/systemsx/cisd/datamover/FileScannedStore.java index 7088a2886a68482321df01c8e36ace02e7f1c1f5..795e8002c415078b9293ff342ce8861f9dd072bc 100644 --- a/datamover/source/java/ch/systemsx/cisd/datamover/FileScannedStore.java +++ b/datamover/source/java/ch/systemsx/cisd/datamover/FileScannedStore.java @@ -22,9 +22,9 @@ import org.apache.commons.lang.StringUtils; import ch.systemsx.cisd.common.Constants; import ch.systemsx.cisd.common.filesystem.BooleanStatus; +import ch.systemsx.cisd.common.filesystem.DirectoryScanningTimerTask.IScannedStore; import ch.systemsx.cisd.common.filesystem.IStoreItemFilter; import ch.systemsx.cisd.common.filesystem.StoreItem; -import ch.systemsx.cisd.common.filesystem.DirectoryScanningTimerTask.IScannedStore; import ch.systemsx.cisd.common.logging.ISimpleLogger; import ch.systemsx.cisd.common.logging.LogLevel; import ch.systemsx.cisd.datamover.filesystem.intf.IFileStore; @@ -72,6 +72,11 @@ final class FileScannedStore implements IScannedStore return fileStore.getLocationDescription(item); } + public StoreItem asStoreItem(String locationDescription) + { + return fileStore.asStoreItem(locationDescription); + } + public StoreItem[] tryListSorted(ISimpleLogger loggerOrNull) { // Older items will be handled before newer items. This becomes important when doing online diff --git a/datamover/source/java/ch/systemsx/cisd/datamover/filesystem/intf/IFileStore.java b/datamover/source/java/ch/systemsx/cisd/datamover/filesystem/intf/IFileStore.java index 96929a35727f911a8a885ccd28c4fcbd0f5a0963..89d0e45fedf493d78a76fa0490f0e90c2300189b 100644 --- a/datamover/source/java/ch/systemsx/cisd/datamover/filesystem/intf/IFileStore.java +++ b/datamover/source/java/ch/systemsx/cisd/datamover/filesystem/intf/IFileStore.java @@ -102,6 +102,12 @@ public interface IFileStore extends ISelfTestable, ILastModificationChecker */ public String getLocationDescription(StoreItem item); + /** + * Constructs a {@link StoreItem} from a location description as created by + * {@link #getLocationDescription(StoreItem)}. + */ + StoreItem asStoreItem(String locationDescription); + /** * Returns this file store as an extended file store if possible. * diff --git a/datamover/source/java/ch/systemsx/cisd/datamover/filesystem/store/FileStoreLocal.java b/datamover/source/java/ch/systemsx/cisd/datamover/filesystem/store/FileStoreLocal.java index b7e9fb40e67339cd13b6c5549f1bc2280e9f0a74..4e457617ae723ca7d454fcfe63a82dde7b1f2fd3 100644 --- a/datamover/source/java/ch/systemsx/cisd/datamover/filesystem/store/FileStoreLocal.java +++ b/datamover/source/java/ch/systemsx/cisd/datamover/filesystem/store/FileStoreLocal.java @@ -20,6 +20,7 @@ import java.io.File; import java.io.IOException; import org.apache.commons.io.FileUtils; +import org.apache.commons.io.FilenameUtils; import org.apache.commons.lang.time.DateUtils; import org.apache.log4j.Logger; @@ -185,6 +186,11 @@ public class FileStoreLocal extends AbstractFileStore implements IExtendedFileSt return getChildFile(item).getPath(); } + public StoreItem asStoreItem(String locationDescription) + { + return new StoreItem(FilenameUtils.getName(locationDescription)); + } + public final StoreItem[] tryListSortByLastModified(final ISimpleLogger loggerOrNull) { final File[] files = FileUtilities.tryListFiles(getPath(), loggerOrNull); diff --git a/datamover/source/java/ch/systemsx/cisd/datamover/filesystem/store/FileStoreRemote.java b/datamover/source/java/ch/systemsx/cisd/datamover/filesystem/store/FileStoreRemote.java index 1370893d349604adc090d585e2482e4d2c4a7042..4df1e918012b87b362edf41fd931cf6ce8c1f24b 100644 --- a/datamover/source/java/ch/systemsx/cisd/datamover/filesystem/store/FileStoreRemote.java +++ b/datamover/source/java/ch/systemsx/cisd/datamover/filesystem/store/FileStoreRemote.java @@ -19,6 +19,7 @@ package ch.systemsx.cisd.datamover.filesystem.store; import java.io.File; import java.util.List; +import org.apache.commons.io.FilenameUtils; import org.apache.commons.lang.StringUtils; import org.apache.log4j.Logger; @@ -476,6 +477,15 @@ public class FileStoreRemote extends AbstractFileStore return getHost() + ":" + getChildFile(item).getPath(); } + public StoreItem asStoreItem(String locationDescription) + { + final int beginIndex = locationDescription.indexOf(':'); + final String path = + (beginIndex < 0) ? locationDescription : locationDescription + .substring(beginIndex + 1); + return new StoreItem(FilenameUtils.getName(path)); + } + private String getHost() { final String host = tryGetHost(); diff --git a/datamover/source/java/ch/systemsx/cisd/datamover/filesystem/store/FileStoreRemoteMounted.java b/datamover/source/java/ch/systemsx/cisd/datamover/filesystem/store/FileStoreRemoteMounted.java index bb859d27e49c104f58f69eb518b05ed0fca5f5aa..68137dca3bb130fc49affec2383fd9d48cc6daa8 100644 --- a/datamover/source/java/ch/systemsx/cisd/datamover/filesystem/store/FileStoreRemoteMounted.java +++ b/datamover/source/java/ch/systemsx/cisd/datamover/filesystem/store/FileStoreRemoteMounted.java @@ -84,6 +84,11 @@ public final class FileStoreRemoteMounted extends AbstractFileStore return localImpl.getLocationDescription(item); } + public StoreItem asStoreItem(String locationDescription) + { + return localImpl.asStoreItem(locationDescription); + } + public final Status delete(final StoreItem item) { try