diff --git a/common/source/java/ch/systemsx/cisd/common/filesystem/FileUtilities.java b/common/source/java/ch/systemsx/cisd/common/filesystem/FileUtilities.java index 162a31e0904ebe81047685586512ecc0b951c99b..625f8354b93434bccab5d407b2a6d4beb380e5fc 100644 --- a/common/source/java/ch/systemsx/cisd/common/filesystem/FileUtilities.java +++ b/common/source/java/ch/systemsx/cisd/common/filesystem/FileUtilities.java @@ -2014,4 +2014,38 @@ public final class FileUtilities } } + private static String getTempDir() + { + return System.getProperty("java.io.tmpdir"); + } + + /** + * Return true if <code>fileName</code> is a valid filename. + * <p> + * The methods works by trying to create a file with the specified name. Thus, the method should + * not be called where performance matters. + */ + public static boolean isValidFileName(String fileName) + { + if (StringUtils.isBlank(fileName) || fileName.contains(File.separator)) + { + return false; + } + + File tmpFile = new File(getTempDir(), fileName); + try + { + if (tmpFile.createNewFile()) + { + tmpFile.delete(); + return true; + } + } catch (IOException ex) + { + throw CheckedExceptionTunnel.wrapIfNecessary(ex); + } + + return tmpFile.exists(); + } + } diff --git a/common/sourceTest/java/ch/systemsx/cisd/common/filesystem/FileUtilitiesTest.java b/common/sourceTest/java/ch/systemsx/cisd/common/filesystem/FileUtilitiesTest.java index 2e8419fdd9129ab7e7056e46a836e83de53448ff..df21eec72749fc1025a18560bf39fc7f8ad0a1d3 100644 --- a/common/sourceTest/java/ch/systemsx/cisd/common/filesystem/FileUtilitiesTest.java +++ b/common/sourceTest/java/ch/systemsx/cisd/common/filesystem/FileUtilitiesTest.java @@ -500,4 +500,14 @@ public final class FileUtilitiesTest extends AbstractFileSystemTestCase assertTrue(FileUtilities.isSymbolicLink(linkRelative)); } + @Test + public void testValidFileName() + { + assertTrue(FileUtilities.isValidFileName("valid-name1")); + assertTrue(FileUtilities.isValidFileName("valid with space and tab\t")); + assertTrue(FileUtilities.isValidFileName("valid.dot")); + assertFalse(FileUtilities.isValidFileName("")); + assertFalse(FileUtilities.isValidFileName("a/b")); + } + } diff --git a/screening/source/java/ch/systemsx/cisd/openbis/dss/etl/jython/JythonPlateDataSetHandler.java b/screening/source/java/ch/systemsx/cisd/openbis/dss/etl/jython/JythonPlateDataSetHandler.java index 1d0731ee3868921ad2e99b9a1b1f1586a117e880..849abd1231fa7932a19430c0dec4564bfd2472f5 100644 --- a/screening/source/java/ch/systemsx/cisd/openbis/dss/etl/jython/JythonPlateDataSetHandler.java +++ b/screening/source/java/ch/systemsx/cisd/openbis/dss/etl/jython/JythonPlateDataSetHandler.java @@ -11,8 +11,11 @@ import java.util.Properties; import org.python.util.PythonInterpreter; import ch.systemsx.cisd.bds.hcs.Location; +import ch.systemsx.cisd.common.exceptions.ConfigurationFailureException; import ch.systemsx.cisd.common.exceptions.UserFailureException; +import ch.systemsx.cisd.common.filesystem.FileUtilities; import ch.systemsx.cisd.common.utilities.IDelegatedActionWithResult; +import ch.systemsx.cisd.common.utilities.PropertyUtils; import ch.systemsx.cisd.etlserver.ITopLevelDataSetRegistratorDelegate; import ch.systemsx.cisd.etlserver.TopLevelDataSetRegistratorGlobalState; import ch.systemsx.cisd.etlserver.registrator.DataSetRegistrationDetails; @@ -49,9 +52,29 @@ import ch.systemsx.cisd.openbis.plugin.screening.shared.basic.dto.ScreeningConst */ public class JythonPlateDataSetHandler extends JythonTopLevelDataSetHandler<DataSetInformation> { + + private final String ORIGINAL_DIRNAME_KEY = "image-datasets-original-dir-name"; + + private final String originalDirName; + public JythonPlateDataSetHandler(TopLevelDataSetRegistratorGlobalState globalState) { super(globalState); + originalDirName = parseOriginalDir(globalState.getThreadParameters().getThreadProperties()); + } + + private String parseOriginalDir(Properties threadProperties) + { + String originalDir = + PropertyUtils.getProperty(threadProperties, ORIGINAL_DIRNAME_KEY, + ScreeningConstants.ORIGINAL_DATA_DIR); + if (false == FileUtilities.isValidFileName(originalDir)) + { + throw ConfigurationFailureException.fromTemplate( + "Invalid folder name specified in '%s': '%s'.", ORIGINAL_DIRNAME_KEY, + originalDir); + } + return originalDir; } /** @@ -278,7 +301,8 @@ public class JythonPlateDataSetHandler extends JythonTopLevelDataSetHandler<Data IDataSetRegistrationDetailsFactory<DataSetInformation> registrationDetailsFactory) { return new ImagingDataSetRegistrationTransaction(rollBackStackParentFolder, - workingDirectory, stagingDirectory, this, registrationDetailsFactory); + workingDirectory, stagingDirectory, this, registrationDetailsFactory, + originalDirName); } }; } @@ -292,10 +316,13 @@ public class JythonPlateDataSetHandler extends JythonTopLevelDataSetHandler<Data { private final JythonPlateDatasetFactory registrationDetailsFactory; + private final String originalDirName; + public ImagingDataSetRegistrationTransaction(File rollBackStackParentFolder, File workingDirectory, File stagingDirectory, DataSetRegistrationService<DataSetInformation> registrationService, - IDataSetRegistrationDetailsFactory<DataSetInformation> registrationDetailsFactory) + IDataSetRegistrationDetailsFactory<DataSetInformation> registrationDetailsFactory, + String originalDirName) { super(rollBackStackParentFolder, workingDirectory, stagingDirectory, registrationService, registrationDetailsFactory); @@ -305,6 +332,7 @@ public class JythonPlateDataSetHandler extends JythonTopLevelDataSetHandler<Data this.registrationDetailsFactory = (JythonPlateDatasetFactory) registrationDetailsFactory; + this.originalDirName = originalDirName; } public IDataSet createNewImageDataSet(SimpleImageDataConfig imageDataSet, @@ -343,8 +371,7 @@ public class JythonPlateDataSetHandler extends JythonTopLevelDataSetHandler<Data // create main dataset (with original images) IDataSet mainDataset = super.createNewDataSet(imageRegistrationDetails); String originalDatasetPathPrefix = - ScreeningConstants.ORIGINAL_DATA_DIR + File.separator - + incomingDirectory.getName(); + originalDirName + File.separator + incomingDirectory.getName(); moveFile(incomingDirectory.getAbsolutePath(), mainDataset, originalDatasetPathPrefix); containedDataSetCodes.add(mainDataset.getDataSetCode());