From 132c558c8f6f5ee26ee6d40219983889d925c813 Mon Sep 17 00:00:00 2001 From: kaloyane <kaloyane> Date: Wed, 27 Apr 2011 12:57:04 +0000 Subject: [PATCH] [LMS-2197] add disambiguation support SVN: 21054 --- .../TemplateBasedDataSetResourceResolver.java | 119 ++++++++++++------ 1 file changed, 79 insertions(+), 40 deletions(-) diff --git a/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/generic/server/ftp/resolver/TemplateBasedDataSetResourceResolver.java b/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/generic/server/ftp/resolver/TemplateBasedDataSetResourceResolver.java index 06b3d5a3250..2db241b759c 100644 --- a/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/generic/server/ftp/resolver/TemplateBasedDataSetResourceResolver.java +++ b/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/generic/server/ftp/resolver/TemplateBasedDataSetResourceResolver.java @@ -18,11 +18,10 @@ package ch.systemsx.cisd.openbis.dss.generic.server.ftp.resolver; import java.util.ArrayList; import java.util.Collections; +import java.util.Comparator; import java.util.Date; -import java.util.HashMap; import java.util.List; import java.util.Map; -import java.util.Map.Entry; import org.apache.commons.lang.StringUtils; import org.apache.commons.lang.time.DateFormatUtils; @@ -50,8 +49,6 @@ import ch.systemsx.cisd.openbis.generic.shared.dto.identifier.ExperimentIdentifi * <p> * Subpaths are resolved as a relative paths starting from the root of a dataset. * <p> - * TODO KE: add disambiguation checks - append an uniqueness factor to (?another variable) to the - * path if no "dataSetCode" variable is used in the template * * @author Kaloyan Enimanev */ @@ -65,6 +62,8 @@ public class TemplateBasedDataSetResourceResolver implements IFtpPathResolver, I private static final String FILE_NAME_VARNAME = "fileName"; + private static final String DISAMBIGUATION_VARNAME = "disambiguation"; + private static final String DATA_SET_DATE_FORMAT = "yyyy-MM-dd-HH-mm"; /** @@ -77,13 +76,15 @@ public class TemplateBasedDataSetResourceResolver implements IFtpPathResolver, I private final Map<String /* dataset type */, String /* subpath */> fileListSubPaths; - private static class DataSetAndFileName + private static class EvaluatedDataSetPath { ExternalData dataSet; // will only be filled when the ${fileName} variable // is used in the template String fileName = StringUtils.EMPTY; + + String evaluatedTemplate; } public TemplateBasedDataSetResourceResolver(FtpServerConfig ftpServerConfig) @@ -106,7 +107,7 @@ public class TemplateBasedDataSetResourceResolver implements IFtpPathResolver, I IETLLIMSService service = resolverContext.getService(); String sessionToken = resolverContext.getSessionToken(); - DataSetAndFileName dataSetAndFileName = + EvaluatedDataSetPath dataSetAndFileName = extractDataSetAndFileName(path, service, sessionToken); if (dataSetAndFileName == null) { @@ -124,7 +125,7 @@ public class TemplateBasedDataSetResourceResolver implements IFtpPathResolver, I return new HierarchicalContentToFtpFileAdapter(path, contentNode); } - private DataSetAndFileName extractDataSetAndFileName(String path, IETLLIMSService service, + private EvaluatedDataSetPath extractDataSetAndFileName(String path, IETLLIMSService service, String sessionToken) { String experimentId = extractExperimentIdentifier(path); @@ -137,24 +138,19 @@ public class TemplateBasedDataSetResourceResolver implements IFtpPathResolver, I List<ExternalData> dataSets = service.listDataSetsByExperimentID(sessionToken, new TechId(experiment)); String pathWithEndSlash = path + FtpConstants.FILE_SEPARATOR; - for (ExternalData dataSet : dataSets) + + for (EvaluatedDataSetPath evaluatedPath : evaluateDataSetPaths(dataSets)) { - Map<String /* fileName */, String /* evaluated */> evaluatedPaths = - getEvaluatedDataSetPaths(dataSet); - for (Entry<String, String> entry : evaluatedPaths.entrySet()) + String fullEvaluatedPath = + experimentId + FtpConstants.FILE_SEPARATOR + evaluatedPath.evaluatedTemplate + + FtpConstants.FILE_SEPARATOR; + if (pathWithEndSlash.startsWith(fullEvaluatedPath)) { - String fullEvaluatedPath = - experimentId + FtpConstants.FILE_SEPARATOR + entry.getValue() - + FtpConstants.FILE_SEPARATOR; - if (pathWithEndSlash.startsWith(fullEvaluatedPath)) - { - DataSetAndFileName result = new DataSetAndFileName(); - result.dataSet = dataSet; - result.fileName = entry.getKey(); - return result; - } + EvaluatedDataSetPath result = new EvaluatedDataSetPath(); + result.dataSet = evaluatedPath.dataSet; + result.fileName = evaluatedPath.fileName; + return result; } - } return null; @@ -198,34 +194,78 @@ public class TemplateBasedDataSetResourceResolver implements IFtpPathResolver, I List<ExternalData> dataSets = service.listDataSetsByExperimentID(sessionToken, new TechId(experiment)); List<String> result = new ArrayList<String>(); - for (ExternalData dataSet : dataSets) + for (EvaluatedDataSetPath evaluatedPath : evaluateDataSetPaths(dataSets)) { - Map<String, String> pathsForDataSet = getEvaluatedDataSetPaths(dataSet); - result.addAll(pathsForDataSet.values()); + result.add(evaluatedPath.evaluatedTemplate); } return result; } - private Map<String /* fileName */, String /* evaluated template */> getEvaluatedDataSetPaths( - ExternalData dataSet) + private List<EvaluatedDataSetPath> evaluateDataSetPaths(List<ExternalData> dataSets) { - Map<String, String> result = new HashMap<String, String>(); + List<EvaluatedDataSetPath> result = new ArrayList<EvaluatedDataSetPath>(); + sortDataSetsById(dataSets); - IHierarchicalContentProvider provider = ServiceProvider.getHierarchicalContentProvider(); - IHierarchicalContent content = provider.asContent(dataSet.getCode()); - String dataSetType = dataSet.getDataSetType().getCode(); - String fileListSubPathOrNull = fileListSubPaths.get(dataSetType); - IHierarchicalContentNode rootNode = content.getNode(fileListSubPathOrNull); - - for (IHierarchicalContentNode fileNode : extractFileNames(rootNode)) + for (int disambiguation = 0; disambiguation < dataSets.size(); disambiguation++) { - String path = evaluateTemplate(dataSet, fileNode.getName()); - result.put(fileNode.getRelativePath(), path); + ExternalData dataSet = dataSets.get(disambiguation); + + IHierarchicalContentProvider provider = + ServiceProvider.getHierarchicalContentProvider(); + IHierarchicalContent content = provider.asContent(dataSet.getCode()); + String dataSetType = dataSet.getDataSetType().getCode(); + String fileListSubPathOrNull = fileListSubPaths.get(dataSetType); + IHierarchicalContentNode rootNode = content.getNode(fileListSubPathOrNull); + String disambiguationVar = computeDisambiguation(disambiguation); + + for (IHierarchicalContentNode fileNode : extractFileNames(rootNode)) + { + EvaluatedDataSetPath evaluatedPath = new EvaluatedDataSetPath(); + evaluatedPath.dataSet = dataSet; + evaluatedPath.fileName = fileNode.getRelativePath(); + evaluatedPath.evaluatedTemplate = + evaluateTemplate(dataSet, fileNode.getName(), disambiguationVar); + result.add(evaluatedPath); + } } return result; } + private void sortDataSetsById(List<ExternalData> dataSets) + { + Collections.sort(dataSets, new Comparator<ExternalData>() + { + public int compare(ExternalData o1, ExternalData o2) + { + long id1 = o1.getId(); + long id2 = o2.getId(); + // do not return directly "id1 - id2" to avoid overflow + if (id1 > id2) + { + return 1; + } else if (id1 < id2) + { + return -1; + } else + { + return 0; + } + } + + }); + } + + /** + * Given a zero-based disambiguation index, produces the values for + * {@value #DISAMBIGUATION_VARNAME}. + */ + private String computeDisambiguation(int disambiguationIdx) + { + int number = 10 + disambiguationIdx; + return Integer.toString(number, 36).toUpperCase(); + } + /** * @return all values to be used when evaluating the template "${fileName}" variable. */ @@ -240,8 +280,7 @@ public class TemplateBasedDataSetResourceResolver implements IFtpPathResolver, I } } - private String evaluateTemplate(ExternalData dataSet, - String fileName) + private String evaluateTemplate(ExternalData dataSet, String fileName, String disambiguation) { ExtendedProperties properties = new ExtendedProperties(); properties.put(DATA_SET_CODE_VARNAME, dataSet.getCode()); @@ -249,6 +288,7 @@ public class TemplateBasedDataSetResourceResolver implements IFtpPathResolver, I String dataSetDate = extractDateValue(dataSet.getRegistrationDate()); properties.put(DATA_SET_DATE_VARNAME, dataSetDate); properties.put(FILE_NAME_VARNAME, fileName); + properties.put(DISAMBIGUATION_VARNAME, disambiguation); String templatePropName = "template"; properties.put(templatePropName, template); @@ -262,5 +302,4 @@ public class TemplateBasedDataSetResourceResolver implements IFtpPathResolver, I return DateFormatUtils.format(dataSetDate, DATA_SET_DATE_FORMAT); } - } -- GitLab