mirror of
https://github.com/Alfresco/alfresco-community-repo.git
synced 2025-08-21 18:09:20 +00:00
Merged HEAD-BUG-FIX (5.1/Cloud) to HEAD (5.1/Cloud)
101299: Merge RA-SPRINT2 to HEAD-BUG-FIX (5.1) 99851: RA-61: move /slingshot/documentlibrary-v2 webscripts. git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/alfresco/HEAD/root@101442 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261
This commit is contained in:
@@ -1,12 +0,0 @@
|
|||||||
<webscript>
|
|
||||||
<shortname>doclist-v2</shortname>
|
|
||||||
<description>Document List v2 Component - doclist data webscript</description>
|
|
||||||
<url>/slingshot/doclib2/doclist/{type}/site/{site}/{container}/{path}</url>
|
|
||||||
<url>/slingshot/doclib2/doclist/{type}/site/{site}/{container}</url>
|
|
||||||
<url>/slingshot/doclib2/doclist/{type}/node/{store_type}/{store_id}/{id}/{path}</url>
|
|
||||||
<url>/slingshot/doclib2/doclist/{type}/node/{store_type}/{store_id}/{id}</url>
|
|
||||||
<format default="json">argument</format>
|
|
||||||
<authentication>user</authentication>
|
|
||||||
<transaction allow="readonly">required</transaction>
|
|
||||||
<lifecycle>internal</lifecycle>
|
|
||||||
</webscript>
|
|
@@ -1,9 +0,0 @@
|
|||||||
<import resource="classpath:/alfresco/templates/webscripts/org/alfresco/slingshot/documentlibrary-v2/evaluator.lib.js">
|
|
||||||
<import resource="classpath:/alfresco/templates/webscripts/org/alfresco/slingshot/documentlibrary-v2/filters.lib.js">
|
|
||||||
<import resource="classpath:/alfresco/templates/webscripts/org/alfresco/slingshot/documentlibrary-v2/parse-args.lib.js">
|
|
||||||
<import resource="classpath:/alfresco/templates/webscripts/org/alfresco/slingshot/documentlibrary-v2/doclist.lib.js">
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Document List Component: doclist
|
|
||||||
*/
|
|
||||||
model.doclist = doclist_main();
|
|
@@ -1,35 +0,0 @@
|
|||||||
<#import "item.lib.ftl" as itemLib />
|
|
||||||
<#assign workingCopyLabel = " " + message("coci_service.working_copy_label")>
|
|
||||||
<#escape x as jsonUtils.encodeJSONString(x)>
|
|
||||||
{
|
|
||||||
"totalRecords": ${doclist.paging.totalRecords?c},
|
|
||||||
<#if doclist.paging.totalRecordsUpper??>
|
|
||||||
"totalRecordsUpper": ${doclist.paging.totalRecordsUpper?c},
|
|
||||||
</#if>
|
|
||||||
"startIndex": ${doclist.paging.startIndex?c},
|
|
||||||
"metadata":
|
|
||||||
{
|
|
||||||
"repositoryId": "${server.id}",
|
|
||||||
<#if (doclist.container.nodeRef)??>"container": "${doclist.container.nodeRef}",</#if>
|
|
||||||
<#if (doclist.parent.nodeJSON)??>"parent": <#noescape>${doclist.parent.nodeJSON},</#noescape></#if>
|
|
||||||
<#if doclist.customJSON??>"custom": <#noescape>${doclist.customJSON},</#noescape></#if>
|
|
||||||
"onlineEditing": ${doclist.onlineEditing?string},
|
|
||||||
"itemCounts":
|
|
||||||
{
|
|
||||||
"folders": ${(doclist.itemCount.folders!0)?c},
|
|
||||||
"documents": ${(doclist.itemCount.documents!0)?c}
|
|
||||||
},
|
|
||||||
"workingCopyLabel": "${workingCopyLabel}"
|
|
||||||
},
|
|
||||||
"items":
|
|
||||||
[
|
|
||||||
<#list doclist.items as item>
|
|
||||||
{
|
|
||||||
"node": <#noescape>${item.nodeJSON}</#noescape>,
|
|
||||||
<#if item.parent??>"parent": <#noescape>${item.parent.nodeJSON},</#noescape></#if>
|
|
||||||
<@itemLib.itemJSON item=item />
|
|
||||||
}<#if item_has_next>,</#if>
|
|
||||||
</#list>
|
|
||||||
]
|
|
||||||
}
|
|
||||||
</#escape>
|
|
@@ -1,356 +0,0 @@
|
|||||||
const REQUEST_MAX = 1000;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Method that performs the actual loading of the nodes.
|
|
||||||
*
|
|
||||||
* Note!
|
|
||||||
* Will optimize performance by using ScriptNode.childFileFolders for directory listings
|
|
||||||
* In other words when the "path" filter is used.
|
|
||||||
*
|
|
||||||
* @method doclist_getAllNodes
|
|
||||||
* @param parsedArgs {Object}
|
|
||||||
* @param filterParams {Object}
|
|
||||||
* @param query {String}
|
|
||||||
* @param totalItemCount {int}
|
|
||||||
* @return {object} Returns the node and corresponding pagination metadata
|
|
||||||
* {
|
|
||||||
* allNodes: {Array}
|
|
||||||
* totalRecords: {int}
|
|
||||||
* requestTotalCountMax: {int}
|
|
||||||
* paged: {boolean}
|
|
||||||
* query: {String}
|
|
||||||
* }
|
|
||||||
*/
|
|
||||||
function doclist_getAllNodes(parsedArgs, filterParams, query, totalItemCount)
|
|
||||||
{
|
|
||||||
var filter = args.filter,
|
|
||||||
totalRecords = 0,
|
|
||||||
requestTotalCountMax = 0,
|
|
||||||
paged = false,
|
|
||||||
allNodes = [];
|
|
||||||
if ((filter || "path") == "path")
|
|
||||||
{
|
|
||||||
// TODO also add DB filter by "node" (in addition to "path")
|
|
||||||
var parentNode = parsedArgs.pathNode;
|
|
||||||
if (parentNode !== null)
|
|
||||||
{
|
|
||||||
var skip = -1,
|
|
||||||
max = -1;
|
|
||||||
|
|
||||||
if (args.size != null)
|
|
||||||
{
|
|
||||||
max = args.size;
|
|
||||||
|
|
||||||
if (args.pos > 0)
|
|
||||||
{
|
|
||||||
skip = (args.pos - 1) * max;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
var sortField = (args.sortField == null ? "cm:name" : args.sortField),
|
|
||||||
sortAsc = (((args.sortAsc == null) || (args.sortAsc == "true")) ? true : false);
|
|
||||||
|
|
||||||
// Get paged set
|
|
||||||
requestTotalCountMax = skip + REQUEST_MAX;
|
|
||||||
var pagedResult = parentNode.childFileFolders(
|
|
||||||
true, true, filterParams.ignoreTypes.concat(filterParams.ignoreAspects),
|
|
||||||
skip, max, requestTotalCountMax, sortField, sortAsc, "");
|
|
||||||
|
|
||||||
allNodes = pagedResult.page;
|
|
||||||
totalRecords = pagedResult.totalResultCountUpper;
|
|
||||||
paged = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// Query the nodes - passing in sort and result limit parameters
|
|
||||||
if (query !== "")
|
|
||||||
{
|
|
||||||
allNodes = search.query(
|
|
||||||
{
|
|
||||||
query: query,
|
|
||||||
language: filterParams.language,
|
|
||||||
page:
|
|
||||||
{
|
|
||||||
maxItems: totalItemCount
|
|
||||||
},
|
|
||||||
sort: filterParams.sort,
|
|
||||||
templates: filterParams.templates,
|
|
||||||
namespace: (filterParams.namespace ? filterParams.namespace : null)
|
|
||||||
});
|
|
||||||
|
|
||||||
totalRecords = allNodes.length;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return {
|
|
||||||
allNodes: allNodes,
|
|
||||||
totalRecords: totalRecords,
|
|
||||||
requestTotalCountMax: requestTotalCountMax,
|
|
||||||
paged: paged,
|
|
||||||
query: query
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Main entry point: Create collection of documents and folders in the given space
|
|
||||||
*
|
|
||||||
* @method doclist_main
|
|
||||||
*/
|
|
||||||
function doclist_main()
|
|
||||||
{
|
|
||||||
// Use helper function to get the arguments
|
|
||||||
var parsedArgs = ParseArgs.getParsedArgs();
|
|
||||||
if (parsedArgs === null)
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
var filter = args.filter,
|
|
||||||
items = [];
|
|
||||||
|
|
||||||
// Try to find a filter query based on the passed-in arguments
|
|
||||||
var allNodes = [],
|
|
||||||
totalRecords = 0,
|
|
||||||
requestTotalCountMax = 0,
|
|
||||||
paged = false,
|
|
||||||
favourites = Common.getFavourites(),
|
|
||||||
filterParams = Filters.getFilterParams(filter, parsedArgs,
|
|
||||||
{
|
|
||||||
favourites: favourites
|
|
||||||
}),
|
|
||||||
query = filterParams.query,
|
|
||||||
allSites = (parsedArgs.nodeRef == "alfresco://sites/home");
|
|
||||||
|
|
||||||
if (logger.isLoggingEnabled())
|
|
||||||
logger.log("doclist.lib.js - NodeRef: " + parsedArgs.nodeRef + " Query: " + query);
|
|
||||||
|
|
||||||
var totalItemCount = filterParams.limitResults ? parseInt(filterParams.limitResults, 10) : -1;
|
|
||||||
// For all sites documentLibrary query we pull in all available results and post filter
|
|
||||||
if (totalItemCount === 0) totalItemCount = -1;
|
|
||||||
else if (allSites) totalItemCount = (totalItemCount > 0 ? totalItemCount * 10 : 500);
|
|
||||||
|
|
||||||
|
|
||||||
var allNodesResult = doclist_getAllNodes(parsedArgs, filterParams, query, totalItemCount);
|
|
||||||
allNodes = allNodesResult.allNodes;
|
|
||||||
totalRecords = allNodesResult.totalRecords;
|
|
||||||
requestTotalCountMax = allNodesResult.requestTotalCountMax;
|
|
||||||
paged = allNodesResult.paged;
|
|
||||||
query = allNodesResult.query;
|
|
||||||
|
|
||||||
|
|
||||||
if (logger.isLoggingEnabled())
|
|
||||||
logger.log("doclist.lib.js - query results: " + allNodes.length);
|
|
||||||
// Generate the qname path match regex required for all sites 'documentLibrary' results match
|
|
||||||
var pathRegex;
|
|
||||||
if (allSites)
|
|
||||||
{
|
|
||||||
// escape the forward slash characters in the qname path
|
|
||||||
// TODO: replace with java.lang.String regex match for performance
|
|
||||||
var pathMatch = new String(parsedArgs.rootNode.qnamePath).replace(/\//g, '\\/') + "\\/.*\\/cm:documentLibrary\\/.*";
|
|
||||||
pathRegex = new RegExp(pathMatch, "gi");
|
|
||||||
if (logger.isLoggingEnabled())
|
|
||||||
logger.log("doclist.lib.js - will match results using regex: " + pathMatch);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Ensure folders and folderlinks appear at the top of the list
|
|
||||||
var folderNodes = [],
|
|
||||||
documentNodes = [];
|
|
||||||
|
|
||||||
for each (node in allNodes)
|
|
||||||
{
|
|
||||||
if (totalItemCount !== 0)
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
if (!allSites || node.qnamePath.match(pathRegex))
|
|
||||||
{
|
|
||||||
totalItemCount--;
|
|
||||||
if (node.isContainer || node.isLinkToContainer)
|
|
||||||
{
|
|
||||||
folderNodes.push(node);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
documentNodes.push(node);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
catch (e)
|
|
||||||
{
|
|
||||||
// Possibly an old indexed node - ignore it
|
|
||||||
}
|
|
||||||
} else break;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Node type counts
|
|
||||||
var folderNodesCount = folderNodes.length,
|
|
||||||
documentNodesCount = documentNodes.length,
|
|
||||||
nodes;
|
|
||||||
|
|
||||||
if (parsedArgs.type === "documents")
|
|
||||||
{
|
|
||||||
nodes = documentNodes;
|
|
||||||
totalRecords -= folderNodesCount;
|
|
||||||
}
|
|
||||||
else if (parsedArgs.type === "folders")
|
|
||||||
{
|
|
||||||
nodes = folderNodes;
|
|
||||||
totalRecords -= documentNodesCount;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// TODO: Sorting with folders at end -- swap order of concat()
|
|
||||||
nodes = folderNodes.concat(documentNodes);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (logger.isLoggingEnabled())
|
|
||||||
logger.log("doclist.lib.js - totalRecords: " + totalRecords);
|
|
||||||
|
|
||||||
// Pagination
|
|
||||||
var pageSize = args.size || nodes.length,
|
|
||||||
pagePos = args.pos || "1",
|
|
||||||
startIndex = (pagePos - 1) * pageSize;
|
|
||||||
|
|
||||||
if (!paged)
|
|
||||||
{
|
|
||||||
// Trim the nodes array down to the page size
|
|
||||||
nodes = nodes.slice(startIndex, pagePos * pageSize);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Common or variable parent container?
|
|
||||||
var parent = null;
|
|
||||||
|
|
||||||
if (!filterParams.variablePath)
|
|
||||||
{
|
|
||||||
// Parent node permissions (and Site role if applicable)
|
|
||||||
parent = Evaluator.run(parsedArgs.pathNode, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
var thumbnail = null,
|
|
||||||
locationNode,
|
|
||||||
item;
|
|
||||||
|
|
||||||
// Loop through and evaluate each node in this result set
|
|
||||||
for each (node in nodes)
|
|
||||||
{
|
|
||||||
// Get evaluated properties.
|
|
||||||
item = Evaluator.run(node);
|
|
||||||
if (item !== null && (filter!=="editingMe" && filter!=="editingOthers" || node.getIsLocked() || item.workingCopy.isWorkingCopy ) )
|
|
||||||
{
|
|
||||||
item.isFavourite = (favourites[item.node.nodeRef] === true);
|
|
||||||
item.likes = Common.getLikes(node);
|
|
||||||
|
|
||||||
// Does this collection of nodes have potentially differering paths?
|
|
||||||
if (filterParams.variablePath || item.isLink)
|
|
||||||
{
|
|
||||||
locationNode = item.isLink ? item.linkedNode : item.node;
|
|
||||||
if (locationNode.isTargetDeleted)
|
|
||||||
{
|
|
||||||
// take location of the link node
|
|
||||||
location =
|
|
||||||
{
|
|
||||||
site: parsedArgs.location.site,
|
|
||||||
siteTitle: parsedArgs.location.siteTitle,
|
|
||||||
sitePreset: parsedArgs.location.sitePreset,
|
|
||||||
container: parsedArgs.location.container,
|
|
||||||
containerType: parsedArgs.location.containerType,
|
|
||||||
path: parsedArgs.location.path,
|
|
||||||
repoPath: parsedArgs.location.repoPath,
|
|
||||||
file: "<Broken Link>"
|
|
||||||
};
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// Ensure we have Read permissions on the destination on the link object
|
|
||||||
if (!locationNode.hasPermission("Read")) continue;
|
|
||||||
location = Common.getLocation(locationNode, parsedArgs.libraryRoot);
|
|
||||||
}
|
|
||||||
// Parent node
|
|
||||||
if (node.parent != null && node.parent.isContainer && node.parent.hasPermission("Read"))
|
|
||||||
{
|
|
||||||
item.parent = Evaluator.run(node.parent, true);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
location =
|
|
||||||
{
|
|
||||||
site: parsedArgs.location.site,
|
|
||||||
siteTitle: parsedArgs.location.siteTitle,
|
|
||||||
sitePreset: parsedArgs.location.sitePreset,
|
|
||||||
container: parsedArgs.location.container,
|
|
||||||
containerType: parsedArgs.location.containerType,
|
|
||||||
path: parsedArgs.location.path,
|
|
||||||
repoPath: parsedArgs.location.repoPath,
|
|
||||||
file: node.name
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
// Resolved location
|
|
||||||
item.location = location;
|
|
||||||
|
|
||||||
items.push(item);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
--totalRecords;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Array Remove - By John Resig (MIT Licensed)
|
|
||||||
var fnArrayRemove = function fnArrayRemove(array, from, to)
|
|
||||||
{
|
|
||||||
var rest = array.slice((to || from) + 1 || array.length);
|
|
||||||
array.length = from < 0 ? array.length + from : from;
|
|
||||||
return array.push.apply(array, rest);
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* De-duplicate orignals for any existing working copies.
|
|
||||||
* This can't be done in evaluator.lib.js as it has no knowledge of the current filter or UI operation.
|
|
||||||
* Note: This may result in pages containing less than the configured amount of items (50 by default).
|
|
||||||
*/
|
|
||||||
for each (item in items)
|
|
||||||
{
|
|
||||||
if (item.workingCopy && item.workingCopy.isWorkingCopy)
|
|
||||||
{
|
|
||||||
var workingCopySource = String(item.workingCopy.sourceNodeRef);
|
|
||||||
for (var i = 0, ii = items.length; i < ii; i++)
|
|
||||||
{
|
|
||||||
if (String(items[i].node.nodeRef) == workingCopySource)
|
|
||||||
{
|
|
||||||
fnArrayRemove(items, i);
|
|
||||||
--totalRecords;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
var paging =
|
|
||||||
{
|
|
||||||
totalRecords: totalRecords,
|
|
||||||
startIndex: startIndex
|
|
||||||
};
|
|
||||||
|
|
||||||
if (paged && (totalRecords == requestTotalCountMax))
|
|
||||||
{
|
|
||||||
paging.totalRecordsUpper = requestTotalCountMax;
|
|
||||||
}
|
|
||||||
|
|
||||||
return (
|
|
||||||
{
|
|
||||||
luceneQuery: query,
|
|
||||||
paging: paging,
|
|
||||||
container: parsedArgs.rootNode,
|
|
||||||
parent: parent,
|
|
||||||
onlineEditing: utils.moduleInstalled("org.alfresco.module.vti"),
|
|
||||||
itemCount:
|
|
||||||
{
|
|
||||||
folders: folderNodesCount,
|
|
||||||
documents: documentNodesCount
|
|
||||||
},
|
|
||||||
items: items,
|
|
||||||
customJSON: slingshotDocLib.getJSON()
|
|
||||||
});
|
|
||||||
}
|
|
@@ -1,118 +0,0 @@
|
|||||||
|
|
||||||
var Evaluator =
|
|
||||||
{
|
|
||||||
/**
|
|
||||||
* Node Type evaluator
|
|
||||||
*/
|
|
||||||
getNodeType: function Evaluator_getNodeType(node)
|
|
||||||
{
|
|
||||||
var nodeType = "document";
|
|
||||||
if (node.isContainer)
|
|
||||||
{
|
|
||||||
nodeType = "folder";
|
|
||||||
}
|
|
||||||
else if (node.isLinkToContainer)
|
|
||||||
{
|
|
||||||
nodeType = "folderlink";
|
|
||||||
}
|
|
||||||
else if (node.isLinkToDocument)
|
|
||||||
{
|
|
||||||
nodeType = "filelink";
|
|
||||||
}
|
|
||||||
return nodeType;
|
|
||||||
},
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Node Evaluator - main entrypoint
|
|
||||||
*/
|
|
||||||
run: function Evaluator_run(node, isParent)
|
|
||||||
{
|
|
||||||
var nodeType = Evaluator.getNodeType(node),
|
|
||||||
workingCopy = {},
|
|
||||||
activeWorkflows = [],
|
|
||||||
isLink = false,
|
|
||||||
linkedNode = null;
|
|
||||||
|
|
||||||
if (!isParent)
|
|
||||||
{
|
|
||||||
// Get relevant actions set
|
|
||||||
switch (nodeType)
|
|
||||||
{
|
|
||||||
/**
|
|
||||||
* SPECIFIC TO: LINK
|
|
||||||
*/
|
|
||||||
case "folderlink":
|
|
||||||
case "filelink":
|
|
||||||
isLink = true;
|
|
||||||
|
|
||||||
linkedNode = node.properties.destination;
|
|
||||||
if (linkedNode == null)
|
|
||||||
{
|
|
||||||
linkedNode = { isTargetDeleted: true };
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* SPECIFIC TO: DOCUMENTS
|
|
||||||
*/
|
|
||||||
case "document":
|
|
||||||
// Working Copy?
|
|
||||||
if (node.hasAspect("{http://www.alfresco.org/model/content/1.0}workingcopy"))
|
|
||||||
{
|
|
||||||
var wcLink = node.sourceAssocs["cm:workingcopylink"];
|
|
||||||
var isWorkingCopy = wcLink != null;
|
|
||||||
if (isWorkingCopy)
|
|
||||||
{
|
|
||||||
var wcNode = wcLink[0];
|
|
||||||
workingCopy["isWorkingCopy"] = true;
|
|
||||||
workingCopy["sourceNodeRef"] = wcNode.nodeRef;
|
|
||||||
if (wcNode.hasAspect("{http://www.alfresco.org/model/content/1.0}versionable"))
|
|
||||||
{
|
|
||||||
workingCopy["workingCopyVersion"] = wcNode.properties["cm:versionLabel"];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
logger.error("Node: " + node.nodeRef +" hasn't \"cm:workingcopylink\" association");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// Locked?
|
|
||||||
else if (node.isLocked && !node.hasAspect("trx:transferred") && node.hasAspect("{http://www.alfresco.org/model/content/1.0}checkedOut"))
|
|
||||||
{
|
|
||||||
var srcNode = node.assocs["cm:workingcopylink"][0];
|
|
||||||
workingCopy["hasWorkingCopy"] = true;
|
|
||||||
workingCopy["workingCopyNodeRef"] = srcNode.nodeRef;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Part of an active workflow? Guard against stale worklow tasks.
|
|
||||||
try
|
|
||||||
{
|
|
||||||
for each (activeWorkflow in node.activeWorkflows)
|
|
||||||
{
|
|
||||||
activeWorkflows.push(activeWorkflow.id);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
catch (e) {}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (node !== null)
|
|
||||||
{
|
|
||||||
return(
|
|
||||||
{
|
|
||||||
node: node,
|
|
||||||
nodeJSON: appUtils.toJSON(node, true),
|
|
||||||
type: nodeType,
|
|
||||||
isLink: isLink,
|
|
||||||
linkedNode: linkedNode,
|
|
||||||
activeWorkflows: activeWorkflows,
|
|
||||||
workingCopy: workingCopy,
|
|
||||||
workingCopyJSON: jsonUtils.toJSONString(workingCopy)
|
|
||||||
});
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
@@ -1,287 +0,0 @@
|
|||||||
var Filters =
|
|
||||||
{
|
|
||||||
/**
|
|
||||||
* Type map to filter required types.
|
|
||||||
* NOTE: "documents" filter also returns folders to show UI hint about hidden folders.
|
|
||||||
*/
|
|
||||||
TYPE_MAP:
|
|
||||||
{
|
|
||||||
"documents": '+(TYPE:"content" OR TYPE:"app:filelink" OR TYPE:"folder")',
|
|
||||||
"folders": '+(TYPE:"folder" OR TYPE:"app:folderlink")',
|
|
||||||
"images": '+@cm\\:content.mimetype:image/*'
|
|
||||||
},
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Types that we want to suppress from the resultset
|
|
||||||
*/
|
|
||||||
IGNORED_TYPES:
|
|
||||||
[
|
|
||||||
"cm:systemfolder",
|
|
||||||
"fm:forums",
|
|
||||||
"fm:forum",
|
|
||||||
"fm:topic",
|
|
||||||
"fm:post"
|
|
||||||
],
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Aspects ignored from the canned query based resultset
|
|
||||||
*/
|
|
||||||
IGNORED_ASPECTS:
|
|
||||||
[
|
|
||||||
"cm:checkedOut"
|
|
||||||
],
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Encode a path with ISO9075 encoding
|
|
||||||
*
|
|
||||||
* @method iso9075EncodePath
|
|
||||||
* @param path {string} Path to be encoded
|
|
||||||
* @return {string} Encoded path
|
|
||||||
*/
|
|
||||||
iso9075EncodePath: function Filter_iso9075EncodePath(path)
|
|
||||||
{
|
|
||||||
var parts = path.split("/");
|
|
||||||
for (var i = 1, ii = parts.length; i < ii; i++)
|
|
||||||
{
|
|
||||||
parts[i] = "cm:" + search.ISO9075Encode(parts[i]);
|
|
||||||
}
|
|
||||||
return parts.join("/");
|
|
||||||
},
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Create filter parameters based on input parameters
|
|
||||||
*
|
|
||||||
* @method getFilterParams
|
|
||||||
* @param filter {string} Required filter
|
|
||||||
* @param parsedArgs {object} Parsed arguments object literal
|
|
||||||
* @param optional {object} Optional arguments depending on filter type
|
|
||||||
* @return {object} Object literal containing parameters to be used in Lucene search
|
|
||||||
*/
|
|
||||||
getFilterParams: function Filter_getFilterParams(filter, parsedArgs, optional)
|
|
||||||
{
|
|
||||||
var filterParams =
|
|
||||||
{
|
|
||||||
query: "+PATH:\"" + parsedArgs.pathNode.qnamePath + "/*\"",
|
|
||||||
limitResults: null,
|
|
||||||
sort: [
|
|
||||||
{
|
|
||||||
column: "@cm:name",
|
|
||||||
ascending: true
|
|
||||||
}],
|
|
||||||
language: "lucene",
|
|
||||||
templates: null,
|
|
||||||
variablePath: true,
|
|
||||||
ignoreTypes: Filters.IGNORED_TYPES,
|
|
||||||
ignoreAspects: Filters.IGNORED_ASPECTS
|
|
||||||
};
|
|
||||||
|
|
||||||
optional = optional || {};
|
|
||||||
|
|
||||||
// Sorting parameters specified?
|
|
||||||
var sortAscending = args.sortAsc,
|
|
||||||
sortField = args.sortField;
|
|
||||||
|
|
||||||
if (sortAscending == "false")
|
|
||||||
{
|
|
||||||
filterParams.sort[0].ascending = false;
|
|
||||||
}
|
|
||||||
if (sortField !== null)
|
|
||||||
{
|
|
||||||
filterParams.sort[0].column = (sortField.indexOf(":") != -1 ? "@" : "") + sortField;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Max returned results specified?
|
|
||||||
var argMax = args.max;
|
|
||||||
if ((argMax !== null) && !isNaN(argMax))
|
|
||||||
{
|
|
||||||
filterParams.limitResults = argMax;
|
|
||||||
}
|
|
||||||
|
|
||||||
var favourites = optional.favourites;
|
|
||||||
if (typeof favourites == "undefined")
|
|
||||||
{
|
|
||||||
favourites = [];
|
|
||||||
}
|
|
||||||
|
|
||||||
// Create query based on passed-in arguments
|
|
||||||
var filterData = String(args.filterData),
|
|
||||||
filterQuery = "";
|
|
||||||
|
|
||||||
// Common types and aspects to filter from the UI - known subtypes of cm:content and cm:folder
|
|
||||||
var filterQueryDefaults = ' -TYPE:"' + Filters.IGNORED_TYPES.join('" -TYPE:"') + '"';
|
|
||||||
|
|
||||||
switch (String(filter))
|
|
||||||
{
|
|
||||||
case "all":
|
|
||||||
filterQuery = "+PATH:\"" + parsedArgs.rootNode.qnamePath + "//*\"";
|
|
||||||
filterQuery += " +TYPE:\"cm:content\"";
|
|
||||||
filterQuery += " -ASPECT:\"cm:checkedOut\"";
|
|
||||||
filterParams.query = filterQuery + filterQueryDefaults;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case "recentlyAdded":
|
|
||||||
case "recentlyModified":
|
|
||||||
case "recentlyCreatedByMe":
|
|
||||||
case "recentlyModifiedByMe":
|
|
||||||
var onlySelf = (filter.indexOf("ByMe")) > 0 ? true : false,
|
|
||||||
dateField = (filter.indexOf("Modified") > 0) ? "modified" : "created",
|
|
||||||
ownerField = (dateField == "created") ? "creator" : "modifier";
|
|
||||||
|
|
||||||
// Default to 7 days - can be overridden using "days" argument
|
|
||||||
var dayCount = 7,
|
|
||||||
argDays = args.days;
|
|
||||||
if ((argDays !== null) && !isNaN(argDays))
|
|
||||||
{
|
|
||||||
dayCount = argDays;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Default limit to 50 documents - can be overridden using "max" argument
|
|
||||||
if (filterParams.limitResults === null)
|
|
||||||
{
|
|
||||||
filterParams.limitResults = 50;
|
|
||||||
}
|
|
||||||
|
|
||||||
var date = new Date();
|
|
||||||
var toQuery = date.getFullYear() + "\\-" + (date.getMonth() + 1) + "\\-" + date.getDate();
|
|
||||||
date.setDate(date.getDate() - dayCount);
|
|
||||||
var fromQuery = date.getFullYear() + "\\-" + (date.getMonth() + 1) + "\\-" + date.getDate();
|
|
||||||
|
|
||||||
filterQuery = this.constructPathQuery(parsedArgs);
|
|
||||||
filterQuery += " +@cm\\:" + dateField + ":[" + fromQuery + "T00\\:00\\:00.000 TO " + toQuery + "T23\\:59\\:59.999]";
|
|
||||||
if (onlySelf)
|
|
||||||
{
|
|
||||||
filterQuery += " +@cm\\:" + ownerField + ":\"" + person.properties.userName + '"';
|
|
||||||
}
|
|
||||||
filterQuery += " +TYPE:\"cm:content\"";
|
|
||||||
|
|
||||||
filterParams.sort = [
|
|
||||||
{
|
|
||||||
column: "@cm:" + dateField,
|
|
||||||
ascending: false
|
|
||||||
}];
|
|
||||||
filterParams.query = filterQuery + filterQueryDefaults;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case "editingMe":
|
|
||||||
filterQuery = this.constructPathQuery(parsedArgs);
|
|
||||||
filterQuery += " +((+@cm\\:workingCopyOwner:\"" + person.properties.userName + '")';
|
|
||||||
filterQuery += " OR (+@cm\\:lockOwner:\"" + person.properties.userName + '"';
|
|
||||||
filterQuery += " +@cm\\:lockType:\"WRITE_LOCK\"))";
|
|
||||||
filterParams.query = filterQuery;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case "editingOthers":
|
|
||||||
filterQuery = this.constructPathQuery(parsedArgs);
|
|
||||||
filterQuery += " +((+ASPECT:\"workingcopy\"";
|
|
||||||
filterQuery += " -@cm\\:workingCopyOwner:\"" + person.properties.userName + '")';
|
|
||||||
filterQuery += " OR (-@cm\\:lockOwner:\"" + person.properties.userName + '"';
|
|
||||||
filterQuery += " +@cm\\:lockType:\"WRITE_LOCK\"))";
|
|
||||||
filterParams.query = filterQuery;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case "favourites":
|
|
||||||
for (var favourite in favourites)
|
|
||||||
{
|
|
||||||
if (filterQuery)
|
|
||||||
{
|
|
||||||
filterQuery += " OR ";
|
|
||||||
}
|
|
||||||
filterQuery += "ID:\"" + favourite + "\"";
|
|
||||||
}
|
|
||||||
|
|
||||||
if (filterQuery.length !== 0)
|
|
||||||
{
|
|
||||||
filterQuery = "+(" + filterQuery + ")";
|
|
||||||
// no need to specify path here for all sites - IDs are exact matches
|
|
||||||
if (parsedArgs.nodeRef != "alfresco://sites/home" && parsedArgs.nodeRef != "alfresco://company/home")
|
|
||||||
{
|
|
||||||
filterQuery += ' +PATH:"' + parsedArgs.rootNode.qnamePath + '//*"';
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// empty favourites query
|
|
||||||
filterQuery = "+ID:\"\"";
|
|
||||||
}
|
|
||||||
|
|
||||||
filterParams.query = filterQuery;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case "synced":
|
|
||||||
filterQuery = this.constructPathQuery(parsedArgs);
|
|
||||||
filterQuery += " +ASPECT:\"sync:syncSetMemberNode\"";
|
|
||||||
filterParams.query = filterQuery;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case "syncedErrors":
|
|
||||||
filterQuery = this.constructPathQuery(parsedArgs);
|
|
||||||
filterQuery += " +ASPECT:\"sync:failed\"";
|
|
||||||
filterParams.query = filterQuery;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case "node":
|
|
||||||
filterParams.variablePath = false;
|
|
||||||
filterParams.query = "+ID:\"" + parsedArgs.nodeRef + "\"";
|
|
||||||
break;
|
|
||||||
|
|
||||||
case "tag":
|
|
||||||
// Remove any trailing "/" character
|
|
||||||
if (filterData.charAt(filterData.length - 1) == "/")
|
|
||||||
{
|
|
||||||
filterData = filterData.slice(0, -1);
|
|
||||||
}
|
|
||||||
filterQuery = this.constructPathQuery(parsedArgs);
|
|
||||||
filterParams.query = filterQuery + " +PATH:\"/cm:taggable/cm:" + search.ISO9075Encode(filterData) + "/member\"";
|
|
||||||
break;
|
|
||||||
|
|
||||||
case "category":
|
|
||||||
// Remove any trailing "/" character
|
|
||||||
if (filterData.charAt(filterData.length - 1) == "/")
|
|
||||||
{
|
|
||||||
filterData = filterData.slice(0, -1);
|
|
||||||
}
|
|
||||||
filterQuery = this.constructPathQuery(parsedArgs);
|
|
||||||
filterParams.query = filterQuery + " +PATH:\"/cm:generalclassifiable" + Filters.iso9075EncodePath(filterData) + "/member\"";
|
|
||||||
break;
|
|
||||||
|
|
||||||
case "aspect":
|
|
||||||
filterQuery = "+PATH:\"" + parsedArgs.rootNode.qnamePath + "//*\"";
|
|
||||||
filterQuery += "+ASPECT:\"" + args.filterData + "\"";
|
|
||||||
filterParams.query = filterQuery;
|
|
||||||
break;
|
|
||||||
|
|
||||||
default: // "path"
|
|
||||||
filterParams.variablePath = false;
|
|
||||||
filterQuery = "+PATH:\"" + parsedArgs.pathNode.qnamePath + "/*\"";
|
|
||||||
filterParams.query = filterQuery + filterQueryDefaults;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Specialise by passed-in type
|
|
||||||
if (filterParams.query !== "")
|
|
||||||
{
|
|
||||||
filterParams.query += " " + (Filters.TYPE_MAP[parsedArgs.type] || "");
|
|
||||||
}
|
|
||||||
|
|
||||||
return filterParams;
|
|
||||||
},
|
|
||||||
|
|
||||||
constructPathQuery: function constructPathQuery(parsedArgs)
|
|
||||||
{
|
|
||||||
var pathQuery = "";
|
|
||||||
if (parsedArgs.libraryRoot != companyhome || parsedArgs.nodeRef != "alfresco://company/home")
|
|
||||||
{
|
|
||||||
if (parsedArgs.nodeRef == "alfresco://sites/home")
|
|
||||||
{
|
|
||||||
// all sites query - better with //cm:*
|
|
||||||
pathQuery = '+PATH:"' + parsedArgs.rootNode.qnamePath + '//cm:*"';
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// site specific query - better with //*
|
|
||||||
pathQuery = '+PATH:"' + parsedArgs.rootNode.qnamePath + '//*"';
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return pathQuery;
|
|
||||||
}
|
|
||||||
};
|
|
@@ -1,46 +0,0 @@
|
|||||||
<#macro itemJSON item>
|
|
||||||
<#local node = item.node>
|
|
||||||
<#local version = "1.0">
|
|
||||||
<#if node.hasAspect("{http://www.alfresco.org/model/content/1.0}versionable")><#local version = node.properties["cm:versionLabel"]!""></#if>
|
|
||||||
<#escape x as jsonUtils.encodeJSONString(x)>
|
|
||||||
"version": "${version}",
|
|
||||||
"webdavUrl": "${node.webdavUrl}",
|
|
||||||
<#if item.activeWorkflows?? && (item.activeWorkflows?size > 0)>"activeWorkflows": ${item.activeWorkflows?size?c},</#if>
|
|
||||||
<#if item.isFavourite??>"isFavourite": ${item.isFavourite?string},</#if>
|
|
||||||
<#if (item.workingCopyJSON?length > 2)>"workingCopy": <#noescape>${item.workingCopyJSON}</#noescape>,</#if>
|
|
||||||
<#if item.likes??>"likes":
|
|
||||||
{
|
|
||||||
"isLiked": ${item.likes.isLiked?string},
|
|
||||||
"totalLikes": ${item.likes.totalLikes?c}
|
|
||||||
}</#if>,
|
|
||||||
"location":
|
|
||||||
{
|
|
||||||
"repositoryId": "${(node.properties["trx:repositoryId"])!(server.id)}",
|
|
||||||
<#if item.location.site??>
|
|
||||||
"site":
|
|
||||||
{
|
|
||||||
"name": "${(item.location.site)!""}",
|
|
||||||
"title": "${(item.location.siteTitle)!""}",
|
|
||||||
"preset": "${(item.location.sitePreset)!""}"
|
|
||||||
},
|
|
||||||
</#if>
|
|
||||||
<#if item.location.container??>
|
|
||||||
"container":
|
|
||||||
{
|
|
||||||
"name": "${(item.location.container)!""}",
|
|
||||||
"type": "${(item.location.containerType)!""}",
|
|
||||||
"nodeRef": "${(item.location.containerNode.nodeRef)!""}"
|
|
||||||
},
|
|
||||||
</#if>
|
|
||||||
"path": "${(item.location.path)!""}",
|
|
||||||
"repoPath": "${(item.location.repoPath)!""}",
|
|
||||||
"file": "${(item.location.file)!""}",
|
|
||||||
"parent":
|
|
||||||
{
|
|
||||||
<#if (item.location.parent.nodeRef)??>
|
|
||||||
"nodeRef": "${item.location.parent.nodeRef}"
|
|
||||||
</#if>
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</#escape>
|
|
||||||
</#macro>
|
|
@@ -1,9 +0,0 @@
|
|||||||
<webscript>
|
|
||||||
<shortname>node-v2</shortname>
|
|
||||||
<description>Document List v2 Component - node data webscript</description>
|
|
||||||
<url>/slingshot/doclib2/node/{store_type}/{store_id}/{id}</url>
|
|
||||||
<format default="json">argument</format>
|
|
||||||
<authentication>user</authentication>
|
|
||||||
<transaction allow="readonly">required</transaction>
|
|
||||||
<lifecycle>internal</lifecycle>
|
|
||||||
</webscript>
|
|
@@ -1,76 +0,0 @@
|
|||||||
<import resource="classpath:/alfresco/templates/webscripts/org/alfresco/slingshot/documentlibrary-v2/evaluator.lib.js">
|
|
||||||
<import resource="classpath:/alfresco/templates/webscripts/org/alfresco/slingshot/documentlibrary-v2/parse-args.lib.js">
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Main entry point: Return single document or folder given it's nodeRef
|
|
||||||
*
|
|
||||||
* @method getDoclist
|
|
||||||
*/
|
|
||||||
function getDoclist()
|
|
||||||
{
|
|
||||||
// Use helper function to get the arguments
|
|
||||||
var parsedArgs = ParseArgs.getParsedArgs();
|
|
||||||
if (parsedArgs === null)
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
parsedArgs.pathNode = ParseArgs.resolveNode(parsedArgs.nodeRef);
|
|
||||||
parsedArgs.location = Common.getLocation(parsedArgs.pathNode, parsedArgs.libraryRoot);
|
|
||||||
|
|
||||||
var favourites = Common.getFavourites(),
|
|
||||||
node = parsedArgs.pathNode;
|
|
||||||
|
|
||||||
var thumbnail = null,
|
|
||||||
item = Evaluator.run(node);
|
|
||||||
|
|
||||||
item.isFavourite = (favourites[node.nodeRef] === true);
|
|
||||||
item.likes = Common.getLikes(node);
|
|
||||||
item.location =
|
|
||||||
{
|
|
||||||
site: parsedArgs.location.site,
|
|
||||||
siteTitle: parsedArgs.location.siteTitle,
|
|
||||||
sitePreset: parsedArgs.location.sitePreset,
|
|
||||||
container: parsedArgs.location.container,
|
|
||||||
containerType: parsedArgs.location.containerType,
|
|
||||||
path: parsedArgs.location.path,
|
|
||||||
repoPath: parsedArgs.location.repoPath,
|
|
||||||
file: node.name
|
|
||||||
};
|
|
||||||
|
|
||||||
item.parent = null;
|
|
||||||
if (node.parent != null && node.parent.isContainer && node.parent.hasPermission("Read"))
|
|
||||||
{
|
|
||||||
item.parent = Evaluator.run(node.parent, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Special case for container and libraryRoot nodes
|
|
||||||
if ((parsedArgs.location.containerNode && String(parsedArgs.location.containerNode.nodeRef) == String(node.nodeRef)) ||
|
|
||||||
(parsedArgs.libraryRoot && String(parsedArgs.libraryRoot.nodeRef) == String(node.nodeRef)))
|
|
||||||
{
|
|
||||||
item.location.file = "";
|
|
||||||
}
|
|
||||||
|
|
||||||
var returnObject = {
|
|
||||||
container: parsedArgs.rootNode,
|
|
||||||
onlineEditing: utils.moduleInstalled("org.alfresco.module.vti"),
|
|
||||||
item: item,
|
|
||||||
customJSON: slingshotDocLib.getJSON()
|
|
||||||
};
|
|
||||||
|
|
||||||
// Additionally include the content if requested by request parameter...
|
|
||||||
if (args["includeContent"] == "true")
|
|
||||||
{
|
|
||||||
returnObject.content = item.node.content
|
|
||||||
}
|
|
||||||
if (args["includeThumbnails"] == "true")
|
|
||||||
{
|
|
||||||
returnObject.thumbnailDefinitions = item.node.thumbnailDefinitions
|
|
||||||
}
|
|
||||||
return (returnObject);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Document List Component: doclist
|
|
||||||
*/
|
|
||||||
model.doclist = getDoclist();
|
|
@@ -1,27 +0,0 @@
|
|||||||
<#import "item.lib.ftl" as itemLib />
|
|
||||||
<#assign workingCopyLabel = " " + message("coci_service.working_copy_label")>
|
|
||||||
<#escape x as jsonUtils.encodeJSONString(x)>
|
|
||||||
{
|
|
||||||
"metadata":
|
|
||||||
{
|
|
||||||
"repositoryId": "${server.id}",
|
|
||||||
<#if doclist.parent?? && doclist.parent.nodeJSON??>"parent": <#noescape>${doclist.parent.nodeJSON},</#noescape></#if>
|
|
||||||
<#if doclist.customJSON??>"custom": <#noescape>${doclist.customJSON},</#noescape></#if>
|
|
||||||
"onlineEditing": ${doclist.onlineEditing?string},
|
|
||||||
"workingCopyLabel": "${workingCopyLabel}",
|
|
||||||
"shareURL": "${site.getShareUrl()}",
|
|
||||||
"serverURL": "${url.server}"
|
|
||||||
},
|
|
||||||
<#if doclist.content??>"itemContent": "${doclist.content}",</#if>
|
|
||||||
"item":
|
|
||||||
{
|
|
||||||
<#if doclist.thumbnailDefinitions??>"thumbnailDefinitions": [<#list doclist.thumbnailDefinitions as thumbnail>"${thumbnail}"<#if thumbnail_has_next>,</#if></#list>],</#if>
|
|
||||||
<#if doclist.item??>
|
|
||||||
<#assign item = doclist.item>
|
|
||||||
"node": <#noescape>${item.nodeJSON}</#noescape>,
|
|
||||||
<#if item.parent?? && item.parent.nodeJSON??>"parent": <#noescape>${item.parent.nodeJSON},</#noescape></#if>
|
|
||||||
<@itemLib.itemJSON item=item />
|
|
||||||
</#if>
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</#escape>
|
|
@@ -1,421 +0,0 @@
|
|||||||
const THUMBNAIL_NAME = "doclib",
|
|
||||||
TYPE_SITES = "st:sites",
|
|
||||||
PREF_DOCUMENT_FAVOURITES = "org.alfresco.share.documents.favourites",
|
|
||||||
PREF_FOLDER_FAVOURITES = "org.alfresco.share.folders.favourites",
|
|
||||||
LIKES_SCHEME = "likesRatingScheme";
|
|
||||||
|
|
||||||
var Common =
|
|
||||||
{
|
|
||||||
/**
|
|
||||||
* Cache for site objects
|
|
||||||
*/
|
|
||||||
SiteCache: {},
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Gets / caches a site object
|
|
||||||
*
|
|
||||||
* @method getSite
|
|
||||||
* @param siteId {string} Site ID
|
|
||||||
*/
|
|
||||||
getSite: function Common_getSite(siteId)
|
|
||||||
{
|
|
||||||
if (typeof Common.SiteCache[siteId] != "object")
|
|
||||||
{
|
|
||||||
Common.SiteCache[siteId] = siteService.getSite(siteId);
|
|
||||||
}
|
|
||||||
return Common.SiteCache[siteId];
|
|
||||||
},
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the user's favourite docs and folders from our slightly eccentric Preferences Service
|
|
||||||
*
|
|
||||||
* @method getFavourites
|
|
||||||
*/
|
|
||||||
getFavourites: function Common_getFavourites()
|
|
||||||
{
|
|
||||||
var prefs = preferenceService.getPreferences(person.properties.userName, PREF_DOCUMENT_FAVOURITES),
|
|
||||||
favourites = {},
|
|
||||||
arrFavs = [],
|
|
||||||
strFavs, f, ff;
|
|
||||||
try
|
|
||||||
{
|
|
||||||
/**
|
|
||||||
* Fasten seatbelts...
|
|
||||||
* An "eval" could be used here, but the Rhino debugger will complain if throws an exception, which gets old very quickly.
|
|
||||||
* e.g. var strFavs = eval('try{(prefs.' + PREF_DOCUMENT_FAVOURITES + ')}catch(e){}');
|
|
||||||
*/
|
|
||||||
if (prefs && prefs.org && prefs.org.alfresco && prefs.org.alfresco.share && prefs.org.alfresco.share.documents)
|
|
||||||
{
|
|
||||||
strFavs = prefs.org.alfresco.share.documents.favourites;
|
|
||||||
if (typeof strFavs == "string")
|
|
||||||
{
|
|
||||||
arrFavs = strFavs.split(",");
|
|
||||||
for (f = 0, ff = arrFavs.length; f < ff; f++)
|
|
||||||
{
|
|
||||||
favourites[arrFavs[f]] = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// Same thing but for folders
|
|
||||||
prefs = preferenceService.getPreferences(person.properties.userName, PREF_FOLDER_FAVOURITES);
|
|
||||||
if (prefs && prefs.org && prefs.org.alfresco && prefs.org.alfresco.share && prefs.org.alfresco.share.folders)
|
|
||||||
{
|
|
||||||
strFavs = prefs.org.alfresco.share.folders.favourites;
|
|
||||||
if (typeof strFavs == "string")
|
|
||||||
{
|
|
||||||
arrFavs = strFavs.split(",");
|
|
||||||
for (f = 0, ff = arrFavs.length; f < ff; f++)
|
|
||||||
{
|
|
||||||
favourites[arrFavs[f]] = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
catch (e)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
return favourites;
|
|
||||||
},
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Generates a location object literal for a given node.
|
|
||||||
* Location is Site-relative unless a libraryRoot node is passed in.
|
|
||||||
*
|
|
||||||
* @method getLocation
|
|
||||||
* @param node {ScriptNode} Node to generate location for
|
|
||||||
* @param libraryRoot {ScriptNode} Optional node to work out relative location from.
|
|
||||||
* @param parent {ScriptNode} Optional parent to use instead of assuming primary parent path
|
|
||||||
* @return {object} Location object literal.
|
|
||||||
*/
|
|
||||||
getLocation: function Common_getLocation(node, libraryRoot, parent)
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
var location = null,
|
|
||||||
siteId = null,
|
|
||||||
qnamePaths,
|
|
||||||
displayPaths;
|
|
||||||
|
|
||||||
if (parent)
|
|
||||||
{
|
|
||||||
qnamePaths = (parent.qnamePath + "/_").split("/");
|
|
||||||
displayPaths = (parent.displayPath + "/" + parent.name).split("/");
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
qnamePaths = node.qnamePath.split("/"),
|
|
||||||
displayPaths = node.displayPath.split("/");
|
|
||||||
}
|
|
||||||
|
|
||||||
if (libraryRoot == undefined && qnamePaths[2] != TYPE_SITES)
|
|
||||||
{
|
|
||||||
libraryRoot = companyhome;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (libraryRoot)
|
|
||||||
{
|
|
||||||
// Generate the path from the supplied library root
|
|
||||||
location =
|
|
||||||
{
|
|
||||||
site: null,
|
|
||||||
container: null,
|
|
||||||
path: "/" + displayPaths.slice(libraryRoot.displayPath.split("/").length + 1, displayPaths.length).join("/"),
|
|
||||||
file: node.name
|
|
||||||
};
|
|
||||||
}
|
|
||||||
else if ((qnamePaths.length > 4) && (qnamePaths[2] == TYPE_SITES))
|
|
||||||
{
|
|
||||||
siteId = displayPaths[3];
|
|
||||||
var siteNode = Common.getSite(siteId),
|
|
||||||
containerId = qnamePaths[4].substr(3);
|
|
||||||
|
|
||||||
if (siteNode != null)
|
|
||||||
{
|
|
||||||
var containerNode = siteNode.getContainer(containerId);
|
|
||||||
if (containerNode != null)
|
|
||||||
{
|
|
||||||
location =
|
|
||||||
{
|
|
||||||
site: siteId,
|
|
||||||
siteNode: siteNode,
|
|
||||||
siteTitle: siteNode.title,
|
|
||||||
sitePreset: siteNode.sitePreset,
|
|
||||||
container: containerId,
|
|
||||||
containerNode: containerNode,
|
|
||||||
containerType: containerNode.typeShort,
|
|
||||||
path: "/" + displayPaths.slice(5, displayPaths.length).join("/"),
|
|
||||||
file: node.name
|
|
||||||
};
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (location == null)
|
|
||||||
{
|
|
||||||
location =
|
|
||||||
{
|
|
||||||
site: siteId,
|
|
||||||
container: null,
|
|
||||||
path: "/" + displayPaths.slice(2, displayPaths.length).join("/"),
|
|
||||||
file: node.name
|
|
||||||
};
|
|
||||||
}
|
|
||||||
// add repository path to response
|
|
||||||
location.repoPath = "/" + displayPaths.slice(2, displayPaths.length).join("/");
|
|
||||||
|
|
||||||
return location;
|
|
||||||
}
|
|
||||||
catch(e)
|
|
||||||
{
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns an object literal representing the current "likes" rating for a node
|
|
||||||
*
|
|
||||||
* @method getLikes
|
|
||||||
* @param node {ScriptNode} Node to query
|
|
||||||
* @return {object} Likes object literal.
|
|
||||||
*/
|
|
||||||
getLikes: function Common_getLikes(node)
|
|
||||||
{
|
|
||||||
var isLiked = false,
|
|
||||||
totalLikes = 0;
|
|
||||||
|
|
||||||
try
|
|
||||||
{
|
|
||||||
totalLikes = ratingService.getRatingsCount(node, LIKES_SCHEME);
|
|
||||||
isLiked = totalLikes === 0 ? false : ratingService.getRating(node, LIKES_SCHEME) !== -1;
|
|
||||||
}
|
|
||||||
catch (e) {}
|
|
||||||
|
|
||||||
return (
|
|
||||||
{
|
|
||||||
isLiked: isLiked,
|
|
||||||
totalLikes: totalLikes
|
|
||||||
});
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
var ParseArgs =
|
|
||||||
{
|
|
||||||
/**
|
|
||||||
* Get and parse arguments
|
|
||||||
*
|
|
||||||
* @method getParsedArgs
|
|
||||||
* @return {array|null} Array containing the validated input parameters
|
|
||||||
*/
|
|
||||||
getParsedArgs: function ParseArgs_getParsedArgs(containerType)
|
|
||||||
{
|
|
||||||
var type = url.templateArgs.type,
|
|
||||||
libraryRoot = args.libraryRoot,
|
|
||||||
rootNode = null,
|
|
||||||
pathNode = null,
|
|
||||||
nodeRef = null,
|
|
||||||
path = "",
|
|
||||||
location = null;
|
|
||||||
|
|
||||||
// Is this library rooted from a non-site nodeRef?
|
|
||||||
if (libraryRoot !== null)
|
|
||||||
{
|
|
||||||
libraryRoot = ParseArgs.resolveNode(libraryRoot);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (url.templateArgs.store_type !== null)
|
|
||||||
{
|
|
||||||
/**
|
|
||||||
* nodeRef input: store_type, store_id and id
|
|
||||||
*/
|
|
||||||
var storeType = url.templateArgs.store_type,
|
|
||||||
storeId = url.templateArgs.store_id,
|
|
||||||
id = url.templateArgs.id;
|
|
||||||
|
|
||||||
nodeRef = storeType + "://" + storeId + "/" + id;
|
|
||||||
rootNode = libraryRoot || ParseArgs.resolveNode(nodeRef);
|
|
||||||
if (rootNode == null)
|
|
||||||
{
|
|
||||||
status.setCode(status.STATUS_NOT_FOUND, "Not a valid nodeRef: '" + nodeRef + "'");
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Special case: make sure filter picks up correct mode
|
|
||||||
if (type == null && args.filter == null)
|
|
||||||
{
|
|
||||||
args.filter = "node";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
/**
|
|
||||||
* Site and container input
|
|
||||||
*/
|
|
||||||
var siteId = url.templateArgs.site,
|
|
||||||
containerId = url.templateArgs.container,
|
|
||||||
siteNode = siteService.getSite(siteId);
|
|
||||||
|
|
||||||
if (siteNode === null)
|
|
||||||
{
|
|
||||||
status.setCode(status.STATUS_GONE, "Site not found: '" + siteId + "'");
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
rootNode = siteNode.getContainer(containerId);
|
|
||||||
if (rootNode === null)
|
|
||||||
{
|
|
||||||
rootNode = siteNode.aquireContainer(containerId, containerType || "cm:folder", {"cm:description": "Document Library"});
|
|
||||||
if (rootNode === null)
|
|
||||||
{
|
|
||||||
status.setCode(status.STATUS_GONE, "Document Library container '" + containerId + "' not found in '" + siteId + "'. (No permission?)");
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Path input?
|
|
||||||
path = url.templateArgs.path || "";
|
|
||||||
pathNode = path.length > 0 ? rootNode.childByNamePath(path) : (pathNode || rootNode);
|
|
||||||
if (pathNode === null)
|
|
||||||
{
|
|
||||||
status.setCode(status.STATUS_NOT_FOUND, "Path not found: '" + path + "'");
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Parent location parameter adjustment
|
|
||||||
var parentNode = null;
|
|
||||||
if (path.length > 0)
|
|
||||||
{
|
|
||||||
var p = path.split("/");
|
|
||||||
p.pop();
|
|
||||||
parentNode = rootNode.childByNamePath(p.join("/"));
|
|
||||||
}
|
|
||||||
location = Common.getLocation(pathNode, libraryRoot, parentNode);
|
|
||||||
if (location === null)
|
|
||||||
{
|
|
||||||
status.setCode(status.STATUS_GONE, "Location is 'null'. (No permission?)");
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
// ACE-565 fix. Commenting current line causes the incorrect folder navigation into Document Library
|
|
||||||
if (path !== "")
|
|
||||||
{
|
|
||||||
location.path = ParseArgs.combinePaths(location.path, location.file);
|
|
||||||
}
|
|
||||||
if (location.repoPath)
|
|
||||||
{
|
|
||||||
location.repoPath = ParseArgs.combinePaths(location.repoPath, location.file);
|
|
||||||
}
|
|
||||||
if (args.filter !== "node" && !pathNode.isContainer)
|
|
||||||
{
|
|
||||||
location.file = "";
|
|
||||||
}
|
|
||||||
|
|
||||||
var objRet =
|
|
||||||
{
|
|
||||||
rootNode: rootNode,
|
|
||||||
pathNode: pathNode,
|
|
||||||
libraryRoot: libraryRoot,
|
|
||||||
location: location,
|
|
||||||
path: path,
|
|
||||||
nodeRef: nodeRef,
|
|
||||||
type: type
|
|
||||||
};
|
|
||||||
|
|
||||||
// Multiple input files in the JSON body?
|
|
||||||
var files = ParseArgs.getMultipleInputValues("nodeRefs");
|
|
||||||
if (typeof files != "string")
|
|
||||||
{
|
|
||||||
objRet.files = files;
|
|
||||||
}
|
|
||||||
|
|
||||||
return objRet;
|
|
||||||
},
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Resolve "virtual" nodeRefs into nodes
|
|
||||||
*
|
|
||||||
* @method resolveVirtualNodeRef
|
|
||||||
* @deprecated for ParseArgs.resolveNode
|
|
||||||
*/
|
|
||||||
resolveVirtualNodeRef: function ParseArgs_resolveVirtualNodeRef(nodeRef)
|
|
||||||
{
|
|
||||||
if (logger.isLoggingEnabled())
|
|
||||||
{
|
|
||||||
logger.log("WARNING: ParseArgs.resolveVirtualNodeRef is deprecated for ParseArgs.resolveNode");
|
|
||||||
}
|
|
||||||
return ParseArgs.resolveNode(nodeRef);
|
|
||||||
},
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Resolve "virtual" nodeRefs, nodeRefs and xpath expressions into nodes
|
|
||||||
*
|
|
||||||
* @method resolveNode
|
|
||||||
* @param reference {string} "virtual" nodeRef, nodeRef or xpath expressions
|
|
||||||
* @return {ScriptNode|null} Node corresponding to supplied expression. Returns null if node cannot be resolved.
|
|
||||||
*/
|
|
||||||
resolveNode: function ParseArgs_resolveNode(reference)
|
|
||||||
{
|
|
||||||
return utils.resolveNodeReference(reference);
|
|
||||||
},
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get multiple input files
|
|
||||||
*
|
|
||||||
* @method getMultipleInputValues
|
|
||||||
* @param param {string} Property name containing the files array
|
|
||||||
* @return {array|string} Array containing the files, or string error
|
|
||||||
*/
|
|
||||||
getMultipleInputValues: function ParseArgs_getMultipleInputValues(param)
|
|
||||||
{
|
|
||||||
var values = [],
|
|
||||||
error = null;
|
|
||||||
|
|
||||||
try
|
|
||||||
{
|
|
||||||
// Was a JSON parameter list supplied?
|
|
||||||
if (typeof json == "object")
|
|
||||||
{
|
|
||||||
if (!json.isNull(param))
|
|
||||||
{
|
|
||||||
var jsonValues = json.get(param);
|
|
||||||
// Convert from JSONArray to JavaScript array
|
|
||||||
for (var i = 0, j = jsonValues.length(); i < j; i++)
|
|
||||||
{
|
|
||||||
values.push(jsonValues.get(i));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
catch(e)
|
|
||||||
{
|
|
||||||
error = e.toString();
|
|
||||||
}
|
|
||||||
|
|
||||||
// Return the values array, or the error string if it was set
|
|
||||||
return (error !== null ? error : values);
|
|
||||||
},
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Append multiple parts of a path, ensuring duplicate path separators are removed.
|
|
||||||
*
|
|
||||||
* @method combinePaths
|
|
||||||
* @param path1 {string} First path
|
|
||||||
* @param path2 {string} Second path
|
|
||||||
* @param ...
|
|
||||||
* @param pathN {string} Nth path
|
|
||||||
* @return {string} A string containing the combined paths
|
|
||||||
*/
|
|
||||||
combinePaths: function ParseArgs_combinePaths()
|
|
||||||
{
|
|
||||||
var path = "", i, ii;
|
|
||||||
for (i = 0, ii = arguments.length; i < ii; i++)
|
|
||||||
{
|
|
||||||
if (arguments[i] !== null)
|
|
||||||
{
|
|
||||||
path += arguments[i] + (arguments[i] !== "/" ? "/" : "");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return path.replace(/\/{2,}/g, "/").replace(/(.)\/$/g, "$1");
|
|
||||||
}
|
|
||||||
};
|
|
Reference in New Issue
Block a user