diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/CommonServer.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/CommonServer.java index cac7bb848dff08faec3354d02c386fe0d07b97fa..3dcf65ef7eceefb90f907cf00c2d67c0e163ae40 100644 --- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/CommonServer.java +++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/CommonServer.java @@ -51,7 +51,6 @@ import ch.systemsx.cisd.openbis.generic.server.business.bo.IExternalDataTable; import ch.systemsx.cisd.openbis.generic.server.business.bo.IGridCustomFilterOrColumnBO; import ch.systemsx.cisd.openbis.generic.server.business.bo.IGroupBO; import ch.systemsx.cisd.openbis.generic.server.business.bo.IMaterialBO; -import ch.systemsx.cisd.openbis.generic.server.business.bo.IMaterialTable; import ch.systemsx.cisd.openbis.generic.server.business.bo.IProjectBO; import ch.systemsx.cisd.openbis.generic.server.business.bo.IPropertyTypeBO; import ch.systemsx.cisd.openbis.generic.server.business.bo.IPropertyTypeTable; @@ -60,6 +59,7 @@ import ch.systemsx.cisd.openbis.generic.server.business.bo.ISampleBO; import ch.systemsx.cisd.openbis.generic.server.business.bo.IVocabularyBO; import ch.systemsx.cisd.openbis.generic.server.business.bo.IVocabularyTermBO; import ch.systemsx.cisd.openbis.generic.server.business.bo.datasetlister.IDatasetLister; +import ch.systemsx.cisd.openbis.generic.server.business.bo.materiallister.IMaterialLister; import ch.systemsx.cisd.openbis.generic.server.business.bo.samplelister.ISampleLister; import ch.systemsx.cisd.openbis.generic.server.dataaccess.IDAOFactory; import ch.systemsx.cisd.openbis.generic.server.dataaccess.IEntityTypeDAO; @@ -141,7 +141,6 @@ import ch.systemsx.cisd.openbis.generic.shared.dto.FileFormatTypePE; import ch.systemsx.cisd.openbis.generic.shared.dto.GridCustomFilterPE; import ch.systemsx.cisd.openbis.generic.shared.dto.GroupPE; import ch.systemsx.cisd.openbis.generic.shared.dto.IEntityInformationHolderDTO; -import ch.systemsx.cisd.openbis.generic.shared.dto.MaterialPE; import ch.systemsx.cisd.openbis.generic.shared.dto.MaterialTypePE; import ch.systemsx.cisd.openbis.generic.shared.dto.MaterialTypePropertyTypePE; import ch.systemsx.cisd.openbis.generic.shared.dto.NewRoleAssignment; @@ -167,7 +166,6 @@ import ch.systemsx.cisd.openbis.generic.shared.translator.DtoConverters; import ch.systemsx.cisd.openbis.generic.shared.translator.ExperimentTranslator; import ch.systemsx.cisd.openbis.generic.shared.translator.ExternalDataTranslator; import ch.systemsx.cisd.openbis.generic.shared.translator.GroupTranslator; -import ch.systemsx.cisd.openbis.generic.shared.translator.MaterialTranslator; import ch.systemsx.cisd.openbis.generic.shared.translator.MaterialTypeTranslator; import ch.systemsx.cisd.openbis.generic.shared.translator.PersonTranslator; import ch.systemsx.cisd.openbis.generic.shared.translator.ProjectTranslator; @@ -852,11 +850,8 @@ public final class CommonServer extends AbstractCommonServer<ICommonServer> impl public List<Material> listMaterials(String sessionToken, MaterialType materialType) { final Session session = getSession(sessionToken); - final IMaterialTable materialTable = businessObjectFactory.createMaterialTable(session); - materialTable.load(materialType.getCode()); - final List<MaterialPE> materials = materialTable.getMaterials(); - Collections.sort(materials); - return MaterialTranslator.translate(materials); + final IMaterialLister materialLister = businessObjectFactory.createMaterialLister(session); + return materialLister.list(materialType); } public void registerSampleType(String sessionToken, SampleType entityType) diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/business/bo/IMaterialTable.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/business/bo/IMaterialTable.java index 437489966c92f341eb463e8b687780ffb5220204..52753e19928f89ea44b1c172ccf6867e94be2f32 100644 --- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/business/bo/IMaterialTable.java +++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/business/bo/IMaterialTable.java @@ -34,6 +34,7 @@ public interface IMaterialTable * * @param materialTypeCodeOrNull the material type code or <code>null</code>. */ + @Deprecated public void load(String materialTypeCodeOrNull); /** Returns the loaded {@link MaterialPE}. */ diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/business/bo/datasetlister/IDatasetLister.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/business/bo/datasetlister/IDatasetLister.java index 0418e32ed690243f66256e9d6e93dfd6bab2c0f6..243a56659a64ac84ef9b43814fe20dbf465c63f1 100644 --- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/business/bo/datasetlister/IDatasetLister.java +++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/business/bo/datasetlister/IDatasetLister.java @@ -33,8 +33,6 @@ public interface IDatasetLister /** @return datasets connected to the experiment with the specified id */ List<ExternalData> listByExperimentTechId(TechId experimentId); - // TODO 2009-09-10, Piotr Buczek: write tests - /** * @return datasets connected to the sample with the specified id * @param showOnlyDirectlyConnected whether to return only directly connected datasets, or also diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/business/bo/materiallister/IMaterialLister.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/business/bo/materiallister/IMaterialLister.java index 0ec60bdefc3c3680cf303193d7daf12134ad4dca..3fda0e9baedbc9d25201d250729f80fa0375af2e 100644 --- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/business/bo/materiallister/IMaterialLister.java +++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/business/bo/materiallister/IMaterialLister.java @@ -19,6 +19,7 @@ package ch.systemsx.cisd.openbis.generic.server.business.bo.materiallister; import java.util.List; import ch.systemsx.cisd.openbis.generic.shared.basic.dto.Material; +import ch.systemsx.cisd.openbis.generic.shared.basic.dto.MaterialType; /** * A class for fast material listing. @@ -29,4 +30,9 @@ public interface IMaterialLister { /** fetches and sets all properties of specified materials */ void enrichWithProperties(List<Material> materials); + + /** + * Returns a sorted list of {@link Material}s of given {@link MaterialType}. + */ + public List<Material> list(MaterialType materialType); } diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/business/bo/materiallister/IMaterialListingQuery.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/business/bo/materiallister/IMaterialListingQuery.java index c07f003cc3a96508b98f894d87f2096178a564b0..759d98ca45abe2519a9afc3e9dc3a9cf91192beb 100644 --- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/business/bo/materiallister/IMaterialListingQuery.java +++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/business/bo/materiallister/IMaterialListingQuery.java @@ -42,6 +42,16 @@ public interface IMaterialListingQuery extends TransactionQuery, IPropertyListin { public static final int FETCH_SIZE = 1000; + /** + * Returns the materials for the given <var>materialTypeId</var> + */ + @Select(sql = "select m.id, m.code, m.dbin_id, m.maty_id, " + + " m.registration_timestamp, m.pers_id_registerer " + + " from materials m where m.dbin_id=?{1} and m.maty_id=?{2} " + + " order by m.code", fetchSize = FETCH_SIZE) + public DataIterator<MaterialRecord> getMaterialsForMaterialType(long dbInstanceId, + long materialTypeId); + // // Entity Properties // diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/business/bo/materiallister/MaterialLister.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/business/bo/materiallister/MaterialLister.java index b652b1130b90b263b5176a0aaa4eaa4c580196fb..09af3162c3cdbc9d3f3096fff294a07c7a1ae3fa 100644 --- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/business/bo/materiallister/MaterialLister.java +++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/business/bo/materiallister/MaterialLister.java @@ -16,6 +16,7 @@ package ch.systemsx.cisd.openbis.generic.server.business.bo.materiallister; +import static org.apache.commons.lang.StringEscapeUtils.escapeHtml; import it.unimi.dsi.fastutil.longs.Long2ObjectMap; import it.unimi.dsi.fastutil.longs.Long2ObjectOpenHashMap; @@ -28,20 +29,49 @@ import ch.systemsx.cisd.openbis.generic.server.business.bo.common.IEntityPropert import ch.systemsx.cisd.openbis.generic.server.business.bo.common.IEntityPropertiesHolderResolver; import ch.systemsx.cisd.openbis.generic.server.business.bo.common.entity.SecondaryEntityDAO; import ch.systemsx.cisd.openbis.generic.server.dataaccess.IDAOFactory; +import ch.systemsx.cisd.openbis.generic.shared.basic.dto.DatabaseInstance; import ch.systemsx.cisd.openbis.generic.shared.basic.dto.IEntityProperty; import ch.systemsx.cisd.openbis.generic.shared.basic.dto.Material; +import ch.systemsx.cisd.openbis.generic.shared.basic.dto.MaterialType; +import ch.systemsx.cisd.openbis.generic.shared.basic.dto.Person; /** - * Fast bd operations on material table. + * Fast DB operations on material table. * * @author Tomasz Pylak + * @author Piotr Buczek */ @Friend(toClasses = { IMaterialListingQuery.class }) public class MaterialLister implements IMaterialLister { + + // + // Input + // + + private final long databaseInstanceId; + + private final DatabaseInstance databaseInstance; + + // + // Working interfaces + // + + private final IMaterialListingQuery query; + private final IEntityPropertiesEnricher propertiesEnricher; + private SecondaryEntityDAO referencedEntityDAO; + + // + // Working data structures + // + + private final Long2ObjectMap<Person> persons = new Long2ObjectOpenHashMap<Person>(); + + // + public static IMaterialLister create(IDAOFactory daoFactory, String baseIndexURL) { MaterialListerDAO dao = MaterialListerDAO.create(daoFactory); @@ -56,13 +86,107 @@ public class MaterialLister implements IMaterialLister IMaterialListingQuery query = dao.getQuery(); EntityPropertiesEnricher propertiesEnricher = new EntityPropertiesEnricher(query, dao.getPropertySetQuery()); - return new MaterialLister(propertiesEnricher); + return new MaterialLister(dao.getDatabaseInstanceId(), dao.getDatabaseInstance(), query, + propertiesEnricher, referencedEntityDAO); } // For unit tests - MaterialLister(IEntityPropertiesEnricher propertiesEnricher) + MaterialLister(final long databaseInstanceId, DatabaseInstance databaseInstance, + final IMaterialListingQuery query, IEntityPropertiesEnricher propertiesEnricher, + SecondaryEntityDAO referencedEntityDAO) { + assert query != null; + + this.databaseInstanceId = databaseInstanceId; + this.databaseInstance = databaseInstance; + this.query = query; this.propertiesEnricher = propertiesEnricher; + this.referencedEntityDAO = referencedEntityDAO; + } + + // + // Listing + // + + public List<Material> list(MaterialType materialType) + { + return enrichMaterials(query.getMaterialsForMaterialType(databaseInstanceId, materialType + .getId()), materialType); + } + + // + // Enriching + // + + private List<Material> enrichMaterials(Iterable<MaterialRecord> materials, + MaterialType materialType) + { + List<MaterialRecord> materialRecords = asList(materials); + final Long2ObjectMap<Material> materialMap = createMaterials(materialRecords, materialType); + enrichWithProperties(materialMap); + return asList(materialMap); + } + + private Long2ObjectMap<Material> createMaterials(Iterable<MaterialRecord> records, + MaterialType materialType) + { + Long2ObjectMap<Material> materials = new Long2ObjectOpenHashMap<Material>(); + for (MaterialRecord record : records) + { + materials.put(record.id, createMaterial(record, materialType)); + } + return materials; + } + + private Material createMaterial(MaterialRecord record, MaterialType materialType) + { + Material material = new Material(); + material.setId(record.id); + material.setCode(escapeHtml(record.code)); + + assert record.maty_id == materialType.getId(); + material.setMaterialType(materialType); + assert record.dbin_id == databaseInstanceId; + material.setDatabaseInstance(databaseInstance); + + material.setRegistrator(getOrCreateRegistrator(record)); + material.setRegistrationDate(record.registration_timestamp); + material.setProperties(new ArrayList<IEntityProperty>()); + + return material; + } + + private Person getOrCreateRegistrator(MaterialRecord row) + { + return getOrCreateRegistrator(row.pers_id_registerer); + } + + private Person getOrCreateRegistrator(long personId) + { + Person registrator = persons.get(personId); + if (registrator == null) + { + registrator = referencedEntityDAO.getPerson(personId); + persons.put(personId, registrator); + } + return registrator; + } + + private static <T> List<T> asList(Iterable<T> items) + { + List<T> result = new ArrayList<T>(); + for (T item : items) + { + result.add(item); + } + return result; + } + + private static <T> List<T> asList(Long2ObjectMap<T> items) + { + List<T> result = new ArrayList<T>(); + org.apache.commons.collections.CollectionUtils.addAll(result, items.values().iterator()); + return result; } private void enrichWithProperties(final Long2ObjectMap<Material> resultMap) @@ -99,4 +223,5 @@ public class MaterialLister implements IMaterialLister material.setProperties(new ArrayList<IEntityProperty>()); } } + } diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/business/bo/materiallister/MaterialRecord.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/business/bo/materiallister/MaterialRecord.java new file mode 100644 index 0000000000000000000000000000000000000000..150838de9b591de4bbf0221fc2563aed5cc541c7 --- /dev/null +++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/business/bo/materiallister/MaterialRecord.java @@ -0,0 +1,28 @@ +package ch.systemsx.cisd.openbis.generic.server.business.bo.materiallister; + +import java.util.Date; + +import ch.rinn.restrictions.Private; +import ch.systemsx.cisd.openbis.generic.server.business.bo.common.CodeRecord; + +/** + * A record object representing one row of the material table. + */ +// CREATE TABLE materials ( +// id tech_id NOT NULL, +// code code NOT NULL, +// maty_id tech_id NOT NULL, +// pers_id_registerer tech_id NOT NULL, +// registration_timestamp time_stamp_dfl NOT NULL DEFAULT now(), +// dbin_id tech_id NOT NULL); +@Private +public class MaterialRecord extends CodeRecord +{ + public Long dbin_id; + + public long maty_id; + + public long pers_id_registerer; + + public Date registration_timestamp; +} diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/dataaccess/IMaterialDAO.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/dataaccess/IMaterialDAO.java index 79c33db9d2d1f2b5ebf18b7a0f420f4d3d6593aa..969a472c0f3d65501763531361986179f42d801c 100644 --- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/dataaccess/IMaterialDAO.java +++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/dataaccess/IMaterialDAO.java @@ -33,6 +33,7 @@ public interface IMaterialDAO extends IGenericDAO<MaterialPE> /** * Lists materials of given type. Fetches also properties and inhibitor. */ + @Deprecated public List<MaterialPE> listMaterialsWithPropertiesAndInhibitor(MaterialTypePE type); /** Inserts given {@link MaterialPE}s into the database. */ diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/basic/dto/MaterialType.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/basic/dto/MaterialType.java index 67bf774740e0f04fe87a098cae63e6a24dee28fa..8b35fafe8d05242d1fae9f5e0c38f53c7d693a0b 100644 --- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/basic/dto/MaterialType.java +++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/basic/dto/MaterialType.java @@ -27,8 +27,20 @@ public class MaterialType extends EntityType { private static final long serialVersionUID = ServiceVersionHolder.VERSION; + private Long id; + private List<MaterialTypePropertyType> materialTypePropertyTypes; + public Long getId() + { + return id; + } + + public void setId(Long id) + { + this.id = id; + } + @Override public List<MaterialTypePropertyType> getAssignedPropertyTypes() { diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/translator/MaterialTypeTranslator.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/translator/MaterialTypeTranslator.java index 239a59c0b4f63a565aaf8c0fe971409592afa1ae..aa28e3b7f77df291b8e64c1366a9a2ccdcbd010f 100644 --- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/translator/MaterialTypeTranslator.java +++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/translator/MaterialTypeTranslator.java @@ -57,6 +57,7 @@ public class MaterialTypeTranslator return null; } final MaterialType result = new MaterialType(); + result.setId(HibernateUtils.getId(entityTypeOrNull)); result.setCode(StringEscapeUtils.escapeHtml(entityTypeOrNull.getCode())); result.setDescription(StringEscapeUtils.escapeHtml(entityTypeOrNull.getDescription())); result.setDatabaseInstance(DatabaseInstanceTranslator.translate(entityTypeOrNull diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/plugin/generic/server/GenericServer.java b/openbis/source/java/ch/systemsx/cisd/openbis/plugin/generic/server/GenericServer.java index 74154eaadc436e14d5cfef4c5e9be92c6135aaac..e9f44ecc77b6ad3c6c78085374c2c7423ad59e23 100644 --- a/openbis/source/java/ch/systemsx/cisd/openbis/plugin/generic/server/GenericServer.java +++ b/openbis/source/java/ch/systemsx/cisd/openbis/plugin/generic/server/GenericServer.java @@ -348,7 +348,6 @@ public final class GenericServer extends AbstractServer<IGenericServer> implemen new SampleIdentifier(new GroupIdentifier(experimentIdentifierOrNull .getDatabaseInstanceCode(), experimentIdentifierOrNull .getGroupCode()), oldSampleIdentifier.getSampleCode()); - // TODO 2009-12-08, Piotr Buczek: does it work well with subcodes? } else { // no experiment - leave sample identifier unchanged