/*
* Copyright 2006-2015 University of Dundee. All rights reserved.
* Use is subject to license terms supplied in LICENSE.txt
*/
package integration;
import static org.testng.AssertJUnit.assertEquals;
import static org.testng.AssertJUnit.assertNotNull;
import static org.testng.AssertJUnit.assertTrue;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.transform.OutputKeys;
import javax.xml.transform.Source;
import javax.xml.transform.Templates;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerException;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.URIResolver;
import javax.xml.transform.stream.StreamResult;
import javax.xml.transform.stream.StreamSource;
import loci.common.Constants;
import loci.common.RandomAccessInputStream;
import loci.common.RandomAccessOutputStream;
import loci.formats.tiff.TiffParser;
import loci.formats.tiff.TiffSaver;
import ome.services.blitz.util.CurrentPlatform;
import ome.specification.OmeValidator;
import ome.specification.XMLMockObjects;
import ome.specification.XMLWriter;
import omero.api.ExporterPrx;
import omero.api.RawFileStorePrx;
import omero.model.FileAnnotation;
import omero.model.FileAnnotationI;
import omero.model.IObject;
import omero.model.Image;
import omero.model.ImageAnnotationLinkI;
import omero.model.ImageI;
import omero.model.OriginalFile;
import omero.model.Pixels;
import omero.model.PixelsI;
import omero.model.PixelsOriginalFileMapI;
import omero.model.Shape;
import omero.sys.Parameters;
import omero.sys.ParametersI;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.io.FileUtils;
import org.apache.commons.lang.RandomStringUtils;
import org.apache.commons.lang.StringUtils;
import org.testng.annotations.AfterClass;
import org.testng.annotations.BeforeClass;
import org.testng.annotations.DataProvider;
import org.testng.annotations.Test;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NamedNodeMap;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
/**
* Collections of tests for the <code>Exporter</code> service.
*
* @author Jean-Marie Burel <a
* href="mailto:j.burel@dundee.ac.uk">j.burel@dundee.ac.uk</a>
* @author Donald MacDonald <a
* href="mailto:donald@lifesci.dundee.ac.uk"
* >donald@lifesci.dundee.ac.uk</a>
* @since 3.0-Beta4
*/
public class ExporterTest extends AbstractServerTest {
/** The ome-tiff extension. */
private static final String OME_TIFF = "ome.tiff";
/** Possible file extension. */
public static final String OME_XML = "ome.xml";
/** Maximum size of pixels read at once. */
private static final int INC = 262144;
/** The catalog file to find. */
private static final String CATALOG = "ome-transforms.xml";
/** The conversion file to find.*/
private static final String UNITS_CONVERSION = "units-conversion.xsl";
/** The <i>name</i> attribute. */
private static final String CURRENT = "current";
/** The <i>schema</i> attribute. */
private static final String SCHEMA = "schema";
/** The <i>target</i> name. */
private static final String TARGET = "target";
/** The <i>transform</i> name. */
private static final String TRANSFORM = "transform";
/** The <i>source</i> node. */
private static final String SOURCE = "source";
/** The <i>file</i> attribute. */
private static final String FILE = "file";
/** Flag indicating to create an image using XML mock and import it.*/
private static final int IMAGE = 0;
/** Flag indicating to create a simple image.*/
private static final int SIMPLE_IMAGE = 1;
/**
* Flag indicating to create an image with ROI using XML mock and
* import it.
*/
private static final int IMAGE_ROI = 2;
/**
* Flag indicating to create an image with annotated acquisition data
* using XML mock and import it.
*/
private static final int IMAGE_ANNOTATED_DATA = 2;
/** The various transforms read from the configuration file.*/
private Map<String, List<String>> downgrades;
/** The collection of transforms to perform upgrade.*/
private Map<String, List<String>> upgrades;
/** The current schema.*/
private String currentSchema;
/** Flag indicating if the platform is Windows or not.*/
private boolean windowsOS;
/**
* Validates the specified input.
*
* @param input
* The input to validate
* @throws Exception
* Thrown if an error occurred during the validation
*/
private void validate(File input) throws Exception {
OmeValidator validator = new OmeValidator();
validator.parseFile(input);
}
/**
* Applies the transforms to the specified XML file.
*
* @param inputXML
* The file to transforms.
* @param transforms
* The collection of transforms.
* @return See above.
* @throws Exception
* Thrown if an error occurred during the transformations.
*/
private File applyTransforms(File inputXML, List<InputStream> transforms)
throws Exception {
TransformerFactory factory;
Transformer transformer;
InputStream stream;
Iterator<InputStream> i = transforms.iterator();
File output;
InputStream in = null;
OutputStream out = null;
Resolver resolver = null;
while (i.hasNext()) {
stream = i.next();
try {
factory = TransformerFactory.newInstance();
resolver = new Resolver();
factory.setURIResolver(resolver);
output = File.createTempFile(
RandomStringUtils.random(100, false, true),
"."+ OME_XML);
output.deleteOnExit();
Source src = new StreamSource(stream);
Templates template = factory.newTemplates(src);
transformer = template.newTransformer();
transformer.setParameter(OutputKeys.ENCODING, Constants.ENCODING);
out = new FileOutputStream(output);
in = new FileInputStream(inputXML);
transformer.transform(new StreamSource(in),
new StreamResult(out));
inputXML = output;
} catch (Exception e) {
throw new Exception("Cannot apply transform", e);
} finally {
if (stream != null) stream.close();
if (out != null) out.close();
if (in != null) in.close();
if (resolver != null) resolver.close();
}
}
File f = File.createTempFile(
RandomStringUtils.random(100, false, true), "."+ OME_XML);
FileUtils.copyFile(inputXML, f);
return f;
}
/**
* Creates an image to export.
*
* @return See above.
* @throws Exception
* Thrown if an error occurred.
*/
private Image createSimpleImageToExport() throws Exception {
Image image = mmFactory.createImage();
image = (Image) iUpdate.saveAndReturnObject(image);
Pixels pixels = image.getPrimaryPixels();
OriginalFile f = mmFactory.createOriginalFile();
f = (OriginalFile) iUpdate.saveAndReturnObject(f);
RawFileStorePrx svc = factory.createRawFileStore();
svc.setFileId(f.getId().getValue());
byte[] data = new byte[] { 1 };
svc.write(data, 0, data.length);
svc.close();
ParametersI param = new ParametersI();
param.addId(f.getId().getValue());
f = (OriginalFile) iQuery.findByQuery(
"select i from OriginalFile i where i.id = :id", param);
// upload file, method tested in RawFileStore
PixelsOriginalFileMapI m = new PixelsOriginalFileMapI();
m.setChild(new PixelsI(pixels.getId().getValue(), false));
m.setParent(f);
m = (PixelsOriginalFileMapI) iUpdate.saveAndReturnObject(m);
return image;
}
/**
* Creates an image to export.
*
* @return See above.
* @throws Exception
* Thrown if an error occurred.
*/
private Image createImageWithROIToExport() throws Exception {
//create an import and image
File f = File.createTempFile(RandomStringUtils.random(100, false, true),
"."+ OME_XML);
XMLMockObjects xml = new XMLMockObjects();
XMLWriter writer = new XMLWriter();
writer.writeFile(f, xml.createImageWithROI(), true);
List<Pixels> pix = null;
try {
// method tested in ImporterTest
pix = importFile(f, OME_XML, true);
return pix.get(0).getImage();
} catch (Throwable e) {
throw new Exception("Cannot create image to import", e);
} finally {
if (f != null) f.delete();
}
}
/**
* Creates an image to export.
*
* @return See above.
* @throws Exception
* Thrown if an error occurred.
*/
private Image createImageWithAnnotatedDataToExport() throws Exception {
//create an import and image
File f = File.createTempFile(RandomStringUtils.random(100, false, true),
"."+ OME_XML);
XMLMockObjects xml = new XMLMockObjects();
XMLWriter writer = new XMLWriter();
writer.writeFile(f, xml.createImageWithAnnotatedAcquisitionData(), true);
List<Pixels> pix = null;
try {
// method tested in ImporterTest
pix = importFile(f, OME_XML, true);
return pix.get(0).getImage();
} catch (Throwable e) {
throw new Exception("Cannot create image to import", e);
} finally {
if (f != null) f.delete();
}
}
/**
* Creates an image to export.
*
* @return See above.
* @throws Exception
* Thrown if an error occurred.
*/
private Image createImageToExport() throws Exception {
//create an import and image
File f = File.createTempFile(RandomStringUtils.random(100, false, true),
"." + OME_XML);
XMLMockObjects xml = new XMLMockObjects();
XMLWriter writer = new XMLWriter();
writer.writeFile(f, xml.createImageWithAcquisitionData(), true);
List<Pixels> pix = null;
try {
// method tested in ImporterTest
pix = importFile(f, OME_XML, true);
return pix.get(0).getImage();
} catch (Throwable e) {
throw new Exception("Cannot create image to import", e);
} finally {
if (f != null) f.delete();
}
}
/**
* Overridden to initialize the list.
*
* @see AbstractServerTest#setUp()
*/
@Override
@BeforeClass
protected void setUp() throws Exception {
super.setUp();
upgrades = new HashMap<String, List<String>>();
downgrades = currentSchema();
windowsOS = CurrentPlatform.isWindows();
}
/**
* Overridden to delete the files.
*
* @see AbstractServerTest#tearDown()
*/
@Override
@AfterClass
public void tearDown() throws Exception {
downgrades.clear();
upgrades.clear();
}
/**
* Tests to export an image as OME-XML.
*
* @throws Exception
* Thrown if an error occurred.
* @see RawFileStoreTest#testUploadFile()
*/
@Test
public void testExportAsOMEXML() throws Exception {
// First create an image
Image image = createImageToExport();
// now export
ExporterPrx exporter = factory.createExporter();
exporter.addImage(image.getId().getValue());
long size = exporter.generateXml();
assertTrue(size > 0);
// now read
byte[] values = exporter.read(0, (int) size);
assertNotNull(values);
assertEquals(values.length, size);
exporter.close();
}
/**
* Tests to export an image as OME-XML. The image has an annotation linked
* to it.
*
* @throws Exception
* Thrown if an error occurred.
* @see RawFileStoreTest#testUploadFile()
*/
@Test
public void testExportAsOMEXMLWithAnnotation() throws Exception {
// First create an image
Image image = createImageToExport();
// Need to have an annotation otherwise does not work
FileAnnotationI fa = new FileAnnotationI();
fa.setDescription(omero.rtypes.rstring("test"));
FileAnnotation a = (FileAnnotation) iUpdate.saveAndReturnObject(fa);
ImageAnnotationLinkI l = new ImageAnnotationLinkI();
l.setChild(a);
l.setParent(new ImageI(image.getId().getValue(), false));
iUpdate.saveAndReturnObject(l);
// now export
ExporterPrx exporter = factory.createExporter();
exporter.addImage(image.getId().getValue());
long size = exporter.generateXml();
assertTrue(size > 0);
// now read
byte[] values = exporter.read(0, (int) size);
assertNotNull(values);
assertEquals(values.length, size);
exporter.close();
}
/**
* Tests to export an image as OME-TIFF. The image has an annotation linked
* to it. Downgrade the image.
*
* @throws Exception
* Thrown if an error occurred.
* @see RawFileStoreTest#testUploadFile()
*/
@Test
public void testExportAsOMETIFFWithAnnotation() throws Exception {
// First create an image
Image image = createImageToExport();
// Need to have an annotation otherwise does not work
FileAnnotationI fa = new FileAnnotationI();
fa.setDescription(omero.rtypes.rstring("test"));
FileAnnotation a = (FileAnnotation) iUpdate.saveAndReturnObject(fa);
ImageAnnotationLinkI l = new ImageAnnotationLinkI();
l.setChild(a);
l.setParent(new ImageI(image.getId().getValue(), false));
iUpdate.saveAndReturnObject(l);
// now export
ExporterPrx exporter = factory.createExporter();
exporter.addImage(image.getId().getValue());
long size = exporter.generateTiff();
assertTrue(size > 0);
// now read
byte[] values = exporter.read(0, (int) size);
assertNotNull(values);
assertEquals(values.length, size);
exporter.close();
}
/**
* Tests to export an image as OME-TIFF.
*
* @throws Exception
* Thrown if an error occurred.
* @see RawFileStoreTest#testUploadFile()
*/
@Test
public void testExportAsOMETIFF() throws Exception {
// First create an image
Image image = createImageToExport();
// now export
ExporterPrx exporter = factory.createExporter();
exporter.addImage(image.getId().getValue());
long size = exporter.generateTiff();
assertTrue(size > 0);
// now read
byte[] values = exporter.read(0, (int) size);
assertNotNull(values);
assertEquals(values.length, size);
exporter.close();
}
/**
* Generates an <code>OME-XML</code> file.
*
* @param index The type of image to import. One of the constants defined
* by this class.
* @return The exporter file.
* @throws Exception Thrown if an error occurred.
*/
private File createImageFile(int index)
throws Exception
{
// First create an image
File f = File.createTempFile(RandomStringUtils.random(100, false, true),
"." + OME_XML);
XMLMockObjects xml = new XMLMockObjects();
XMLWriter writer = new XMLWriter();
if (index == IMAGE_ROI) {
writer.writeFile(f, xml.createImageWithROI(), true);
} else if (index == IMAGE_ANNOTATED_DATA) {
writer.writeFile(f, xml.createImageWithAnnotatedAcquisitionData(),
true);
} else {
writer.writeFile(f, xml.createImageWithAcquisitionData(), true);
}
return f;
}
/**
* Exports the file with the specified extension either
* <code>OME-XML</code> or <code>OME-TIFF</code>.
*
* @param extension The extension to use.
* @param index The type of image to import. One of the constants defined
* by this class.
* @return The exporter file.
* @throws Exception Thrown if an error occurred.
*/
private File export(String extension, int index)
throws Exception
{
// First create an image
Image image = null;
if (index == SIMPLE_IMAGE) {
image = createSimpleImageToExport();
} else if (index == IMAGE_ROI) {
image = createImageWithROIToExport();
} else {
image = createImageToExport();
}
File f = File.createTempFile(RandomStringUtils.random(100, false, true),
"."+ extension);
FileOutputStream stream = new FileOutputStream(f);
ExporterPrx store = null;
try {
try {
store = factory.createExporter();
store.addImage(image.getId().getValue());
long size;
if (OME_TIFF.equals(extension)) {
size = store.generateTiff();
} else {
size = store.generateXml();
}
long offset = 0;
try {
for (offset = 0; (offset + INC) < size;) {
stream.write(store.read(offset, INC));
offset += INC;
}
} finally {
stream.write(store.read(offset, (int) (size - offset)));
stream.close();
}
} catch (Exception e) {
if (stream != null)
stream.close();
if (f != null)
f.delete();
throw e;
}
} finally {
try {
if (store != null)
store.close();
} catch (Exception e) {
throw e;
}
}
return f;
}
/**
* Parse the target node.
*
* @param node The node to parse.
* @param sheets Hosts the result.
*/
private void parseTarget(Element node, Map<String, List<String>> sheets)
{
Node attribute;
NamedNodeMap map;
NodeList transforms;
map = node.getAttributes();
String schema = null;
List<String> list = null;
for (int j = 0; j < map.getLength(); j++) {
attribute = map.item(j);
schema = attribute.getNodeValue();
transforms = node.getElementsByTagName(TRANSFORM);
list = new ArrayList<String>();
for (int i = 0; i < transforms.getLength(); i++) {
Node a;
NamedNodeMap m = transforms.item(i).getAttributes();
for (int k = 0; k < m.getLength(); k++) {
attribute = m.item(k);
if (FILE.equals(attribute.getNodeName()))
list.add(attribute.getNodeValue());
}
}
}
if (StringUtils.isNotBlank(schema) && CollectionUtils.isNotEmpty(list)) {
sheets.put(schema, list);
}
}
/**
* Extracts the value of the current schema.
*
* @param schema The current value.
* @throws Exception Thrown when an error occurred while parsing the file.
*/
private Map<String, List<String>> extractCurrentSchema(String schema,
Document document)
throws Exception
{
NodeList list = document.getElementsByTagName(SOURCE);
Element n;
Node attribute;
NamedNodeMap map;
NodeList t;
Map<String, List<String>> transforms =
new HashMap<String, List<String>>();
Map<String, List<String>> umap;
for (int i = 0; i < list.getLength(); ++i) {
n = (Element) list.item(i);
map = n.getAttributes();
for (int j = 0; j < map.getLength(); j++) {
attribute = map.item(j);
if (SCHEMA.equals(attribute.getNodeName())) {
if (schema.equals(attribute.getNodeValue())) {
t = n.getElementsByTagName(TARGET);
for (int k = 0; k < t.getLength(); k++) {
parseTarget((Element) t.item(k), transforms);
}
} else {
NodeList nl = n.getElementsByTagName("upgrades");
umap = new HashMap<String, List<String>>();
String src = attribute.getNodeValue();
for (int k = 0; k < nl.getLength(); k++) {
Element node = (Element) nl.item(k);
NodeList tt = node.getElementsByTagName(TARGET);
for (int l = 0; l < tt.getLength(); l++) {
parseTarget((Element) tt.item(l), umap);
}
//parse the map
Iterator<Entry<String, List<String>>> kk =
umap.entrySet().iterator();
Entry<String, List<String>> e;
List<String> vl;
Iterator<String> jj;
while (kk.hasNext()) {
e = kk.next();
if (e.getKey().equals(schema)) {
upgrades.put(src, e.getValue());
}
}
}
}
}
}
}
return transforms;
}
/**
* Reads the current schema.
*
* @return See above.
* @throws Exception Thrown if an error occurred while reading.
*/
private Map<String, List<String>> currentSchema() throws Exception
{
InputStream stream = getStream(CATALOG);
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
try {
DocumentBuilder builder = dbf.newDocumentBuilder();
Document doc = builder.parse(stream);
currentSchema = doc.getDocumentElement().getAttribute(CURRENT);
if (StringUtils.isBlank(currentSchema))
throw new Exception("No schema specified.");
return extractCurrentSchema(currentSchema, doc);
} catch (Exception e) {
throw new Exception("Unable to parse the catalog.", e);
} finally {
if (stream != null) stream.close();
}
}
/**
* Prepares elements used to perform downgrade or upgrade.
*
* @param values The map to create the transform from.
* @return See above.
* @throws Exception Thrown if an error occurred.
*/
private Object[][] createList(Map<String, List<String>> values)
throws Exception
{
List<Target> targets = new ArrayList<Target>();
Object[][] data = null;
List<String> l;
Iterator<String> j;
Entry<String, List<String>> e;
Iterator<Entry<String, List<String>>> i = values.entrySet().iterator();
while (i.hasNext()) {
e = i.next();
l = e.getValue();
List<InputStream> streams = new ArrayList<InputStream>();
j = l.iterator();
while (j.hasNext()) {
streams.add(getStream(j.next()));
}
targets.add(new Target(streams, e.getKey()));
}
int index = 0;
Iterator<Target> k = targets.iterator();
data = new Object[targets.size()][1];
while (k.hasNext()) {
data[index][0] = k.next();
index++;
}
return data;
}
/**
* Creates the transformations.
* @return Object[][] data.
*/
@DataProvider(name = "createTransform")
public Object[][] createTransform() throws Exception {
return createList(downgrades);
}
/**
* Creates the upgrade transformation.
* @return Object[][] data.
*/
@DataProvider(name = "createUpgrade")
public Object[][] createUpgrade() throws Exception {
return createList(upgrades);
}
/**
* Retrieve the input stream.
*
* @param name The name of the stream.
* @return See above.
*/
private InputStream getStream(String name)
{
if (windowsOS) {
return this.getClass().getClassLoader().getResourceAsStream(
"transforms/"+name);
}
return this.getClass().getResourceAsStream("/transforms/"+name);
}
/**
* Returns the list of transformations to generate the file to upgrade.
*
* @param target The schema to start from for the upgrade.
* @return See above.
*/
private List<InputStream> retrieveDowngrade(String target)
{
List<String> list = downgrades.get(target);
if (CollectionUtils.isEmpty(list)) return null;
List<InputStream> streams = new ArrayList<InputStream>();
Iterator<String> j = list.iterator();
while (j.hasNext()) {
streams.add(getStream(j.next()));
}
return streams;
}
/**
* Test the downgrade of an image with acquisition data.
* @throws Exception Thrown if an error occurred.
*/
@Test(dataProvider = "createTransform")
public void testDowngradeImageWithAcquisition(Target target) throws Exception {
File f = null;
File transformed = null;
try {
f = createImageFile(IMAGE);
//transform
transformed = applyTransforms(f, target.getTransforms());
//validate the file
validate(transformed);
//import the file
importFile(transformed, OME_XML);
} catch (Throwable e) {
throw new Exception("Cannot downgrade image: "+target.getSource(),
e);
} finally {
if (f != null) f.delete();
if (transformed != null) transformed.delete();
}
}
/**
* Test the downgrade of an image with ROi.
* @throws Exception Thrown if an error occurred.
*/
@Test(dataProvider = "createTransform")
public void testDowngradeImageWithROI(Target target) throws Exception {
File f = null;
File transformed = null;
try {
f = createImageFile(IMAGE_ROI);
//transform
transformed = applyTransforms(f, target.getTransforms());
//validate the file
validate(transformed);
//import the file
importFile(transformed, OME_XML);
} catch (Throwable e) {
throw new Exception("Cannot downgrade image: "+target.getSource(),
e);
} finally {
if (f != null) f.delete();
if (transformed != null) transformed.delete();
}
}
/**
* Test the downgrade of an image with annotated acquisition data
* @throws Exception Thrown if an error occurred.
*/
@Test(dataProvider = "createTransform")
public void testDowngradeImageWithAnnotatedAcquisitionData(Target target) throws Exception {
File f = null;
File transformed = null;
try {
f = createImageFile(IMAGE_ANNOTATED_DATA);
//transform
transformed = applyTransforms(f, target.getTransforms());
//validate the file
validate(transformed);
//import the file
importFile(transformed, OME_XML);
} catch (Throwable e) {
throw new Exception("Cannot downgrade image: "+target.getSource(),
e);
} finally {
if (f != null) f.delete();
if (transformed != null) transformed.delete();
}
}
/**
* Test if an image built with current schema validates.
* @throws Exception Thrown if an error occurred.
*/
public void testValidateImageWithAcquisition() throws Exception {
File f = null;
try {
f = createImageFile(IMAGE);
validate(f);
} catch (Throwable e) {
throw new Exception("Cannot validate the image: ", e);
} finally {
if (f != null) f.delete();
}
}
/**
* Test if an image with ROI built with current schema validates.
* @throws Exception Thrown if an error occurred.
*/
public void testValidateImageWithROI() throws Exception {
File f = null;
try {
f = createImageFile(IMAGE_ROI);
validate(f);
} catch (Throwable e) {
throw new Exception("Cannot validate the image: ", e);
} finally {
if (f != null) f.delete();
}
}
/**
* Test if an image with annotated acquisition data built with current
* schema validates.
* @throws Exception Thrown if an error occurred.
*/
public void testValidateImageWithAnnotatedAcquisition() throws Exception {
File f = null;
try {
f = createImageFile(IMAGE_ANNOTATED_DATA);
validate(f);
} catch (Throwable e) {
throw new Exception("Cannot validate the image: ", e);
} finally {
if (f != null) f.delete();
}
}
/**
* Test the export of an image as OME-XML. Downgrade it.
* @throws Exception Thrown if an error occurred.
*/
@Test(dataProvider = "createTransform")
public void testExportAsOMEXMLDowngrade(Target target) throws Exception {
File f = null;
File transformed = null;
try {
f = export(OME_XML, IMAGE);
//transform
transformed = applyTransforms(f, target.getTransforms());
//validate the file
validate(transformed);
//import the file
importFile(transformed, OME_XML);
} catch (Throwable e) {
throw new Exception("Cannot downgrade image: "+target.getSource(),
e);
} finally {
if (f != null) f.delete();
if (transformed != null) transformed.delete();
}
}
/**
* Test the export of an image as OME-XML. Downgrade it.
* @throws Exception Thrown if an error occurred.
*/
@Test(dataProvider = "createTransform")
public void testExportAsOMEXMLDowngradeSimpleImage(Target target)
throws Exception {
File f = null;
File transformed = null;
try {
f = export(OME_XML, SIMPLE_IMAGE);
//transform
transformed = applyTransforms(f, target.getTransforms());
//validate the file
validate(transformed);
//import the file
importFile(transformed, OME_XML);
} catch (Throwable e) {
throw new Exception("Cannot downgrade image: "+target.getSource(),
e);
} finally {
if (f != null) f.delete();
if (transformed != null) transformed.delete();
}
}
/**
* Test the export of an image with ROI as OME-XML. Downgrade it.
* @throws Exception Thrown if an error occurred.
*/
@Test(dataProvider = "createTransform")
public void testExportAsOMEXMLDowngradeImageWithROI(Target target) throws Exception {
File f = null;
File transformed = null;
try {
f = export(OME_XML, IMAGE_ROI);
//transform
transformed = applyTransforms(f, target.getTransforms());
//validate the file
validate(transformed);
//import the file
importFile(transformed, OME_XML);
} catch (Throwable e) {
throw new Exception("Cannot downgrade image: "+target.getSource(),
e);
} finally {
if (f != null) f.delete();
if (transformed != null) transformed.delete();
}
}
/**
* Tests to export an image as OME-TIFF and downgrade it.
*
* @throws Exception
* Thrown if an error occurred.
* @see RawFileStoreTest#testUploadFile()
*/
@Test(dataProvider = "createTransform")
public void testExportAsOMETIFFDowngrade(Target target) throws Exception {
File f = null;
File transformed = null;
File inputXML = null;
RandomAccessInputStream in = null;
RandomAccessOutputStream out = null;
RandomAccessOutputStream tiffOutput = null;
File tiffXML = null;
try {
f = export(OME_TIFF, IMAGE);
//extract XML and copy to tmp file
String path = f.getAbsolutePath();
TiffParser parser = new TiffParser(path);
inputXML = File.createTempFile(RandomStringUtils.random(100, false,
true),"." + OME_XML);
FileUtils.writeStringToFile(inputXML, parser.getComment(),
Constants.ENCODING);
//transform XML
transformed = applyTransforms(inputXML, target.getTransforms());
validate(transformed);
String comment = FileUtils.readFileToString(transformed,
Constants.ENCODING);
tiffOutput = new RandomAccessOutputStream(path);
TiffSaver saver = new TiffSaver(tiffOutput, path);
saver.setBigTiff(parser.isBigTiff());
in = new RandomAccessInputStream(path);
saver.overwriteComment(in, comment);
tiffOutput.close();
//import the file
importFile(f, OME_TIFF);
} catch (Throwable e) {
throw new Exception("Cannot downgrade image: "+target.getSource(),
e);
} finally {
if (f != null) f.delete();
if (transformed != null) transformed.delete();
if (inputXML != null) inputXML.delete();
if (in != null) in.close();
if (tiffXML != null) tiffXML.delete();
}
}
/**
* Test the upgrade of an image with acquisition data.
* @throws Exception Thrown if an error occurred.
*/
@Test(dataProvider = "createUpgrade")
public void testUpgradeImageWithAcquisition(Target target) throws Exception {
File f = null;
File transformed = null;
File upgraded = null;
try {
f = createImageFile(IMAGE); //2015 image
List<InputStream> transforms = retrieveDowngrade(target.getSource());
//Create file to upgrade
transformed = applyTransforms(f, transforms);
//now upgrade the file.
upgraded = applyTransforms(transformed, target.getTransforms());
//validate the file
validate(upgraded);
//import the file
importFile(upgraded, OME_XML);
} catch (Throwable e) {
throw new Exception("Cannot upgrade image: "+target.getSource(),
e);
} finally {
if (f != null) f.delete();
if (transformed != null) transformed.delete();
if (upgraded != null) upgraded.delete();
}
}
/**
* Test the upgrade of an image with ROI.
* @throws Exception Thrown if an error occurred.
*/
@Test(dataProvider = "createUpgrade")
public void testUpgradeImageWithROI(Target target) throws Exception {
File f = null;
File transformed = null;
File upgraded = null;
try {
f = createImageFile(IMAGE_ROI); //2015 image
List<InputStream> transforms = retrieveDowngrade(target.getSource());
//Create file to upgrade
transformed = applyTransforms(f, transforms);
//now upgrade the file.
upgraded = applyTransforms(transformed, target.getTransforms());
//validate the file
validate(upgraded);
//import the file
importFile(upgraded, OME_XML);
} catch (Throwable e) {
throw new Exception("Cannot upgrade image: "+target.getSource(),
e);
} finally {
if (f != null) f.delete();
if (transformed != null) transformed.delete();
if (upgraded != null) upgraded.delete();
}
}
/**
* Test the upgrade of an image with annotated acquisition.
* @throws Exception Thrown if an error occurred.
*/
@Test(dataProvider = "createUpgrade")
public void testUpgradeImageWithAnnotatedAcquisition(Target target) throws Exception {
File f = null;
File transformed = null;
File upgraded = null;
try {
f = createImageFile(IMAGE_ANNOTATED_DATA); //2015 image
List<InputStream> transforms = retrieveDowngrade(target.getSource());
//Create file to upgrade
transformed = applyTransforms(f, transforms);
//now upgrade the file.
upgraded = applyTransforms(transformed, target.getTransforms());
//validate the file
validate(upgraded);
//import the file
importFile(upgraded, OME_XML);
} catch (Throwable e) {
throw new Exception("Cannot upgrade image: "+target.getSource(),
e);
} finally {
if (f != null) f.delete();
if (transformed != null) transformed.delete();
if (upgraded != null) upgraded.delete();
}
}
// Path not in ome-transforms but stylesheets are available
/**
* Test the upgrade of an image from 2003-FC to 2008-09.
* @throws Exception Thrown if an error occurred.
*/
public void testUpgradeImage2003FCto200809() throws Exception
{
File f = null;
File transformed = null;
File upgraded = null;
try {
f = createImageFile(IMAGE); //2015 image
List<InputStream> transforms = retrieveDowngrade("2003-FC");
//Create file to upgrade
transformed = applyTransforms(f, transforms);
//now upgrade the file to 2008-09
List<InputStream> upgrades = new ArrayList<InputStream>();
upgrades.add(getStream("2003-FC-to-2008-09.xsl"));
upgraded = applyTransforms(transformed, upgrades);
//validate the file
validate(upgraded);
//import the file
importFile(upgraded, OME_XML);
} catch (Throwable e) {
throw new Exception("Cannot transform image to 2008-09", e);
} finally {
if (f != null) f.delete();
if (transformed != null) transformed.delete();
if (upgraded != null) upgraded.delete();
}
}
/**
* Test the upgrade of an image from 2007-06 to 2008-02.
* @throws Exception Thrown if an error occurred.
*/
public void testUpgradeImage200706to200802() throws Exception
{
File f = null;
File transformed = null;
File upgraded = null;
try {
f = createImageFile(IMAGE); //2015 image
List<InputStream> transforms = retrieveDowngrade("2007-06");
//Create file to upgrade
transformed = applyTransforms(f, transforms);
//now upgrade the file to 2008-02
List<InputStream> upgrades = new ArrayList<InputStream>();
upgrades.add(getStream("2007-06-to-2008-02.xsl"));
upgraded = applyTransforms(transformed, upgrades);
//validate the file
validate(upgraded);
//import the file
importFile(upgraded, OME_XML);
} catch (Throwable e) {
throw new Exception("Cannot transform image to 2008-02", e);
} finally {
if (f != null) f.delete();
if (transformed != null) transformed.delete();
if (upgraded != null) upgraded.delete();
}
}
/**
* Test the upgrade of an image from 2007-06 to 2008-09.
* @throws Exception Thrown if an error occurred.
*/
public void testUpgradeImage200706to200809() throws Exception
{
File f = null;
File transformed = null;
File upgraded = null;
try {
f = createImageFile(IMAGE); //2015 image
List<InputStream> transforms = retrieveDowngrade("2007-06");
//Create file to upgrade
transformed = applyTransforms(f, transforms);
//now upgrade the file to 2008-09
List<InputStream> upgrades = new ArrayList<InputStream>();
upgrades.add(getStream("2007-06-to-2008-09.xsl"));
upgraded = applyTransforms(transformed, upgrades);
//validate the file
validate(upgraded);
//import the file
importFile(upgraded, OME_XML);
} catch (Throwable e) {
throw new Exception("Cannot transform image to 2008-09", e);
} finally {
if (f != null) f.delete();
if (transformed != null) transformed.delete();
if (upgraded != null) upgraded.delete();
}
}
/**
* Test that the shapes in an image's ROI survive export then import.
* @throws Throwable unexpected
*/
@Test
public void testExportImportROIs() throws Throwable {
/* export then import an image */
final File exportedFile = export(OME_TIFF, IMAGE_ROI);
final Pixels pixels = importFile(exportedFile, OME_TIFF).get(0);
/* find which kinds of shape are expected */
final Set<String> remainingClasses = new HashSet<String>();
for (final String fullClassName : XMLMockObjects.SHAPES) {
remainingClasses.add(fullClassName.substring(fullClassName.lastIndexOf('.') + 1));
}
/* find the image's shapes */
final String hql = "FROM Shape WHERE roi.image.id = :id";
final Parameters params = new ParametersI().addId(pixels.getImage().getId().getValue());
final List<IObject> shapes = iQuery.findAllByQuery(hql, params);
/* check that the image has the expected shapes */
for (final IObject result : shapes) {
Class<? extends IObject> resultClass = result.getClass();
while (resultClass.getSuperclass() != Shape.class) {
resultClass = resultClass.getSuperclass().asSubclass(IObject.class);
}
assertTrue(remainingClasses.remove(resultClass.getSimpleName()));
}
assertTrue(remainingClasses.isEmpty());
}
class Target {
/** The transforms to apply.*/
private List<InputStream> transforms;
/** The source schema.*/
private String source;
/**
* Creates a new instance.
*
* @param transforms The transforms to apply.
* @param source The source schema.
*/
Target(List<InputStream> transforms, String source)
{
this.transforms = transforms;
this.source = source;
}
/**
* Returns the transforms to apply.
*
* @return See above.
*/
List<InputStream> getTransforms() { return transforms; }
/**
* Returns the source schema.
*
* @return See above.
*/
String getSource() { return source; }
}
class Resolver implements URIResolver {
/** The stream.*/
private InputStream stream;
/** Close the input stream if not <code>null</code>.*/
public void close()
throws Exception
{
if (stream != null) stream.close();
}
@Override
public Source resolve(String href, String base)
throws TransformerException {
stream = getStream(UNITS_CONVERSION);
return new StreamSource(stream);
}
}
}