/*
*------------------------------------------------------------------------------
* Copyright (C) 2015 University of Dundee. 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 ij.IJ;
import ij.ImagePlus;
import java.io.File;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Iterator;
import java.util.List;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.io.FilenameUtils;
import org.openmicroscopy.shoola.env.data.OmeroImageService;
import org.openmicroscopy.shoola.env.data.OmeroMetadataService;
import org.openmicroscopy.shoola.env.data.model.FileObject;
import org.openmicroscopy.shoola.env.data.model.ResultsObject;
import omero.gateway.SecurityContext;
import org.openmicroscopy.shoola.env.data.views.BatchCall;
import org.openmicroscopy.shoola.env.data.views.BatchCallTree;
import org.openmicroscopy.shoola.util.CommonsLangUtils;
import org.openmicroscopy.shoola.util.roi.io.ROIReader;
import com.google.common.io.Files;
import omero.gateway.model.ExperimenterData;
import omero.gateway.model.FileAnnotationData;
import omero.gateway.model.ImageData;
import omero.gateway.model.ROIData;
/**
* Saving the ImageJ results back to OMERO.
* @author Jean-Marie Burel
* <a href="mailto:j.burel@dundee.ac.uk">j.burel@dundee.ac.uk</a>
* @since 5.1
*/
public class ResultsSaver
extends BatchCallTree
{
/** The security context.*/
private SecurityContext ctx;
/** The results to save.*/
private ResultsObject results;
/** Reference to the Image Service.*/
private OmeroImageService svc;
/** Reference to the Metadata Service.*/
private OmeroMetadataService msvc;
/** The partial result.*/
private Object result;
/**
* Create a temporary file
*
* @param img The image object to handle.
* @param fileName The name to use if any.
* @return See above.
*/
private File createFile(ImagePlus img, String fileName)
{
File dir = Files.createTempDir();
String name;
if (CommonsLangUtils.isBlank(fileName)) {
name = "ImageJ-"+FilenameUtils.getBaseName(
FilenameUtils.removeExtension(img.getTitle()))+"-Results-";
name += new SimpleDateFormat("yyyy-MM-dd").format(new Date());
} else {
name = FilenameUtils.removeExtension(fileName);
}
name += ".csv";
try {
File f = new File(dir, name);
//read data
ROIReader reader = new ROIReader();
if (!reader.readResults(f)) {
f.delete();
dir.delete();
return null;
}
dir.deleteOnExit();
return f;
} catch (Exception e) {
context.getLogger().error(this,
"Cannot create file to save results"+e.getMessage());
}
return null;
}
/** Create call to save the results.*/
private void saveROIandTableResults()
{
List<Object> objects = results.getRefObjects();
Iterator<Object> i = objects.iterator();
Object o;
FileObject file;
long id;
ROIReader reader = new ROIReader();
List<ROIData> rois;
ExperimenterData exp = ctx.getExperimenterData();
final long expID = exp.getId();
while (i.hasNext()) {
o = i.next();
if (o instanceof FileObject) {
file = (FileObject) o;
id = file.getOMEROID();
if (id >= 0) {
if (file.getGroupID() > 0) {
ctx = new SecurityContext(file.getGroupID());
}
ImagePlus img = (ImagePlus) file.getFile();
rois = reader.readImageJROIFromSources(id, img);
//create a tmp file.
File f = createFile(img, results.getTableName());
final String description = "Save ROIs Results";
final long imageID = id;
final File fi = f;
final List<ROIData> list = rois;
add(new BatchCall(description) {
public void doCall() {
try {
//first save the roi
if (CollectionUtils.isNotEmpty(list)) {
svc.saveROI(ctx, imageID, expID, list);
}
if (fi != null) {
FileAnnotationData fa =
new FileAnnotationData(fi);
//TODO: create ns.
result = msvc.annotate(ctx, ImageData.class,
imageID, fa);
}
} catch (Exception e) {
IJ.log("error:"+e.toString());
context.getLogger().error(this,
"Cannot Save the ROIs results: "
+e.getMessage());
} finally {
if (fi != null) fi.delete();
}
}
});
}
}
}
}
/** Create call to save the results.*/
private void saveTableResults()
{
List<Object> objects = results.getRefObjects();
Iterator<Object> i = objects.iterator();
Object o;
FileObject file;
long id;
while (i.hasNext()) {
o = i.next();
if (o instanceof FileObject) {
file = (FileObject) o;
id = file.getOMEROID();
if (id >= 0) {
if (file.getGroupID() > 0) {
ctx = new SecurityContext(file.getGroupID());
}
ImagePlus img = (ImagePlus) file.getFile();
//create a tmp file.
File f = createFile(img, results.getTableName());
if (f != null) {
final String description = "Save Table Results";
final long imageID = id;
final File fi = f;
add(new BatchCall(description) {
public void doCall() {
try {
FileAnnotationData fa =
new FileAnnotationData(fi);
//TODO: create ns.
result = msvc.annotate(ctx, ImageData.class,
imageID, fa);
} catch (Exception e) {
context.getLogger().error(this,
"Cannot Save the ROIs results: "
+e.getMessage());
} finally {
fi.delete();
}
}
});
}
}
}
}
}
/** Create call to save the rois.*/
private void saveROI()
{
List<Object> objects = results.getRefObjects();
Iterator<Object> i = objects.iterator();
Object o;
FileObject file;
long id;
ROIReader reader = new ROIReader();
List<ROIData> rois;
ExperimenterData exp = ctx.getExperimenterData();
final long expID = exp.getId();
while (i.hasNext()) {
o = i.next();
if (o instanceof FileObject) {
file = (FileObject) o;
id = file.getOMEROID();
if (id >= 0) {
if (file.getGroupID() > 0) {
ctx = new SecurityContext(file.getGroupID());
}
ImagePlus img = (ImagePlus) file.getFile();
rois = reader.readImageJROIFromSources(id, img);
if (CollectionUtils.isNotEmpty(rois)) {
final String description = "Save ROIs";
final long imageID = id;
final List<ROIData> list = rois;
add(new BatchCall(description) {
public void doCall() {
try {
result = svc.saveROI(ctx, imageID, expID,
list);
} catch (Exception e) {
context.getLogger().error(this,
"Cannot Save ImageJ rois: "
+e.getMessage());
}
}
});
}
}
}
}
}
/**
* Creates a new instance.
*
* @param ctx The security context.
* @param results The results to save.
*/
public ResultsSaver(SecurityContext ctx, ResultsObject results)
{
this.ctx = ctx;
if (results == null) {
throw new IllegalArgumentException("No results to save.");
}
this.results = results;
svc = context.getImageService();
msvc = context.getMetadataService();
}
/** Builds the tree to save the results.*/
protected void buildTree()
{
List<Object> objects = results.getRefObjects();
if (CollectionUtils.isNotEmpty(objects)) {
if (results.isROI()) {
if (results.isTable()) {
saveROIandTableResults();
} else {
saveROI();
}
} else {
if (results.isTable()) {
saveTableResults();
}
}
}
}
/**
* Returns the result.
* This will be packed by the framework into a feedback event and
* sent to the provided call observer, if any.
*
* @return A non-null object.
*/
protected Object getPartialResult() { return result; }
/**
* Returns <code>null</code> as there's no final result.
* @see BatchCallTree#getResult()
*/
protected Object getResult() { return null; }
}