blob: e40c7794f159855c68a85afe6f6d4ffb66841fb9 [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.apache.chemistry.opencmis.inmemory.storedobj.impl;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.math.BigInteger;
import java.util.ArrayList;
import java.util.List;
import org.apache.chemistry.opencmis.commons.data.ContentStream;
import org.apache.chemistry.opencmis.commons.data.RenditionData;
import org.apache.chemistry.opencmis.commons.exceptions.CmisInvalidArgumentException;
import org.apache.chemistry.opencmis.commons.exceptions.CmisRuntimeException;
import org.apache.chemistry.opencmis.commons.impl.IOUtils;
import org.apache.chemistry.opencmis.commons.impl.dataobjects.RenditionDataImpl;
import org.apache.chemistry.opencmis.inmemory.storedobj.api.Content;
import org.apache.chemistry.opencmis.inmemory.storedobj.api.Folder;
import org.apache.chemistry.opencmis.inmemory.storedobj.api.StoredObject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class RenditionUtil {
private static final Logger LOG = LoggerFactory.getLogger(RenditionUtil.class.getName());
private static final int BUFFER_SIZE = 65536;
public static final String RENDITION_MIME_TYPE_JPEG = "image/jpeg";
public static final String RENDITION_MIME_TYPE_PNG = "image/png";
public static final String RENDITION_SUFFIX = "-rendition";
public static final int THUMBNAIL_SIZE = 100;
public static final int ICON_SIZE = 32;
public static boolean hasRendition(StoredObject so, String user) {
if (so instanceof Folder) {
return true;
} else if (so instanceof Content) {
ContentStream contentStream = ((Content)so).getContent();
if (null == contentStream) {
return false;
}
String mimeType = contentStream.getMimeType();
return isImage(mimeType) || isAudio(mimeType) || isVideo(mimeType) || isPDF(mimeType) || isPowerpoint(mimeType)
|| isExcel(mimeType) || isWord(mimeType) || isHtml(mimeType) || isPlainText(mimeType);
} else {
return false;
}
}
private static boolean isImage(String mimeType) {
return mimeType.startsWith("image/");
}
private static boolean isWord(String mimeType) {
return mimeType.equals("application/vnd.openxmlformats-officedocument.wordprocessingml.document")
|| mimeType.equals("application/ms-word");
}
private static boolean isExcel(String mimeType) {
return mimeType.equals("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet")
|| mimeType.equals("application/vnd.ms-excel");
}
private static boolean isPowerpoint(String mimeType) {
return mimeType.equals("application/vnd.openxmlformats-officedocument.presentationml.slideshow")
|| mimeType.equals("application/vnd.openxmlformats-officedocument.presentationml.presentation")
|| mimeType.equals("application/vnd.ms-powerpoint");
}
private static boolean isPDF(String mimeType) {
return mimeType.equals("application/pdf");
}
private static boolean isHtml(String mimeType) {
return mimeType.equals("text/html");
}
private static boolean isAudio(String mimeType) {
return mimeType.startsWith("audio/");
}
private static boolean isVideo(String mimeType) {
return mimeType.startsWith("video/");
}
private static boolean isPlainText(String mimeType) {
return mimeType.equals("text/plain");
}
public static ContentStream getIconFromResourceDir(String name) throws IOException {
InputStream imageStream = StoredObjectImpl.class.getResourceAsStream(name);
ByteArrayOutputStream ba = new ByteArrayOutputStream();
byte[] buffer = new byte[BUFFER_SIZE];
int noBytesRead = 0;
try {
while ((noBytesRead = imageStream.read(buffer)) >= 0) {
ba.write(buffer, 0, noBytesRead);
}
} finally {
IOUtils.closeQuietly(ba);
IOUtils.closeQuietly(imageStream);
}
ContentStreamDataImpl content = new ContentStreamDataImpl(0);
content.setFileName(name);
content.setMimeType("image/png");
content.setContent(new ByteArrayInputStream(ba.toByteArray()));
return content;
}
public static boolean testRenditionFilterForImage(String[] formats) {
if (formats.length == 1 && null != formats[0] && formats[0].equals("cmis:none")) {
return false;
} else {
return arrayContainsString(formats, "*") || arrayContainsString(formats, "image/*")
|| arrayContainsString(formats, "image/jpeg");
}
}
private static boolean arrayContainsString(String[] formats, String val) {
for (String s : formats) {
if (val.equals(s)) {
return true;
}
}
return false;
}
public static ContentStream getRenditionContent(StoredObject so, String streamId, long offset, long length) {
if (so instanceof Folder) {
return RenditionUtil.getFolderRenditionContent(streamId, offset, length);
}
if (!(so instanceof Content)) {
throw new CmisInvalidArgumentException("Only objects with content can have a rendition");
}
ContentStream contentStream = ((Content)so).getContent();
if (null == contentStream) {
return null;
}
String mimeType = contentStream.getMimeType();
try {
if (isImage(mimeType)) {
ImageThumbnailGenerator generator = new ImageThumbnailGenerator(contentStream.getStream());
return generator.getRendition(THUMBNAIL_SIZE, 0);
} else if (isAudio(mimeType)) {
return getIconFromResourceDir("/audio-x-generic.png");
} else if (isVideo(mimeType)) {
return getIconFromResourceDir("/video-x-generic.png");
} else if (isPDF(mimeType)) {
return getIconFromResourceDir("/application-pdf.png");
} else if (isWord(mimeType)) {
return getIconFromResourceDir("/application-msword.png");
} else if (isPowerpoint(mimeType)) {
return getIconFromResourceDir("/application-vnd.ms-powerpoint.png");
} else if (isExcel(mimeType)) {
return getIconFromResourceDir("/application-vnd.ms-excel.png");
} else if (isHtml(mimeType)) {
return getIconFromResourceDir("/text-html.png");
} else if (isPlainText(mimeType)) {
return getIconFromResourceDir("/text-x-generic.png");
} else {
return null;
}
} catch (IOException e) {
LOG.error("Failed to generate rendition: ", e);
throw new CmisRuntimeException("Failed to generate rendition: " + e);
}
}
private static ContentStream getFolderRenditionContent(String streamId, long offset, long length) {
try {
return getIconFromResourceDir("/folder.png");
} catch (IOException e) {
LOG.error("Failed to generate rendition: ", e);
throw new CmisRuntimeException("Failed to generate rendition: " + e);
}
}
public static List<RenditionData> getRenditions(StoredObject so, String renditionFilter, long maxItems, long skipCount) {
String tokenizer = "[\\s;]";
if (null == renditionFilter) {
return null;
}
String[] formats = renditionFilter.split(tokenizer);
boolean isImageRendition = RenditionUtil.testRenditionFilterForImage(formats);
if (!(so instanceof Content) && !(so instanceof Folder)) {
return null;
}
if (isImageRendition && hasRendition(so, null)) {
String mimeType;
if (so instanceof Folder) {
mimeType = "image/png";
} else {
ContentStream contentStream = ((Content)so).getContent();
mimeType = contentStream.getMimeType();
}
List<RenditionData> renditions = new ArrayList<RenditionData>(1);
RenditionDataImpl rendition = new RenditionDataImpl();
if (mimeType.equals("image/jpeg")) {
rendition.setBigHeight(BigInteger.valueOf(THUMBNAIL_SIZE));
rendition.setBigWidth(BigInteger.valueOf(THUMBNAIL_SIZE));
rendition.setMimeType(RENDITION_MIME_TYPE_JPEG);
} else {
rendition.setBigHeight(BigInteger.valueOf(ICON_SIZE));
rendition.setBigWidth(BigInteger.valueOf(ICON_SIZE));
rendition.setMimeType(RENDITION_MIME_TYPE_PNG);
}
rendition.setKind("cmis:thumbnail");
rendition.setRenditionDocumentId(so.getId());
rendition.setStreamId(so.getId() + RENDITION_SUFFIX);
rendition.setBigLength(BigInteger.valueOf(-1L));
rendition.setTitle(so.getName());
renditions.add(rendition);
return renditions;
} else {
return null;
}
}
}