diff --git a/datastore_server/source/java/ch/ethz/sis/openbis/generic/server/dss/plugins/sync/common/EntityRetriever.java b/datastore_server/source/java/ch/ethz/sis/openbis/generic/server/dss/plugins/sync/common/EntityRetriever.java index 510b319354f25287fbfd3e93349e52376f4c6c51..9b0bb4e473eacffa3b3b2543db745027367e3e84 100644 --- a/datastore_server/source/java/ch/ethz/sis/openbis/generic/server/dss/plugins/sync/common/EntityRetriever.java +++ b/datastore_server/source/java/ch/ethz/sis/openbis/generic/server/dss/plugins/sync/common/EntityRetriever.java @@ -112,6 +112,11 @@ public class EntityRetriever graph = new EntityGraph<Node<?>>(); // add shared samples + /* + * adding shared samples to the entity graph for a space means if we are synching from multiple spaces, each entity graph (for each space) + * will have the shared entity. When we add them to the RL (Resource List) in the data source servlet, any duplicate will throw an error when + * using the Resync library. To work around this we catch the duplicate exceptions where a shared sample is involved. + */ findSharedSamples(); // build the graph for the space from top-down starting from projects diff --git a/datastore_server/source/java/ch/ethz/sis/openbis/generic/server/dss/plugins/sync/harvester/config/ConfigReader.java b/datastore_server/source/java/ch/ethz/sis/openbis/generic/server/dss/plugins/sync/harvester/config/ConfigReader.java index 6c8009cceae905fa8e6dda6459c62f846150f27a..eb969e940d48c315f3ac91563f9e756ed4d19ac7 100644 --- a/datastore_server/source/java/ch/ethz/sis/openbis/generic/server/dss/plugins/sync/harvester/config/ConfigReader.java +++ b/datastore_server/source/java/ch/ethz/sis/openbis/generic/server/dss/plugins/sync/harvester/config/ConfigReader.java @@ -31,6 +31,8 @@ import java.util.Map; import java.util.regex.Matcher; import java.util.regex.Pattern; +import org.apache.commons.lang3.StringUtils; + import ch.systemsx.cisd.common.exceptions.ConfigurationFailureException; public class ConfigReader @@ -155,15 +157,11 @@ public class ConfigReader throw new ConfigurationFailureException("Section '" + section + " does not exist."); } String val = map.get(key); - if (val == null) - { - return null; - } - if (val.trim().equals("") == true) + if (StringUtils.isBlank(val) == true) { return null; } - return val; + return val.trim(); } public int getInt(String section, String key, int defaultvalue, boolean mandatory) diff --git a/datastore_server/source/java/ch/ethz/sis/openbis/generic/server/dss/plugins/sync/harvester/synchronizer/EntitySynchronizer.java b/datastore_server/source/java/ch/ethz/sis/openbis/generic/server/dss/plugins/sync/harvester/synchronizer/EntitySynchronizer.java index ab0aaaa30e191bde84f75df3ce6a6339db6ef711..54524d4f48d78b735f959d70097dfca063048631 100644 --- a/datastore_server/source/java/ch/ethz/sis/openbis/generic/server/dss/plugins/sync/harvester/synchronizer/EntitySynchronizer.java +++ b/datastore_server/source/java/ch/ethz/sis/openbis/generic/server/dss/plugins/sync/harvester/synchronizer/EntitySynchronizer.java @@ -37,6 +37,7 @@ import java.util.Set; import org.apache.commons.codec.binary.Hex; import org.apache.commons.io.FileUtils; import org.apache.commons.lang.ArrayUtils; +import org.apache.commons.lang3.StringUtils; import org.apache.log4j.Logger; import org.w3c.dom.Document; @@ -188,7 +189,7 @@ public class EntitySynchronizer operationLog.info("parsing the resource list xml document"); String dataSourcePrefix = config.getDataSourceAlias(); INameTranslator nameTranslator = null; - if (dataSourcePrefix != null && dataSourcePrefix.trim().equals("") == false) + if (StringUtils.isBlank(dataSourcePrefix) == false) { nameTranslator = new PrefixBasedNameTranslator(dataSourcePrefix); } diff --git a/datastore_server/source/java/ch/ethz/sis/openbis/generic/server/dss/plugins/sync/harvester/synchronizer/ResourceListParser.java b/datastore_server/source/java/ch/ethz/sis/openbis/generic/server/dss/plugins/sync/harvester/synchronizer/ResourceListParser.java index 891a44c4cc31e978929fa433c18aafca26f81031..4e4756b2ed9a8877ab18a528f2a7a271c6ffdefd 100644 --- a/datastore_server/source/java/ch/ethz/sis/openbis/generic/server/dss/plugins/sync/harvester/synchronizer/ResourceListParser.java +++ b/datastore_server/source/java/ch/ethz/sis/openbis/generic/server/dss/plugins/sync/harvester/synchronizer/ResourceListParser.java @@ -35,6 +35,7 @@ import javax.xml.xpath.XPathExpression; import javax.xml.xpath.XPathExpressionException; import javax.xml.xpath.XPathFactory; +import org.apache.commons.lang.StringUtils; import org.w3c.dom.Document; import org.w3c.dom.Element; import org.w3c.dom.Node; @@ -44,10 +45,10 @@ import ch.ethz.sis.openbis.generic.asapi.v3.dto.dataset.DataSetKind; import ch.ethz.sis.openbis.generic.server.dss.plugins.sync.harvester.synchronizer.ResourceListParserData.Connection; import ch.ethz.sis.openbis.generic.server.dss.plugins.sync.harvester.synchronizer.ResourceListParserData.IncomingDataSet; import ch.ethz.sis.openbis.generic.server.dss.plugins.sync.harvester.synchronizer.ResourceListParserData.IncomingExperiment; -import ch.ethz.sis.openbis.generic.server.dss.plugins.sync.harvester.synchronizer.ResourceListParserData.MasterData; -import ch.ethz.sis.openbis.generic.server.dss.plugins.sync.harvester.synchronizer.ResourceListParserData.MaterialWithLastModificationDate; import ch.ethz.sis.openbis.generic.server.dss.plugins.sync.harvester.synchronizer.ResourceListParserData.IncomingProject; import ch.ethz.sis.openbis.generic.server.dss.plugins.sync.harvester.synchronizer.ResourceListParserData.IncomingSample; +import ch.ethz.sis.openbis.generic.server.dss.plugins.sync.harvester.synchronizer.ResourceListParserData.MasterData; +import ch.ethz.sis.openbis.generic.server.dss.plugins.sync.harvester.synchronizer.ResourceListParserData.MaterialWithLastModificationDate; import ch.ethz.sis.openbis.generic.server.dss.plugins.sync.harvester.synchronizer.translator.DefaultNameTranslator; import ch.ethz.sis.openbis.generic.server.dss.plugins.sync.harvester.synchronizer.translator.INameTranslator; import ch.systemsx.cisd.openbis.generic.shared.basic.dto.DataSetType; @@ -273,49 +274,63 @@ public class ResourceListParser private void parseDataSetMetaData(XPath xpath, String permId, Node xdNode, Date lastModificationDate) { String code = extractCode(xdNode); - String sample = extractAttribute(xdNode, "sample"); - String experiment = extractAttribute(xdNode, "experiment"); + String sample = extractAttribute(xdNode, "sample", true); + String experiment = extractAttribute(xdNode, "experiment", true); String type = extractType(xdNode); String dsKind = extractAttribute(xdNode, "dsKind"); - NewExternalData ds = new NewExternalData(); + NewExternalData ds = null; if (dsKind.equals(DataSetKind.CONTAINER.toString())) { ds = new NewContainerDataSet(); - ds.setCode(code); - ds.setDataSetType(new DataSetType(type)); - ds.setDataStoreCode(this.dataStoreCode); - if (sample.trim().equals("") == false) - { - ds.setSampleIdentifierOrNull(getSampleIdentifier(sample)); - } - if (experiment.trim().equals("") == false) - { - ds.setExperimentIdentifierOrNull(getExperimentIdentifier(experiment)); - } } else if (dsKind.equals(DataSetKind.PHYSICAL.toString())) { - ds.setCode(code); - ds.setDataSetType(new DataSetType(type)); - ds.setDataStoreCode(this.dataStoreCode); - if (sample.trim().equals("") == false) - { - ds.setSampleIdentifierOrNull(getSampleIdentifier(sample)); - } - if (experiment.trim().equals("") == false) - { - ds.setExperimentIdentifierOrNull(getExperimentIdentifier(experiment)); - } + ds = new NewExternalData(); } + // else if (dsKind.equals(DataSetKind.LINK.toString())) { + // ds = new NewLinkDataSet(); + // ((NewLinkDataSet)ds). + // } + else + { + throw new IllegalArgumentException(dsKind + " data sets are currently not supported"); + } + ds.setCode(code); + ds.setDataSetType(new DataSetType(type)); + ds.setDataStoreCode(this.dataStoreCode); + + ds.setSampleIdentifierOrNull(getSampleIdentifier(sample)); + ds.setExperimentIdentifierOrNull(getExperimentIdentifier(experiment)); + IncomingDataSet incomingDataSet = data.new IncomingDataSet(ds, lastModificationDate); data.getDataSetsToProcess().put(permId, incomingDataSet); incomingDataSet.setConnections(parseConnections(xpath, xdNode)); ds.setDataSetProperties(parseDataSetProperties(xpath, xdNode)); } - private String extractAttribute(Node xdNode, String attrName) + private String extractAttribute(Node xdNode, String attrName, boolean nullAllowed) + { + String val = xdNode.getAttributes().getNamedItem(attrName).getTextContent(); + if (StringUtils.isBlank(val) == true) + { + if (nullAllowed == false) + { + throw new IllegalArgumentException(attrName + " cannot be empty in Resource List"); + } + else + { + return null; + } + } + else + { + return val.trim(); + } + } + + private String extractAttribute(Node xdNode, String attrName) throws IllegalArgumentException { - return xdNode.getAttributes().getNamedItem(attrName).getTextContent(); + return extractAttribute(xdNode, attrName, false); } private String extractCode(Node xdNode) @@ -325,15 +340,23 @@ public class ResourceListParser private SampleIdentifier getSampleIdentifier(String sampleIdentifierStr) { + if (sampleIdentifierStr == null) + { + return null; + } SampleIdentifier sampleIdentifier = SampleIdentifierFactory.parse(sampleIdentifierStr); SpaceIdentifier spaceLevel = sampleIdentifier.getSpaceLevel(); String originalSpaceCode = spaceLevel.getSpaceCode(); return new SampleIdentifier(new SpaceIdentifier(nameTranslator.translate(originalSpaceCode)), sampleIdentifier.getSampleCode()); } - private ExperimentIdentifier getExperimentIdentifier(String experiment) + private ExperimentIdentifier getExperimentIdentifier(String experimentIdentifierStr) { - ExperimentIdentifier experimentIdentifier = ExperimentIdentifierFactory.parse(experiment); + if (experimentIdentifierStr == null) + { + return null; + } + ExperimentIdentifier experimentIdentifier = ExperimentIdentifierFactory.parse(experimentIdentifierStr); String originalSpaceCode = experimentIdentifier.getSpaceCode(); String projectCode = experimentIdentifier.getProjectCode(); String expCode = experimentIdentifier.getExperimentCode(); @@ -345,9 +368,9 @@ public class ResourceListParser String code = extractCode(xdNode); String desc = xdNode.getAttributes().getNamedItem("desc").getTextContent(); - String space = extractSpace(xdNode); - // TODO is there a better way to create project identifier below? - NewProject newProject = new NewProject("/" + nameTranslator.translate(space) + "/" + code, desc); + String space = extractSpace(xdNode, false); + ProjectIdentifier projectIdentifier = createProjectIdentifier(code, space); + NewProject newProject = new NewProject(projectIdentifier.toString(), desc); newProject.setPermID(permId); IncomingProject incomingProject = data.new IncomingProject(newProject, lastModificationDate); @@ -356,6 +379,26 @@ public class ResourceListParser incomingProject.setHasAttachments(hasAttachments(xpath, xdNode)); } + private ProjectIdentifier createProjectIdentifier(String code, String space) + { + return new ProjectIdentifier(createSpaceIdentifier(space), code); + } + + private SampleIdentifier createSampleIdentifier(String code, String space) + { + if (space == null) + { + return new SampleIdentifier(nameTranslator.translate(code)); + } + SpaceIdentifier spaceIdentifier = createSpaceIdentifier(space); + return new SampleIdentifier(spaceIdentifier, code); + } + + private SpaceIdentifier createSpaceIdentifier(String space) + { + return new SpaceIdentifier(nameTranslator.translate(space)); + } + private void parseMaterialMetaData(XPath xpath, String permId, Node xdNode, Date lastModificationDate) { String code = extractCode(xdNode); @@ -457,7 +500,7 @@ public class ResourceListParser String code = extractCode(xdNode); String type = extractType(xdNode); String project = extractAttribute(xdNode, "project"); - String space = extractSpace(xdNode); + String space = extractSpace(xdNode, false); NewExperiment newExp = new NewExperiment("/" + nameTranslator.translate(space) + "/" + project + "/" + code, type); newExp.setPermID(permId); IncomingExperiment incomingExperiment = data.new IncomingExperiment(newExp, lastModificationDate); @@ -471,15 +514,20 @@ public class ResourceListParser { String code = extractCode(xdNode); String type = extractType(xdNode); - String experiment = extractAttribute(xdNode, "experiment"); - String space = extractSpace(xdNode); + String experiment = extractAttribute(xdNode, "experiment", true); + String space = extractSpace(xdNode, true); SampleType sampleType = new SampleType(); sampleType.setCode(type); - NewSample newSample = new NewSample("/" + nameTranslator.translate(space) + "/" + code, sampleType, null, null, - experiment.trim().equals("") ? null : experiment, null, null, new IEntityProperty[0], + SampleIdentifier identifier = createSampleIdentifier(code, space); + NewSample newSample = new NewSample(identifier.toString(), sampleType, null, null, + experiment, null, null, new IEntityProperty[0], new ArrayList<NewAttachment>()); newSample.setPermID(permId); + if (space == null) + { + newSample.setDefaultSpaceIdentifier(null); + } IncomingSample incomingSample = data.new IncomingSample(newSample, lastModificationDate); data.getSamplesToProcess().put(permId, incomingSample); incomingSample.setHasAttachments(hasAttachments(xpath, xdNode)); @@ -492,10 +540,13 @@ public class ResourceListParser return extractAttribute(xdNode, "type"); } - private String extractSpace(Node xdNode) + private String extractSpace(Node xdNode, boolean nullAllowed) { - String space = extractAttribute(xdNode, "space"); - data.getHarvesterSpaceList().add(nameTranslator.translate(space)); + String space = extractAttribute(xdNode, "space", nullAllowed); + if (space != null) + { + data.getHarvesterSpaceList().add(nameTranslator.translate(space)); + } return space; }