diff --git a/common/source/java/ch/systemsx/cisd/common/io/ByteArrayBasedContent.java b/common/source/java/ch/systemsx/cisd/common/io/ByteArrayBasedContent.java index 5e9627f18e79407fbff0870e57ff270bf3e8fe32..9ba45c46f3f27077bf6bd49f30996c0fe2cc8366 100644 --- a/common/source/java/ch/systemsx/cisd/common/io/ByteArrayBasedContent.java +++ b/common/source/java/ch/systemsx/cisd/common/io/ByteArrayBasedContent.java @@ -18,6 +18,10 @@ package ch.systemsx.cisd.common.io; import java.io.ByteArrayInputStream; import java.io.InputStream; +import java.nio.ByteBuffer; + +import ch.systemsx.cisd.common.filesystem.ByteBufferRandomAccessFile; +import ch.systemsx.cisd.common.filesystem.IRandomAccessFile; /** * Content based on an array of bytes. @@ -69,4 +73,9 @@ public class ByteArrayBasedContent implements IContent { return new ByteArrayInputStream(byteArray); } + + public IRandomAccessFile getReadOnlyRandomAccessFile() + { + return new ByteBufferRandomAccessFile(ByteBuffer.wrap(byteArray)); + } } diff --git a/common/source/java/ch/systemsx/cisd/common/io/ContentProviderBasedContent.java b/common/source/java/ch/systemsx/cisd/common/io/ContentProviderBasedContent.java index 647e96f9937b250b66e8d249ab2054120ca53e1e..8ff889b3de31b7965db4c554c4ef0c816978b56e 100644 --- a/common/source/java/ch/systemsx/cisd/common/io/ContentProviderBasedContent.java +++ b/common/source/java/ch/systemsx/cisd/common/io/ContentProviderBasedContent.java @@ -18,6 +18,8 @@ package ch.systemsx.cisd.common.io; import java.io.InputStream; +import ch.systemsx.cisd.common.filesystem.IRandomAccessFile; + /** * Content based on a {@link IContentProvider}. * @@ -56,6 +58,11 @@ public class ContentProviderBasedContent implements IContent return getContent().getInputStream(); } + public IRandomAccessFile getReadOnlyRandomAccessFile() + { + return getContent().getReadOnlyRandomAccessFile(); + } + private IContent getContent() { if (content == null) @@ -64,5 +71,5 @@ public class ContentProviderBasedContent implements IContent } return content; } - + } diff --git a/common/source/java/ch/systemsx/cisd/common/io/FileBasedContent.java b/common/source/java/ch/systemsx/cisd/common/io/FileBasedContent.java index b76e440084379932ec71fe1ae81a6712218f3087..4442ae357fba4f2e815b9733a9e8fada29aed116 100644 --- a/common/source/java/ch/systemsx/cisd/common/io/FileBasedContent.java +++ b/common/source/java/ch/systemsx/cisd/common/io/FileBasedContent.java @@ -20,9 +20,13 @@ import java.io.BufferedInputStream; import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; +import java.io.IOException; import java.io.InputStream; +import java.io.RandomAccessFile; import ch.systemsx.cisd.base.exceptions.CheckedExceptionTunnel; +import ch.systemsx.cisd.common.filesystem.IRandomAccessFile; +import ch.systemsx.cisd.common.filesystem.RandomAccessFileImpl; /** * File content. Wraps an instance of {@link File}. @@ -78,4 +82,15 @@ public class FileBasedContent implements IContent throw CheckedExceptionTunnel.wrapIfNecessary(ex); } } + + public IRandomAccessFile getReadOnlyRandomAccessFile() + { + try + { + return new RandomAccessFileImpl(new RandomAccessFile(file, "r")); + } catch (IOException ex) + { + throw CheckedExceptionTunnel.wrapIfNecessary(ex); + } + } } diff --git a/common/source/java/ch/systemsx/cisd/common/io/IContent.java b/common/source/java/ch/systemsx/cisd/common/io/IContent.java index e2b6037273f64861b0ab2a897d2477e7769710f6..cf4b6b330456233031f4d57ee71f24e4abbd4f53 100644 --- a/common/source/java/ch/systemsx/cisd/common/io/IContent.java +++ b/common/source/java/ch/systemsx/cisd/common/io/IContent.java @@ -18,8 +18,10 @@ package ch.systemsx.cisd.common.io; import java.io.InputStream; +import ch.systemsx.cisd.common.filesystem.IRandomAccessFile; + /** - * Abstract of streamable binary content with name and known size. + * Abstract of streamable and random-accessible binary content with name and known size. * * @author Franz-Josef Elmer */ @@ -40,6 +42,11 @@ public interface IContent */ public boolean exists(); + /** + * Returns a random access file object for read-only use. + */ + public IRandomAccessFile getReadOnlyRandomAccessFile(); + /** * Returns a new instance of an input stream over the complete content. Note that the returned * {@link InputStream} is expected to have {@link InputStream#markSupported()} diff --git a/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/generic/shared/utils/ImageUtil.java b/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/generic/shared/utils/ImageUtil.java index 52521107b7437e7f3021674922efaa7e8e8be5e7..9a1f18c3cdeb009c5a69d75b88b0f6394b91a95d 100644 --- a/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/generic/shared/utils/ImageUtil.java +++ b/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/generic/shared/utils/ImageUtil.java @@ -37,12 +37,13 @@ import javax.imageio.ImageIO; import org.apache.commons.io.IOUtils; -import com.sun.media.jai.codec.FileSeekableStream; import com.sun.media.jai.codec.ImageCodec; import com.sun.media.jai.codec.ImageDecoder; import ch.systemsx.cisd.base.exceptions.CheckedExceptionTunnel; import ch.systemsx.cisd.common.exceptions.EnvironmentFailureException; +import ch.systemsx.cisd.common.io.FileBasedContent; +import ch.systemsx.cisd.common.io.IContent; import ch.systemsx.cisd.common.utilities.DataTypeUtil; /** @@ -182,9 +183,9 @@ public class ImageUtil * @throws IllegalArgumentException if the input stream doesn't start with a magic number * identifying supported image format. */ - public static BufferedImage loadImage(InputStream inputStream) + public static BufferedImage loadImage(IContent content) { - return loadImage(inputStream, 0); + return loadImage(content, 0); } /** @@ -195,12 +196,12 @@ public class ImageUtil * @throws IllegalArgumentException if the input stream doesn't start with a magic number * identifying supported image format. */ - public static BufferedImage loadImage(InputStream inputStream, int page) + public static BufferedImage loadImage(IContent content, int page) { - InputStream markSupportingInputStream = inputStream; - if (inputStream.markSupported() == false) + InputStream markSupportingInputStream = content.getInputStream(); + if (markSupportingInputStream.markSupported() == false) { - markSupportingInputStream = new BufferedInputStream(inputStream); + markSupportingInputStream = new BufferedInputStream(markSupportingInputStream); } String fileType = DataTypeUtil.tryToFigureOutFileTypeOf(markSupportingInputStream); return loadImage(markSupportingInputStream, fileType, page); @@ -214,7 +215,7 @@ public class ImageUtil * @throws IllegalArgumentException if the input stream doesn't start with a magic number * identifying supported image format. */ - public static BufferedImage loadImage(InputStream inputStream, String fileType, int page) + private static BufferedImage loadImage(InputStream inputStream, String fileType, int page) { try { @@ -251,15 +252,7 @@ public class ImageUtil { throw new IllegalArgumentException("File does not exist: " + file.getAbsolutePath()); } - try - { - FileSeekableStream inStream = new FileSeekableStream(file); - return loadImage(inStream); - } catch (IOException ex) - { - throw new IllegalArgumentException("Isn't a valid image file: " - + file.getAbsolutePath() + ". Error: " + ex.getMessage()); - } + return loadImage(new FileBasedContent(file)); } /** diff --git a/datastore_server/sourceTest/java/ch/systemsx/cisd/openbis/dss/generic/shared/utils/ImageUtilTest.java b/datastore_server/sourceTest/java/ch/systemsx/cisd/openbis/dss/generic/shared/utils/ImageUtilTest.java index 2d8e8ac588c9c9d1b590b09a24739b803ff6a831..22b9bbcae4b03e6c04c6c1b46e1f8f8af6816efa 100644 --- a/datastore_server/sourceTest/java/ch/systemsx/cisd/openbis/dss/generic/shared/utils/ImageUtilTest.java +++ b/datastore_server/sourceTest/java/ch/systemsx/cisd/openbis/dss/generic/shared/utils/ImageUtilTest.java @@ -18,8 +18,6 @@ package ch.systemsx.cisd.openbis.dss.generic.shared.utils; import java.awt.image.BufferedImage; import java.io.File; -import java.io.FileInputStream; -import java.io.FileNotFoundException; import java.io.IOException; import java.io.InputStream; @@ -27,7 +25,9 @@ import org.testng.AssertJUnit; import org.testng.annotations.BeforeMethod; import org.testng.annotations.Test; -import ch.systemsx.cisd.base.exceptions.CheckedExceptionTunnel; +import ch.systemsx.cisd.common.filesystem.IRandomAccessFile; +import ch.systemsx.cisd.common.io.FileBasedContent; +import ch.systemsx.cisd.common.io.IContent; /** * @@ -36,6 +36,37 @@ import ch.systemsx.cisd.base.exceptions.CheckedExceptionTunnel; */ public class ImageUtilTest extends AssertJUnit { + private static class MockIContent implements IContent + { + final MockInputStream is = new MockInputStream(); + + public String tryGetName() + { + throw new UnsupportedOperationException(); + } + + public long getSize() + { + throw new UnsupportedOperationException(); + } + + public boolean exists() + { + throw new UnsupportedOperationException(); + } + + public IRandomAccessFile getReadOnlyRandomAccessFile() + { + throw new UnsupportedOperationException(); + } + + public InputStream getInputStream() + { + return is; + } + + } + private static class MockInputStream extends InputStream { boolean closeInvoked; @@ -100,17 +131,17 @@ public class ImageUtilTest extends AssertJUnit @Test public void testInputStreamAutomaticallyClosed() { - MockInputStream inputStream = new MockInputStream(); + MockIContent content = new MockIContent(); try { - ImageUtil.loadImage(inputStream); + ImageUtil.loadImage(content); fail("IllegalArgumentException expected"); } catch (IllegalArgumentException ex) { assertEquals("File type of an image input stream couldn't be determined.", ex.getMessage()); } - assertEquals(true, inputStream.closeInvoked); + assertEquals(true, content.is.closeInvoked); } private BufferedImage loadImageByFile(String fileName) @@ -123,15 +154,7 @@ public class ImageUtilTest extends AssertJUnit private BufferedImage loadImageByInputStream(String fileName) { File file = new File(dir, fileName); - BufferedImage image; - try - { - image = ImageUtil.loadImage(new FileInputStream(file)); - } catch (FileNotFoundException ex) - { - throw CheckedExceptionTunnel.wrapIfNecessary(ex); - } - return image; + return ImageUtil.loadImage(new FileBasedContent(file)); } private void assertImageSize(int expectedWith, int expectedHeight, BufferedImage image) diff --git a/screening/source/java/ch/systemsx/cisd/openbis/dss/generic/server/images/ImageChannelsUtils.java b/screening/source/java/ch/systemsx/cisd/openbis/dss/generic/server/images/ImageChannelsUtils.java index 4e4ab5dc8979dc19a9c4139486f7a74937f62d4b..6b22e8228d4fedabb45026766c70e9fe898e3f75 100644 --- a/screening/source/java/ch/systemsx/cisd/openbis/dss/generic/server/images/ImageChannelsUtils.java +++ b/screening/source/java/ch/systemsx/cisd/openbis/dss/generic/server/images/ImageChannelsUtils.java @@ -24,7 +24,6 @@ import java.awt.image.RenderedImage; import java.io.ByteArrayOutputStream; import java.io.File; import java.io.IOException; -import java.io.InputStream; import java.util.ArrayList; import java.util.Arrays; import java.util.List; @@ -470,12 +469,11 @@ public class ImageChannelsUtils private static BufferedImage loadImage(AbsoluteImageReference imageReference) { IContent content = imageReference.getContent(); - InputStream inputStream = content.getInputStream(); // extracts the correct page if necessary int page = (imageReference.tryGetPage() != null) ? imageReference.tryGetPage() : 0; - BufferedImage image = ImageUtil.loadImage(inputStream, page); + BufferedImage image = ImageUtil.loadImage(content, page); return image; } diff --git a/screening/source/java/ch/systemsx/cisd/openbis/dss/screening/server/DssServiceRpcScreening.java b/screening/source/java/ch/systemsx/cisd/openbis/dss/screening/server/DssServiceRpcScreening.java index ed4cf6cb7ace14b5bad31a26709a98ee11c97856..ad6ef6d49e67738051f1a56c49f464cffad508ed 100644 --- a/screening/source/java/ch/systemsx/cisd/openbis/dss/screening/server/DssServiceRpcScreening.java +++ b/screening/source/java/ch/systemsx/cisd/openbis/dss/screening/server/DssServiceRpcScreening.java @@ -219,7 +219,7 @@ public class DssServiceRpcScreening extends AbstractDssServiceRpc<IDssServiceRpc IImagingDatasetLoader imageAccessor) { IContent imageFile = getAnyImagePath(imageAccessor, dataset); - BufferedImage image = ImageUtil.loadImage(imageFile.getInputStream()); + BufferedImage image = ImageUtil.loadImage(imageFile); Size imageSize = new Size(image.getWidth(), image.getHeight()); return imageSize; } diff --git a/screening/sourceTest/java/ch/systemsx/cisd/openbis/dss/generic/server/images/ImageChannelsUtilsTest.java b/screening/sourceTest/java/ch/systemsx/cisd/openbis/dss/generic/server/images/ImageChannelsUtilsTest.java index 00b25a1caac2e399b112dabecfac5d45baef6d20..db7cc1938fe1c4c4fc7454668f8314875506ba7b 100644 --- a/screening/sourceTest/java/ch/systemsx/cisd/openbis/dss/generic/server/images/ImageChannelsUtilsTest.java +++ b/screening/sourceTest/java/ch/systemsx/cisd/openbis/dss/generic/server/images/ImageChannelsUtilsTest.java @@ -242,7 +242,7 @@ public class ImageChannelsUtilsTest extends AssertJUnit private String getImageContentDescription(IContent image) { - BufferedImage bufferedImage = ImageUtil.loadImage(image.getInputStream()); + BufferedImage bufferedImage = ImageUtil.loadImage(image); return getImageContentDescription(bufferedImage); } diff --git a/screening/sourceTest/java/ch/systemsx/cisd/openbis/dss/screening/server/DssServiceRpcScreeningTest.java b/screening/sourceTest/java/ch/systemsx/cisd/openbis/dss/screening/server/DssServiceRpcScreeningTest.java index 4abfe1dda2c313b6a4d24746f5182a0de891deb0..2269ffb0c839c7124fe03f59b8a2f5e04ddf878d 100644 --- a/screening/sourceTest/java/ch/systemsx/cisd/openbis/dss/screening/server/DssServiceRpcScreeningTest.java +++ b/screening/sourceTest/java/ch/systemsx/cisd/openbis/dss/screening/server/DssServiceRpcScreeningTest.java @@ -17,7 +17,6 @@ package ch.systemsx.cisd.openbis.dss.screening.server; import java.awt.image.BufferedImage; -import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.File; import java.io.IOException; @@ -42,6 +41,7 @@ import ch.systemsx.cisd.base.image.IImageTransformer; import ch.systemsx.cisd.base.image.IImageTransformerFactory; import ch.systemsx.cisd.base.mdarray.MDFloatArray; import ch.systemsx.cisd.bds.hcs.Location; +import ch.systemsx.cisd.common.io.ByteArrayBasedContent; import ch.systemsx.cisd.common.io.ConcatenatedFileOutputStreamWriter; import ch.systemsx.cisd.common.io.FileBasedContent; import ch.systemsx.cisd.common.io.IContent; @@ -333,7 +333,8 @@ public class DssServiceRpcScreeningTest extends AssertJUnit { ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); imagesWriter.writeNextBlock(outputStream); - return ImageUtil.loadImage(new ByteArrayInputStream(outputStream.toByteArray())); + return ImageUtil + .loadImage(new ByteArrayBasedContent(outputStream.toByteArray(), "UNKNOWN")); } @Test @@ -448,14 +449,14 @@ public class DssServiceRpcScreeningTest extends AssertJUnit ImgDatasetDTO dataset = createDataset(datasetId); dataset.setContainerId(containerId); dataset.setPermId(DATASET_CODE); - + long experimentId = 888; ImgContainerDTO container = new ImgContainerDTO(null, null, null, experimentId); container.setId(containerId); one(dao).tryGetDatasetByPermId(DATASET_CODE); will(returnValue(dataset)); - + allowing(dao).hasDatasetChannels(DATASET_CODE); will(returnValue(false)); @@ -601,7 +602,8 @@ public class DssServiceRpcScreeningTest extends AssertJUnit private FeatureVectorDatasetReference createFeatureVectorDatasetReference(String dataSetCode) { - return new FeatureVectorDatasetReference(dataSetCode, "", null, null, null, null, null, null); + return new FeatureVectorDatasetReference(dataSetCode, "", null, null, null, null, null, + null); } // Used for the authorization test