diff --git a/screening/source/java/ch/systemsx/cisd/openbis/dss/generic/server/AbstractImagesDownloadServlet.java b/screening/source/java/ch/systemsx/cisd/openbis/dss/generic/server/AbstractImagesDownloadServlet.java index 327264e035cff17fb0d9cef60a48fa612fbbb0f2..fb2200c43560598224b81a5f7e5d33dbc66ea28a 100644 --- a/screening/source/java/ch/systemsx/cisd/openbis/dss/generic/server/AbstractImagesDownloadServlet.java +++ b/screening/source/java/ch/systemsx/cisd/openbis/dss/generic/server/AbstractImagesDownloadServlet.java @@ -152,21 +152,29 @@ abstract class AbstractImagesDownloadServlet extends AbstractDatasetDownloadServ protected final void doGet(final HttpServletRequest request, final HttpServletResponse response) throws ServletException, IOException { + TileImageReference reference = null; try { - TileImageReference params = RequestParams.createTileImageReference(request); - HttpSession session = tryGetOrCreateSession(request, params.getSessionId()); + reference = RequestParams.createTileImageReference(request); + HttpSession session = tryGetOrCreateSession(request, reference.getSessionId()); if (session == null) { printSessionExpired(response); } else { - deliverFile(response, params, session); + deliverFile(response, reference, session); } } catch (Exception e) { - //e.printStackTrace(); - printErrorResponse(response, "Error: " + e.getMessage()); + String message = "Error: Couldn't deliver image"; + if (reference != null) + { + message += + " for data set " + reference.getDatasetCode() + " and channel " + + reference.getChannel(); + } + operationLog.error(message, e); + printErrorResponse(response, message); } } diff --git a/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/client/web/client/application/detailviewers/ImageUrlUtils.java b/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/client/web/client/application/detailviewers/ImageUrlUtils.java index 4e249b680ba4f4574fae2025595fecd75e4f09b0..25f6094e0848fa28cb0f1f315a4ea56a526ff722 100644 --- a/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/client/web/client/application/detailviewers/ImageUrlUtils.java +++ b/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/client/web/client/application/detailviewers/ImageUrlUtils.java @@ -104,6 +104,11 @@ public class ImageUrlUtils methodWithParameters.addParameter("wellCol", images.getWellLocation().getColumn()); methodWithParameters.addParameter("tileRow", tileRow); methodWithParameters.addParameter("tileCol", tileCol); + String signature = images.getTransformerFactorySignatureOrNull(channel); + if (signature != null) + { + methodWithParameters.addParameter("transformerFactorySignature", signature); + } String linkURL = createImageLinks ? methodWithParameters.toString() : null; methodWithParameters.addParameter("mode", "thumbnail" + width + "x" + height); diff --git a/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/client/web/client/application/detailviewers/WellImages.java b/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/client/web/client/application/detailviewers/WellImages.java index cc903c989d264bdaaad66d518d98605ee5075fc8..f8224c7cf88bc9e175a3dc618850a71d3237d862 100644 --- a/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/client/web/client/application/detailviewers/WellImages.java +++ b/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/client/web/client/application/detailviewers/WellImages.java @@ -91,4 +91,10 @@ public class WellImages { return getDataset().getDatastoreCode(); } + + public String getTransformerFactorySignatureOrNull(String channelCode) + { + return getImageParams().getTransformerFactorySignatureOrNull(channelCode); + } + } diff --git a/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/client/web/client/application/detailviewers/heatmaps/PlateLayouter.java b/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/client/web/client/application/detailviewers/heatmaps/PlateLayouter.java index cb9031ab21056e851c501bef2e860c459409e81f..49eb90f491b29bc11efa438a5b6c9a0ee3c9e385 100644 --- a/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/client/web/client/application/detailviewers/heatmaps/PlateLayouter.java +++ b/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/client/web/client/application/detailviewers/heatmaps/PlateLayouter.java @@ -36,10 +36,13 @@ import com.extjs.gxt.ui.client.widget.layout.RowLayout; import com.extjs.gxt.ui.client.widget.layout.TableLayout; import com.google.gwt.user.client.ui.Widget; +import ch.systemsx.cisd.openbis.generic.client.web.client.application.AbstractAsyncCallback; import ch.systemsx.cisd.openbis.generic.client.web.client.application.renderer.IRealNumberRenderer; import ch.systemsx.cisd.openbis.generic.client.web.client.application.renderer.RealNumberRenderer; import ch.systemsx.cisd.openbis.generic.client.web.client.application.util.GWTUtils; import ch.systemsx.cisd.openbis.generic.client.web.client.application.util.IMessageProvider; +import ch.systemsx.cisd.openbis.generic.shared.basic.TechId; +import ch.systemsx.cisd.openbis.plugin.screening.client.web.client.IScreeningClientServiceAsync; import ch.systemsx.cisd.openbis.plugin.screening.client.web.client.application.ScreeningViewContext; import ch.systemsx.cisd.openbis.plugin.screening.client.web.client.application.detailviewers.DefaultChannelState; import ch.systemsx.cisd.openbis.plugin.screening.client.web.client.application.detailviewers.PlateStyleSetter; @@ -283,15 +286,31 @@ public class PlateLayouter private static Component createWellWidget(final WellData wellData, final DefaultChannelState channelState, final PlateLayouterModel model, - final ScreeningViewContext viewContext) + final ScreeningViewContext screeningViewContext) { Component widget = createWellBox(wellData); + widget.addListener(Events.OnMouseDown, new Listener<BaseEvent>() { public void handleEvent(BaseEvent ce) { - WellContentDialog.showContentDialog(wellData, model.tryGetImageDataset(), - channelState, viewContext); + IScreeningClientServiceAsync service = screeningViewContext.getService(); + // Reload meta data because they might be out dated especially when + // image transformer factory has changed. For the image URL the + // signature of the factory is needed to distinguish them. This is important + // because Web browser cache images. + service.getPlateContentForDataset(new TechId(model.tryGetImageDataset() + .getDatasetId()), new AbstractAsyncCallback<PlateImages>( + screeningViewContext) + { + @Override + protected void process(PlateImages plateContent) + { + DatasetImagesReference ds = plateContent.getImagesDataset(); + WellContentDialog.showContentDialog(wellData, ds, channelState, + screeningViewContext); + } + }); } }); widget.sinkEvents(Events.OnMouseDown.getEventCode()); diff --git a/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/shared/basic/dto/DatasetImagesReference.java b/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/shared/basic/dto/DatasetImagesReference.java index 8651299b3e6b23b69fd411529ef758b03f1195a0..426ba14a206320d7c0d2a37495d06eb2c5270f52 100644 --- a/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/shared/basic/dto/DatasetImagesReference.java +++ b/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/shared/basic/dto/DatasetImagesReference.java @@ -60,6 +60,11 @@ public class DatasetImagesReference implements IsSerializable { return dataset.getCode(); } + + public Long getDatasetId() + { + return dataset.getId(); + } public DatasetReference getDatasetReference() { diff --git a/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/shared/basic/dto/PlateImageParameters.java b/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/shared/basic/dto/PlateImageParameters.java index 27ae3a545aff57ff282d21a54a835df68151880d..7995a4f4340a02354fdc78926564248fb2cde7ae 100644 --- a/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/shared/basic/dto/PlateImageParameters.java +++ b/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/shared/basic/dto/PlateImageParameters.java @@ -16,7 +16,9 @@ package ch.systemsx.cisd.openbis.plugin.screening.shared.basic.dto; +import java.util.HashMap; import java.util.List; +import java.util.Map; import com.google.gwt.user.client.rpc.IsSerializable; @@ -42,6 +44,8 @@ public class PlateImageParameters implements IsSerializable private List<String> channelsLabels; + private Map<String, String> channelsTransformerFactorySignatures = new HashMap<String, String>(); + // true if any well in the dataset has a time series (or depth stack) of images private boolean isMultidimensional; @@ -130,4 +134,14 @@ public class PlateImageParameters implements IsSerializable return channelsLabels; } + public void addTransformerFactorySignatureFor(String channelCode, String signatureOrNull) + { + channelsTransformerFactorySignatures.put(channelCode, signatureOrNull); + } + + public String getTransformerFactorySignatureOrNull(String channelCode) + { + return channelsTransformerFactorySignatures.get(channelCode); + } + } diff --git a/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/shared/imaging/HCSDatasetLoader.java b/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/shared/imaging/HCSDatasetLoader.java index 9f2b1d0e38a877f85e987c1718d3a0d49a150dc1..893f5c48c74563fc79b89f555ca95c04e8177514 100644 --- a/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/shared/imaging/HCSDatasetLoader.java +++ b/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/shared/imaging/HCSDatasetLoader.java @@ -21,7 +21,9 @@ import java.util.List; import org.apache.commons.lang.StringEscapeUtils; +import ch.systemsx.cisd.common.utilities.MD5ChecksumCalculator; import ch.systemsx.cisd.openbis.plugin.screening.shared.basic.dto.PlateImageParameters; +import ch.systemsx.cisd.openbis.plugin.screening.shared.basic.dto.ScreeningConstants; import ch.systemsx.cisd.openbis.plugin.screening.shared.basic.dto.WellImageChannelStack; import ch.systemsx.cisd.openbis.plugin.screening.shared.basic.dto.WellLocation; import ch.systemsx.cisd.openbis.plugin.screening.shared.imaging.dataaccess.IImagingReadonlyQueryDAO; @@ -29,6 +31,7 @@ import ch.systemsx.cisd.openbis.plugin.screening.shared.imaging.dataaccess.ImgCh import ch.systemsx.cisd.openbis.plugin.screening.shared.imaging.dataaccess.ImgChannelStackDTO; import ch.systemsx.cisd.openbis.plugin.screening.shared.imaging.dataaccess.ImgContainerDTO; import ch.systemsx.cisd.openbis.plugin.screening.shared.imaging.dataaccess.ImgDatasetDTO; +import ch.systemsx.cisd.openbis.plugin.screening.shared.imaging.dataaccess.ImgExperimentDTO; /** * Helper class for easy handling of HCS image dataset standard structure with no code for handling @@ -43,12 +46,14 @@ public class HCSDatasetLoader implements IHCSDatasetLoader protected final ImgDatasetDTO dataset; + private final String mergedChannelTransformerFactorySignature; + protected ImgContainerDTO container; protected Integer channelCount; protected List<ImgChannelDTO> channels; - + public HCSDatasetLoader(IImagingReadonlyQueryDAO query, String datasetPermId) { this.query = query; @@ -57,9 +62,11 @@ public class HCSDatasetLoader implements IHCSDatasetLoader { throw new IllegalStateException(String.format("Dataset '%s' not found", datasetPermId)); } + long experimentId = getContainer().getExperimentId(); + ImgExperimentDTO experiment = query.tryGetExperimentById(experimentId); + mergedChannelTransformerFactorySignature = getSignature(experiment.getSerializedImageTransformerFactory()); this.channels = - query.getChannelsByDatasetIdOrExperimentId(getDataset().getId(), getContainer() - .getExperimentId()); + query.getChannelsByDatasetIdOrExperimentId(getDataset().getId(), experimentId); } protected final ImgContainerDTO getContainer() @@ -115,16 +122,30 @@ public class HCSDatasetLoader implements IHCSDatasetLoader params.setTileRowsNum(getDataset().getFieldNumberOfRows()); params.setTileColsNum(getDataset().getFieldNumberOfColumns()); params.setIsMultidimensional(dataset.getIsMultidimensional()); + params.addTransformerFactorySignatureFor(ScreeningConstants.MERGED_CHANNELS, + mergedChannelTransformerFactorySignature); List<String> channelsCodes = new ArrayList<String>(); List<String> channelsLabels = new ArrayList<String>(); for (ImgChannelDTO channel : channels) { // TODO 2010-11-19, IA: is this escaping needed? - channelsCodes.add(StringEscapeUtils.escapeCsv(channel.getCode())); + String channelCode = StringEscapeUtils.escapeCsv(channel.getCode()); + channelsCodes.add(channelCode); channelsLabels.add(StringEscapeUtils.escapeCsv(channel.getLabel())); + params.addTransformerFactorySignatureFor(channelCode, getSignature(channel + .getSerializedImageTransformerFactory())); } params.setChannelsCodes(channelsCodes); params.setChannelsLabels(channelsLabels); return params; } + + private String getSignature(byte[] bytesOrNull) + { + if (bytesOrNull == null) + { + return null; + } + return MD5ChecksumCalculator.calculate(bytesOrNull).substring(0, 10); + } } \ No newline at end of file