mirror of
https://github.com/Alfresco/alfresco-community-repo.git
synced 2025-08-14 17:58:59 +00:00
Merged THOR1_SPRINTS to HEAD
Performance improvement: prevent unnecessary 304 revalidation requests for thumbnails in detailed view of My-Documents and Recently Modified Documents dashlets Fixed bean config problem (caused by r34662) Fix build break Refactored revalidation code to remove previously added WebScripts that are now surplus to requirements Performance improvement: prevent unnecessary 304 revalidation for avatars on site colleagues dashlet Performance improvement: prevent unnecessary 304 revalidation for avatars on following/follwers pages Performance improvement: prevent unnecessary 304 revalidation for avatars in activity feeds Performance improvement: prevent unecessary 304 revalidation for user avatar thumbnails in header WebScript Prevent 304 revalidations for unchanged thumbnails in document library, web preview and search git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/alfresco/HEAD/root@34698 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261
This commit is contained in:
@@ -24,7 +24,9 @@
|
|||||||
"firstName": "${authority.properties.firstName!""}",
|
"firstName": "${authority.properties.firstName!""}",
|
||||||
"lastName": "${authority.properties.lastName!""}",
|
"lastName": "${authority.properties.lastName!""}",
|
||||||
<#if authority.assocs["cm:avatar"]??>
|
<#if authority.assocs["cm:avatar"]??>
|
||||||
"avatar": "${"api/node/" + authority.assocs["cm:avatar"][0].nodeRef?string?replace('://','/') + "/content/thumbnails/avatar"}",
|
<#assign avatarNodeRef>${authority.assocs["cm:avatar"][0].nodeRef?string?replace('://','/')}</#assign>
|
||||||
|
"avatar": "${"api/node/" + avatarNodeRef + "/content/thumbnails/avatar"}",
|
||||||
|
"avatarNode": "${avatarNodeRef}",
|
||||||
</#if>
|
</#if>
|
||||||
<#if authority.properties.jobtitle??>
|
<#if authority.properties.jobtitle??>
|
||||||
"jobtitle": "${authority.properties.jobtitle}",
|
"jobtitle": "${authority.properties.jobtitle}",
|
||||||
|
@@ -7,6 +7,7 @@
|
|||||||
Please note that Alfresco does not currently use the filename template-arg and that it will be ignored.
|
Please note that Alfresco does not currently use the filename template-arg and that it will be ignored.
|
||||||
Therefore a GET to these URLs will return the same resource as to the equivalent URLs without it.
|
Therefore a GET to these URLs will return the same resource as to the equivalent URLs without it.
|
||||||
</description>
|
</description>
|
||||||
|
<url>/api/node/{store_type}/{store_id}/{id}/content{property}/thumbnails/{thumbnailname}?c={queueforcecreate?}&ph={placeholder?}&lastModified={modified?}</url>
|
||||||
<url>/api/node/{store_type}/{store_id}/{id}/content{property}/thumbnails/{thumbnailname}?c={queueforcecreate?}&ph={placeholder?}</url>
|
<url>/api/node/{store_type}/{store_id}/{id}/content{property}/thumbnails/{thumbnailname}?c={queueforcecreate?}&ph={placeholder?}</url>
|
||||||
<url>/api/path/{store_type}/{store_id}/{id}/content{property}/thumbnails/{thumbnailname}?c={queueforcecreate?}&ph={placeholder?}</url>
|
<url>/api/path/{store_type}/{store_id}/{id}/content{property}/thumbnails/{thumbnailname}?c={queueforcecreate?}&ph={placeholder?}</url>
|
||||||
<url>/api/node/{store_type}/{store_id}/{id}/content{property}/thumbnails/{thumbnailname}/{filename}?c={queueforcecreate?}&ph={placeholder?}</url>
|
<url>/api/node/{store_type}/{store_id}/{id}/content{property}/thumbnails/{thumbnailname}/{filename}?c={queueforcecreate?}&ph={placeholder?}</url>
|
||||||
|
@@ -1,5 +1,17 @@
|
|||||||
function main()
|
function main()
|
||||||
{
|
{
|
||||||
|
// Indicate whether or not the thumbnail can be cached by the browser. Caching is allowed if the lastModified
|
||||||
|
// argument is provided as this is an indication of request uniqueness and therefore the browser will have
|
||||||
|
// the latest thumbnail image.
|
||||||
|
if (args.lastModified != null)
|
||||||
|
{
|
||||||
|
model.allowBrowserToCache = "true";
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
model.allowBrowserToCache = "false";
|
||||||
|
}
|
||||||
|
|
||||||
// Get the node from the URL
|
// Get the node from the URL
|
||||||
var pathSegments = url.match.split("/");
|
var pathSegments = url.match.split("/");
|
||||||
var reference = [ url.templateArgs.store_type, url.templateArgs.store_id ].concat(url.templateArgs.id.split("/"));
|
var reference = [ url.templateArgs.store_type, url.templateArgs.store_id ].concat(url.templateArgs.id.split("/"));
|
||||||
|
@@ -47,6 +47,13 @@
|
|||||||
"modifiedOn": "<@dateFormat node.properties.modified />",
|
"modifiedOn": "<@dateFormat node.properties.modified />",
|
||||||
"modifiedBy": "${modifiedBy}",
|
"modifiedBy": "${modifiedBy}",
|
||||||
"modifiedByUser": "${modifiedByUser}",
|
"modifiedByUser": "${modifiedByUser}",
|
||||||
|
<#if node.hasAspect("cm:thumbnailModification")>
|
||||||
|
<#list node.properties.lastThumbnailModification as thumbnailMod>
|
||||||
|
<#if thumbnailMod?contains("doclib")>
|
||||||
|
"lastThumbnailModification": "${thumbnailMod}",
|
||||||
|
</#if>
|
||||||
|
</#list>
|
||||||
|
</#if>
|
||||||
"lockedBy": "${lockedBy}",
|
"lockedBy": "${lockedBy}",
|
||||||
"lockedByUser": "${lockedByUser}",
|
"lockedByUser": "${lockedByUser}",
|
||||||
"size": "${node.size?c}",
|
"size": "${node.size?c}",
|
||||||
|
@@ -3,6 +3,10 @@
|
|||||||
<description>
|
<description>
|
||||||
Returns a user avatar image in the format specified by the thumbnailname, or the "avatar" preset if omitted.
|
Returns a user avatar image in the format specified by the thumbnailname, or the "avatar" preset if omitted.
|
||||||
</description>
|
</description>
|
||||||
|
<url>/slingshot/profile/avatar/avatar</url>
|
||||||
|
<url>/slingshot/profile/avatar/avatar/thumbnail/{thumbnailname}</url>
|
||||||
|
<url>/slingshot/profile/avatar/{store_type}/{store_id}/{id}/thumbnail/{thumbnailname}</url>
|
||||||
|
<url>/slingshot/profile/avatar/{store_type}/{store_id}/{id}</url>
|
||||||
<url>/slingshot/profile/avatar/{username}/thumbnail/{thumbnailname}</url>
|
<url>/slingshot/profile/avatar/{username}/thumbnail/{thumbnailname}</url>
|
||||||
<url>/slingshot/profile/avatar/{username}</url>
|
<url>/slingshot/profile/avatar/{username}</url>
|
||||||
<format default="">argument</format>
|
<format default="">argument</format>
|
||||||
|
@@ -24,21 +24,51 @@ function main()
|
|||||||
{
|
{
|
||||||
var userName = url.templateArgs.username,
|
var userName = url.templateArgs.username,
|
||||||
thumbnailName = url.templateArgs.thumbnailname || "avatar",
|
thumbnailName = url.templateArgs.thumbnailname || "avatar",
|
||||||
person = people.getPerson(userName);
|
avatarNode;
|
||||||
|
|
||||||
|
// If there is no store type, store id or id on the request then this WebScript has most likely been requested
|
||||||
|
// for a user with no avatar image so we will just return the placeholder image.
|
||||||
|
if (userName == null && url.templateArgs.store_type == null && url.templateArgs.store_id == null && url.templateArgs.id == null)
|
||||||
|
{
|
||||||
|
// If there is no userName or nodeRef data then we want to return the browser cacheable placeholder...
|
||||||
|
model.contentPath = getPlaceholder(thumbnailName);
|
||||||
|
model.allowBrowserToCache = "true";
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
else if (url.templateArgs.store_type == null && url.templateArgs.store_id == null && url.templateArgs.id == null)
|
||||||
|
{
|
||||||
|
// There is no nodeRef data but there is a username... this should return the user image that needs revalidation
|
||||||
|
var person = people.getPerson(userName);
|
||||||
if (person == null)
|
if (person == null)
|
||||||
{
|
{
|
||||||
// Stream the placeholder image
|
// Stream the placeholder image
|
||||||
model.contentPath = getPlaceholder(thumbnailName);
|
model.contentPath = getPlaceholder(thumbnailName);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
// Retrieve the avatar NodeRef for this person, if there is one.
|
// Retrieve the avatar NodeRef for this person, if there is one.
|
||||||
var avatarAssoc = person.assocs["cm:avatar"];
|
var avatarAssoc = person.assocs["cm:avatar"];
|
||||||
|
|
||||||
if (avatarAssoc != null)
|
if (avatarAssoc != null)
|
||||||
{
|
{
|
||||||
var avatarNode = avatarAssoc[0];
|
avatarNode = avatarAssoc[0];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (userName == null)
|
||||||
|
{
|
||||||
|
// There is no user name but there is nodeREf data... this should return the image that CAN be cached by the browser
|
||||||
|
model.allowBrowserToCache = "true";
|
||||||
|
avatarNode = search.findNode(url.templateArgs.store_type + "://" + url.templateArgs.store_id + "/" + url.templateArgs.id);
|
||||||
|
if (avatarNode == null)
|
||||||
|
{
|
||||||
|
// Stream the placeholder image if the avatar node cannot be found.
|
||||||
|
model.contentPath = getPlaceholder(thumbnailName);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get the thumbnail for the avatar...
|
||||||
if (avatarNode != null)
|
if (avatarNode != null)
|
||||||
{
|
{
|
||||||
// Get the thumbnail
|
// Get the thumbnail
|
||||||
@@ -66,7 +96,6 @@ function main()
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
// Stream the placeholder image
|
// Stream the placeholder image
|
||||||
model.contentPath = getPlaceholder(thumbnailName);
|
model.contentPath = getPlaceholder(thumbnailName);
|
||||||
|
@@ -197,12 +197,12 @@ public class StreamContent extends AbstractWebScript implements ResourceLoaderAw
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Stream the content
|
// Stream the content
|
||||||
streamContent(req, res, nodeRef, propertyQName, attach);
|
streamContent(req, res, nodeRef, propertyQName, attach, model);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// Stream the content
|
// Stream the content
|
||||||
streamContent(req, res, contentPath, attach);
|
streamContent(req, res, contentPath, attach, model);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -309,10 +309,33 @@ public class StreamContent extends AbstractWebScript implements ResourceLoaderAw
|
|||||||
* @param attach Indicates whether the content should be streamed as an attachment or not
|
* @param attach Indicates whether the content should be streamed as an attachment or not
|
||||||
* @throws IOException
|
* @throws IOException
|
||||||
*/
|
*/
|
||||||
protected void streamContent(WebScriptRequest req, WebScriptResponse res, NodeRef nodeRef, QName propertyQName,
|
protected void streamContent(WebScriptRequest req,
|
||||||
|
WebScriptResponse res,
|
||||||
|
NodeRef nodeRef,
|
||||||
|
QName propertyQName,
|
||||||
boolean attach) throws IOException
|
boolean attach) throws IOException
|
||||||
{
|
{
|
||||||
streamContent(req, res, nodeRef, propertyQName, attach, null);
|
streamContent(req, res, nodeRef, propertyQName, attach, null, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Streams the content on a given node's content property to the response of the web script.
|
||||||
|
*
|
||||||
|
* @param req Request
|
||||||
|
* @param res Response
|
||||||
|
* @param nodeRef The node reference
|
||||||
|
* @param propertyQName The content property name
|
||||||
|
* @param attach Indicates whether the content should be streamed as an attachment or not
|
||||||
|
* @throws IOException
|
||||||
|
*/
|
||||||
|
protected void streamContent(WebScriptRequest req,
|
||||||
|
WebScriptResponse res,
|
||||||
|
NodeRef nodeRef,
|
||||||
|
QName propertyQName,
|
||||||
|
boolean attach,
|
||||||
|
Map<String, Object> model) throws IOException
|
||||||
|
{
|
||||||
|
streamContent(req, res, nodeRef, propertyQName, attach, null, model);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -326,8 +349,33 @@ public class StreamContent extends AbstractWebScript implements ResourceLoaderAw
|
|||||||
* @param attachFileName Optional file name to use when attach is <code>true</code>
|
* @param attachFileName Optional file name to use when attach is <code>true</code>
|
||||||
* @throws IOException
|
* @throws IOException
|
||||||
*/
|
*/
|
||||||
protected void streamContent(WebScriptRequest req, WebScriptResponse res, NodeRef nodeRef, QName propertyQName,
|
protected void streamContent(WebScriptRequest req,
|
||||||
boolean attach, String attachFileName) throws IOException
|
WebScriptResponse res,
|
||||||
|
NodeRef nodeRef,
|
||||||
|
QName propertyQName,
|
||||||
|
boolean attach,
|
||||||
|
String attachFileName) throws IOException
|
||||||
|
{
|
||||||
|
streamContent(req, res, nodeRef, propertyQName, attach, attachFileName, null);
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* Streams the content on a given node's content property to the response of the web script.
|
||||||
|
*
|
||||||
|
* @param req Request
|
||||||
|
* @param res Response
|
||||||
|
* @param nodeRef The node reference
|
||||||
|
* @param propertyQName The content property name
|
||||||
|
* @param attach Indicates whether the content should be streamed as an attachment or not
|
||||||
|
* @param attachFileName Optional file name to use when attach is <code>true</code>
|
||||||
|
* @throws IOException
|
||||||
|
*/
|
||||||
|
protected void streamContent(WebScriptRequest req,
|
||||||
|
WebScriptResponse res,
|
||||||
|
NodeRef nodeRef,
|
||||||
|
QName propertyQName,
|
||||||
|
boolean attach,
|
||||||
|
String attachFileName,
|
||||||
|
Map<String, Object> model) throws IOException
|
||||||
{
|
{
|
||||||
if (logger.isDebugEnabled())
|
if (logger.isDebugEnabled())
|
||||||
logger.debug("Retrieving content from node ref " + nodeRef.toString() + " (property: " + propertyQName.toString() + ") (attach: " + attach + ")");
|
logger.debug("Retrieving content from node ref " + nodeRef.toString() + " (property: " + propertyQName.toString() + ") (attach: " + attach + ")");
|
||||||
@@ -381,7 +429,7 @@ public class StreamContent extends AbstractWebScript implements ResourceLoaderAw
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Stream the content
|
// Stream the content
|
||||||
streamContentImpl(req, res, reader, attach, modified, modified == null ? null : String.valueOf(modified.getTime()), attachFileName);
|
streamContentImpl(req, res, reader, attach, modified, modified == null ? null : String.valueOf(modified.getTime()), attachFileName, model);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -393,10 +441,30 @@ public class StreamContent extends AbstractWebScript implements ResourceLoaderAw
|
|||||||
* @param attach Indicates whether the content should be streamed as an attachment or not
|
* @param attach Indicates whether the content should be streamed as an attachment or not
|
||||||
* @throws IOException
|
* @throws IOException
|
||||||
*/
|
*/
|
||||||
protected void streamContent(WebScriptRequest req, WebScriptResponse res, String resourcePath,
|
protected void streamContent(WebScriptRequest req,
|
||||||
|
WebScriptResponse res,
|
||||||
|
String resourcePath,
|
||||||
boolean attach) throws IOException
|
boolean attach) throws IOException
|
||||||
{
|
{
|
||||||
streamContent(req, res, resourcePath, attach, null);
|
streamContent(req, res, resourcePath, attach, null, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Streams content back to client from a given resource path.
|
||||||
|
*
|
||||||
|
* @param req The request
|
||||||
|
* @param res The response
|
||||||
|
* @param resourcePath The classpath resource path the content is required for
|
||||||
|
* @param attach Indicates whether the content should be streamed as an attachment or not
|
||||||
|
* @throws IOException
|
||||||
|
*/
|
||||||
|
protected void streamContent(WebScriptRequest req,
|
||||||
|
WebScriptResponse res,
|
||||||
|
String resourcePath,
|
||||||
|
boolean attach,
|
||||||
|
Map<String, Object> model) throws IOException
|
||||||
|
{
|
||||||
|
streamContent(req, res, resourcePath, attach, null, model);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -409,8 +477,30 @@ public class StreamContent extends AbstractWebScript implements ResourceLoaderAw
|
|||||||
* @param attachFileName Optional file name to use when attach is <code>true</code>
|
* @param attachFileName Optional file name to use when attach is <code>true</code>
|
||||||
* @throws IOException
|
* @throws IOException
|
||||||
*/
|
*/
|
||||||
protected void streamContent(WebScriptRequest req, WebScriptResponse res, String resourcePath,
|
protected void streamContent(WebScriptRequest req,
|
||||||
boolean attach, String attachFileName) throws IOException
|
WebScriptResponse res,
|
||||||
|
String resourcePath,
|
||||||
|
boolean attach,
|
||||||
|
String attachFileName) throws IOException
|
||||||
|
{
|
||||||
|
streamContent(req, res, resourcePath, attach, attachFileName, null);
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* Streams content back to client from a given resource path.
|
||||||
|
*
|
||||||
|
* @param req The request
|
||||||
|
* @param res The response
|
||||||
|
* @param resourcePath The classpath resource path the content is required for.
|
||||||
|
* @param attach Indicates whether the content should be streamed as an attachment or not
|
||||||
|
* @param attachFileName Optional file name to use when attach is <code>true</code>
|
||||||
|
* @throws IOException
|
||||||
|
*/
|
||||||
|
protected void streamContent(WebScriptRequest req,
|
||||||
|
WebScriptResponse res,
|
||||||
|
String resourcePath,
|
||||||
|
boolean attach,
|
||||||
|
String attachFileName,
|
||||||
|
Map<String, Object> model) throws IOException
|
||||||
{
|
{
|
||||||
if (logger.isDebugEnabled())
|
if (logger.isDebugEnabled())
|
||||||
logger.debug("Retrieving content from resource path " + resourcePath + " (attach: " + attach + ")");
|
logger.debug("Retrieving content from resource path " + resourcePath + " (attach: " + attach + ")");
|
||||||
@@ -437,7 +527,7 @@ public class StreamContent extends AbstractWebScript implements ResourceLoaderAw
|
|||||||
FileCopyUtils.copy(is, os);
|
FileCopyUtils.copy(is, os);
|
||||||
|
|
||||||
// stream the contents of the file, but using the modifiedDate of the original resource.
|
// stream the contents of the file, but using the modifiedDate of the original resource.
|
||||||
streamContent(req, res, file, resourceLastModified, attach, attachFileName);
|
streamContent(req, res, file, resourceLastModified, attach, attachFileName, model);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -449,10 +539,30 @@ public class StreamContent extends AbstractWebScript implements ResourceLoaderAw
|
|||||||
* @param attach Indicates whether the content should be streamed as an attachment or not
|
* @param attach Indicates whether the content should be streamed as an attachment or not
|
||||||
* @throws IOException
|
* @throws IOException
|
||||||
*/
|
*/
|
||||||
protected void streamContent(WebScriptRequest req, WebScriptResponse res, File file, boolean attach)
|
protected void streamContent(WebScriptRequest req,
|
||||||
throws IOException
|
WebScriptResponse res,
|
||||||
|
File file,
|
||||||
|
boolean attach) throws IOException
|
||||||
{
|
{
|
||||||
streamContent(req, res, file, attach, null);
|
streamContent(req, res, file, attach, null, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Streams content back to client from a given resource path.
|
||||||
|
*
|
||||||
|
* @param req The request
|
||||||
|
* @param res The response
|
||||||
|
* @param resourcePath The resource path the content is required for
|
||||||
|
* @param attach Indicates whether the content should be streamed as an attachment or not
|
||||||
|
* @throws IOException
|
||||||
|
*/
|
||||||
|
protected void streamContent(WebScriptRequest req,
|
||||||
|
WebScriptResponse res,
|
||||||
|
File file,
|
||||||
|
boolean attach,
|
||||||
|
Map<String, Object> model) throws IOException
|
||||||
|
{
|
||||||
|
streamContent(req, res, file, attach, null, model);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -466,10 +576,34 @@ public class StreamContent extends AbstractWebScript implements ResourceLoaderAw
|
|||||||
* @param attachFileName Optional file name to use when attach is <code>true</code>
|
* @param attachFileName Optional file name to use when attach is <code>true</code>
|
||||||
* @throws IOException
|
* @throws IOException
|
||||||
*/
|
*/
|
||||||
protected void streamContent(WebScriptRequest req, WebScriptResponse res, File file, boolean attach,
|
protected void streamContent(WebScriptRequest req,
|
||||||
|
WebScriptResponse res,
|
||||||
|
File file,
|
||||||
|
boolean attach,
|
||||||
String attachFileName) throws IOException
|
String attachFileName) throws IOException
|
||||||
{
|
{
|
||||||
streamContent(req, res, file, null, attach, attachFileName);
|
streamContent(req, res, file, null, attach, attachFileName, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Streams content back to client from a given File. The Last-Modified header will reflect the
|
||||||
|
* given file's modification timestamp.
|
||||||
|
*
|
||||||
|
* @param req The request
|
||||||
|
* @param res The response
|
||||||
|
* @param file The file whose content is to be streamed.
|
||||||
|
* @param attach Indicates whether the content should be streamed as an attachment or not
|
||||||
|
* @param attachFileName Optional file name to use when attach is <code>true</code>
|
||||||
|
* @throws IOException
|
||||||
|
*/
|
||||||
|
protected void streamContent(WebScriptRequest req,
|
||||||
|
WebScriptResponse res,
|
||||||
|
File file,
|
||||||
|
boolean attach,
|
||||||
|
String attachFileName,
|
||||||
|
Map<String, Object> model) throws IOException
|
||||||
|
{
|
||||||
|
streamContent(req, res, file, null, attach, attachFileName, model);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -484,8 +618,34 @@ public class StreamContent extends AbstractWebScript implements ResourceLoaderAw
|
|||||||
* @param attachFileName Optional file name to use when attach is <code>true</code>
|
* @param attachFileName Optional file name to use when attach is <code>true</code>
|
||||||
* @throws IOException
|
* @throws IOException
|
||||||
*/
|
*/
|
||||||
protected void streamContent(WebScriptRequest req, WebScriptResponse res, File file, Long modifiedTime,
|
protected void streamContent(WebScriptRequest req,
|
||||||
boolean attach, String attachFileName) throws IOException
|
WebScriptResponse res,
|
||||||
|
File file,
|
||||||
|
Long modifiedTime,
|
||||||
|
boolean attach,
|
||||||
|
String attachFileName) throws IOException
|
||||||
|
{
|
||||||
|
streamContent(req, res, file, modifiedTime, attach, attachFileName, null);
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* Streams content back to client from a given File.
|
||||||
|
*
|
||||||
|
* @param req The request
|
||||||
|
* @param res The response
|
||||||
|
* @param file The file whose content is to be streamed.
|
||||||
|
* @param modifiedTime The modified datetime to use for the streamed content. If <tt>null</tt> the
|
||||||
|
* file's timestamp will be used.
|
||||||
|
* @param attach Indicates whether the content should be streamed as an attachment or not
|
||||||
|
* @param attachFileName Optional file name to use when attach is <code>true</code>
|
||||||
|
* @throws IOException
|
||||||
|
*/
|
||||||
|
protected void streamContent(WebScriptRequest req,
|
||||||
|
WebScriptResponse res,
|
||||||
|
File file,
|
||||||
|
Long modifiedTime,
|
||||||
|
boolean attach,
|
||||||
|
String attachFileName,
|
||||||
|
Map<String, Object> model) throws IOException
|
||||||
{
|
{
|
||||||
if (logger.isDebugEnabled())
|
if (logger.isDebugEnabled())
|
||||||
logger.debug("Retrieving content from file " + file.getAbsolutePath() + " (attach: " + attach + ")");
|
logger.debug("Retrieving content from file " + file.getAbsolutePath() + " (attach: " + attach + ")");
|
||||||
@@ -507,8 +667,7 @@ public class StreamContent extends AbstractWebScript implements ResourceLoaderAw
|
|||||||
long lastModified = modifiedTime == null ? file.lastModified() : modifiedTime;
|
long lastModified = modifiedTime == null ? file.lastModified() : modifiedTime;
|
||||||
Date lastModifiedDate = new Date(lastModified);
|
Date lastModifiedDate = new Date(lastModified);
|
||||||
|
|
||||||
streamContentImpl(req, res, reader, attach, lastModifiedDate,
|
streamContentImpl(req, res, reader, attach, lastModifiedDate, String.valueOf(lastModifiedDate.getTime()), attachFileName, model);
|
||||||
String.valueOf(lastModifiedDate.getTime()), attachFileName);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -523,8 +682,36 @@ public class StreamContent extends AbstractWebScript implements ResourceLoaderAw
|
|||||||
* @param attachFileName Optional file name to use when attach is <code>true</code>
|
* @param attachFileName Optional file name to use when attach is <code>true</code>
|
||||||
* @throws IOException
|
* @throws IOException
|
||||||
*/
|
*/
|
||||||
protected void streamContentImpl(WebScriptRequest req, WebScriptResponse res, ContentReader reader, boolean attach,
|
protected void streamContentImpl(WebScriptRequest req,
|
||||||
Date modified, String eTag, String attachFileName) throws IOException
|
WebScriptResponse res,
|
||||||
|
ContentReader reader,
|
||||||
|
boolean attach,
|
||||||
|
Date modified,
|
||||||
|
String eTag,
|
||||||
|
String attachFileName) throws IOException
|
||||||
|
{
|
||||||
|
streamContentImpl(req, res, reader, attach, modified, eTag, attachFileName, null);
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* Stream content implementation
|
||||||
|
*
|
||||||
|
* @param req The request
|
||||||
|
* @param res The response
|
||||||
|
* @param reader The reader
|
||||||
|
* @param attach Indicates whether the content should be streamed as an attachment or not
|
||||||
|
* @param modified Modified date of content
|
||||||
|
* @param eTag ETag to use
|
||||||
|
* @param attachFileName Optional file name to use when attach is <code>true</code>
|
||||||
|
* @throws IOException
|
||||||
|
*/
|
||||||
|
protected void streamContentImpl(WebScriptRequest req,
|
||||||
|
WebScriptResponse res,
|
||||||
|
ContentReader reader,
|
||||||
|
boolean attach,
|
||||||
|
Date modified,
|
||||||
|
String eTag,
|
||||||
|
String attachFileName,
|
||||||
|
Map<String, Object> model) throws IOException
|
||||||
{
|
{
|
||||||
setAttachment(res, attach, attachFileName);
|
setAttachment(res, attach, attachFileName);
|
||||||
|
|
||||||
@@ -548,13 +735,7 @@ public class StreamContent extends AbstractWebScript implements ResourceLoaderAw
|
|||||||
res.setHeader("Content-Length", Long.toString(reader.getSize()));
|
res.setHeader("Content-Length", Long.toString(reader.getSize()));
|
||||||
|
|
||||||
// set caching
|
// set caching
|
||||||
Cache cache = new Cache();
|
setResponseCache(res, modified, eTag, model);
|
||||||
cache.setNeverCache(false);
|
|
||||||
cache.setMustRevalidate(true);
|
|
||||||
cache.setMaxAge(0L);
|
|
||||||
cache.setLastModified(modified);
|
|
||||||
cache.setETag(eTag);
|
|
||||||
res.setCache(cache);
|
|
||||||
|
|
||||||
// get the content and stream directly to the response output stream
|
// get the content and stream directly to the response output stream
|
||||||
// assuming the repository is capable of streaming in chunks, this should allow large files
|
// assuming the repository is capable of streaming in chunks, this should allow large files
|
||||||
@@ -576,6 +757,36 @@ public class StreamContent extends AbstractWebScript implements ResourceLoaderAw
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the cache settings on the response
|
||||||
|
*
|
||||||
|
* @param res
|
||||||
|
* @param modified
|
||||||
|
* @param eTag
|
||||||
|
*/
|
||||||
|
protected void setResponseCache(WebScriptResponse res, Date modified, String eTag, Map<String, Object> model)
|
||||||
|
{
|
||||||
|
Cache cache = new Cache();
|
||||||
|
if (model == null || model.get("allowBrowserToCache") == null || ((String)model.get("allowBrowserToCache")).equals("false"))
|
||||||
|
{
|
||||||
|
cache.setNeverCache(false);
|
||||||
|
cache.setMustRevalidate(true);
|
||||||
|
cache.setMaxAge(0L);
|
||||||
|
cache.setLastModified(modified);
|
||||||
|
cache.setETag(eTag);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
cache.setNeverCache(false);
|
||||||
|
cache.setMustRevalidate(false);
|
||||||
|
cache.setMaxAge(Long.MAX_VALUE);
|
||||||
|
cache.setLastModified(modified);
|
||||||
|
cache.setETag(eTag);
|
||||||
|
res.setCache(cache);
|
||||||
|
}
|
||||||
|
res.setCache(cache);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set attachment header
|
* Set attachment header
|
||||||
*
|
*
|
||||||
|
@@ -26,6 +26,7 @@ import java.util.List;
|
|||||||
|
|
||||||
import org.alfresco.model.ContentModel;
|
import org.alfresco.model.ContentModel;
|
||||||
import org.alfresco.query.PagingRequest;
|
import org.alfresco.query.PagingRequest;
|
||||||
|
import org.alfresco.service.cmr.repository.AssociationRef;
|
||||||
import org.alfresco.service.cmr.repository.NodeRef;
|
import org.alfresco.service.cmr.repository.NodeRef;
|
||||||
import org.alfresco.service.cmr.repository.NodeService;
|
import org.alfresco.service.cmr.repository.NodeService;
|
||||||
import org.alfresco.service.cmr.security.NoSuchPersonException;
|
import org.alfresco.service.cmr.security.NoSuchPersonException;
|
||||||
@@ -174,6 +175,18 @@ public abstract class AbstractSubscriptionServiceWebScript extends AbstractWebSc
|
|||||||
result.put("userStatusTime", statusTimeJson);
|
result.put("userStatusTime", statusTimeJson);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Get the avatar for the user id if one is available
|
||||||
|
List<AssociationRef> assocRefs = this.nodeService.getTargetAssocs(node, ContentModel.ASSOC_AVATAR);
|
||||||
|
if (!assocRefs.isEmpty())
|
||||||
|
{
|
||||||
|
NodeRef avatarNodeRef = assocRefs.get(0).getTargetRef();
|
||||||
|
result.put("avatar", avatarNodeRef.toString());
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
result.put("avatar", "avatar"); // This indicates to just use a placeholder
|
||||||
|
}
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user