diff --git a/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/executor/common/TechIdStringIdentifierRecord.java b/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/executor/common/TechIdStringIdentifierRecord.java new file mode 100644 index 0000000000000000000000000000000000000000..f23e48b0a22305bfea3295a6148a97b126415b9e --- /dev/null +++ b/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/executor/common/TechIdStringIdentifierRecord.java @@ -0,0 +1,28 @@ +/* + * Copyright 2015 ETH Zuerich, SIS + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package ch.ethz.sis.openbis.generic.server.api.v3.executor.common; + +/** + * + * + * @author Franz-Josef Elmer + */ +public class TechIdStringIdentifierRecord +{ + public Long id; + public String identifier; +} diff --git a/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/executor/method/MapSampleSqlMethodExecutor.java b/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/executor/method/MapSampleSqlMethodExecutor.java index 8f7010094691569d0d81162028b93a15337f5b28..d769bb9c49eb5140484b674d4fef6faf50d1870b 100644 --- a/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/executor/method/MapSampleSqlMethodExecutor.java +++ b/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/executor/method/MapSampleSqlMethodExecutor.java @@ -16,22 +16,16 @@ package ch.ethz.sis.openbis.generic.server.api.v3.executor.method; -import java.util.Collection; -import java.util.LinkedHashMap; -import java.util.Map; - import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; -import ch.ethz.sis.openbis.generic.server.api.v3.executor.IOperationContext; import ch.ethz.sis.openbis.generic.server.api.v3.executor.common.IMapObjectByIdExecutor; -import ch.ethz.sis.openbis.generic.server.api.v3.executor.sample.IMapSampleByIdExecutor; +import ch.ethz.sis.openbis.generic.server.api.v3.executor.sample.IMapSampleTechIdByIdExecutor; import ch.ethz.sis.openbis.generic.server.api.v3.translator.ITranslator; import ch.ethz.sis.openbis.generic.server.api.v3.translator.entity.sample.sql.ISampleSqlTranslator; import ch.ethz.sis.openbis.generic.shared.api.v3.dto.entity.sample.Sample; import ch.ethz.sis.openbis.generic.shared.api.v3.dto.fetchoptions.sample.SampleFetchOptions; import ch.ethz.sis.openbis.generic.shared.api.v3.dto.id.sample.ISampleId; -import ch.systemsx.cisd.openbis.generic.shared.dto.SamplePE; /** * @author pkupczyk @@ -42,7 +36,7 @@ public class MapSampleSqlMethodExecutor extends AbstractMapMethodExecutor<ISampl { @Autowired - private IMapSampleByIdExecutor mapExecutor; + private IMapSampleTechIdByIdExecutor mapExecutor; @Autowired private ISampleSqlTranslator translator; @@ -50,23 +44,7 @@ public class MapSampleSqlMethodExecutor extends AbstractMapMethodExecutor<ISampl @Override protected IMapObjectByIdExecutor<ISampleId, Long> getMapExecutor() { - // TODO replace with ISampleId -> Long mapExecutor once there is one - return new IMapObjectByIdExecutor<ISampleId, Long>() - { - @Override - public Map<ISampleId, Long> map(IOperationContext context, Collection<? extends ISampleId> ids) - { - Map<ISampleId, SamplePE> peMap = mapExecutor.map(context, ids); - Map<ISampleId, Long> idMap = new LinkedHashMap<ISampleId, Long>(); - - for (Map.Entry<ISampleId, SamplePE> peEntry : peMap.entrySet()) - { - idMap.put(peEntry.getKey(), peEntry.getValue().getId()); - } - - return idMap; - } - }; + return mapExecutor; } @Override diff --git a/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/executor/sample/IMapSampleTechIdByIdExecutor.java b/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/executor/sample/IMapSampleTechIdByIdExecutor.java new file mode 100644 index 0000000000000000000000000000000000000000..21f5be72d9dbd35edb5ac67332133ab348a979de --- /dev/null +++ b/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/executor/sample/IMapSampleTechIdByIdExecutor.java @@ -0,0 +1,30 @@ +/* + * Copyright 2015 ETH Zuerich, SIS + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package ch.ethz.sis.openbis.generic.server.api.v3.executor.sample; + +import ch.ethz.sis.openbis.generic.server.api.v3.executor.common.IMapObjectByIdExecutor; +import ch.ethz.sis.openbis.generic.shared.api.v3.dto.id.sample.ISampleId; + +/** + * + * + * @author Franz-Josef Elmer + */ +public interface IMapSampleTechIdByIdExecutor extends IMapObjectByIdExecutor<ISampleId, Long> +{ + +} diff --git a/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/executor/sample/ListSampleTechIdByIdentifier.java b/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/executor/sample/ListSampleTechIdByIdentifier.java new file mode 100644 index 0000000000000000000000000000000000000000..dc4c7ef7ac3c0e99c1d3bb0796c8beb08c440741 --- /dev/null +++ b/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/executor/sample/ListSampleTechIdByIdentifier.java @@ -0,0 +1,158 @@ +/* + * Copyright 2015 ETH Zuerich, SIS + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package ch.ethz.sis.openbis.generic.server.api.v3.executor.sample; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Map.Entry; + +import net.lemnik.eodsql.QueryTool; + +import ch.ethz.sis.openbis.generic.server.api.v3.executor.common.TechIdStringIdentifierRecord; +import ch.ethz.sis.openbis.generic.server.api.v3.helper.common.IListObjectById; +import ch.ethz.sis.openbis.generic.shared.api.v3.dto.id.sample.SampleIdentifier; +import ch.systemsx.cisd.openbis.generic.shared.basic.CodeConverter; +import ch.systemsx.cisd.openbis.generic.shared.dto.identifier.SampleIdentifierFactory; + +/** + * + * + * @author Franz-Josef Elmer + */ +public class ListSampleTechIdByIdentifier implements IListObjectById<SampleIdentifier, Long> +{ + private Map<Long, SampleIdentifier> identifiersByTechIds = new HashMap<Long, SampleIdentifier>(); + + @Override + public Class<SampleIdentifier> getIdClass() + { + return SampleIdentifier.class; + } + + @Override + public SampleIdentifier createId(Long techId) + { + return identifiersByTechIds.get(techId); + } + + @Override + public List<Long> listByIds(List<SampleIdentifier> ids) + { + Map<Key, Map<String, SampleIdentifier>> groupedIdentifiers = new HashMap<>(); + for (SampleIdentifier sampleIdentifier : ids) + { + ch.systemsx.cisd.openbis.generic.shared.dto.identifier.SampleIdentifier sampleIdentifier2 + = SampleIdentifierFactory.parse(sampleIdentifier.getIdentifier()); + String spaceCode = null; + if (sampleIdentifier2.isSpaceLevel()) + { + spaceCode = CodeConverter.tryToDatabase(sampleIdentifier2.getSpaceLevel().getSpaceCode()); + } + String sampleSubCode = CodeConverter.tryToDatabase(sampleIdentifier2.getSampleSubCode()); + String containerCode = CodeConverter.tryToDatabase(sampleIdentifier2.tryGetContainerCode()); + Key key = new Key(spaceCode, containerCode); + Map<String, SampleIdentifier> identifiersByCode = groupedIdentifiers.get(key); + if (identifiersByCode == null) + { + identifiersByCode = new HashMap<>(); + groupedIdentifiers.put(key, identifiersByCode); + } + identifiersByCode.put(sampleSubCode, sampleIdentifier); + } + SampleQuery query = QueryTool.getManagedQuery(SampleQuery.class); + for (Entry<Key, Map<String, SampleIdentifier>> entry : groupedIdentifiers.entrySet()) + { + Key key = entry.getKey(); + Map<String, SampleIdentifier> identifiersByCode = entry.getValue(); + List<TechIdStringIdentifierRecord> records = list(query, key, identifiersByCode.keySet()); + for (TechIdStringIdentifierRecord record : records) + { + String sampleCode = record.identifier; + identifiersByTechIds.put(record.id, identifiersByCode.get(sampleCode)); + } + } + return new ArrayList<>(identifiersByTechIds.keySet()); + } + + private List<TechIdStringIdentifierRecord> list(SampleQuery query, Key key, Collection<String> codes) + { + String[] codesArray = codes.toArray(new String[codes.size()]); + String spaceCode = key.spaceCodeOrNull; + String containerCode = key.containerCodeOrNull; + if (spaceCode == null) + { + if (containerCode == null) + { + return query.listSharedSampleTechIdsByCodes(codesArray); + } + return query.listSharedSampleTechIdsByContainerCodeAndCodes(containerCode, codesArray); + } + if (containerCode == null) + { + return query.listSpaceSampleTechIdsByCodes(spaceCode, codesArray); + } + return query.listSpaceSampleTechIdsByContainerCodeAndCodes(spaceCode, containerCode, codesArray); + } + + private static final class Key + { + private String spaceCodeOrNull; + private String containerCodeOrNull; + + Key(String spaceCodeOrNull, String containerCodeOrNull) + { + this.spaceCodeOrNull = spaceCodeOrNull; + this.containerCodeOrNull = containerCodeOrNull; + } + + @Override + public boolean equals(Object obj) + { + if (obj == this) + { + return true; + } + if (obj instanceof Key == false) + { + return false; + } + Key key = (Key) obj; + return isEqual(spaceCodeOrNull, key.spaceCodeOrNull) + && isEqual(containerCodeOrNull, key.containerCodeOrNull); + } + + private boolean isEqual(String str1, String str2) + { + return str1 == null ? str1 == str2 : str1.equals(str2); + } + + @Override + public int hashCode() + { + return 37 * calcHashCode(spaceCodeOrNull) + calcHashCode(containerCodeOrNull); + } + + private int calcHashCode(String str) + { + return str == null ? 0 : str.hashCode(); + } + } + +} diff --git a/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/executor/sample/ListSampleTechIdByPermId.java b/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/executor/sample/ListSampleTechIdByPermId.java new file mode 100644 index 0000000000000000000000000000000000000000..6905e21ba1e90275c8fc33d9e12942db441468c3 --- /dev/null +++ b/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/executor/sample/ListSampleTechIdByPermId.java @@ -0,0 +1,70 @@ +/* + * Copyright 2015 ETH Zuerich, SIS + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package ch.ethz.sis.openbis.generic.server.api.v3.executor.sample; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import net.lemnik.eodsql.QueryTool; + +import ch.ethz.sis.openbis.generic.server.api.v3.executor.common.TechIdStringIdentifierRecord; +import ch.ethz.sis.openbis.generic.server.api.v3.helper.common.IListObjectById; +import ch.ethz.sis.openbis.generic.shared.api.v3.dto.id.sample.SamplePermId; + +/** + * + * + * @author Franz-Josef Elmer + */ +public class ListSampleTechIdByPermId implements IListObjectById<SamplePermId, Long> +{ + private Map<Long, SamplePermId> permIdsByTechIds = new HashMap<Long, SamplePermId>(); + + @Override + public Class<SamplePermId> getIdClass() + { + return SamplePermId.class; + } + + @Override + public SamplePermId createId(Long techId) + { + return permIdsByTechIds.get(techId); + } + + @Override + public List<Long> listByIds(List<SamplePermId> ids) + { + SampleQuery query = QueryTool.getManagedQuery(SampleQuery.class); + + List<String> permIds = new ArrayList<>(ids.size()); + for (SamplePermId permId : ids) + { + permIds.add(permId.getPermId()); + } + List<Long> techIds = new ArrayList<>(); + for (TechIdStringIdentifierRecord record : query.listSampleTechIdsByPermIds(permIds.toArray(new String[permIds.size()]))) + { + techIds.add(record.id); + permIdsByTechIds.put(record.id, new SamplePermId(record.identifier)); + } + return techIds; + } + +} diff --git a/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/executor/sample/MapSampleTechIdByIdExecutor.java b/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/executor/sample/MapSampleTechIdByIdExecutor.java new file mode 100644 index 0000000000000000000000000000000000000000..fc3a69622099792365c023534e67ddeeb2619574 --- /dev/null +++ b/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/executor/sample/MapSampleTechIdByIdExecutor.java @@ -0,0 +1,48 @@ +/* + * Copyright 2015 ETH Zuerich, SIS + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package ch.ethz.sis.openbis.generic.server.api.v3.executor.sample; + +import java.util.LinkedList; +import java.util.List; + +import org.springframework.stereotype.Component; + +import ch.ethz.sis.openbis.generic.server.api.v3.executor.IOperationContext; +import ch.ethz.sis.openbis.generic.server.api.v3.executor.common.AbstractMapObjectByIdExecutor; +import ch.ethz.sis.openbis.generic.server.api.v3.helper.common.IListObjectById; +import ch.ethz.sis.openbis.generic.shared.api.v3.dto.id.sample.ISampleId; + +/** + * + * + * @author Franz-Josef Elmer + */ +@Component +public class MapSampleTechIdByIdExecutor extends AbstractMapObjectByIdExecutor<ISampleId, Long> implements IMapSampleTechIdByIdExecutor +{ + + @Override + protected List<IListObjectById<? extends ISampleId, Long>> createListers(IOperationContext context) + { + List<IListObjectById<? extends ISampleId, Long>> listers = + new LinkedList<IListObjectById<? extends ISampleId, Long>>(); + listers.add(new ListSampleTechIdByPermId()); + listers.add(new ListSampleTechIdByIdentifier()); + return listers; + } + +} diff --git a/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/executor/sample/SampleQuery.java b/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/executor/sample/SampleQuery.java new file mode 100644 index 0000000000000000000000000000000000000000..d3033ac0e634125f4f43061c728d9b5c12861e97 --- /dev/null +++ b/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/executor/sample/SampleQuery.java @@ -0,0 +1,61 @@ +/* + * Copyright 2015 ETH Zuerich, SIS + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package ch.ethz.sis.openbis.generic.server.api.v3.executor.sample; + +import java.util.List; + +import net.lemnik.eodsql.Select; +import net.lemnik.eodsql.TypeMapper; + +import ch.ethz.sis.openbis.generic.server.api.v3.executor.common.TechIdStringIdentifierRecord; +import ch.ethz.sis.openbis.generic.server.api.v3.translator.entity.common.sql.ObjectQuery; +import ch.systemsx.cisd.common.db.mapper.StringArrayMapper; + +/** + * + * + * @author Franz-Josef Elmer + */ +public interface SampleQuery extends ObjectQuery +{ + @Select(sql = "select id, perm_id as identifier from samples where perm_id = any(?{1})", parameterBindings = + { StringArrayMapper.class }, fetchSize = FETCH_SIZE) + public List<TechIdStringIdentifierRecord> listSampleTechIdsByPermIds(String[] permIds); + + @Select(sql = "select id, code as identifier from samples " + + "where space_id is null and samp_id_part_of is null and code = any(?{1})", parameterBindings = + { StringArrayMapper.class }, fetchSize = FETCH_SIZE) + public List<TechIdStringIdentifierRecord> listSharedSampleTechIdsByCodes(String[] codes); + + @Select(sql = "select s.id, s.code as identifier from samples s join samples cs on s.samp_id_part_of = cs.id " + + "where s.space_id is null and cs.code = ?{1} and s.code = any(?{2})", parameterBindings = + { TypeMapper.class, StringArrayMapper.class }, fetchSize = FETCH_SIZE) + public List<TechIdStringIdentifierRecord> listSharedSampleTechIdsByContainerCodeAndCodes(String containerCode, + String[] codes); + + @Select(sql = "select s.id, s.code as identifier from samples s join spaces sp on s.space_id = sp.id " + + "where sp.code = ?{1} and samp_id_part_of is null and s.code = any(?{2})", parameterBindings = + { TypeMapper.class, StringArrayMapper.class }, fetchSize = FETCH_SIZE) + public List<TechIdStringIdentifierRecord> listSpaceSampleTechIdsByCodes(String spaceCode, String[] codes); + + @Select(sql = "select s.id, s.code as identifier from samples s join spaces sp on s.space_id = sp.id " + + "join samples cs on s.samp_id_part_of = cs.id " + + "where sp.code = ?{1} and cs.code = ?{2} and s.code = any(?{3})", parameterBindings = + { TypeMapper.class, TypeMapper.class, StringArrayMapper.class }, fetchSize = FETCH_SIZE) + public List<TechIdStringIdentifierRecord> listSpaceSampleTechIdsByContainerCodeAndCodes(String spaceCode, + String containerCode, String[] codes); +} diff --git a/openbis/sourceTest/java/ch/ethz/sis/openbis/systemtest/api/v3/MapSampleTest.java b/openbis/sourceTest/java/ch/ethz/sis/openbis/systemtest/api/v3/MapSampleTest.java index 6b3c096073449a45bca514412c19eac6197a5002..936facf86f4111a9121213f173c32efcb0aa23ad 100644 --- a/openbis/sourceTest/java/ch/ethz/sis/openbis/systemtest/api/v3/MapSampleTest.java +++ b/openbis/sourceTest/java/ch/ethz/sis/openbis/systemtest/api/v3/MapSampleTest.java @@ -102,19 +102,25 @@ public class MapSampleTest extends AbstractSampleTest SampleIdentifier identifier1 = new SampleIdentifier("/CISD/CP-TEST-1"); SampleIdentifier identifier2 = new SampleIdentifier("/TEST-SPACE/CP-TEST-4"); SampleIdentifier identifier3 = new SampleIdentifier("/CISD/3VCP8"); + SampleIdentifier identifier4 = new SampleIdentifier("/MP"); + SampleIdentifier identifier5 = new SampleIdentifier("/MP:A03"); + SampleIdentifier identifier6 = new SampleIdentifier("/CISD/CL1:A03"); - Map<ISampleId, Sample> map = v3api.mapSamples(sessionToken, Arrays.asList(identifier1, identifier2, identifier3), new SampleFetchOptions()); + List<SampleIdentifier> identifiers = Arrays.asList(identifier1, identifier2, identifier3, identifier4, + identifier5, identifier6); + Map<ISampleId, Sample> map = v3api.mapSamples(sessionToken, identifiers, new SampleFetchOptions()); - assertEquals(3, map.size()); + assertEquals(map.size(), identifiers.size()); Iterator<Sample> iter = map.values().iterator(); - assertEquals(iter.next().getIdentifier(), identifier1); - assertEquals(iter.next().getIdentifier(), identifier2); - assertEquals(iter.next().getIdentifier(), identifier3); - - assertEquals(map.get(identifier1).getIdentifier(), identifier1); - assertEquals(map.get(identifier2).getIdentifier(), identifier2); - assertEquals(map.get(identifier3).getIdentifier(), identifier3); + for (SampleIdentifier identifier : identifiers) + { + assertEquals(iter.next().getIdentifier(), identifier); + } + for (SampleIdentifier identifier : identifiers) + { + assertEquals(map.get(identifier).getIdentifier(), identifier); + } v3api.logout(sessionToken); }