use of java.nio.channels.Channel in project dataverse by IQSS.
the class StorageIOTest method testGetChannel.
@Test
public void testGetChannel() throws FileNotFoundException {
assertEquals(null, instance.getChannel());
Channel c = new RandomAccessFile("src/main/java/Bundle.properties", "r").getChannel();
instance.setChannel(c);
assertEquals(c, instance.getChannel());
}
use of java.nio.channels.Channel in project dataverse by IQSS.
the class ImageThumbConverter method generateImageThumbnailFromInputStream.
/*
* This is the actual workhorse method that does the rescaling of the full
* size image:
*/
private static boolean generateImageThumbnailFromInputStream(StorageIO<DataFile> storageIO, int size, InputStream inputStream) {
BufferedImage fullSizeImage;
try {
logger.fine("attempting to read the image file with ImageIO.read(InputStream), " + storageIO.getDataFile().getStorageIdentifier());
fullSizeImage = ImageIO.read(inputStream);
} catch (Exception ioex) {
logger.warning("Caught exception attempting to read the image file with ImageIO.read(InputStream)");
return false;
}
if (fullSizeImage == null) {
logger.warning("could not read image with ImageIO.read()");
return false;
}
int width = fullSizeImage.getWidth(null);
int height = fullSizeImage.getHeight(null);
logger.fine("image dimensions: " + width + "x" + height + "(" + storageIO.getDataFile().getStorageIdentifier() + ")");
OutputStream outputStream = null;
// With some storage drivers, we can open a WritableChannel, or OutputStream
// to directly write the generated thumbnail that we want to cache;
// Some drivers (like Swift) do not support that, and will give us an
// "operation not supported" exception. If that's the case, we'll have
// to save the output into a temp file, and then copy it over to the
// permanent storage using the DataAccess IO "save" command:
boolean tempFileRequired = false;
File tempFile = null;
try {
Channel outputChannel = storageIO.openAuxChannel(THUMBNAIL_SUFFIX + size, DataAccessOption.WRITE_ACCESS);
outputStream = Channels.newOutputStream((WritableByteChannel) outputChannel);
logger.fine("Opened an auxiliary channel/output stream " + THUMBNAIL_SUFFIX + size + " on " + storageIO.getDataFile().getStorageIdentifier());
} catch (Exception ioex) {
logger.fine("Failed to open an auxiliary channel/output stream " + THUMBNAIL_SUFFIX + size + " on " + storageIO.getDataFile().getStorageIdentifier());
tempFileRequired = true;
}
if (tempFileRequired) {
try {
tempFile = File.createTempFile("tempFileToRescale", ".tmp");
outputStream = new FileOutputStream(tempFile);
} catch (IOException ioex) {
logger.fine("GenerateImageThumb: failed to open a temporary file.");
return false;
}
}
try {
rescaleImage(fullSizeImage, width, height, size, outputStream);
if (tempFileRequired) {
storageIO.savePathAsAux(Paths.get(tempFile.getAbsolutePath()), THUMBNAIL_SUFFIX + size);
}
} catch (Exception ioex) {
logger.warning("Failed to rescale and/or save the image: " + ioex.getMessage());
return false;
}
return true;
}
use of java.nio.channels.Channel in project dataverse by IQSS.
the class ImageThumbConverter method getImageThumbnailAsBase64.
/**
* This method is suitable for returning a string to embed in an HTML img
* tag (or JSF h:graphicImage tag) because the string begins with
* "data:image/png;base64," but it is not suitable for returning a
* downloadable image via an API call.
*/
public static String getImageThumbnailAsBase64(DataFile file, int size) {
logger.fine("entering getImageThumbnailAsBase64, size " + size + ", for " + file.getStorageIdentifier());
// to check anything else:
if (file == null || !FileUtil.isThumbnailSupported(file)) {
logger.fine("No thumbnail support for " + file.getContentType());
return null;
}
StorageIO<DataFile> storageIO = null;
try {
storageIO = file.getStorageIO();
} catch (Exception ioEx) {
logger.fine("Caught an exception while trying to obtain a thumbnail as Base64 string - could not open StorageIO on the datafile.");
return null;
}
if (storageIO == null) {
return null;
}
// skip the "isAvailable()" check - and just try to open the cached object.
// if we can't open it, then we'll try to generate it. In other words, we are doing it in
// the reverse order - and his way we can save one extra lookup, for a thumbnail
// that's already cached - and on some storage media (specifically, S3)
// lookups are actually more expensive than reads.
// (an experiment...)
// if (!isThumbnailAvailable(storageIO, size)) {
// logger.info("no thumbnail available for " + file.getStorageIdentifier());
// return null;
// }
// we are skipping this StorageIO.open() call as well - since this
// is another (potentially expensive) S3/swift lookup.
// storageIO.open();
Channel cachedThumbnailChannel = null;
try {
cachedThumbnailChannel = storageIO.openAuxChannel(THUMBNAIL_SUFFIX + size);
} catch (Exception ioEx) {
cachedThumbnailChannel = null;
}
if (cachedThumbnailChannel == null) {
logger.fine("Null channel for aux object " + THUMBNAIL_SUFFIX + size);
// try to generate, if not available:
boolean generated = false;
if (file.getContentType().substring(0, 6).equalsIgnoreCase("image/")) {
generated = generateImageThumbnail(storageIO, size);
} else if (file.getContentType().equalsIgnoreCase("application/pdf")) {
generated = generatePDFThumbnail(storageIO, size);
} else if (file.getContentType().equalsIgnoreCase("application/zipped-shapefile") || (file.isTabularData() && file.hasGeospatialTag())) {
generated = generateWorldMapThumbnail(storageIO, size);
}
if (generated) {
// try to open again:
try {
cachedThumbnailChannel = storageIO.openAuxChannel(THUMBNAIL_SUFFIX + size);
} catch (Exception ioEx) {
cachedThumbnailChannel = null;
}
}
// if still null - give up:
if (cachedThumbnailChannel == null) {
return null;
}
}
InputStream cachedThumbnailInputStream = Channels.newInputStream((ReadableByteChannel) cachedThumbnailChannel);
// , cachedThumbnailSize);
return getImageAsBase64FromInputStream(cachedThumbnailInputStream);
}
use of java.nio.channels.Channel in project dataverse by IQSS.
the class ImageThumbConverter method getImageThumbnailAsInputStream.
// Note that this method works on ALL file types for which thumbnail
// generation is supported - image/*, pdf, worldmap and geo-tagged tabular;
// not just on images! The type differentiation is handled inside
// isThumbnailAvailable(); if the thumbnail is not yet cached, that
// method will attempt to generate and cache it. And once it's cached,
// it is the same "auxiliary file", or an extra file with the .thumb[size]
// extension - which is the same for all supported types.
// Note that this method is mainly used by the data access API methods.
// Whenever a page needs a thumbnail, we prefer to rely on the Base64
// string version.
public static InputStreamIO getImageThumbnailAsInputStream(StorageIO<DataFile> storageIO, int size) {
if (!isThumbnailAvailable(storageIO, size)) {
return null;
}
// If we got that far, it's now reasonable to expect that the thumbnail
// has been generated cached.
InputStream cachedThumbnailInputStream = null;
try {
storageIO.open();
Channel cachedThumbnailChannel = storageIO.openAuxChannel(THUMBNAIL_SUFFIX + size);
if (cachedThumbnailChannel == null) {
logger.warning("Null channel for aux object " + THUMBNAIL_SUFFIX + size);
return null;
}
cachedThumbnailInputStream = Channels.newInputStream((ReadableByteChannel) cachedThumbnailChannel);
int cachedThumbnailSize = (int) storageIO.getAuxObjectSize(THUMBNAIL_SUFFIX + size);
InputStreamIO inputStreamIO = new InputStreamIO(cachedThumbnailInputStream, cachedThumbnailSize);
inputStreamIO.setMimeType(THUMBNAIL_MIME_TYPE);
String fileName = storageIO.getFileName();
if (fileName != null) {
fileName = fileName.replaceAll("\\.[^\\.]*$", ".png");
inputStreamIO.setFileName(fileName);
}
return inputStreamIO;
} catch (Exception ioex) {
if (cachedThumbnailInputStream != null) {
try {
cachedThumbnailInputStream.close();
} catch (IOException e) {
}
}
return null;
}
}
use of java.nio.channels.Channel in project dataverse by IQSS.
the class ImageThumbConverter method generateWorldMapThumbnail.
/*
* Note that the "WorldMapThumbnail" generator does the exact same thing as the
* "regular image" thumbnail generator.
* The only difference is that the image generator uses the main file as
* as the source; and the one for the worldmap uses an auxiliary file
* with the ".img" extension (or the swift, etc. equivalent). This file is
* produced and dropped into the Dataset directory (Swift container, etc.)
* the first time the user actually runs WorldMap on the main file.
* Also note that it works the exact same way for tabular-mapped-as-worldmap
* files as well.
*/
private static boolean generateWorldMapThumbnail(StorageIO<DataFile> storageIO, int size) {
InputStream worldMapImageInputStream = null;
try {
storageIO.open();
Channel worldMapImageChannel = storageIO.openAuxChannel(WORLDMAP_IMAGE_SUFFIX);
if (worldMapImageChannel == null) {
logger.warning("Could not open channel for aux ." + WORLDMAP_IMAGE_SUFFIX + " object; (" + size + ")");
return false;
}
worldMapImageInputStream = Channels.newInputStream((ReadableByteChannel) worldMapImageChannel);
long worldMapImageSize = storageIO.getAuxObjectSize(WORLDMAP_IMAGE_SUFFIX);
if (isImageOverSizeLimit(worldMapImageSize)) {
logger.fine("WorldMap image too large - skipping");
worldMapImageInputStream.close();
return false;
}
} catch (FileNotFoundException fnfe) {
logger.fine("No .img file for this worldmap file yet; giving up. Original Error: " + fnfe);
return false;
} catch (IOException ioex) {
logger.warning("caught IOException trying to open an input stream for worldmap .img file (" + storageIO.getDataFile().getStorageIdentifier() + "). Original Error: " + ioex);
return false;
}
return generateImageThumbnailFromInputStream(storageIO, size, worldMapImageInputStream);
}
Aggregations