diff --git a/common/source/java/ch/systemsx/cisd/common/io/DefaultFileBasedHierarchicalContentNode.java b/common/source/java/ch/systemsx/cisd/common/io/DefaultFileBasedHierarchicalContentNode.java index 04677f257c3393012621757aeafc3b406192001f..ab414f19ecaae65a46ee483ac2afc124658fbc14 100644 --- a/common/source/java/ch/systemsx/cisd/common/io/DefaultFileBasedHierarchicalContentNode.java +++ b/common/source/java/ch/systemsx/cisd/common/io/DefaultFileBasedHierarchicalContentNode.java @@ -83,6 +83,11 @@ class DefaultFileBasedHierarchicalContentNode extends AbstractHierarchicalConten return file.isDirectory(); } + public long getLastModified() + { + return file.lastModified(); + } + @Override public List<IHierarchicalContentNode> doGetChildNodes() { diff --git a/common/source/java/ch/systemsx/cisd/common/io/HDF5ContainerBasedHierarchicalContentNode.java b/common/source/java/ch/systemsx/cisd/common/io/HDF5ContainerBasedHierarchicalContentNode.java index e870f861fdf76615b0d2deace7730b2ac8fa85d8..63a89f40c7bc2a1d1bb90b3fce4721899d0df4af 100644 --- a/common/source/java/ch/systemsx/cisd/common/io/HDF5ContainerBasedHierarchicalContentNode.java +++ b/common/source/java/ch/systemsx/cisd/common/io/HDF5ContainerBasedHierarchicalContentNode.java @@ -187,6 +187,11 @@ public class HDF5ContainerBasedHierarchicalContentNode extends return true; } + public long getLastModified() + { + return file.lastModified(); + } + public File getFile() throws UnsupportedOperationException { throw new UnsupportedOperationException("This is not a normal directory node."); @@ -267,6 +272,11 @@ public class HDF5ContainerBasedHierarchicalContentNode extends return false; } + public long getLastModified() + { + return file.lastModified(); + } + public File getFile() throws UnsupportedOperationException { throw new UnsupportedOperationException("This is not a normal file node."); diff --git a/common/source/java/ch/systemsx/cisd/common/io/IHierarchicalContentNode.java b/common/source/java/ch/systemsx/cisd/common/io/IHierarchicalContentNode.java index 32a88091f09070e9c41352d415d8daca21bd5660..ff27ec822d57a17ad3997c216ede91d7cacbbf27 100644 --- a/common/source/java/ch/systemsx/cisd/common/io/IHierarchicalContentNode.java +++ b/common/source/java/ch/systemsx/cisd/common/io/IHierarchicalContentNode.java @@ -51,6 +51,14 @@ public interface IHierarchicalContentNode * otherwise. */ boolean isDirectory(); + + /** + * Returns the time this node or the persistent object containing this node has been modified. + * + * @return A long value representing the time of last modification, measured in milliseconds + * since the epoch (00:00:00 GMT, January 1, 1970). + */ + long getLastModified(); /** * List of child nodes of this node. diff --git a/common/source/java/ch/systemsx/cisd/common/io/VirtualHierarchicalContent.java b/common/source/java/ch/systemsx/cisd/common/io/VirtualHierarchicalContent.java index ce4300bc42092504bd18a1ee595cf9aedc9fec89..9a4335ba702d75c3d540579fc60481f0024b3844 100644 --- a/common/source/java/ch/systemsx/cisd/common/io/VirtualHierarchicalContent.java +++ b/common/source/java/ch/systemsx/cisd/common/io/VirtualHierarchicalContent.java @@ -391,6 +391,11 @@ class VirtualHierarchicalContent implements IHierarchicalContent return lastNode().isDirectory(); } + public long getLastModified() + { + return lastNode().getLastModified(); + } + public List<IHierarchicalContentNode> getChildNodes() throws UnsupportedOperationException { IVirtualNodeListMerger listMerger = nodeMergerFactory.createNodeListMerger(); diff --git a/common/sourceTest/java/ch/systemsx/cisd/common/io/AbstractHierarchicalContentNodeTest.java b/common/sourceTest/java/ch/systemsx/cisd/common/io/AbstractHierarchicalContentNodeTest.java index 25be091d5827c7fc37512b1beb334577e3271f0b..b32a35f474f03dffbaef78483d8acc533fe5c426 100644 --- a/common/sourceTest/java/ch/systemsx/cisd/common/io/AbstractHierarchicalContentNodeTest.java +++ b/common/sourceTest/java/ch/systemsx/cisd/common/io/AbstractHierarchicalContentNodeTest.java @@ -152,6 +152,11 @@ public class AbstractHierarchicalContentNodeTest extends AssertJUnit return false; } + public long getLastModified() + { + return 0; + } + @Override protected InputStream doGetInputStream() { @@ -209,6 +214,11 @@ public class AbstractHierarchicalContentNodeTest extends AssertJUnit return false; } + public long getLastModified() + { + return 0; + } + @Override protected InputStream doGetInputStream() { diff --git a/common/sourceTest/java/ch/systemsx/cisd/common/io/DefaultFileBasedHierarchicalContentTest.java b/common/sourceTest/java/ch/systemsx/cisd/common/io/DefaultFileBasedHierarchicalContentTest.java index eaf3c7034bb46abfc19cbce8c155596a7b7d6a0f..bd3ace20c5e59befafea9f0190d37c102dccf811 100644 --- a/common/sourceTest/java/ch/systemsx/cisd/common/io/DefaultFileBasedHierarchicalContentTest.java +++ b/common/sourceTest/java/ch/systemsx/cisd/common/io/DefaultFileBasedHierarchicalContentTest.java @@ -491,8 +491,9 @@ public class DefaultFileBasedHierarchicalContentTest extends AbstractFileSystemT assertEquals("This is not a normal file node.", ex.getMessage()); } // file info access - assertEquals(expectedFile.getName(), fileNode.getName()); - assertEquals(expectedFile.length(), fileNode.getFileLength()); + assertEquals("File: " + expectedFile, expectedFile.getName(), fileNode.getName()); + assertEquals("File: " + expectedFile, expectedFile.length(), fileNode.getFileLength()); + assertEquals("File: " + expectedFile, expectedFile.lastModified(), fileNode.getLastModified()); final String expectedFileData = expectedFile.getName() + " data"; // check random access to file content @@ -571,6 +572,11 @@ public class DefaultFileBasedHierarchicalContentTest extends AbstractFileSystemT return file.exists(); } + public long getLastModified() + { + return file.lastModified(); + } + public long getFileLength() throws UnsupportedOperationException { throw new UnsupportedOperationException(METHOD_NOT_IMPLEMENTED); diff --git a/common/sourceTest/java/ch/systemsx/cisd/common/io/VirtualNodeTest.java b/common/sourceTest/java/ch/systemsx/cisd/common/io/VirtualNodeTest.java index 011eff97ee0999fdaad28bb524012a6c8c9d7c27..380bfd63d1b003baa91ee1004d35e938c95d6914 100644 --- a/common/sourceTest/java/ch/systemsx/cisd/common/io/VirtualNodeTest.java +++ b/common/sourceTest/java/ch/systemsx/cisd/common/io/VirtualNodeTest.java @@ -271,6 +271,23 @@ public class VirtualNodeTest extends AbstractFileSystemTestCase context.assertIsSatisfied(); } + + @Test + public void testLastModified() + { + final IHierarchicalContentNode virtualNode = createVirtualNode(); + context.checking(new Expectations() + { + { + one(node1).getLastModified(); + will(returnValue(42L)); + } + }); + + assertEquals(42, virtualNode.getLastModified()); + + context.assertIsSatisfied(); + } @Test public void testGetChildNodes() diff --git a/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/generic/server/UploadingCommand.java b/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/generic/server/UploadingCommand.java index fdf4ebceba0604f43cb07d38d7927bff0b2c1858..79a3f1e9bd57c19d6dbdab7c0d20e8b676d866c5 100644 --- a/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/generic/server/UploadingCommand.java +++ b/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/generic/server/UploadingCommand.java @@ -18,7 +18,6 @@ package ch.systemsx.cisd.openbis.dss.generic.server; import java.io.ByteArrayInputStream; import java.io.File; -import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; @@ -40,6 +39,8 @@ import ch.systemsx.cisd.cifex.rpc.client.ICIFEXComponent; import ch.systemsx.cisd.cifex.rpc.client.ICIFEXUploader; import ch.systemsx.cisd.cifex.rpc.client.gui.IProgressListener; import ch.systemsx.cisd.cifex.shared.basic.Constants; +import ch.systemsx.cisd.common.io.IHierarchicalContent; +import ch.systemsx.cisd.common.io.IHierarchicalContentNode; import ch.systemsx.cisd.common.logging.LogCategory; import ch.systemsx.cisd.common.logging.LogFactory; import ch.systemsx.cisd.common.mail.IMailClient; @@ -48,7 +49,8 @@ import ch.systemsx.cisd.common.mail.MailClientParameters; import ch.systemsx.cisd.common.types.BooleanOrUnknown; import ch.systemsx.cisd.common.utilities.TokenGenerator; import ch.systemsx.cisd.openbis.dss.generic.shared.IDataSetDirectoryProvider; -import ch.systemsx.cisd.openbis.generic.shared.basic.dto.DataSet; +import ch.systemsx.cisd.openbis.dss.generic.shared.IHierarchicalContentProvider; +import ch.systemsx.cisd.openbis.dss.generic.shared.ServiceProvider; import ch.systemsx.cisd.openbis.generic.shared.basic.dto.Experiment; import ch.systemsx.cisd.openbis.generic.shared.basic.dto.ExternalData; import ch.systemsx.cisd.openbis.generic.shared.basic.dto.IEntityProperty; @@ -57,8 +59,6 @@ import ch.systemsx.cisd.openbis.generic.shared.basic.dto.Project; import ch.systemsx.cisd.openbis.generic.shared.basic.dto.Sample; import ch.systemsx.cisd.openbis.generic.shared.basic.dto.Space; import ch.systemsx.cisd.openbis.generic.shared.dto.DataSetUploadContext; -import ch.systemsx.cisd.openbis.generic.shared.dto.DatasetDescription; -import ch.systemsx.cisd.openbis.generic.shared.translator.DataSetTranslator; import de.schlichtherle.util.zip.ZipEntry; import de.schlichtherle.util.zip.ZipOutputStream; @@ -285,6 +285,8 @@ class UploadingCommand implements IDataSetCommand @Private boolean deleteAfterUploading = true; + @Private transient IHierarchicalContentProvider hierarchicalContentProvider; + UploadingCommand(ICIFEXRPCServiceFactory cifexServiceFactory, MailClientParameters mailClientParameters, List<ExternalData> dataSets, DataSetUploadContext context, String cifexAdminUserOrNull, @@ -412,37 +414,34 @@ class UploadingCommand implements IDataSetCommand zipOutputStream = new ZipOutputStream(outputStream); for (ExternalData externalData : dataSets) { - DataSet dataSet = externalData.tryGetAsDataSet(); - assert dataSet != null : "container datasets are currently not supported by DSS client"; - - DatasetDescription dataSetDescription = - DataSetTranslator.translateToDescription(dataSet); - File dataSetFile = dataSetDirectoryProvider.getDataSetDirectory(dataSetDescription); - if (dataSetFile.exists() == false) - { - notificationLog.error("Data set '" + dataSetFile + "' does not exist."); - return false; - } - String newRootPath = createRootPath(dataSet); + String newRootPath = createRootPath(externalData) + "/"; try { - addEntry(zipOutputStream, newRootPath + "/meta-data.tsv", + addEntry(zipOutputStream, newRootPath + "meta-data.tsv", System.currentTimeMillis(), - new ByteArrayInputStream(createMetaData(dataSet).getBytes())); + new ByteArrayInputStream(createMetaData(externalData).getBytes())); } catch (IOException ex) { notificationLog.error( - "Couldn't add meta date for data set '" + dataSet.getCode() + "Couldn't add meta date for data set '" + externalData.getCode() + "' to zip file.", ex); return false; } + IHierarchicalContent root = null; + try + { + root = getHierarchicalContentProvider().asContent(externalData.getCode()); + } catch (Exception ex) + { + notificationLog.error("Data set " + externalData.getCode() + " does not exist.", ex); + return false; + } try { - addTo(zipOutputStream, dataSetFile.getCanonicalPath().length(), newRootPath, - dataSetFile); + addTo(zipOutputStream, newRootPath, root.getRootNode()); } catch (IOException ex) { - notificationLog.error("Couldn't add data set '" + dataSetFile + notificationLog.error("Couldn't add data set '" + externalData.getCode() + "' to zip file.", ex); return false; } @@ -466,8 +465,35 @@ class UploadingCommand implements IDataSetCommand } } } + + private IHierarchicalContentProvider getHierarchicalContentProvider() + { + if (hierarchicalContentProvider == null) + { + hierarchicalContentProvider = ServiceProvider.getHierarchicalContentProvider(); + } + return hierarchicalContentProvider; + } + + private void addTo(ZipOutputStream zipOutputStream, String newRootPath, + IHierarchicalContentNode node) throws IOException + { + if (node.isDirectory()) + { + List<IHierarchicalContentNode> childNodes = node.getChildNodes(); + for (IHierarchicalContentNode childNode : childNodes) + { + addTo(zipOutputStream, newRootPath, childNode); + } + } else + { + addEntry(zipOutputStream, newRootPath + node.getRelativePath(), node.getLastModified(), + node.getInputStream()); + } + } - private String createMetaData(DataSet dataSet) + @SuppressWarnings("deprecation") + private String createMetaData(ExternalData dataSet) { MetaDataBuilder builder = new MetaDataBuilder(); builder.dataSet("code", dataSet.getCode()); @@ -525,24 +551,6 @@ class UploadingCommand implements IDataSetCommand + "/" + (sample == null ? "" : sample.getCode() + "/") + dataSet.getCode(); } - private void addTo(ZipOutputStream zipOutputStream, int oldRootPathLength, String newRootPath, - File file) throws IOException - { - if (file.isFile()) - { - String zipEntryPath = - newRootPath + file.getCanonicalPath().substring(oldRootPathLength); - addEntry(zipOutputStream, zipEntryPath, file.lastModified(), new FileInputStream(file)); - } else - { - File[] files = file.listFiles(); - for (File childFile : files) - { - addTo(zipOutputStream, oldRootPathLength, newRootPath, childFile); - } - } - } - private void addEntry(ZipOutputStream zipOutputStream, String zipEntryPath, long lastModified, InputStream in) throws IOException { diff --git a/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/generic/shared/content/PathInfoProviderBasedHierarchicalContent.java b/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/generic/shared/content/PathInfoProviderBasedHierarchicalContent.java index cfa2fb148658bb7ce3bb8cfd5cd972c21634fe76..5705ef4d4e147d82c639964674a7e94eed817393 100644 --- a/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/generic/shared/content/PathInfoProviderBasedHierarchicalContent.java +++ b/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/generic/shared/content/PathInfoProviderBasedHierarchicalContent.java @@ -207,6 +207,11 @@ class PathInfoProviderBasedHierarchicalContent implements IHierarchicalContent return pathInfo.isDirectory(); } + public long getLastModified() + { + return System.currentTimeMillis(); + } + @Override protected String doGetRelativePath() { diff --git a/datastore_server/sourceTest/java/ch/systemsx/cisd/openbis/dss/generic/server/UploadingCommandTest.java b/datastore_server/sourceTest/java/ch/systemsx/cisd/openbis/dss/generic/server/UploadingCommandTest.java index 3be648335bc76f2a8fa81a2b98446d3eeccab437..a7abb605823c809a5cc6229be39f2b7ef08c1561 100644 --- a/datastore_server/sourceTest/java/ch/systemsx/cisd/openbis/dss/generic/server/UploadingCommandTest.java +++ b/datastore_server/sourceTest/java/ch/systemsx/cisd/openbis/dss/generic/server/UploadingCommandTest.java @@ -47,9 +47,13 @@ import ch.systemsx.cisd.cifex.rpc.client.ICIFEXUploader; import ch.systemsx.cisd.cifex.rpc.client.gui.IProgressListener; import ch.systemsx.cisd.common.exceptions.AuthorizationFailureException; import ch.systemsx.cisd.common.filesystem.FileUtilities; +import ch.systemsx.cisd.common.io.DefaultFileBasedHierarchicalContentFactory; +import ch.systemsx.cisd.common.io.IHierarchicalContent; import ch.systemsx.cisd.common.logging.BufferedAppender; import ch.systemsx.cisd.common.mail.MailClientParameters; +import ch.systemsx.cisd.common.utilities.IDelegatedAction; import ch.systemsx.cisd.openbis.dss.generic.shared.IDataSetDirectoryProvider; +import ch.systemsx.cisd.openbis.dss.generic.shared.IHierarchicalContentProvider; import ch.systemsx.cisd.openbis.dss.generic.shared.IShareIdManager; import ch.systemsx.cisd.openbis.generic.shared.basic.dto.ExternalData; import ch.systemsx.cisd.openbis.generic.shared.basic.dto.IDatasetLocation; @@ -74,11 +78,48 @@ import ch.systemsx.cisd.openbis.generic.shared.translator.ExperimentTranslator; @Friend(toClasses = UploadingCommand.class) public class UploadingCommandTest extends AssertJUnit { + private static final File TEST_FOLDER = new File("targets/upload-test"); private static final File STORE = new File(TEST_FOLDER, "store"); private static final String SHARE_ID = "share-id"; + + private static final String LOCATION_PREFIX = "ds"; + + private static final IHierarchicalContentProvider HIERARCHICAL_CONTENT_PROVIDER = + new IHierarchicalContentProvider() + { + private DefaultFileBasedHierarchicalContentFactory hierarchicalContentFactory = + new DefaultFileBasedHierarchicalContentFactory(); + + public IHierarchicalContent asContent(File datasetDirectory) + { + return hierarchicalContentFactory.asHierarchicalContent(datasetDirectory, + IDelegatedAction.DO_NOTHING); + } + + public IHierarchicalContent asContent(IDatasetLocation datasetLocation) + { + return getContent(datasetLocation.getDataSetLocation()); + } + + public IHierarchicalContent getContent(String location) + { + return asContent(new File(new File(STORE, SHARE_ID), location)); + } + + public IHierarchicalContent asContent(ExternalData dataSet) + { + return getContent(dataSet.getCode()); + } + + public IHierarchicalContent asContent(String dataSetCode) + throws IllegalArgumentException + { + return getContent(LOCATION_PREFIX + dataSetCode); + } + }; private static final class MockDataSetDirectoryProvider implements IDataSetDirectoryProvider { @@ -110,9 +151,9 @@ public class UploadingCommandTest extends AssertJUnit private static final File EMAILS = new File(TEST_FOLDER, "emails"); - private static final String LOCATION1 = "ds1"; + private static final String LOCATION1 = LOCATION_PREFIX + "1"; - private static final String LOCATION2 = "ds2"; + private static final String LOCATION2 = LOCATION_PREFIX + "2"; private static final String SESSION_TOKEN = "session42"; @@ -183,33 +224,36 @@ public class UploadingCommandTest extends AssertJUnit createTestData(LOCATION1); ds2 = createTestData(LOCATION2); ExternalData dataSet1 = - DataSetTranslator.translate(createDataSet("1", LOCATION1), "?", + DataSetTranslator.translate(createDataSet("1"), "?", ExperimentTranslator.LoadableFields.PROPERTIES); System.out.println("ds1:" + dataSet1.getExperiment().getProperties()); ExternalData dataSet2 = - DataSetTranslator.translate(createDataSet("2", LOCATION2), "?", + DataSetTranslator.translate(createDataSet("2"), "?", ExperimentTranslator.LoadableFields.PROPERTIES); dataSets = Arrays.<ExternalData> asList(dataSet1, dataSet2); command = new UploadingCommand(factory, mailClientParameters, dataSets, uploadContext, null, null); + command.hierarchicalContentProvider = HIERARCHICAL_CONTENT_PROVIDER; commandAdminSession = new UploadingCommand(factory, mailClientParameters, dataSets, uploadContextNoPasswordAuthenticated, "admin", "admpwd"); + commandAdminSession.hierarchicalContentProvider = HIERARCHICAL_CONTENT_PROVIDER; commandAdminSessionNotAuthenticated = new UploadingCommand(factory, mailClientParameters, dataSets, uploadContextNoPasswordNotAuthenticated, "admin", "admpwd"); + commandAdminSessionNotAuthenticated.hierarchicalContentProvider = HIERARCHICAL_CONTENT_PROVIDER; command.deleteAfterUploading = false; commandAdminSession.deleteAfterUploading = false; commandAdminSessionNotAuthenticated.deleteAfterUploading = false; } - private ExternalDataPE createDataSet(String code, String location) + private ExternalDataPE createDataSet(String code) { ExternalDataPE externalData = new ExternalDataPE(); externalData.setCode(code); externalData.setShareId(SHARE_ID); - externalData.setLocation(location); + externalData.setLocation(LOCATION_PREFIX + code); externalData.setDerived(true); // measured == (derived == false) DataSetTypePE dataSetTypePE = new DataSetTypePE(); dataSetTypePE.setCode("D"); @@ -283,7 +327,8 @@ public class UploadingCommandTest extends AssertJUnit private String getNormalizedLogContent() { - return logRecorder.getLogContent().replaceAll(" [^ ]*\\.zip", " <zipfile>"); + return logRecorder.getLogContent().replaceAll(" [^ ]*\\.zip", " <zipfile>") + .replaceAll("\n\ta.*\\)", "").replaceAll("[^:]*" + TEST_FOLDER.getPath(), ""); } @AfterMethod @@ -438,8 +483,9 @@ public class UploadingCommandTest extends AssertJUnit command.execute(directoryProvider); checkEmail("Couldn't create zip file"); - assertEquals("ERROR NOTIFY.UploadingCommand" - + " - Data set 'targets/upload-test/store/share-id/ds2' does not exist." + assertEquals("ERROR NOTIFY.UploadingCommand - Data set 2 does not exist." + + OSUtilities.LINE_SEPARATOR + + "java.lang.IllegalArgumentException:/store/share-id/ds2 doesn't exist" + OSUtilities.LINE_SEPARATOR + INFO_MAIL_PREFIX + "Sending message from 'a@bc.de' to recipients '[user@bc.de]'", getNormalizedLogContent()); diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/business/bo/DataSetTable.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/business/bo/DataSetTable.java index f7c0ec246ba4d3e1cb292291ce230f9973f55862..43af0d7af2fcbe0f043dedfbd21b4ac7bb8e87ac 100644 --- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/business/bo/DataSetTable.java +++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/business/bo/DataSetTable.java @@ -23,7 +23,6 @@ import java.util.HashMap; import java.util.HashSet; import java.util.Iterator; import java.util.LinkedHashMap; -import java.util.LinkedHashSet; import java.util.List; import java.util.Map; import java.util.Map.Entry; @@ -129,7 +128,7 @@ public final class DataSetTable extends AbstractDataSetBusinessObject implements List<String> notAvailableDatasets = new ArrayList<String>(); for (DataPE dataSet : datasets) { - if (dataSet.isAvailable() == false) + if (dataSet.isExternalData() && dataSet.isAvailable() == false) { notAvailableDatasets.add(dataSet.getCode()); } @@ -327,21 +326,20 @@ public final class DataSetTable extends AbstractDataSetBusinessObject implements public String uploadLoadedDataSetsToCIFEX(DataSetUploadContext uploadContext) { assertDatasetsAreAvailable(dataSets); - Map<DataStorePE, List<ExternalDataPE>> map = groupExternalDataByDataStores(); + Map<DataStorePE, List<DataPE>> map = groupDataByDataStores(); assertDataSetsAreKnown(map); - assertNoContainerDataSets(map); uploadContext.setUserEMail(session.getPrincipal().getEmail()); uploadContext.setSessionUserID(session.getUserName()); if (StringUtils.isBlank(uploadContext.getComment())) { uploadContext.setComment(createUploadComment(dataSets)); } - List<ExternalDataPE> dataSetsWithUnknownDSS = new ArrayList<ExternalDataPE>(); - for (Map.Entry<DataStorePE, List<ExternalDataPE>> entry : map.entrySet()) + List<DataPE> dataSetsWithUnknownDSS = new ArrayList<DataPE>(); + for (Map.Entry<DataStorePE, List<DataPE>> entry : map.entrySet()) { DataStorePE dataStore = entry.getKey(); - List<ExternalDataPE> externalDatas = entry.getValue(); - for (ExternalDataPE dataSet : externalDatas) + List<DataPE> dataSetsOfStore = entry.getValue(); + for (DataPE dataSet : dataSetsOfStore) { HibernateUtils.initialize(dataSet.getParents()); HibernateUtils.initialize(dataSet.getProperties()); @@ -359,35 +357,35 @@ public final class DataSetTable extends AbstractDataSetBusinessObject implements } if (StringUtils.isBlank(dataStore.getRemoteUrl())) { - dataSetsWithUnknownDSS.addAll(externalDatas); + dataSetsWithUnknownDSS.addAll(dataSetsOfStore); } else { - uploadDataSetsToCIFEX(dataStore, externalDatas, uploadContext); + uploadDataSetsToCIFEX(dataStore, dataSetsOfStore, uploadContext); } } StringBuilder builder = new StringBuilder(); if (dataSetsWithUnknownDSS.isEmpty() == false) { builder.append("The following data sets couldn't been uploaded because of unkown data store:"); - for (ExternalDataPE externalDataPE : dataSetsWithUnknownDSS) + for (DataPE dataSet : dataSetsWithUnknownDSS) { - builder.append(' ').append(externalDataPE.getCode()); + builder.append(' ').append(dataSet.getCode()); } } return builder.toString(); } - private void assertDataSetsAreKnown(Map<DataStorePE, List<ExternalDataPE>> map) + private <D extends DataPE> void assertDataSetsAreKnown(Map<DataStorePE, List<D>> map) { // Set<String> knownLocations = new LinkedHashSet<String>(); List<String> unknownDataSets = new ArrayList<String>(); - for (Map.Entry<DataStorePE, List<ExternalDataPE>> entry : map.entrySet()) + for (Map.Entry<DataStorePE, List<D>> entry : map.entrySet()) { DataStorePE dataStore = entry.getKey(); - List<ExternalDataPE> externalDatas = entry.getValue(); + List<ExternalDataPE> externalDatas = filterRealDataSets(entry.getValue()); Set<String> knownLocations = getKnownDataSets(dataStore, createDatasetDescriptions(externalDatas)); - for (ExternalDataPE dataSet : entry.getValue()) + for (ExternalDataPE dataSet : externalDatas) { if (dataSet.getStatus() == DataSetArchivingStatus.ARCHIVED) { @@ -407,34 +405,44 @@ public final class DataSetTable extends AbstractDataSetBusinessObject implements + unknownDataSets); } } - - private void assertNoContainerDataSets(Map<DataStorePE, List<ExternalDataPE>> map) + + private List<ExternalDataPE> filterRealDataSets(List<? extends DataPE> mixedDataSets) { - Set<String> containerDataSets = new LinkedHashSet<String>(); - for (Map.Entry<DataStorePE, List<ExternalDataPE>> entry : map.entrySet()) + List<ExternalDataPE> realDataSets = new ArrayList<ExternalDataPE>(); + for (DataPE dataSet : mixedDataSets) { - for (ExternalDataPE dataSet : entry.getValue()) + if (dataSet instanceof ExternalDataPE) { - if (dataSet.isContainer()) - { - containerDataSets.add(dataSet.getCode()); - } + realDataSets.add((ExternalDataPE) dataSet); } } + return realDataSets; + } - if (false == containerDataSets.isEmpty()) + /** groups data sets by data stores */ + private Map<DataStorePE, List<DataPE>> groupDataByDataStores() + { + Map<DataStorePE, List<DataPE>> map = + new LinkedHashMap<DataStorePE, List<DataPE>>(); + for (DataPE dataSet : dataSets) { - throw new UserFailureException( - "The following data sets are container data sets and cannot be uploaded to CIFEX. " - + containerDataSets); + DataStorePE dataStore = dataSet.getDataStore(); + List<DataPE> list = map.get(dataStore); + if (list == null) + { + list = new ArrayList<DataPE>(); + map.put(dataStore, list); + } + list.add(dataSet); } + return map; } - /** groups data sets by data stores filtering out virtual data sets */ + /** groups data sets by data stores filtering out container data sets */ private Map<DataStorePE, List<ExternalDataPE>> groupExternalDataByDataStores() { Map<DataStorePE, List<ExternalDataPE>> map = - new LinkedHashMap<DataStorePE, List<ExternalDataPE>>(); + new LinkedHashMap<DataStorePE, List<ExternalDataPE>>(); for (DataPE dataSet : dataSets) { if (dataSet.isExternalData()) @@ -451,7 +459,7 @@ public final class DataSetTable extends AbstractDataSetBusinessObject implements } return map; } - + /** groups all data sets (both virtual and non-virtual) by data stores */ private Map<DataStorePE, List<DataPE>> groupDataSetsByDataStores() { @@ -470,7 +478,7 @@ public final class DataSetTable extends AbstractDataSetBusinessObject implements return map; } - private void uploadDataSetsToCIFEX(DataStorePE dataStore, List<ExternalDataPE> list, + private void uploadDataSetsToCIFEX(DataStorePE dataStore, List<DataPE> list, DataSetUploadContext context) { IDataStoreService service = dssFactory.create(dataStore.getRemoteUrl());