From 1afe8c6f6d242d0cfe7285544af2228bd3efd7b3 Mon Sep 17 00:00:00 2001 From: gakin <gakin> Date: Tue, 4 Apr 2017 13:02:50 +0000 Subject: [PATCH] SSDMSSDM-4584 NameTranslation for data coming from different data sources, fix related to SSDM-5014, refactoring SVN: 38013 --- .../synchronizer/EntitySynchronizer.java | 45 ++++++---- .../synchronizer/MasterDataParser.java | 46 +++++----- .../synchronizer/MasterDataSynchronizer.java | 2 - .../synchronizer/ResourceListParser.java | 88 +++++++++++++------ .../synchronizer/ResourceListParserData.java | 4 +- .../translator/PrefixBasedNameTranslator.java | 24 ++++- 6 files changed, 135 insertions(+), 74 deletions(-) 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 54524d4f48d..d95d501e8af 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 @@ -35,6 +35,8 @@ import java.util.Properties; import java.util.Set; import org.apache.commons.codec.binary.Hex; +import org.apache.commons.collections.keyvalue.MultiKey; +import org.apache.commons.collections.map.MultiKeyMap; import org.apache.commons.io.FileUtils; import org.apache.commons.lang.ArrayUtils; import org.apache.commons.lang3.StringUtils; @@ -74,6 +76,7 @@ import ch.ethz.sis.openbis.generic.server.dss.plugins.sync.harvester.synchronize import ch.ethz.sis.openbis.generic.server.dss.plugins.sync.harvester.synchronizer.translator.PrefixBasedNameTranslator; import ch.ethz.sis.openbis.generic.shared.entitygraph.EntityGraph; import ch.ethz.sis.openbis.generic.shared.entitygraph.Node; +import ch.systemsx.cisd.cifex.shared.basic.UserFailureException; import ch.systemsx.cisd.common.concurrent.ITaskExecutor; import ch.systemsx.cisd.common.concurrent.ParallelizedExecutor; import ch.systemsx.cisd.common.exceptions.Status; @@ -187,21 +190,31 @@ public class EntitySynchronizer // Parse the resource list: This sends back all projects, // experiments, samples and data sets contained in the XML together with their last modification date to be used for filtering operationLog.info("parsing the resource list xml document"); - String dataSourcePrefix = config.getDataSourceAlias(); + String dataSourceAlias = config.getDataSourceAlias(); INameTranslator nameTranslator = null; - if (StringUtils.isBlank(dataSourcePrefix) == false) + if (config.isTranslateUsingDataSourceAlias() == true) { - nameTranslator = new PrefixBasedNameTranslator(dataSourcePrefix); + if (StringUtils.isBlank(dataSourceAlias) == true) + { + throw new UserFailureException("Please specify a data source alias in the config file to be used in name translations."); + } + else + { + nameTranslator = new PrefixBasedNameTranslator(dataSourceAlias); + } } - ResourceListParser parser = ResourceListParser.create(nameTranslator, dataStoreCode); + // even when do not translate other things, we always translate space name. + // TODO re-think + ResourceListParser parser = ResourceListParser.create(nameTranslator, new PrefixBasedNameTranslator(dataSourceAlias), dataStoreCode); ResourceListParserData data = parser.parseResourceListDocument(doc); processDeletions(data); operationLog.info("registering master data"); - masterDataSyncronizer = new MasterDataSynchronizer(config.getHarvesterUser(), config.getHarvesterPass(), data.getMasterData()); + masterDataSyncronizer = + new MasterDataSynchronizer(config.getHarvesterUser(), config.getHarvesterPass(), data.getMasterData()); registerMasterData(data); AtomicEntityOperationDetailsBuilder builder = new AtomicEntityOperationDetailsBuilder(); @@ -233,7 +246,7 @@ public class EntitySynchronizer data.filterPhysicalDataSetsByLastModificationDate(lastSyncTimestamp, dataSetsCodesToRetry); operationLog.info("Registering data sets..."); DataSetRegistrationSummary dsRegistrationSummary = registerPhysicalDataSets(physicalDSMap); - // backup the current not synced data set codes file, delete the original file + // backup the current not synched data set codes file, delete the original file saveFailedEntitiesFile(dsRegistrationSummary.notRegisteredDataSetCodes, notSyncedAttachmentsHolders); @@ -491,7 +504,7 @@ public class EntitySynchronizer Set<String> incomingExperimentPermIds = data.getExperimentsToProcess().keySet(); Set<String> incomingSamplePermIds = data.getSamplesToProcess().keySet(); Set<String> incomingDataSetCodes = data.getDataSetsToProcess().keySet(); - Set<String> incomingMaterialCodes = data.getMaterialsToProcess().keySet(); + MultiKeyMap<String, MaterialWithLastModificationDate> incomingMaterials = data.getMaterialsToProcess(); // find projects, experiments, samples and data sets to be deleted List<ProjectPermId> projectPermIds = new ArrayList<ProjectPermId>(); @@ -588,7 +601,7 @@ public class EntitySynchronizer for (ch.ethz.sis.openbis.generic.asapi.v3.dto.material.Material material : materials) { - if (incomingMaterialCodes.contains(material.getCode()) == false) + if (incomingMaterials.containsKey(material.getCode(), material.getType().getCode()) == false) { matPermIds.add(new MaterialPermId(material.getCode(), material.getType().getCode())); } @@ -613,6 +626,11 @@ public class EntitySynchronizer expDeletionOpts.setReason("sync experiment deletions"); IDeletionId expDeletionId = v3Api.deleteExperiments(sessionToken, experimentPermIds, expDeletionOpts); + // confirm deletions: Deletions need be confirm in the right order because of dependencies(foreign key constraints) + v3Api.confirmDeletions(sessionToken, Collections.singletonList(dsDeletionId)); + v3Api.confirmDeletions(sessionToken, Collections.singletonList(smpDeletionId)); + v3Api.confirmDeletions(sessionToken, Collections.singletonList(expDeletionId)); + // delete projects ProjectDeletionOptions prjDeletionOpts = new ProjectDeletionOptions(); prjDeletionOpts.setReason("Sync projects"); @@ -629,10 +647,7 @@ public class EntitySynchronizer { operationLog.warn("One or more materials could not be deleted due to: " + e.getMessage()); } - - // confirm deletions - ArrayList<IDeletionId> deletionIds = new ArrayList<IDeletionId>(); - + StringBuffer summary = new StringBuffer(); if (projectPermIds.size() > 0) { @@ -644,20 +659,16 @@ public class EntitySynchronizer } if (expDeletionId != null) { - deletionIds.add(expDeletionId); summary.append(experimentPermIds.size() + " experiments,"); } if (smpDeletionId != null) { - deletionIds.add(smpDeletionId); summary.append(samplePermIds.size() + " samples,"); } if (dsDeletionId != null) { - deletionIds.add(dsDeletionId); summary.append(dsPermIds.size() + " data sets"); } - v3Api.confirmDeletions(sessionToken, deletionIds); // Arrays.asList(expDeletionId, dsDeletionId, smpDeletionId) if (summary.length() > 0) { @@ -747,7 +758,7 @@ public class EntitySynchronizer private void processMaterials(ResourceListParserData data, AtomicEntityOperationDetailsBuilder builder) { // process materials - Map<String, MaterialWithLastModificationDate> materialsToProcess = data.getMaterialsToProcess(); + Map<MultiKey<String>, MaterialWithLastModificationDate> materialsToProcess = data.getMaterialsToProcess(); for (MaterialWithLastModificationDate newMaterialWithType : materialsToProcess.values()) { NewMaterialWithType incomingMaterial = newMaterialWithType.getMaterial(); diff --git a/datastore_server/source/java/ch/ethz/sis/openbis/generic/server/dss/plugins/sync/harvester/synchronizer/MasterDataParser.java b/datastore_server/source/java/ch/ethz/sis/openbis/generic/server/dss/plugins/sync/harvester/synchronizer/MasterDataParser.java index a2a134250b5..12e042a1e4f 100644 --- a/datastore_server/source/java/ch/ethz/sis/openbis/generic/server/dss/plugins/sync/harvester/synchronizer/MasterDataParser.java +++ b/datastore_server/source/java/ch/ethz/sis/openbis/generic/server/dss/plugins/sync/harvester/synchronizer/MasterDataParser.java @@ -29,6 +29,7 @@ import javax.xml.xpath.XPathExpression; import javax.xml.xpath.XPathExpressionException; import org.apache.commons.collections.map.MultiKeyMap; +import org.apache.commons.lang3.StringUtils; import org.w3c.dom.Document; import org.w3c.dom.Element; import org.w3c.dom.Node; @@ -184,17 +185,14 @@ public class MasterDataParser for (int i = 0; i < pluginNodes.getLength(); i++) { Element pluginElement = (Element) pluginNodes.item(i); - Script plugin = new Script(); - // String code = getAttribute(pluginElement, "code"); - plugin.setName(getAttribute(pluginElement, "name")); + plugin.setName(nameTranslator.translate(getAttribute(pluginElement, "name"))); plugin.setDescription(getAttribute(pluginElement, "description")); String entityKind = getAttribute(pluginElement, "entityKind").trim(); plugin.setScriptType(ScriptType.valueOf(getAttribute(pluginElement, "type"))); plugin.setPluginType(PluginType.JYTHON); plugin.setEntityKind(entityKind.equals("") ? null : new EntityKind[] { EntityKind.valueOf(entityKind) }); plugin.setScript(pluginElement.getTextContent()); - validationPlugins.put(plugin.getName(), plugin); } } @@ -245,8 +243,7 @@ public class MasterDataParser for (int i = 0; i < vocabNodes.getLength(); i++) { Element vocabElement = (Element) vocabNodes.item(i); - String code = getAttribute(vocabElement, "code"); - + String code = nameTranslator.translate(getAttribute(vocabElement, "code")); NewVocabulary newVocabulary = new NewVocabulary(); newVocabulary.setCode(code); newVocabulary.setDescription(getAttribute(vocabElement, "description")); @@ -299,7 +296,7 @@ public class MasterDataParser { Element materialTypeElement = (Element) matTypeNodes.item(i); MaterialType materialType = new MaterialType(); - materialType.setCode(getAttribute(materialTypeElement, "code")); + materialType.setCode(nameTranslator.translate(getAttribute(materialTypeElement, "code"))); materialType.setDescription(getAttribute(materialTypeElement, "description")); String validationPluginName = getAttribute(materialTypeElement, "validationPlugin"); if (validationPluginName != null) @@ -308,7 +305,7 @@ public class MasterDataParser } materialTypes.put(materialType.getCode(), materialType); - parsePropertyAssignments(EntityKind.MATERIAL, materialType, materialTypeElement.getElementsByTagName("propertyAssignments")); + parsePropertyAssignments(EntityKind.MATERIAL, materialType, materialTypeElement); } } @@ -325,9 +322,8 @@ public class MasterDataParser for (int i = 0; i < expTypeNodes.getLength(); i++) { Element expTypeElement = (Element) expTypeNodes.item(i); - String code = getAttribute(expTypeElement, "code"); ExperimentType expType = new ExperimentType(); - expType.setCode(code); + expType.setCode(nameTranslator.translate(getAttribute(expTypeElement, "code"))); expType.setDescription(getAttribute(expTypeElement, "description")); String validationPluginName = getAttribute(expTypeElement, "validationPlugin"); if (validationPluginName != null) @@ -336,7 +332,7 @@ public class MasterDataParser } experimentTypes.put(expType.getCode(), expType); - parsePropertyAssignments(EntityKind.EXPERIMENT, expType, expTypeElement.getElementsByTagName("xmd:propertyAssignments")); + parsePropertyAssignments(EntityKind.EXPERIMENT, expType, expTypeElement); } } @@ -354,7 +350,7 @@ public class MasterDataParser { Element sampleTypeElement = (Element) sampleTypeNodes.item(i); SampleType sampleType = new SampleType(); - sampleType.setCode(getAttribute(sampleTypeElement, "code")); + sampleType.setCode(nameTranslator.translate(getAttribute(sampleTypeElement, "code"))); sampleType.setDescription(getAttribute(sampleTypeElement, "description")); sampleType.setListable(Boolean.valueOf(getAttribute(sampleTypeElement, "listable"))); sampleType.setShowContainer(Boolean.valueOf(getAttribute(sampleTypeElement, "showContainer"))); @@ -370,7 +366,7 @@ public class MasterDataParser } sampleTypes.put(sampleType.getCode(), sampleType); - parsePropertyAssignments(EntityKind.SAMPLE, sampleType, sampleTypeElement.getElementsByTagName("xmd:propertyAssignments")); + parsePropertyAssignments(EntityKind.SAMPLE, sampleType, sampleTypeElement); } } @@ -387,9 +383,8 @@ public class MasterDataParser for (int i = 0; i < dataSetTypeNodes.getLength(); i++) { Element dataSetTypeElement = (Element) dataSetTypeNodes.item(i); - String code = getAttribute(dataSetTypeElement, "code"); DataSetType dataSetType = new DataSetType(); - dataSetType.setCode(code); + dataSetType.setCode(nameTranslator.translate(getAttribute(dataSetTypeElement, "code"))); dataSetType.setDescription(getAttribute(dataSetTypeElement, "description")); dataSetType.setDataSetKind(DataSetKind.valueOf(getAttribute(dataSetTypeElement, "dataSetKind"))); String mainDataSetPattern = getAttribute(dataSetTypeElement, "mainDataSetPattern"); @@ -417,13 +412,14 @@ public class MasterDataParser } dataSetTypes.put(dataSetType.getCode(), dataSetType); - parsePropertyAssignments(EntityKind.DATA_SET, dataSetType, dataSetTypeElement.getElementsByTagName("xmd:propertyAssignments")); + parsePropertyAssignments(EntityKind.DATA_SET, dataSetType, dataSetTypeElement); } } - private void parsePropertyAssignments(EntityKind entityKind, EntityType entityType, NodeList propertyAssignmentsNode) + private void parsePropertyAssignments(EntityKind entityKind, EntityType entityType, Element entityTypeElement) throws XPathExpressionException { + NodeList propertyAssignmentsNode = entityTypeElement.getElementsByTagName("xmd:propertyAssignments"); if (propertyAssignmentsNode.getLength() == 0) { return; @@ -438,6 +434,7 @@ public class MasterDataParser { Element propertyAssignmentElement = (Element) propertyAssignmentNodes.item(i); String propertyTypeCode = getAttribute(propertyAssignmentElement, "propertyTypeCode"); + propertyTypeCode = nameTranslator.translate(propertyTypeCode); NewETPTAssignment assignment = new NewETPTAssignment(); assignment.setPropertyTypeCode(propertyTypeCode); assignment.setEntityKind(entityType.getEntityKind()); @@ -465,33 +462,34 @@ public class MasterDataParser for (int i = 0; i < propertyTypeNodes.getLength(); i++) { Element propertyTypeElement = (Element) propertyTypeNodes.item(i); - PropertyType newPropertyType = new PropertyType(); - String code = getAttribute(propertyTypeElement, "code"); + PropertyType newPropertyType = new PropertyType(); + Boolean isInternalNameSpace = Boolean.valueOf(getAttribute(propertyTypeElement, "internalNamespace")); + String code = nameTranslator.translate(getAttribute(propertyTypeElement, "code")); + newPropertyType.setCode(CodeConverter.tryToBusinessLayer(code, isInternalNameSpace)); newPropertyType.setLabel(getAttribute(propertyTypeElement, "label")); DataTypeCode dataTypeCode = DataTypeCode.valueOf(getAttribute(propertyTypeElement, "dataType")); newPropertyType.setDataType(new DataType(dataTypeCode)); newPropertyType.setDescription(getAttribute(propertyTypeElement, "description")); + newPropertyType.setInternalNamespace(isInternalNameSpace); newPropertyType.setManagedInternally(Boolean.valueOf(getAttribute(propertyTypeElement, "managedInternally"))); - newPropertyType.setInternalNamespace(Boolean.valueOf(getAttribute(propertyTypeElement, "internalNamespace"))); - newPropertyType.setCode(CodeConverter.tryToBusinessLayer(code, newPropertyType.isInternalNamespace())); propertyTypes.put(newPropertyType.getCode(), newPropertyType); if (dataTypeCode.equals(DataTypeCode.CONTROLLEDVOCABULARY)) { - String vocabularyCode = getAttribute(propertyTypeElement, "vocabulary"); + String vocabularyCode = nameTranslator.translate((getAttribute(propertyTypeElement, "vocabulary"))); newPropertyType.setVocabulary(vocabularies.get(vocabularyCode)); } else if (dataTypeCode.equals(DataTypeCode.MATERIAL)) { String materialCode = getAttribute(propertyTypeElement, "material"); - if (materialCode.trim().length() < 1) + if (StringUtils.isBlank(materialCode)) { newPropertyType.setMaterialType(null); // material of any type } else { - newPropertyType.setMaterialType(materialTypes.get(materialCode)); + newPropertyType.setMaterialType(materialTypes.get(nameTranslator.translate(materialCode))); } } } diff --git a/datastore_server/source/java/ch/ethz/sis/openbis/generic/server/dss/plugins/sync/harvester/synchronizer/MasterDataSynchronizer.java b/datastore_server/source/java/ch/ethz/sis/openbis/generic/server/dss/plugins/sync/harvester/synchronizer/MasterDataSynchronizer.java index a417361f20a..3cae25520e4 100644 --- a/datastore_server/source/java/ch/ethz/sis/openbis/generic/server/dss/plugins/sync/harvester/synchronizer/MasterDataSynchronizer.java +++ b/datastore_server/source/java/ch/ethz/sis/openbis/generic/server/dss/plugins/sync/harvester/synchronizer/MasterDataSynchronizer.java @@ -180,8 +180,6 @@ public class MasterDataSynchronizer existingVocabulary.setURLTemplate(newVocabulary.getURLTemplate()); existingVocabulary.setChosenFromList(newVocabulary.isChosenFromList()); commonServer.updateVocabulary(sessionToken, existingVocabulary); - // vocabulary.setTerms(newVocabulary.getTerms()); - processVocabularyTerms(sessionToken, commonServer, newVocabulary, existingVocabulary); } else 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 4e4756b2ed9..317deec3302 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 @@ -15,6 +15,9 @@ */ package ch.ethz.sis.openbis.generic.server.dss.plugins.sync.harvester.synchronizer; +import static ch.systemsx.cisd.openbis.generic.shared.basic.dto.MaterialIdentifier.TYPE_SEPARATOR_PREFIX; +import static ch.systemsx.cisd.openbis.generic.shared.basic.dto.MaterialIdentifier.TYPE_SEPARATOR_SUFFIX; + import java.text.DateFormat; import java.text.ParseException; import java.text.SimpleDateFormat; @@ -51,9 +54,12 @@ import ch.ethz.sis.openbis.generic.server.dss.plugins.sync.harvester.synchronize 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.ethz.sis.openbis.generic.server.dss.plugins.sync.harvester.synchronizer.translator.PrefixBasedNameTranslator; import ch.systemsx.cisd.openbis.generic.shared.basic.dto.DataSetType; +import ch.systemsx.cisd.openbis.generic.shared.basic.dto.DataTypeCode; import ch.systemsx.cisd.openbis.generic.shared.basic.dto.EntityProperty; import ch.systemsx.cisd.openbis.generic.shared.basic.dto.IEntityProperty; +import ch.systemsx.cisd.openbis.generic.shared.basic.dto.MaterialIdentifier; import ch.systemsx.cisd.openbis.generic.shared.basic.dto.NewAttachment; import ch.systemsx.cisd.openbis.generic.shared.basic.dto.NewExperiment; import ch.systemsx.cisd.openbis.generic.shared.basic.dto.NewMaterialWithType; @@ -80,6 +86,8 @@ public class ResourceListParser private final INameTranslator nameTranslator; + private final INameTranslator spaceNameTranslator; + private final String dataStoreCode; public INameTranslator getNameTranslator() @@ -87,25 +95,26 @@ public class ResourceListParser return nameTranslator; } - private ResourceListParser(INameTranslator nameTranslator, String dataStoreCode) + private ResourceListParser(INameTranslator nameTranslator, PrefixBasedNameTranslator spaceNameTranslator, String dataStoreCode) { this.data = new ResourceListParserData(); this.nameTranslator = nameTranslator; this.dataStoreCode = dataStoreCode; + this.spaceNameTranslator = spaceNameTranslator; } - public static ResourceListParser create(INameTranslator nameTranslator, String dataStoreCode) + public static ResourceListParser create(INameTranslator nameTranslator, PrefixBasedNameTranslator spaceNameTranslator, String dataStoreCode) { if (nameTranslator == null) { - return create(dataStoreCode); + return create(spaceNameTranslator, dataStoreCode); } - return new ResourceListParser(nameTranslator, dataStoreCode); + return new ResourceListParser(nameTranslator, spaceNameTranslator, dataStoreCode); } - public static ResourceListParser create(String dataStoreCode) + public static ResourceListParser create(PrefixBasedNameTranslator spaceNameTranslator, String dataStoreCode) { - return create(new DefaultNameTranslator(), dataStoreCode); + return create(new DefaultNameTranslator(), spaceNameTranslator, dataStoreCode); } public ResourceListParserData parseResourceListDocument(Document doc) throws XPathExpressionException @@ -227,7 +236,7 @@ public class ResourceListParser { parseDataSetMetaData(xpath, extractDataSetCodeFromURI(uri), xdNode, lastModificationDate); } - else if (EntityKind.MATERIAL.equals(entityKind)) + else if (EntityKind.MATERIAL.getLabel().equals(entityKind)) { parseMaterialMetaData(xpath, extractMaterialCodeFromURI(uri), xdNode, lastModificationDate); } @@ -379,6 +388,11 @@ public class ResourceListParser incomingProject.setHasAttachments(hasAttachments(xpath, xdNode)); } + private ExperimentIdentifier createExperimentIdentifier(String spaceId, String prjCode, String expCode) + { + return new ExperimentIdentifier(createProjectIdentifier(prjCode, spaceId), expCode); + } + private ProjectIdentifier createProjectIdentifier(String code, String space) { return new ProjectIdentifier(createSpaceIdentifier(space), code); @@ -401,12 +415,12 @@ public class ResourceListParser private void parseMaterialMetaData(XPath xpath, String permId, Node xdNode, Date lastModificationDate) { - String code = extractCode(xdNode); + String code = nameTranslator.translate(extractCode(xdNode)); String type = extractType(xdNode); NewMaterialWithType newMaterial = new NewMaterialWithType(code, type); MaterialWithLastModificationDate materialWithLastModDate = data.new MaterialWithLastModificationDate(newMaterial, lastModificationDate); - data.getMaterialsToProcess().put(code, materialWithLastModDate); + data.getMaterialsToProcess().put(code, type, materialWithLastModDate); newMaterial.setProperties(parseProperties(xpath, xdNode)); } @@ -442,22 +456,11 @@ public class ResourceListParser private List<NewProperty> parseDataSetProperties(XPath xpath, Node xdNode) { - + EntityProperty[] entityProperties = parseProperties(xpath, xdNode); List<NewProperty> dsProperties = new ArrayList<NewProperty>(); - Element docElement = (Element) xdNode; - NodeList propsNode = docElement.getElementsByTagName("x:properties"); - if (propsNode.getLength() == 1) + for (EntityProperty entityProperty : entityProperties) { - Element propsElement = (Element) propsNode.item(0); - NodeList propertyNodes = propsElement.getElementsByTagName("x:property"); - for (int i = 0; i < propertyNodes.getLength(); i++) - { - Element propertyElement = (Element) propertyNodes.item(i); - // TODO proper error handling needed below in case the XML is not correct and item 0 does not exist - String code = propertyElement.getElementsByTagName("x:code").item(0).getTextContent(); - String val = propertyElement.getElementsByTagName("x:value").item(0).getTextContent(); - dsProperties.add(new NewProperty(code, val)); - } + dsProperties.add(new NewProperty(entityProperty.getPropertyType().getCode(), entityProperty.getValue())); } return dsProperties; } @@ -489,19 +492,50 @@ public class ResourceListParser { EntityProperty property = new EntityProperty(); PropertyType propertyType = new PropertyType(); - propertyType.setCode(code); + String translatedCode = nameTranslator.translate(code); + PropertyType pt = data.getMasterData().getPropertyTypesToProcess().get(translatedCode); + if (pt.getDataType().getCode().equals(DataTypeCode.MATERIAL)) + { + if (val != null) + { + val = nameTranslator.translate(val); + val = translateMaterialIdentifier(val); + } + + } + propertyType.setCode(translatedCode); property.setPropertyType(propertyType); property.setValue(val); return property; } + private String translateMaterialIdentifier(String value) { + if (StringUtils.isBlank(value)) + { + return null; + } + int typePrefix = value.indexOf(TYPE_SEPARATOR_PREFIX); + if (typePrefix == -1) + { + return null; + } + String code = value.substring(0, typePrefix); + String typeCode = nameTranslator.translate(value.substring(typePrefix + TYPE_SEPARATOR_PREFIX.length())); + // we allow to omit the closing brace + if (typeCode.endsWith(TYPE_SEPARATOR_SUFFIX)) + { + typeCode = typeCode.substring(0, typeCode.length() - TYPE_SEPARATOR_SUFFIX.length()); + } + return new MaterialIdentifier(code, typeCode).toString(); + } private void parseExperimentMetaData(XPath xpath, String permId, Node xdNode, Date lastModificationDate) { String code = extractCode(xdNode); String type = extractType(xdNode); String project = extractAttribute(xdNode, "project"); String space = extractSpace(xdNode, false); - NewExperiment newExp = new NewExperiment("/" + nameTranslator.translate(space) + "/" + project + "/" + code, type); + ExperimentIdentifier experimentIdentifier = createExperimentIdentifier(space, project, code); + NewExperiment newExp = new NewExperiment(experimentIdentifier.toString(), type); newExp.setPermID(permId); IncomingExperiment incomingExperiment = data.new IncomingExperiment(newExp, lastModificationDate); data.getExperimentsToProcess().put(permId, incomingExperiment); @@ -537,7 +571,7 @@ public class ResourceListParser private String extractType(Node xdNode) { - return extractAttribute(xdNode, "type"); + return nameTranslator.translate(extractAttribute(xdNode, "type")); } private String extractSpace(Node xdNode, boolean nullAllowed) @@ -545,7 +579,7 @@ public class ResourceListParser String space = extractAttribute(xdNode, "space", nullAllowed); if (space != null) { - data.getHarvesterSpaceList().add(nameTranslator.translate(space)); + data.getHarvesterSpaceList().add(spaceNameTranslator.translate(space)); } return space; } diff --git a/datastore_server/source/java/ch/ethz/sis/openbis/generic/server/dss/plugins/sync/harvester/synchronizer/ResourceListParserData.java b/datastore_server/source/java/ch/ethz/sis/openbis/generic/server/dss/plugins/sync/harvester/synchronizer/ResourceListParserData.java index 036c18f0ab7..52a05b820ab 100644 --- a/datastore_server/source/java/ch/ethz/sis/openbis/generic/server/dss/plugins/sync/harvester/synchronizer/ResourceListParserData.java +++ b/datastore_server/source/java/ch/ethz/sis/openbis/generic/server/dss/plugins/sync/harvester/synchronizer/ResourceListParserData.java @@ -66,7 +66,7 @@ public class ResourceListParserData private Map<String, IncomingDataSet> dataSetsToProcess = new HashMap<String, ResourceListParserData.IncomingDataSet>(); - private Map<String, MaterialWithLastModificationDate> materialsToProcess = new HashMap<String, MaterialWithLastModificationDate>(); + private MultiKeyMap<String, MaterialWithLastModificationDate> materialsToProcess = new MultiKeyMap<String, MaterialWithLastModificationDate>(); public MasterData getMasterData() { @@ -108,7 +108,7 @@ public class ResourceListParserData return dataSetsToProcess; } - public Map<String, MaterialWithLastModificationDate> getMaterialsToProcess() + public MultiKeyMap<String, MaterialWithLastModificationDate> getMaterialsToProcess() { return materialsToProcess; } diff --git a/datastore_server/source/java/ch/ethz/sis/openbis/generic/server/dss/plugins/sync/harvester/synchronizer/translator/PrefixBasedNameTranslator.java b/datastore_server/source/java/ch/ethz/sis/openbis/generic/server/dss/plugins/sync/harvester/synchronizer/translator/PrefixBasedNameTranslator.java index bfc2ccc5646..6b879ce25de 100644 --- a/datastore_server/source/java/ch/ethz/sis/openbis/generic/server/dss/plugins/sync/harvester/synchronizer/translator/PrefixBasedNameTranslator.java +++ b/datastore_server/source/java/ch/ethz/sis/openbis/generic/server/dss/plugins/sync/harvester/synchronizer/translator/PrefixBasedNameTranslator.java @@ -16,6 +16,8 @@ package ch.ethz.sis.openbis.generic.server.dss.plugins.sync.harvester.synchronizer.translator; +import static ch.systemsx.cisd.openbis.generic.shared.basic.BasicConstant.INTERNAL_NAMESPACE_PREFIX; + import org.apache.commons.lang3.StringUtils; /** @@ -32,11 +34,29 @@ public class PrefixBasedNameTranslator implements INameTranslator this.prefix = prefix; } + private String translateInternal(String name) + { + return prefix + "_" + name; + } + + /** + * INTERNAL_NAMESPACE_PREFIX is checked because of the following cases following cases: 1. While parsing master data, for property types with dataType = CONTROLLEDVOCABULARY or + * MATERIAL in which case the vocabulary or material attribute might start with $ (INTERNAL_NAMESPACE_PREFIX) 2. While parsing master data, for + * property assignments where property type code might start with $ (INTERNAL_NAMESPACE_PREFIX) the prop. assignment element in the incoming xml + * will start with $ if propertyTypeCode is internalNamespace. 3. While parsing meta data, the property code will will start with $ if + * propertyTypeCode is internalNamespac + */ @Override public String translate(String name) { assert StringUtils.isBlank(name) == false : "Prefix translation can only be done for non-null values"; - return prefix + "_" + name; + if (name.startsWith(INTERNAL_NAMESPACE_PREFIX)) + { + return INTERNAL_NAMESPACE_PREFIX + translateInternal(name.substring(INTERNAL_NAMESPACE_PREFIX.length())); + } + else + { + return translateInternal(name); + } } - } -- GitLab