Thumbanil API: suport for placeholder thumbnails added and queueing of thumbnails for creation on get

git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/alfresco/HEAD/root@9434 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261
This commit is contained in:
Roy Wetherall
2008-06-10 10:27:35 +00:00
parent 98df967450
commit 3febbb8396
4 changed files with 182 additions and 40 deletions

View File

@@ -1,8 +1,8 @@
<webscript kind="org.alfresco.repository.content.stream"> <webscript kind="org.alfresco.repository.content.stream">
<shortname>Thumbnails</shortname> <shortname>Thumbnails</shortname>
<description>Get a named thumbnail for a content resource</description> <description>Get a named thumbnail for a content resource</description>
<url>/api/node/{store_type}/{store_id}/{id}/content{property}/thumbnails/{thumbnailname}</url> <url>/api/node/{store_type}/{store_id}/{id}/content{property}/thumbnails/{thumbnailname}?qc={queuecreate?}&amp;ph={placeholder?}</url>
<url>/api/path/{store_type}/{store_id}/{id}/content{property}/thumbnails/{thumbnailname}</url> <url>/api/path/{store_type}/{store_id}/{id}/content{property}/thumbnails/{thumbnailname}?qc={queuecreate?}&amp;ph={placeholder?}</url>
<format default="">argument</format> <format default="">argument</format>
<authentication>guest</authentication> <authentication>guest</authentication>
<transaction>required</transaction> <transaction>required</transaction>

View File

@@ -22,17 +22,60 @@ function main()
return; return;
} }
// Get the queue create flag
var qc = false;
var qcString = args.qc;
if (qcString != null)
{
qc = utils.toBoolean(qcString);
}
// Get the place holder flag
var ph = false;
var phString = args.ph;
if (phString != null)
{
ph = utils.toBoolean(phString);
}
// Get the thumbnail // Get the thumbnail
var thumbnail = node.getThumbnail(thumbnailName); var thumbnail = node.getThumbnail(thumbnailName);
if (thumbnail == null) if (thumbnail == null)
{ {
// 404 since no thumbnail was found // Queue the creation of the thumbnail if appropriate
status.setCode(status.STATUS_NOT_FOUND, "Thumbnail was not found"); if (qc == true)
return; {
node.createThumbnail(thumbnailName, true);
}
if (ph == true)
{
// Try and get the place holder resource
var phPath = thumbnailService.getPlaceHolderResourcePath(thumbnailName);
if (phPath == null)
{
// 404 since no thumbnail was found
status.setCode(status.STATUS_NOT_FOUND, "Thumbnail was not found and no place holde resource set for '" + thumbnailName + "'");
return;
}
else
{
// Set the resouce path in the model ready for the content stream to send back to the client
model.contentPath = phPath;
}
}
else
{
// 404 since no thumbnail was found
status.setCode(status.STATUS_NOT_FOUND, "Thumbnail was not found");
return;
}
} }
else
// Place the details of the thumbnail into the model, this will be used to stream the content to the client {
model.contentNode = thumbnail; // Place the details of the thumbnail into the model, this will be used to stream the content to the client
model.contentNode = thumbnail;
}
} }
main(); main();

View File

@@ -24,7 +24,10 @@
*/ */
package org.alfresco.repo.web.scripts.content; package org.alfresco.repo.web.scripts.content;
import java.io.File;
import java.io.IOException; import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.Writer; import java.io.Writer;
import java.net.SocketException; import java.net.SocketException;
import java.util.Date; import java.util.Date;
@@ -36,6 +39,7 @@ import javax.servlet.http.HttpServletResponse;
import org.alfresco.model.ContentModel; import org.alfresco.model.ContentModel;
import org.alfresco.repo.content.MimetypeMap; import org.alfresco.repo.content.MimetypeMap;
import org.alfresco.repo.content.filestore.FileContentReader;
import org.alfresco.service.cmr.repository.ContentIOException; import org.alfresco.service.cmr.repository.ContentIOException;
import org.alfresco.service.cmr.repository.ContentReader; import org.alfresco.service.cmr.repository.ContentReader;
import org.alfresco.service.cmr.repository.ContentService; import org.alfresco.service.cmr.repository.ContentService;
@@ -45,6 +49,7 @@ import org.alfresco.service.cmr.repository.NodeService;
import org.alfresco.service.cmr.security.AccessStatus; import org.alfresco.service.cmr.security.AccessStatus;
import org.alfresco.service.cmr.security.PermissionService; import org.alfresco.service.cmr.security.PermissionService;
import org.alfresco.service.namespace.QName; import org.alfresco.service.namespace.QName;
import org.alfresco.util.TempFileProvider;
import org.alfresco.web.scripts.AbstractWebScript; import org.alfresco.web.scripts.AbstractWebScript;
import org.alfresco.web.scripts.Cache; import org.alfresco.web.scripts.Cache;
import org.alfresco.web.scripts.Container; import org.alfresco.web.scripts.Container;
@@ -59,6 +64,9 @@ import org.alfresco.web.scripts.servlet.WebScriptServletRequest;
import org.alfresco.web.scripts.servlet.WebScriptServletResponse; import org.alfresco.web.scripts.servlet.WebScriptServletResponse;
import org.apache.commons.logging.Log; import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory; import org.apache.commons.logging.LogFactory;
import org.springframework.util.FileCopyUtils;
import de.schlichtherle.io.FileOutputStream;
/** /**
* Web script 'type' that can be used when the binary data of a content property needs to be streamed back to the client * Web script 'type' that can be used when the binary data of a content property needs to be streamed back to the client
@@ -169,33 +177,44 @@ public class StreamContent extends AbstractWebScript
sendStatus(req, res, status, cache, format, templateModel); sendStatus(req, res, status, cache, format, templateModel);
} }
else else
{ {
// Get the content parameters from the model // Get the attachement property value
NodeRef nodeRef = (NodeRef)model.get("contentNode");
if (nodeRef == null)
{
throw new WebScriptException("The content node was not specified so the content cannot be streamed to the client");
}
QName propertyQName = null;
String contentProperty = (String)model.get("contentProperty");
if (contentProperty == null)
{
// default to the standard content property
propertyQName = ContentModel.PROP_CONTENT;
}
else
{
propertyQName = QName.createQName(contentProperty);
}
Boolean attachBoolean = (Boolean)model.get("attach"); Boolean attachBoolean = (Boolean)model.get("attach");
boolean attach = false; boolean attach = false;
if (attachBoolean != null) if (attachBoolean != null)
{ {
attach = attachBoolean.booleanValue(); attach = attachBoolean.booleanValue();
} }
// Stream the content String contentPath = (String)model.get("contentPath");
streamContent(req, res, nodeRef, propertyQName, attach); if (contentPath == null)
{
// Get the content parameters from the model
NodeRef nodeRef = (NodeRef)model.get("contentNode");
if (nodeRef == null)
{
throw new WebScriptException("The content node was not specified so the content cannot be streamed to the client");
}
QName propertyQName = null;
String contentProperty = (String)model.get("contentProperty");
if (contentProperty == null)
{
// default to the standard content property
propertyQName = ContentModel.PROP_CONTENT;
}
else
{
propertyQName = QName.createQName(contentProperty);
}
// Stream the content
streamContent(req, res, nodeRef, propertyQName, attach);
}
else
{
// Stream the content
streamContent(req, res, contentPath, attach);
}
} }
} }
catch(Throwable e) catch(Throwable e)
@@ -345,6 +364,72 @@ public class StreamContent extends AbstractWebScript
} }
} }
// get the content reader
ContentReader reader = contentService.getReader(nodeRef, propertyQName);
if (reader == null || !reader.exists())
{
throw new WebScriptException(HttpServletResponse.SC_NOT_FOUND, "Unable to locate content for node ref " + nodeRef + " (property: " + propertyQName.toString() + ")");
}
// Stream the cotent
streamContentImpl(req, res, reader, attach, modified);
}
/**
* Streams content back to client from a given resource path
*
* @param req
* @param res
* @param resourcePath
* @param attach
* @throws IOException
*/
protected void streamContent(WebScriptRequest req, WebScriptResponse res, String resourcePath, boolean attach)
throws IOException
{
String ext = "";
String mimetype = MimetypeMap.MIMETYPE_BINARY;
int extIndex = resourcePath.lastIndexOf('.');
if (extIndex != -1)
{
ext = resourcePath.substring(extIndex + 1);
String mt = mimetypeService.getMimetypesByExtension().get(ext);
if (mt != null)
{
mimetype = mt;
}
}
File file = TempFileProvider.createTempFile("streamContent-", ext);
InputStream is = this.getClass().getClassLoader().getResourceAsStream(resourcePath);
OutputStream os = new FileOutputStream(file);
FileCopyUtils.copy(is, os);
FileContentReader reader = new FileContentReader(file);
reader.setMimetype(mimetype);
reader.setEncoding("UTF-8");
streamContentImpl(req, res, reader, attach, new Date(file.lastModified()));
}
/**
* Stream content implementation
*
* @param req
* @param res
* @param reader
* @param attach
* @param modified
* @throws IOException
*/
protected void streamContentImpl(WebScriptRequest req, WebScriptResponse res, ContentReader reader, boolean attach, Date modified)
throws IOException
{
HttpServletRequest httpReq = ((WebScriptServletRequest)req).getHttpServletRequest();
HttpServletResponse httpRes = ((WebScriptServletResponse)res).getHttpServletResponse();
// handle attachment // handle attachment
if (attach == true) if (attach == true)
{ {
@@ -353,13 +438,6 @@ public class StreamContent extends AbstractWebScript
httpRes.setHeader("Content-Disposition", "attachment"); httpRes.setHeader("Content-Disposition", "attachment");
} }
// get the content reader
ContentReader reader = contentService.getReader(nodeRef, propertyQName);
if (reader == null || !reader.exists())
{
throw new WebScriptException(HttpServletResponse.SC_NOT_FOUND, "Unable to locate content for node ref " + nodeRef + " (property: " + propertyQName.toString() + ")");
}
// establish mimetype // establish mimetype
String mimetype = reader.getMimetype(); String mimetype = reader.getMimetype();
String extensionPath = req.getExtensionPath(); String extensionPath = req.getExtensionPath();
@@ -401,13 +479,12 @@ public class StreamContent extends AbstractWebScript
{ {
// the client cut the connection - our mission was accomplished apart from a little error message // the client cut the connection - our mission was accomplished apart from a little error message
if (logger.isInfoEnabled()) if (logger.isInfoEnabled())
logger.info("Client aborted stream read:\n\tnode: " + nodeRef + "\n\tcontent: " + reader); logger.info("Client aborted stream read:\n\tcontent: " + reader);
} }
catch (ContentIOException e2) catch (ContentIOException e2)
{ {
if (logger.isInfoEnabled()) if (logger.isInfoEnabled())
logger.info("Client aborted stream read:\n\tnode: " + nodeRef + "\n\tcontent: " + reader); logger.info("Client aborted stream read:\n\tcontent: " + reader);
} }
} }
} }

View File

@@ -131,7 +131,7 @@ public class ThumbnailServiceTest extends BaseWebScriptTest
public void testCreateAsyncThumbnail() throws Exception public void testCreateAsyncThumbnail() throws Exception
{ {
// Check for pdfToSWF transformation before doing test // Check for pdfToSWF transformation before doing test
if (this.contentService.getTransformer(MimetypeMap.MIMETYPE_PDF, MimetypeMap.MIMETYPE_FLASH) != null) if (this.contentService.getTransformer(MimetypeMap.MIMETYPE_PDF, MimetypeMap.MIMETYPE_FLASH) != null)
{ {
String url = "/api/node/" + pdfNode.getStoreRef().getProtocol() + "/" + pdfNode.getStoreRef().getIdentifier() + "/" + pdfNode.getId() + "/content/thumbnails?as=true"; String url = "/api/node/" + pdfNode.getStoreRef().getProtocol() + "/" + pdfNode.getStoreRef().getIdentifier() + "/" + pdfNode.getId() + "/content/thumbnails?as=true";
@@ -179,5 +179,27 @@ public class ThumbnailServiceTest extends BaseWebScriptTest
} }
} }
public void testPlaceHolder()
throws Exception
{
if (this.contentService.getTransformer(MimetypeMap.MIMETYPE_PDF, MimetypeMap.MIMETYPE_FLASH) != null)
{
// Check that there is no place holder set for webpreview
this.getRequest(getThumbnailsURL(pdfNode) + "/webpreview", 404);
this.getRequest(getThumbnailsURL(pdfNode) + "/webpreview?ph=true", 404);
}
// Check that here is a place holder for medium
this.getRequest(getThumbnailsURL(jpgNode) + "/medium", 404);
this.getRequest(getThumbnailsURL(jpgNode) + "/medium?ph=true", 200);
System.out.println(getThumbnailsURL(jpgNode) + "/medium?ph=true");
}
private String getThumbnailsURL(NodeRef nodeRef)
{
return "/api/node/" + nodeRef.getStoreRef().getProtocol() + "/" + nodeRef.getStoreRef().getIdentifier() + "/" + nodeRef.getId() + "/content/thumbnails";
}
} }