/* *------------------------------------------------------------------------------ * Copyright (C) 2013-2014 University of Dundee & Open Microscopy Environment. * All rights reserved. * * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * *------------------------------------------------------------------------------ */ package org.openmicroscopy.shoola.env.data.views.calls; import java.awt.image.BufferedImage; import java.util.ArrayList; import java.util.HashMap; import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.Map.Entry; import org.openmicroscopy.shoola.env.data.OmeroImageService; import org.openmicroscopy.shoola.env.data.OmeroDataService; import org.openmicroscopy.shoola.env.data.model.ImageCheckerResult; import org.openmicroscopy.shoola.env.data.model.ThumbnailData; import omero.gateway.SecurityContext; import org.openmicroscopy.shoola.env.data.views.BatchCall; import org.openmicroscopy.shoola.env.data.views.BatchCallTree; import org.openmicroscopy.shoola.env.rnd.RenderingControl; import org.openmicroscopy.shoola.util.image.geom.Factory; import omero.gateway.exception.DSAccessException; import omero.gateway.exception.DSOutOfServiceException; import omero.gateway.exception.RenderingServiceException; import org.openmicroscopy.shoola.env.data.model.MIFResultObject; import omero.gateway.model.DataObject; import omero.gateway.model.DatasetData; import omero.gateway.model.ImageData; /** * Checks if the images in the specified containers are split between * or not all selected. * * @author Jean-Marie Burel      * <a href="mailto:j.burel@dundee.ac.uk">j.burel@dundee.ac.uk</a> * @since 5.0 */ public class ImageSplitChecker extends BatchCallTree { /** Result of the call. */ private ImageCheckerResult result = new ImageCheckerResult(); /** Loads the specified tree. */ private BatchCall loadCall; /** The service used to load the thumbnails.*/ private OmeroImageService service; /** * Loads the thumbnails for passed collection of images. * * @param ctx The security context to use. * @param images The collection of images to handle. */ private List<ThumbnailData> loadThumbails(SecurityContext ctx, List<ImageData> images) { List<ThumbnailData> thumbnails = new ArrayList<ThumbnailData>(); try { Map<Long, ImageData> map = new HashMap<Long, ImageData>(); Iterator<ImageData> i = images.iterator(); ImageData img; while (i.hasNext()) { img = i.next(); map.put(img.getDefaultPixels().getId(), img); } Map<Long, BufferedImage> m = service.getThumbnailSet(ctx, map.keySet(), Factory.THUMB_DEFAULT_WIDTH); Iterator<Long> j = m.keySet().iterator(); long pixelsID; BufferedImage thumbPix; ImageData obj; long imageID = -1; while (j.hasNext()) { pixelsID = j.next(); obj = map.get(pixelsID); imageID = ((ImageData) obj).getId(); thumbPix = (BufferedImage) m.get(pixelsID); if (thumbPix != null) thumbnails.add(new ThumbnailData(imageID, thumbPix, true)); } } catch (RenderingServiceException e) { context.getLogger().error(this, "Cannot retrieve thumbnail: "+e.getExtendedMessage()); } return thumbnails; } /** * Creates a {@link BatchCall} to retrieve rendering control. * * @param ctx The security context. * @param rootType The top-most type which will be searched. * @param rootIDs A set of the IDs of objects. * @return The {@link BatchCall}. */ private BatchCall makeBatchCall(final Map<SecurityContext, List<DataObject>> objects) { return new BatchCall("Checking for split MIF ") { public void doCall() throws Exception { OmeroDataService svc = context.getDataService(); Entry<SecurityContext, List<DataObject>> e; Iterator<Entry<SecurityContext, List<DataObject>>> i = objects.entrySet().iterator(); Iterator<DataObject> j; List<Long> ids; DataObject uo; Map<Long, Map<Boolean, List<ImageData>>> r; MIFResultObject mif; List<ImageData> images; List<ImageData> linkCheckImages = new ArrayList<ImageData>(); while (i.hasNext()) { linkCheckImages.clear();; e = i.next(); j = e.getValue().iterator(); ids = new ArrayList<Long>(); Class<?> klass = null; while (j.hasNext()) { uo = j.next(); klass = uo.getClass(); ids.add(uo.getId()); if(uo instanceof ImageData) { ImageData img = (ImageData)uo; linkCheckImages.add(img); } } r = svc.getImagesBySplitFilesets(e.getKey(), klass, ids); if (r != null && r.size() > 0) { mif = new MIFResultObject(e.getKey(), r); //load the thumbnails for a limited number of images. images = mif.getImages(); mif.setThumbnails(loadThumbails(e.getKey(), images)); result.getMifResults().add(mif); } if(!linkCheckImages.isEmpty()) { loadDatasetLinks(e.getKey(), linkCheckImages); } } } }; } /** * Loads the datasets the given images are linked to * @param ctx The security context to use for the query * @param imgs The images */ private void loadDatasetLinks(SecurityContext ctx, List<ImageData> imgs) { try { List<Long> imgIds = new ArrayList<Long>(); for(ImageData img : imgs) { imgIds.add(img.getId()); } OmeroDataService svc = context.getDataService(); Map<Long, List<DatasetData>> queryResult = svc.findDatasetsByImageId(ctx, imgIds); for(Long imgId: queryResult.keySet()) { List<DatasetData> ds = queryResult.get(imgId); ImageData img = null; for(ImageData tmp : imgs) { if(tmp.getId()==imgId) { img = tmp; break; } } if(img!=null) { result.addDatasets(img, ds); } } } catch (DSOutOfServiceException e) { context.getLogger().error(this, "Cannot retrieve datasets: " + e.getMessage()); } catch (DSAccessException e) { context.getLogger().error(this, "Cannot retrieve datasets: " + e.getMessage()); } } /** * Adds the {@link #loadCall} to the computation tree. * * @see BatchCallTree#buildTree() */ protected void buildTree() { add(loadCall); } /** * Returns the {@link RenderingControl}. * * @see BatchCallTree#getResult() */ protected Object getResult() { return result; } /** * Creates a new instance. * If bad arguments are passed, we throw a runtime exception so to fail * early and in the caller's thread. * * @param objects The object to handle. */ public ImageSplitChecker(Map<SecurityContext, List<DataObject>> objects) { if (objects == null || objects.size() == 0) throw new IllegalArgumentException("No object to check."); service = context.getImageService(); loadCall = makeBatchCall(objects); } }