mirror of
https://github.com/Alfresco/alfresco-community-repo.git
synced 2025-08-07 17:49:17 +00:00
Merge from WCM-CUOMO2 to HEAD - Remote API
- Revisions 11077, 11081, 11107, 11155, 11452, 11537, 11568, 11571, 11767, 11804, 11808 - Adjustments to the AVM Remote Store to fully allow it to interact with any AVM store based on store id and web application id. The latter is provided to allow WCM Web Project stores to play nicely with non-WCM stores (like sitestore). - Additional arguments to AVM Remote Store can be passed in as request parameters or as tokenized strings (/s/<store>/w/<webapp>) which allows for URL addressability using a remotestore prefix. - Additional remote API's for web framework to allow for AVM metadata query and some redirection - Best effort to merge stuff without breaking any of Mark or Jan's code. Will work at manual integration of REST API bits tomorrow. Expect good things. git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/alfresco/HEAD/root@11811 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261
This commit is contained in:
@@ -3,7 +3,11 @@
|
|||||||
<description>Remote service mirroring the Store interface - to an AVM store</description>
|
<description>Remote service mirroring the Store interface - to an AVM store</description>
|
||||||
<url>/remotestore/{method}</url>
|
<url>/remotestore/{method}</url>
|
||||||
<url>/remotestore/{method}/{path}</url>
|
<url>/remotestore/{method}/{path}</url>
|
||||||
<authentication>none</authentication>
|
<url>/remotestore/{method}/s/{store}</url>
|
||||||
|
<url>/remotestore/{method}/s/{store}/{path}</url>
|
||||||
|
<url>/remotestore/{method}/s/{store}/w/{webapp}</url>
|
||||||
|
<url>/remotestore/{method}/s/{store}/w/{webapp}/{path}</url>
|
||||||
|
<authentication>guest</authentication>
|
||||||
<transaction>required</transaction>
|
<transaction>required</transaction>
|
||||||
<format default="">argument</format>
|
<format default="">argument</format>
|
||||||
</webscript>
|
</webscript>
|
@@ -0,0 +1,8 @@
|
|||||||
|
<webscript>
|
||||||
|
<shortname>Web Content Management - List Sandboxes</shortname>
|
||||||
|
<description>Web Content Management - List Sandboxes</description>
|
||||||
|
<url>/api/wcm/sandbox/list</url>
|
||||||
|
<format default="html">argument</format>
|
||||||
|
<authentication>user</authentication>
|
||||||
|
<transaction>required</transaction>
|
||||||
|
</webscript>
|
@@ -0,0 +1,16 @@
|
|||||||
|
{
|
||||||
|
"results" : [
|
||||||
|
|
||||||
|
<#assign first = true>
|
||||||
|
<#list results as result>
|
||||||
|
<#if first == false>,</#if>
|
||||||
|
|
||||||
|
{
|
||||||
|
"name" : "${result.name}"
|
||||||
|
}
|
||||||
|
|
||||||
|
<#assign first = false>
|
||||||
|
</#list>
|
||||||
|
|
||||||
|
]
|
||||||
|
}
|
@@ -0,0 +1,29 @@
|
|||||||
|
var webproject = args["webproject"];
|
||||||
|
|
||||||
|
var dmType = "{http://www.alfresco.org/model/wcmappmodel/1.0}webfolder";
|
||||||
|
var query = "TYPE:\"" + dmType + "\"";
|
||||||
|
|
||||||
|
var webprojects = search.luceneSearch(query);
|
||||||
|
|
||||||
|
var results = null;
|
||||||
|
var avmStoreId = null;
|
||||||
|
|
||||||
|
// walk through the projects, get the avm store id (for staging)
|
||||||
|
for(var i = 0; i < webprojects.length; i++)
|
||||||
|
{
|
||||||
|
var projName = webprojects[i].name;
|
||||||
|
if(projName == webproject)
|
||||||
|
{
|
||||||
|
avmStoreId = webprojects[i].properties["{http://www.alfresco.org/model/wcmappmodel/1.0}avmstore"];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(avmStoreId != null)
|
||||||
|
{
|
||||||
|
results = new Array();
|
||||||
|
results[results.length] = avm.lookupStore(avmStoreId);
|
||||||
|
results[results.length] = avm.lookupStore(avmStoreId + "--admin");
|
||||||
|
}
|
||||||
|
|
||||||
|
model.results = results;
|
||||||
|
|
@@ -0,0 +1,8 @@
|
|||||||
|
<webscript>
|
||||||
|
<shortname>Web Content Management - Sandbox GET</shortname>
|
||||||
|
<description>Web Content Management - Sandbox GET</description>
|
||||||
|
<url>/api/wcm/sandbox/{id}</url>
|
||||||
|
<format default="json"/>
|
||||||
|
<authentication>user</authentication>
|
||||||
|
<transaction>required</transaction>
|
||||||
|
</webscript>
|
@@ -0,0 +1,19 @@
|
|||||||
|
function main()
|
||||||
|
{
|
||||||
|
// Get the node from the URL
|
||||||
|
var pathSegments = url.match.split("/");
|
||||||
|
var reference = [ url.templateArgs.store_type, url.templateArgs.store_id ].concat(url.templateArgs.id.split("/"));
|
||||||
|
var node = search.findNode(pathSegments[2], reference);
|
||||||
|
|
||||||
|
// 404 if the node is not found
|
||||||
|
if (node == null)
|
||||||
|
{
|
||||||
|
status.setCode(status.STATUS_NOT_FOUND, "The node could not be found");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get the tags of the node
|
||||||
|
model.tags = node.tags;
|
||||||
|
}
|
||||||
|
|
||||||
|
main();
|
@@ -0,0 +1,5 @@
|
|||||||
|
[
|
||||||
|
<#list tags as tag>
|
||||||
|
${jsonUtils.encodeJSONString(tag)}<#if tag_has_next>,</#if>
|
||||||
|
</#list>
|
||||||
|
]
|
@@ -0,0 +1,8 @@
|
|||||||
|
<webscript>
|
||||||
|
<shortname>Web Content Management - Sandbox POST</shortname>
|
||||||
|
<description>Web Content Management - Sandbox POST</description>
|
||||||
|
<url>/api/wcm/sandbox</url>
|
||||||
|
<format default="json"/>
|
||||||
|
<authentication>user</authentication>
|
||||||
|
<transaction>required</transaction>
|
||||||
|
</webscript>
|
@@ -0,0 +1,19 @@
|
|||||||
|
function main()
|
||||||
|
{
|
||||||
|
// Get the node from the URL
|
||||||
|
var pathSegments = url.match.split("/");
|
||||||
|
var reference = [ url.templateArgs.store_type, url.templateArgs.store_id ].concat(url.templateArgs.id.split("/"));
|
||||||
|
var node = search.findNode(pathSegments[2], reference);
|
||||||
|
|
||||||
|
// 404 if the node is not found
|
||||||
|
if (node == null)
|
||||||
|
{
|
||||||
|
status.setCode(status.STATUS_NOT_FOUND, "The node could not be found");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get the tags of the node
|
||||||
|
model.tags = node.tags;
|
||||||
|
}
|
||||||
|
|
||||||
|
main();
|
@@ -0,0 +1,5 @@
|
|||||||
|
[
|
||||||
|
<#list tags as tag>
|
||||||
|
${jsonUtils.encodeJSONString(tag)}<#if tag_has_next>,</#if>
|
||||||
|
</#list>
|
||||||
|
]
|
@@ -0,0 +1,8 @@
|
|||||||
|
<webscript>
|
||||||
|
<shortname>Web Content Management - List Web Projects</shortname>
|
||||||
|
<description>Web Content Management - List Web Projects</description>
|
||||||
|
<url>/api/wcm/webproject/list</url>
|
||||||
|
<format default="html">argument</format>
|
||||||
|
<authentication>user</authentication>
|
||||||
|
<transaction>required</transaction>
|
||||||
|
</webscript>
|
@@ -0,0 +1,18 @@
|
|||||||
|
{
|
||||||
|
"results" : [
|
||||||
|
|
||||||
|
<#assign first = true>
|
||||||
|
<#list results as result>
|
||||||
|
<#if first == false>,</#if>
|
||||||
|
|
||||||
|
{
|
||||||
|
"name" : "${result.name}"
|
||||||
|
,
|
||||||
|
"nodeRef" : "${result.nodeRef}"
|
||||||
|
}
|
||||||
|
|
||||||
|
<#assign first = false>
|
||||||
|
</#list>
|
||||||
|
|
||||||
|
]
|
||||||
|
}
|
@@ -0,0 +1,5 @@
|
|||||||
|
var dmType = "{http://www.alfresco.org/model/wcmappmodel/1.0}webfolder";
|
||||||
|
var query = "TYPE:\"" + dmType + "\"";
|
||||||
|
var results = search.luceneSearch(query);
|
||||||
|
|
||||||
|
model.results = results;
|
@@ -0,0 +1,8 @@
|
|||||||
|
<webscript>
|
||||||
|
<shortname>Web Content Management - Web Project GET</shortname>
|
||||||
|
<description>Web Content Management - Web Project GET</description>
|
||||||
|
<url>/api/wcm/webproject</url>
|
||||||
|
<format default="html"/>
|
||||||
|
<authentication>user</authentication>
|
||||||
|
<transaction>required</transaction>
|
||||||
|
</webscript>
|
@@ -0,0 +1,11 @@
|
|||||||
|
<#if result?exists>
|
||||||
|
{
|
||||||
|
"name" : "${result.name}"
|
||||||
|
,
|
||||||
|
"id" : "${result.webProjectId}"
|
||||||
|
,
|
||||||
|
"stagingSandboxId" : "${result.sandboxId}"
|
||||||
|
,
|
||||||
|
"stagingStoreId" : "${result.storeId}"
|
||||||
|
}
|
||||||
|
</#if>
|
@@ -0,0 +1,23 @@
|
|||||||
|
var id = args["id"];
|
||||||
|
|
||||||
|
var dmType = "{http://www.alfresco.org/model/wcmappmodel/1.0}webfolder";
|
||||||
|
var query = "TYPE:\"" + dmType + "\"";
|
||||||
|
|
||||||
|
var webprojects = search.luceneSearch(query);
|
||||||
|
|
||||||
|
var result = { };
|
||||||
|
|
||||||
|
// walk through the projects, get the avm store id (for staging)
|
||||||
|
for(var i = 0; i < webprojects.length; i++)
|
||||||
|
{
|
||||||
|
var projName = webprojects[i].name;
|
||||||
|
if(projName == id)
|
||||||
|
{
|
||||||
|
result["name"] = projName;
|
||||||
|
result["webProjectId"] = id;
|
||||||
|
result["storeId"] = webprojects[i].properties["{http://www.alfresco.org/model/wcmappmodel/1.0}avmstore"];
|
||||||
|
result["sandboxId"] = webprojects[i].properties["{http://www.alfresco.org/model/wcmappmodel/1.0}avmstore"];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
model.result = result;
|
@@ -0,0 +1,8 @@
|
|||||||
|
<webscript>
|
||||||
|
<shortname>Web Content Management - Web Project POST</shortname>
|
||||||
|
<description>Web Content Management - Web Project POST</description>
|
||||||
|
<url>/api/wcm/webproject</url>
|
||||||
|
<format default="json"/>
|
||||||
|
<authentication>user</authentication>
|
||||||
|
<transaction>required</transaction>
|
||||||
|
</webscript>
|
@@ -0,0 +1,30 @@
|
|||||||
|
// arguments
|
||||||
|
var jsonString = args["json"];
|
||||||
|
|
||||||
|
model.status = null;
|
||||||
|
|
||||||
|
if(jsonString != null)
|
||||||
|
{
|
||||||
|
// load arguments into object
|
||||||
|
var json = eval('(' + jsonString + ')');
|
||||||
|
|
||||||
|
// attributes
|
||||||
|
var id = json.id;
|
||||||
|
var title = json.title;
|
||||||
|
var description = json.description;
|
||||||
|
|
||||||
|
// TODO: create the web project
|
||||||
|
|
||||||
|
// set back onto return
|
||||||
|
model.webProjectId = id;
|
||||||
|
model.storeId = id;
|
||||||
|
model.sandboxId = id;
|
||||||
|
|
||||||
|
model.status = 'ok';
|
||||||
|
}
|
||||||
|
|
||||||
|
if(model.status == null)
|
||||||
|
{
|
||||||
|
model.status = 'error';
|
||||||
|
}
|
||||||
|
|
@@ -0,0 +1,13 @@
|
|||||||
|
{
|
||||||
|
"status" : "${status}"
|
||||||
|
|
||||||
|
<#if status == 'ok'>
|
||||||
|
,
|
||||||
|
"webProjectId" : "${webProjectId}"
|
||||||
|
,
|
||||||
|
"sandboxId" : "${sandboxId}"
|
||||||
|
,
|
||||||
|
"storeId" : "${storeId}"
|
||||||
|
</#if>
|
||||||
|
|
||||||
|
}
|
@@ -0,0 +1,8 @@
|
|||||||
|
<webscript>
|
||||||
|
<shortname>AVM Metadata Retrieval Service</shortname>
|
||||||
|
<description>AVM Metadata Retrieval Service</description>
|
||||||
|
<url>/webframework/avm/metadata/{storeId}/{webappId}/{path}</url>
|
||||||
|
<format default="html">argument</format>
|
||||||
|
<authentication>user</authentication>
|
||||||
|
<transaction>required</transaction>
|
||||||
|
</webscript>
|
@@ -0,0 +1,87 @@
|
|||||||
|
{
|
||||||
|
<@serialize object=object includeChildren=includeChildren includeContent=includeContent/>
|
||||||
|
}
|
||||||
|
|
||||||
|
<#macro serialize object includeChildren includeContent>
|
||||||
|
"isContainer" : ${object.isContainer?string}
|
||||||
|
,
|
||||||
|
"isDocument" : ${object.isDocument?string}
|
||||||
|
,
|
||||||
|
"url" : "${object.url}"
|
||||||
|
,
|
||||||
|
"downloadUrl" : "${object.downloadUrl}"
|
||||||
|
|
||||||
|
<#if object.mimetype?exists>
|
||||||
|
,
|
||||||
|
"mimetype" : "${object.mimetype}"
|
||||||
|
</#if>
|
||||||
|
,
|
||||||
|
"size" : "${object.size}"
|
||||||
|
,
|
||||||
|
"displayPath" : "${object.displayPath}"
|
||||||
|
,
|
||||||
|
"qnamePath" : "${object.qnamePath}"
|
||||||
|
,
|
||||||
|
"icon16" : "${object.icon16}"
|
||||||
|
,
|
||||||
|
"icon32" : "${object.icon32}"
|
||||||
|
,
|
||||||
|
"isLocked" : ${object.isLocked?string}
|
||||||
|
,
|
||||||
|
"id" : "${object.id}"
|
||||||
|
,
|
||||||
|
"nodeRef" : "${object.nodeRef}"
|
||||||
|
,
|
||||||
|
"name" : "${object.name}"
|
||||||
|
,
|
||||||
|
"type" : "${object.type}"
|
||||||
|
,
|
||||||
|
"isCategory" : ${object.isCategory?string}
|
||||||
|
|
||||||
|
<#if object.properties?exists>
|
||||||
|
,
|
||||||
|
"properties" :
|
||||||
|
{
|
||||||
|
<#assign first = true>
|
||||||
|
<#list object.properties?keys as key>
|
||||||
|
<#if object.properties[key]?exists>
|
||||||
|
<#assign val = object.properties[key]>
|
||||||
|
<#if val?is_string == true>
|
||||||
|
<#if first == false>,</#if>
|
||||||
|
"${key}" : "${val?js_string}"
|
||||||
|
<#assign first = false>
|
||||||
|
<#elseif val?is_date == true>
|
||||||
|
<#if first == false>,</#if>
|
||||||
|
"${key}" : "${val?datetime}"
|
||||||
|
<#assign first = false>
|
||||||
|
<#elseif val?is_boolean == true>
|
||||||
|
<#if first == false>,</#if>
|
||||||
|
"${key}" : "${val?string}"
|
||||||
|
<#assign first = false>
|
||||||
|
</#if>
|
||||||
|
</#if>
|
||||||
|
</#list>
|
||||||
|
}
|
||||||
|
</#if>
|
||||||
|
|
||||||
|
<#if includeChildren && object.children?exists>
|
||||||
|
,
|
||||||
|
"children" :
|
||||||
|
[
|
||||||
|
<#assign first = true>
|
||||||
|
<#list object.children as child>
|
||||||
|
<#if first == false>
|
||||||
|
,
|
||||||
|
</#if>
|
||||||
|
{
|
||||||
|
<@serialize object=child includeChildren=false includeContent=includeContent/>
|
||||||
|
}
|
||||||
|
<#assign first = false>
|
||||||
|
</#list>
|
||||||
|
]
|
||||||
|
<#else>
|
||||||
|
,
|
||||||
|
"children" : []
|
||||||
|
</#if>
|
||||||
|
|
||||||
|
</#macro>
|
@@ -0,0 +1,17 @@
|
|||||||
|
model.includeChildren = true;
|
||||||
|
model.includeContent = false;
|
||||||
|
|
||||||
|
var object = null;
|
||||||
|
|
||||||
|
var storeId = url.templateArgs["storeId"];
|
||||||
|
var webappId = url.templateArgs["webappId"];
|
||||||
|
var path = url.templateArgs["path"];
|
||||||
|
|
||||||
|
var storeRootNode = avm.lookupStoreRoot(storeId);
|
||||||
|
if (storeRootNode != null)
|
||||||
|
{
|
||||||
|
var path = storeRootNode.path + "/" + webappId + "/" + path;
|
||||||
|
object = avm.lookupNode(path);
|
||||||
|
}
|
||||||
|
|
||||||
|
model.object = object;
|
@@ -0,0 +1,9 @@
|
|||||||
|
<webscript>
|
||||||
|
<shortname>JSF Redirection Handler</shortname>
|
||||||
|
<description>JSF Redirection Handler</description>
|
||||||
|
<url>/webframework/redirect/jsf-client/{command}/{objectType}/{storeType}/{storeId}/{nodeId}</url>
|
||||||
|
<url>/webframework/redirect/jsf-client/{command}/{objectType}/{webProjectId}</url>
|
||||||
|
<format default="html">argument</format>
|
||||||
|
<authentication>user</authentication>
|
||||||
|
<transaction>required</transaction>
|
||||||
|
</webscript>
|
@@ -0,0 +1,5 @@
|
|||||||
|
<#if redirectUrl?exists>
|
||||||
|
<script language="Javascript">
|
||||||
|
window.location.href = "${redirectUrl}";
|
||||||
|
</script>
|
||||||
|
</#if>
|
@@ -0,0 +1,40 @@
|
|||||||
|
model.command = url.templateArgs["command"];
|
||||||
|
model.objectType = url.templateArgs["objectType"];
|
||||||
|
|
||||||
|
if("browse" == model.command)
|
||||||
|
{
|
||||||
|
if("node" == model.objectType)
|
||||||
|
{
|
||||||
|
var storeType = url.templateArgs["storeType"];
|
||||||
|
var storeId = url.templateArgs["storeId"];
|
||||||
|
var nodeId = url.templateArgs["nodeId"];
|
||||||
|
|
||||||
|
model.redirectUrl = "/alfresco/n/browse/"+storeType+"/"+storeId+"/"+nodeId;
|
||||||
|
}
|
||||||
|
|
||||||
|
if("webproject" == model.objectType)
|
||||||
|
{
|
||||||
|
model.webProjectId = url.templateArgs["webProjectId"];
|
||||||
|
|
||||||
|
// look up the web project
|
||||||
|
var dmType = "{http://www.alfresco.org/model/wcmappmodel/1.0}webfolder";
|
||||||
|
var query = "TYPE:\"" + dmType + "\"";
|
||||||
|
|
||||||
|
var webprojects = search.luceneSearch(query);
|
||||||
|
|
||||||
|
// walk through the projects, get the avm store id (for staging)
|
||||||
|
for(var i = 0; i < webprojects.length; i++)
|
||||||
|
{
|
||||||
|
var projId = webprojects[i].name;
|
||||||
|
if(projId == model.webProjectId)
|
||||||
|
{
|
||||||
|
var storeType = webprojects[i].properties["{http://www.alfresco.org/model/system/1.0}store-protocol"];
|
||||||
|
var storeId = webprojects[i].properties["{http://www.alfresco.org/model/system/1.0}store-identifier"];
|
||||||
|
var nodeId = webprojects[i].properties["{http://www.alfresco.org/model/system/1.0}node-uuid"];
|
||||||
|
|
||||||
|
model.redirectUrl = "/alfresco/n/browse/"+storeType+"/"+storeId+"/"+nodeId;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@@ -10,8 +10,11 @@
|
|||||||
"url" : "${object.url}"
|
"url" : "${object.url}"
|
||||||
,
|
,
|
||||||
"downloadUrl" : "${object.downloadUrl}"
|
"downloadUrl" : "${object.downloadUrl}"
|
||||||
|
|
||||||
|
<#if object.mimetype?exists>
|
||||||
,
|
,
|
||||||
"mimetype" : "${mimetype}"
|
"mimetype" : "${object.mimetype}"
|
||||||
|
</#if>
|
||||||
,
|
,
|
||||||
"size" : "${object.size}"
|
"size" : "${object.size}"
|
||||||
,
|
,
|
||||||
@@ -57,7 +60,7 @@
|
|||||||
<#assign first = false>
|
<#assign first = false>
|
||||||
<#elseif val?is_boolean == true>
|
<#elseif val?is_boolean == true>
|
||||||
<#if first == false>,</#if>
|
<#if first == false>,</#if>
|
||||||
"${key}" : "${val}"
|
"${key}" : "${val?string}"
|
||||||
<#assign first = false>
|
<#assign first = false>
|
||||||
</#if>
|
</#if>
|
||||||
</#if>
|
</#if>
|
||||||
|
@@ -32,7 +32,7 @@ else
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
path = "/Company Home" + path;
|
//path = "/Company Home" + path;
|
||||||
}
|
}
|
||||||
|
|
||||||
// look up the content by path
|
// look up the content by path
|
||||||
@@ -40,4 +40,3 @@ else
|
|||||||
}
|
}
|
||||||
|
|
||||||
model.object = object;
|
model.object = object;
|
||||||
model.mimetype = object.mimetype;
|
|
@@ -246,22 +246,28 @@
|
|||||||
<property name="mimetypeService" ref="MimetypeService" />
|
<property name="mimetypeService" ref="MimetypeService" />
|
||||||
<property name="avmService" ref="AVMService" />
|
<property name="avmService" ref="AVMService" />
|
||||||
<property name="searchService" ref="SearchService" />
|
<property name="searchService" ref="SearchService" />
|
||||||
|
<!--
|
||||||
<property name="rootPath"><value>alfresco</value></property>
|
<property name="rootPath"><value>alfresco</value></property>
|
||||||
<property name="store"><value>sitestore</value></property>
|
<property name="store"><value>sitestore</value></property>
|
||||||
|
-->
|
||||||
</bean>
|
</bean>
|
||||||
<bean id="webscript.org.alfresco.repository.store.remoteavm.post" class="org.alfresco.repo.web.scripts.bean.AVMRemoteStore" parent="webscript">
|
<bean id="webscript.org.alfresco.repository.store.remoteavm.post" class="org.alfresco.repo.web.scripts.bean.AVMRemoteStore" parent="webscript">
|
||||||
<property name="mimetypeService" ref="MimetypeService" />
|
<property name="mimetypeService" ref="MimetypeService" />
|
||||||
<property name="avmService" ref="AVMService" />
|
<property name="avmService" ref="AVMService" />
|
||||||
<property name="searchService" ref="SearchService" />
|
<property name="searchService" ref="SearchService" />
|
||||||
|
<!--
|
||||||
<property name="rootPath"><value>alfresco</value></property>
|
<property name="rootPath"><value>alfresco</value></property>
|
||||||
<property name="store"><value>sitestore</value></property>
|
<property name="store"><value>sitestore</value></property>
|
||||||
|
-->
|
||||||
</bean>
|
</bean>
|
||||||
<bean id="webscript.org.alfresco.repository.store.remoteavm.delete" class="org.alfresco.repo.web.scripts.bean.AVMRemoteStore" parent="webscript">
|
<bean id="webscript.org.alfresco.repository.store.remoteavm.delete" class="org.alfresco.repo.web.scripts.bean.AVMRemoteStore" parent="webscript">
|
||||||
<property name="mimetypeService" ref="MimetypeService" />
|
<property name="mimetypeService" ref="MimetypeService" />
|
||||||
<property name="avmService" ref="AVMService" />
|
<property name="avmService" ref="AVMService" />
|
||||||
<property name="searchService" ref="SearchService" />
|
<property name="searchService" ref="SearchService" />
|
||||||
|
<!--
|
||||||
<property name="rootPath"><value>alfresco</value></property>
|
<property name="rootPath"><value>alfresco</value></property>
|
||||||
<property name="store"><value>sitestore</value></property>
|
<property name="store"><value>sitestore</value></property>
|
||||||
|
-->
|
||||||
</bean>
|
</bean>
|
||||||
|
|
||||||
|
|
||||||
|
@@ -28,6 +28,7 @@ import java.io.IOException;
|
|||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
import java.io.Writer;
|
import java.io.Writer;
|
||||||
import java.net.SocketException;
|
import java.net.SocketException;
|
||||||
|
import java.util.List;
|
||||||
import java.util.SortedMap;
|
import java.util.SortedMap;
|
||||||
import java.util.regex.Pattern;
|
import java.util.regex.Pattern;
|
||||||
|
|
||||||
@@ -36,6 +37,7 @@ import org.alfresco.repo.content.MimetypeMap;
|
|||||||
import org.alfresco.repo.security.authentication.AuthenticationUtil;
|
import org.alfresco.repo.security.authentication.AuthenticationUtil;
|
||||||
import org.alfresco.repo.security.authentication.AuthenticationUtil.RunAsWork;
|
import org.alfresco.repo.security.authentication.AuthenticationUtil.RunAsWork;
|
||||||
import org.alfresco.repo.security.permissions.AccessDeniedException;
|
import org.alfresco.repo.security.permissions.AccessDeniedException;
|
||||||
|
import org.alfresco.repo.web.scripts.RepoStore;
|
||||||
import org.alfresco.service.cmr.avm.AVMExistsException;
|
import org.alfresco.service.cmr.avm.AVMExistsException;
|
||||||
import org.alfresco.service.cmr.avm.AVMNodeDescriptor;
|
import org.alfresco.service.cmr.avm.AVMNodeDescriptor;
|
||||||
import org.alfresco.service.cmr.avm.AVMNotFoundException;
|
import org.alfresco.service.cmr.avm.AVMNotFoundException;
|
||||||
@@ -43,6 +45,9 @@ import org.alfresco.service.cmr.avm.AVMService;
|
|||||||
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.ContentWriter;
|
import org.alfresco.service.cmr.repository.ContentWriter;
|
||||||
|
import org.alfresco.service.cmr.repository.NodeRef;
|
||||||
|
import org.alfresco.service.cmr.repository.StoreRef;
|
||||||
|
import org.alfresco.service.cmr.search.ResultSet;
|
||||||
import org.alfresco.service.cmr.search.SearchService;
|
import org.alfresco.service.cmr.search.SearchService;
|
||||||
import org.alfresco.web.scripts.Status;
|
import org.alfresco.web.scripts.Status;
|
||||||
import org.alfresco.web.scripts.WebScriptException;
|
import org.alfresco.web.scripts.WebScriptException;
|
||||||
@@ -62,7 +67,7 @@ public class AVMRemoteStore extends BaseRemoteStore
|
|||||||
{
|
{
|
||||||
private static final Log logger = LogFactory.getLog(AVMRemoteStore.class);
|
private static final Log logger = LogFactory.getLog(AVMRemoteStore.class);
|
||||||
|
|
||||||
private String rootPath;
|
private String rootPath = "/";
|
||||||
private AVMService avmService;
|
private AVMService avmService;
|
||||||
private SearchService searchService;
|
private SearchService searchService;
|
||||||
|
|
||||||
@@ -72,6 +77,11 @@ public class AVMRemoteStore extends BaseRemoteStore
|
|||||||
*/
|
*/
|
||||||
public void setRootPath(String rootPath)
|
public void setRootPath(String rootPath)
|
||||||
{
|
{
|
||||||
|
if(rootPath != null && rootPath.length() == 0)
|
||||||
|
{
|
||||||
|
rootPath = "/";
|
||||||
|
}
|
||||||
|
|
||||||
this.rootPath = rootPath;
|
this.rootPath = rootPath;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -94,13 +104,14 @@ public class AVMRemoteStore extends BaseRemoteStore
|
|||||||
/**
|
/**
|
||||||
* Gets the last modified timestamp for the document.
|
* Gets the last modified timestamp for the document.
|
||||||
*
|
*
|
||||||
|
* @param store the store id
|
||||||
* @param path document path to an existing document
|
* @param path document path to an existing document
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
protected void lastModified(WebScriptResponse res, String path)
|
protected void lastModified(WebScriptResponse res, String store, String path)
|
||||||
throws IOException
|
throws IOException
|
||||||
{
|
{
|
||||||
String avmPath = buildAVMPath(path);
|
String avmPath = buildAVMPath(store, path);
|
||||||
AVMNodeDescriptor desc = this.avmService.lookup(-1, avmPath);
|
AVMNodeDescriptor desc = this.avmService.lookup(-1, avmPath);
|
||||||
if (desc == null)
|
if (desc == null)
|
||||||
{
|
{
|
||||||
@@ -116,9 +127,9 @@ public class AVMRemoteStore extends BaseRemoteStore
|
|||||||
* @see org.alfresco.repo.web.scripts.bean.BaseRemoteStore#getDocument(org.alfresco.web.scripts.WebScriptResponse, java.lang.String)
|
* @see org.alfresco.repo.web.scripts.bean.BaseRemoteStore#getDocument(org.alfresco.web.scripts.WebScriptResponse, java.lang.String)
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
protected void getDocument(final WebScriptResponse res, final String path) throws IOException
|
protected void getDocument(final WebScriptResponse res, final String store, final String path) throws IOException
|
||||||
{
|
{
|
||||||
final String avmPath = buildAVMPath(path);
|
final String avmPath = buildAVMPath(store, path);
|
||||||
final AVMNodeDescriptor desc = this.avmService.lookup(-1, avmPath);
|
final AVMNodeDescriptor desc = this.avmService.lookup(-1, avmPath);
|
||||||
if (desc == null)
|
if (desc == null)
|
||||||
{
|
{
|
||||||
@@ -201,9 +212,9 @@ public class AVMRemoteStore extends BaseRemoteStore
|
|||||||
* @see org.alfresco.repo.web.scripts.bean.BaseRemoteStore#hasDocument(org.alfresco.web.scripts.WebScriptResponse, java.lang.String)
|
* @see org.alfresco.repo.web.scripts.bean.BaseRemoteStore#hasDocument(org.alfresco.web.scripts.WebScriptResponse, java.lang.String)
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
protected void hasDocument(WebScriptResponse res, String path) throws IOException
|
protected void hasDocument(WebScriptResponse res, String store, String path) throws IOException
|
||||||
{
|
{
|
||||||
String avmPath = buildAVMPath(path);
|
String avmPath = buildAVMPath(store, path);
|
||||||
AVMNodeDescriptor desc = this.avmService.lookup(-1, avmPath);
|
AVMNodeDescriptor desc = this.avmService.lookup(-1, avmPath);
|
||||||
|
|
||||||
Writer out = res.getWriter();
|
Writer out = res.getWriter();
|
||||||
@@ -215,14 +226,14 @@ public class AVMRemoteStore extends BaseRemoteStore
|
|||||||
* @see org.alfresco.repo.web.scripts.bean.BaseRemoteStore#createDocument(org.alfresco.web.scripts.WebScriptResponse, java.lang.String, java.io.InputStream)
|
* @see org.alfresco.repo.web.scripts.bean.BaseRemoteStore#createDocument(org.alfresco.web.scripts.WebScriptResponse, java.lang.String, java.io.InputStream)
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
protected void createDocument(final WebScriptResponse res, final String path, final InputStream content)
|
protected void createDocument(final WebScriptResponse res, final String store, final String path, final InputStream content)
|
||||||
{
|
{
|
||||||
AuthenticationUtil.runAs(new RunAsWork<Object>()
|
AuthenticationUtil.runAs(new RunAsWork<Object>()
|
||||||
{
|
{
|
||||||
@SuppressWarnings("synthetic-access")
|
@SuppressWarnings("synthetic-access")
|
||||||
public Object doWork() throws Exception
|
public Object doWork() throws Exception
|
||||||
{
|
{
|
||||||
String avmPath = buildAVMPath(path);
|
String avmPath = buildAVMPath(store, path);
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
String[] parts = AVMNodeConverter.SplitBase(avmPath);
|
String[] parts = AVMNodeConverter.SplitBase(avmPath);
|
||||||
@@ -241,6 +252,7 @@ public class AVMRemoteStore extends BaseRemoteStore
|
|||||||
}
|
}
|
||||||
|
|
||||||
avmService.createFile(parts[0], parts[1], content);
|
avmService.createFile(parts[0], parts[1], content);
|
||||||
|
avmService.createSnapshot(store, "AVMRemoteStore.createDocument()", path);
|
||||||
}
|
}
|
||||||
catch (AccessDeniedException ae)
|
catch (AccessDeniedException ae)
|
||||||
{
|
{
|
||||||
@@ -259,9 +271,9 @@ public class AVMRemoteStore extends BaseRemoteStore
|
|||||||
* @see org.alfresco.repo.web.scripts.bean.BaseRemoteStore#updateDocument(org.alfresco.web.scripts.WebScriptResponse, java.lang.String, java.io.InputStream)
|
* @see org.alfresco.repo.web.scripts.bean.BaseRemoteStore#updateDocument(org.alfresco.web.scripts.WebScriptResponse, java.lang.String, java.io.InputStream)
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
protected void updateDocument(final WebScriptResponse res, final String path, final InputStream content)
|
protected void updateDocument(final WebScriptResponse res, final String store, final String path, final InputStream content)
|
||||||
{
|
{
|
||||||
final String avmPath = buildAVMPath(path);
|
final String avmPath = buildAVMPath(store, path);
|
||||||
AVMNodeDescriptor desc = this.avmService.lookup(-1, avmPath);
|
AVMNodeDescriptor desc = this.avmService.lookup(-1, avmPath);
|
||||||
if (desc == null)
|
if (desc == null)
|
||||||
{
|
{
|
||||||
@@ -292,9 +304,9 @@ public class AVMRemoteStore extends BaseRemoteStore
|
|||||||
* @see org.alfresco.repo.web.scripts.bean.BaseRemoteStore#deleteDocument(org.alfresco.web.scripts.WebScriptResponse, java.lang.String)
|
* @see org.alfresco.repo.web.scripts.bean.BaseRemoteStore#deleteDocument(org.alfresco.web.scripts.WebScriptResponse, java.lang.String)
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
protected void deleteDocument(final WebScriptResponse res, final String path)
|
protected void deleteDocument(final WebScriptResponse res, final String store, final String path)
|
||||||
{
|
{
|
||||||
final String avmPath = buildAVMPath(path);
|
final String avmPath = buildAVMPath(store, path);
|
||||||
AVMNodeDescriptor desc = this.avmService.lookup(-1, avmPath);
|
AVMNodeDescriptor desc = this.avmService.lookup(-1, avmPath);
|
||||||
if (desc == null)
|
if (desc == null)
|
||||||
{
|
{
|
||||||
@@ -310,6 +322,7 @@ public class AVMRemoteStore extends BaseRemoteStore
|
|||||||
try
|
try
|
||||||
{
|
{
|
||||||
avmService.removeNode(avmPath);
|
avmService.removeNode(avmPath);
|
||||||
|
avmService.createSnapshot(store, "AVMRemoteStore.deleteDocument()", path);
|
||||||
}
|
}
|
||||||
catch (AccessDeniedException ae)
|
catch (AccessDeniedException ae)
|
||||||
{
|
{
|
||||||
@@ -324,9 +337,9 @@ public class AVMRemoteStore extends BaseRemoteStore
|
|||||||
* @see org.alfresco.repo.web.scripts.bean.BaseRemoteStore#listDocuments(org.alfresco.web.scripts.WebScriptResponse, java.lang.String, boolean)
|
* @see org.alfresco.repo.web.scripts.bean.BaseRemoteStore#listDocuments(org.alfresco.web.scripts.WebScriptResponse, java.lang.String, boolean)
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
protected void listDocuments(WebScriptResponse res, String path, boolean recurse) throws IOException
|
protected void listDocuments(WebScriptResponse res, String store, String path, boolean recurse) throws IOException
|
||||||
{
|
{
|
||||||
String avmPath = buildAVMPath(path);
|
String avmPath = buildAVMPath(store, path);
|
||||||
AVMNodeDescriptor node = this.avmService.lookup(-1, avmPath);
|
AVMNodeDescriptor node = this.avmService.lookup(-1, avmPath);
|
||||||
if (node == null)
|
if (node == null)
|
||||||
{
|
{
|
||||||
@@ -336,7 +349,7 @@ public class AVMRemoteStore extends BaseRemoteStore
|
|||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
traverseNode(res.getWriter(), node, null, recurse);
|
traverseNode(res.getWriter(), store, node, recurse);
|
||||||
}
|
}
|
||||||
catch (AccessDeniedException ae)
|
catch (AccessDeniedException ae)
|
||||||
{
|
{
|
||||||
@@ -348,13 +361,45 @@ public class AVMRemoteStore extends BaseRemoteStore
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void traverseNode(Writer out, String store, AVMNodeDescriptor node, boolean recurse)
|
||||||
|
throws IOException
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* The node path appears as such:
|
||||||
|
* project1:/www/avm_webapps/ROOT/WEB-INF/classes/alfresco/site-data/template-instances/file.xml
|
||||||
|
*/
|
||||||
|
int cropPoint = store.length() + this.rootPath.length() + 1;
|
||||||
|
SortedMap<String, AVMNodeDescriptor> listing = this.avmService.getDirectoryListing(node);
|
||||||
|
for (AVMNodeDescriptor n : listing.values())
|
||||||
|
{
|
||||||
|
if (n.isFile())
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
String myPath = n.getPath();
|
||||||
|
String origPath = node.getPath();
|
||||||
|
|
||||||
|
String toWrite = myPath.substring(origPath.length());
|
||||||
|
out.write(toWrite);
|
||||||
|
out.write("\n");
|
||||||
|
*/
|
||||||
|
|
||||||
|
out.write(n.getPath().substring(cropPoint));
|
||||||
|
out.write("\n");
|
||||||
|
}
|
||||||
|
else if (recurse && n.isDirectory())
|
||||||
|
{
|
||||||
|
traverseNode(out, store, n, recurse);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* (non-Javadoc)
|
/* (non-Javadoc)
|
||||||
* @see org.alfresco.repo.web.scripts.bean.BaseRemoteStore#listDocuments(org.alfresco.web.scripts.WebScriptResponse, java.lang.String, java.lang.String)
|
* @see org.alfresco.repo.web.scripts.bean.BaseRemoteStore#listDocuments(org.alfresco.web.scripts.WebScriptResponse, java.lang.String, java.lang.String)
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
protected void listDocuments(WebScriptResponse res, String path, String pattern) throws IOException
|
protected void listDocuments(WebScriptResponse res, final String store, String path, String pattern) throws IOException
|
||||||
{
|
{
|
||||||
String avmPath = buildAVMPath(path);
|
String avmPath = buildAVMPath(store, path);
|
||||||
AVMNodeDescriptor node = this.avmService.lookup(-1, avmPath);
|
AVMNodeDescriptor node = this.avmService.lookup(-1, avmPath);
|
||||||
if (node == null)
|
if (node == null)
|
||||||
{
|
{
|
||||||
@@ -368,70 +413,68 @@ public class AVMRemoteStore extends BaseRemoteStore
|
|||||||
}
|
}
|
||||||
|
|
||||||
String matcher = pattern.replace(".","\\.").replace("*",".*");
|
String matcher = pattern.replace(".","\\.").replace("*",".*");
|
||||||
|
final Pattern pat = Pattern.compile(matcher);
|
||||||
|
|
||||||
try
|
String encPath = RepoStore.encodePathISO9075(path);
|
||||||
|
final StringBuilder query = new StringBuilder(128);
|
||||||
|
|
||||||
|
query.append("+PATH:\"").append(this.rootPath)
|
||||||
|
.append(encPath.length() != 0 ? ('/' + encPath) : "")
|
||||||
|
.append("//*\" +QNAME:")
|
||||||
|
.append(pattern);
|
||||||
|
|
||||||
|
/*
|
||||||
|
query.append("+PATH:\"/").append(this.rootPath)
|
||||||
|
.append(encPath.length() != 0 ? ('/' + encPath) : "")
|
||||||
|
.append("//*\" +QNAME:")
|
||||||
|
.append(pattern);
|
||||||
|
*/
|
||||||
|
|
||||||
|
final Writer out = res.getWriter();
|
||||||
|
final StoreRef avmStore = new StoreRef(StoreRef.PROTOCOL_AVM + StoreRef.URI_FILLER + store);
|
||||||
|
AuthenticationUtil.runAs(new RunAsWork<Object>()
|
||||||
{
|
{
|
||||||
traverseNode(res.getWriter(), node, Pattern.compile(matcher), true);
|
@SuppressWarnings("synthetic-access")
|
||||||
}
|
public Object doWork() throws Exception
|
||||||
catch (AccessDeniedException ae)
|
{
|
||||||
{
|
int cropPoint = store.length() + rootPath.length() + 1;
|
||||||
res.setStatus(Status.STATUS_UNAUTHORIZED);
|
ResultSet resultSet = searchService.query(avmStore, SearchService.LANGUAGE_LUCENE, query.toString());
|
||||||
}
|
try
|
||||||
finally
|
{
|
||||||
{
|
List<NodeRef> nodes = resultSet.getNodeRefs();
|
||||||
res.getWriter().close();
|
for (NodeRef nodeRef : nodes)
|
||||||
}
|
{
|
||||||
|
String path = AVMNodeConverter.ToAVMVersionPath(nodeRef).getSecond();
|
||||||
|
String name = path.substring(path.lastIndexOf('/') + 1);
|
||||||
|
if (pat.matcher(name).matches())
|
||||||
|
{
|
||||||
|
out.write(path.substring(cropPoint));
|
||||||
|
out.write("\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
resultSet.close();
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}, AuthenticationUtil.getSystemUserName());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
* @param store the store id
|
||||||
* @param path root path relative
|
* @param path root path relative
|
||||||
*
|
*
|
||||||
* @return full AVM path to document including store and root path components
|
* @return full AVM path to document including store and root path components
|
||||||
*/
|
*/
|
||||||
private String buildAVMPath(String path)
|
private String buildAVMPath(String store, String path)
|
||||||
{
|
{
|
||||||
return this.store + ":/" + this.rootPath + (path != null ? ("/" + path) : "");
|
//return store + ":/" + this.rootPath + (path != null ? ("/" + path) : "");
|
||||||
}
|
if(path.startsWith("/"))
|
||||||
|
{
|
||||||
/**
|
path = path.substring(1);
|
||||||
* Traverse a Node and recursively output the file paths it contains.
|
}
|
||||||
*
|
return store + ":" + this.rootPath + (path != null ? path : "");
|
||||||
* @param out Writer for output - relative paths separated by newline characters
|
|
||||||
* @param node The AVM Node to traverse
|
|
||||||
* @param pattern Optional Pattern to match filenames against
|
|
||||||
* @param recurse True to recurse sub-directories
|
|
||||||
*
|
|
||||||
* @throws IOException
|
|
||||||
*/
|
|
||||||
private void traverseNode(Writer out, AVMNodeDescriptor node, Pattern pattern, boolean recurse)
|
|
||||||
throws IOException
|
|
||||||
{
|
|
||||||
int cropPoint = this.store.length() + this.rootPath.length() + 3;
|
|
||||||
SortedMap<String, AVMNodeDescriptor> listing = this.avmService.getDirectoryListing(node);
|
|
||||||
for (AVMNodeDescriptor n : listing.values())
|
|
||||||
{
|
|
||||||
if (n.isFile())
|
|
||||||
{
|
|
||||||
String path = n.getPath();
|
|
||||||
if (pattern != null)
|
|
||||||
{
|
|
||||||
String name = path.substring(path.lastIndexOf('/') + 1);
|
|
||||||
if (pattern.matcher(name).matches())
|
|
||||||
{
|
|
||||||
out.write(path.substring(cropPoint));
|
|
||||||
out.write("\n");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
out.write(path.substring(cropPoint));
|
|
||||||
out.write("\n");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (recurse && n.isDirectory())
|
|
||||||
{
|
|
||||||
traverseNode(out, n, pattern, recurse);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -28,6 +28,7 @@ import java.io.IOException;
|
|||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.StringTokenizer;
|
||||||
|
|
||||||
import javax.servlet.http.HttpServletRequest;
|
import javax.servlet.http.HttpServletRequest;
|
||||||
|
|
||||||
@@ -49,6 +50,8 @@ import org.apache.commons.logging.LogFactory;
|
|||||||
*
|
*
|
||||||
* Request format:
|
* Request format:
|
||||||
* <servicepath>/<method>/<path>[?<args>]
|
* <servicepath>/<method>/<path>[?<args>]
|
||||||
|
* <servicepath>/<method>/s/<store>/<path>[?<args>]
|
||||||
|
* <servicepath>/<method>/s/<store>/w/<webapp>/<path>[?<args>]
|
||||||
*
|
*
|
||||||
* Example:
|
* Example:
|
||||||
* /service/remotestore/lastmodified/sites/xyz/pages/page.xml
|
* /service/remotestore/lastmodified/sites/xyz/pages/page.xml
|
||||||
@@ -57,6 +60,11 @@ import org.apache.commons.logging.LogFactory;
|
|||||||
* /service/remotestore -> service path
|
* /service/remotestore -> service path
|
||||||
* /lastmodified -> method name
|
* /lastmodified -> method name
|
||||||
* /sites/../page.xml -> document path
|
* /sites/../page.xml -> document path
|
||||||
|
*
|
||||||
|
* optional request parameters:
|
||||||
|
*
|
||||||
|
* s -> the avm store id
|
||||||
|
* w -> the wcm web application id
|
||||||
*
|
*
|
||||||
* Note: path is relative to the root path as configured for this webscript bean
|
* Note: path is relative to the root path as configured for this webscript bean
|
||||||
*
|
*
|
||||||
@@ -81,19 +89,25 @@ import org.apache.commons.logging.LogFactory;
|
|||||||
*/
|
*/
|
||||||
public abstract class BaseRemoteStore extends AbstractWebScript
|
public abstract class BaseRemoteStore extends AbstractWebScript
|
||||||
{
|
{
|
||||||
private static final Log logger = LogFactory.getLog(BaseRemoteStore.class);
|
public static final String TOKEN_STORE = "s";
|
||||||
|
public static final String TOKEN_WEBAPP = "w";
|
||||||
|
|
||||||
|
public static final String REQUEST_PARAM_STORE = "s";
|
||||||
|
public static final String REQUEST_PARAM_WEBAPP = "w";
|
||||||
|
|
||||||
|
private static final Log logger = LogFactory.getLog(BaseRemoteStore.class);
|
||||||
|
|
||||||
protected String store;
|
protected String defaultStore;
|
||||||
protected ContentService contentService;
|
protected ContentService contentService;
|
||||||
protected MimetypeService mimetypeService;
|
protected MimetypeService mimetypeService;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param store the store name of the store to process document requests against
|
* @param defaultStore the default store name of the store to process document requests against
|
||||||
*/
|
*/
|
||||||
public void setStore(String store)
|
public void setStore(String defaultStore)
|
||||||
{
|
{
|
||||||
this.store = store;
|
this.defaultStore = defaultStore;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -124,79 +138,156 @@ public abstract class BaseRemoteStore extends AbstractWebScript
|
|||||||
}
|
}
|
||||||
|
|
||||||
HttpServletRequest httpReq = ((WebScriptServletRequest)req).getHttpServletRequest();
|
HttpServletRequest httpReq = ((WebScriptServletRequest)req).getHttpServletRequest();
|
||||||
|
|
||||||
// break down and validate the request - expecting method name and document path
|
// the request path for the remote store
|
||||||
String extPath = req.getExtensionPath();
|
String extPath = req.getExtensionPath();
|
||||||
String[] extParts = extPath == null ? new String[0] : extPath.split("/");
|
|
||||||
if (extParts.length < 1)
|
// values that we need to determine
|
||||||
|
String methodName = null;
|
||||||
|
String store = null;
|
||||||
|
String webapp = null;
|
||||||
|
StringBuilder pathBuilder = null;
|
||||||
|
|
||||||
|
// tokenize the path and figure out tokenized values
|
||||||
|
StringTokenizer tokenizer = new StringTokenizer(extPath, "/");
|
||||||
|
if (tokenizer.hasMoreTokens())
|
||||||
{
|
{
|
||||||
throw new WebScriptException("Remote Store expecting method name.");
|
methodName = tokenizer.nextToken();
|
||||||
|
|
||||||
|
if (tokenizer.hasMoreTokens())
|
||||||
|
{
|
||||||
|
String el = tokenizer.nextToken();
|
||||||
|
|
||||||
|
if (TOKEN_STORE.equals(el))
|
||||||
|
{
|
||||||
|
// if the token is "s", then the next token is the id of the store
|
||||||
|
store = tokenizer.nextToken();
|
||||||
|
|
||||||
|
// reset el
|
||||||
|
el = (tokenizer.hasMoreTokens() ? tokenizer.nextToken() : null);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (TOKEN_WEBAPP.equals(el))
|
||||||
|
{
|
||||||
|
// if the token is "w", then the next token is a WCM webapp id
|
||||||
|
webapp = tokenizer.nextToken();
|
||||||
|
|
||||||
|
// reset el
|
||||||
|
el = (tokenizer.hasMoreTokens() ? tokenizer.nextToken() : null);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
while(el != null)
|
||||||
|
{
|
||||||
|
if(pathBuilder == null)
|
||||||
|
{
|
||||||
|
pathBuilder = new StringBuilder(128);
|
||||||
|
}
|
||||||
|
pathBuilder.append("/");
|
||||||
|
pathBuilder.append(el);
|
||||||
|
|
||||||
|
el = (tokenizer.hasMoreTokens() ? tokenizer.nextToken() : null);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
throw new WebScriptException("Unable to tokenize web path: " + extPath);
|
||||||
}
|
}
|
||||||
|
|
||||||
// extract path from url extension
|
// if we don't have a store, check whether it came in on a request parameter
|
||||||
String path = null;
|
if (store == null)
|
||||||
if (extParts.length >= 2)
|
|
||||||
{
|
{
|
||||||
path = req.getExtensionPath().substring(extParts[0].length() + 1);
|
store = req.getParameter(REQUEST_PARAM_STORE);
|
||||||
|
if (store == null)
|
||||||
|
{
|
||||||
|
store = this.defaultStore;
|
||||||
|
}
|
||||||
|
if (store == null)
|
||||||
|
{
|
||||||
|
// not good, we should have a store by this point
|
||||||
|
|
||||||
|
// this means that a store was not passed in and that we
|
||||||
|
// also didn't have a configured store
|
||||||
|
throw new WebScriptException("Unable to determine which store to operate against. A store was not specified and a default was not provided.");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// if we don't have a webapp, check whether it may have been passed in on a request parameter
|
||||||
|
if (webapp == null)
|
||||||
|
{
|
||||||
|
webapp = req.getParameter(REQUEST_PARAM_WEBAPP);
|
||||||
|
}
|
||||||
|
|
||||||
|
// if we do have a webapp, allow for path prepending
|
||||||
|
if (webapp != null)
|
||||||
|
{
|
||||||
|
pathBuilder.insert(0, "/www/avm_webapps/" + webapp);
|
||||||
|
}
|
||||||
|
|
||||||
|
// convert down to the path
|
||||||
|
String path = pathBuilder.toString();
|
||||||
|
|
||||||
|
// debugger information
|
||||||
if (logger.isDebugEnabled())
|
if (logger.isDebugEnabled())
|
||||||
logger.debug("Remote store method: " + extParts[0] + " path: " + path);
|
{
|
||||||
|
logger.debug("Remote method: " + methodName);
|
||||||
// TODO: support storeref name override as argument? (i.e. for AVM virtualisation)
|
logger.debug("Remote store id: " + store);
|
||||||
|
logger.debug("Remote path: " + path);
|
||||||
|
}
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
// generate enum from string method name - so we can use a fast switch table lookup
|
// generate enum from string method name - so we can use a fast switch table lookup
|
||||||
APIMethod method = APIMethod.valueOf(extParts[0].toUpperCase());
|
APIMethod method = APIMethod.valueOf(methodName.toUpperCase());
|
||||||
switch (method)
|
switch (method)
|
||||||
{
|
{
|
||||||
case LASTMODIFIED:
|
case LASTMODIFIED:
|
||||||
validatePath(path);
|
validatePath(path);
|
||||||
lastModified(res, path);
|
lastModified(res, store, path);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case HAS:
|
case HAS:
|
||||||
validatePath(path);
|
validatePath(path);
|
||||||
hasDocument(res, path);
|
hasDocument(res, store, path);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case GET:
|
case GET:
|
||||||
validatePath(path);
|
validatePath(path);
|
||||||
getDocument(res, path);
|
getDocument(res, store, path);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case LIST:
|
case LIST:
|
||||||
listDocuments(res, path, false);
|
listDocuments(res, store, path, false);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case LISTALL:
|
case LISTALL:
|
||||||
listDocuments(res, path, true);
|
listDocuments(res, store, path, true);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case LISTPATTERN:
|
case LISTPATTERN:
|
||||||
listDocuments(res, path, req.getParameter("m"));
|
listDocuments(res, store, path, req.getParameter("m"));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case CREATE:
|
case CREATE:
|
||||||
validatePath(path);
|
validatePath(path);
|
||||||
createDocument(res, path, httpReq.getInputStream());
|
createDocument(res, store, path, httpReq.getInputStream());
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case UPDATE:
|
case UPDATE:
|
||||||
validatePath(path);
|
validatePath(path);
|
||||||
updateDocument(res, path, httpReq.getInputStream());
|
updateDocument(res, store, path, httpReq.getInputStream());
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case DELETE:
|
case DELETE:
|
||||||
validatePath(path);
|
validatePath(path);
|
||||||
deleteDocument(res, path);
|
deleteDocument(res, store, path);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch (IllegalArgumentException enumErr)
|
catch (IllegalArgumentException enumErr)
|
||||||
{
|
{
|
||||||
throw new WebScriptException("Unknown method specified to remote store API: " + extParts[0]);
|
throw new WebScriptException("Unknown method specified to remote store API: " + methodName);
|
||||||
}
|
}
|
||||||
catch (IOException ioErr)
|
catch (IOException ioErr)
|
||||||
{
|
{
|
||||||
@@ -233,9 +324,10 @@ public abstract class BaseRemoteStore extends AbstractWebScript
|
|||||||
*
|
*
|
||||||
* The output will be the last modified date as a long toString().
|
* The output will be the last modified date as a long toString().
|
||||||
*
|
*
|
||||||
|
* @param store the store id
|
||||||
* @param path document path to an existing document
|
* @param path document path to an existing document
|
||||||
*/
|
*/
|
||||||
protected abstract void lastModified(WebScriptResponse res, String path)
|
protected abstract void lastModified(WebScriptResponse res, String store, String path)
|
||||||
throws IOException;
|
throws IOException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -243,9 +335,10 @@ public abstract class BaseRemoteStore extends AbstractWebScript
|
|||||||
*
|
*
|
||||||
* The output will be either the string "true" or the string "false".
|
* The output will be either the string "true" or the string "false".
|
||||||
*
|
*
|
||||||
|
* @param store the store id
|
||||||
* @param path document path
|
* @param path document path
|
||||||
*/
|
*/
|
||||||
protected abstract void hasDocument(WebScriptResponse res, String path)
|
protected abstract void hasDocument(WebScriptResponse res, String store, String path)
|
||||||
throws IOException;
|
throws IOException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -253,12 +346,13 @@ public abstract class BaseRemoteStore extends AbstractWebScript
|
|||||||
*
|
*
|
||||||
* The output will be the document content stream.
|
* The output will be the document content stream.
|
||||||
*
|
*
|
||||||
|
* @param store the store id
|
||||||
* @param path document path
|
* @param path document path
|
||||||
* @return
|
* @return
|
||||||
*
|
*
|
||||||
* @throws IOException if an error occurs retrieving the document
|
* @throws IOException if an error occurs retrieving the document
|
||||||
*/
|
*/
|
||||||
protected abstract void getDocument(WebScriptResponse res, String path)
|
protected abstract void getDocument(WebScriptResponse res, String store, String path)
|
||||||
throws IOException;
|
throws IOException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -267,12 +361,13 @@ public abstract class BaseRemoteStore extends AbstractWebScript
|
|||||||
* The output will be the list of relative document paths found under the path.
|
* The output will be the list of relative document paths found under the path.
|
||||||
* Separated by newline characters.
|
* Separated by newline characters.
|
||||||
*
|
*
|
||||||
|
* @param store the store id
|
||||||
* @param path document path
|
* @param path document path
|
||||||
* @param recurse true to peform a recursive list, false for direct children only.
|
* @param recurse true to peform a recursive list, false for direct children only.
|
||||||
*
|
*
|
||||||
* @throws IOException if an error occurs listing the documents
|
* @throws IOException if an error occurs listing the documents
|
||||||
*/
|
*/
|
||||||
protected abstract void listDocuments(WebScriptResponse res, String path, boolean recurse)
|
protected abstract void listDocuments(WebScriptResponse res, String store, String path, boolean recurse)
|
||||||
throws IOException;
|
throws IOException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -281,42 +376,46 @@ public abstract class BaseRemoteStore extends AbstractWebScript
|
|||||||
* The output will be the list of relative document paths found under the path that
|
* The output will be the list of relative document paths found under the path that
|
||||||
* match the given file pattern. Separated by newline characters.
|
* match the given file pattern. Separated by newline characters.
|
||||||
*
|
*
|
||||||
|
* @param store the store id
|
||||||
* @param path document path
|
* @param path document path
|
||||||
* @param pattern file pattern to match - allows wildcards e.g. *.xml or site*.xml
|
* @param pattern file pattern to match - allows wildcards e.g. *.xml or site*.xml
|
||||||
*
|
*
|
||||||
* @throws IOException if an error occurs listing the documents
|
* @throws IOException if an error occurs listing the documents
|
||||||
*/
|
*/
|
||||||
protected abstract void listDocuments(WebScriptResponse res, String path, String pattern)
|
protected abstract void listDocuments(WebScriptResponse res, String store, String path, String pattern)
|
||||||
throws IOException;
|
throws IOException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a document.
|
* Creates a document.
|
||||||
*
|
*
|
||||||
* @param path document path
|
* @param store the store id
|
||||||
|
* @param path document path
|
||||||
* @param content content of the document to write
|
* @param content content of the document to write
|
||||||
*
|
*
|
||||||
* @throws IOException if the create fails
|
* @throws IOException if the create fails
|
||||||
*/
|
*/
|
||||||
protected abstract void createDocument(WebScriptResponse res, String path, InputStream content);
|
protected abstract void createDocument(WebScriptResponse res, String store, String path, InputStream content);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Updates an existing document.
|
* Updates an existing document.
|
||||||
*
|
*
|
||||||
|
* @param store the store id
|
||||||
* @param path document path
|
* @param path document path
|
||||||
* @param content content to update the document with
|
* @param content content to update the document with
|
||||||
*
|
*
|
||||||
* @throws IOException if the update fails
|
* @throws IOException if the update fails
|
||||||
*/
|
*/
|
||||||
protected abstract void updateDocument(WebScriptResponse res, String path, InputStream content);
|
protected abstract void updateDocument(WebScriptResponse res, String store, String path, InputStream content);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Deletes an existing document.
|
* Deletes an existing document.
|
||||||
*
|
*
|
||||||
|
* @param store the store id
|
||||||
* @param path document path
|
* @param path document path
|
||||||
*
|
*
|
||||||
* @throws IOException if the delete fails
|
* @throws IOException if the delete fails
|
||||||
*/
|
*/
|
||||||
protected abstract void deleteDocument(WebScriptResponse res, String path);
|
protected abstract void deleteDocument(WebScriptResponse res, String store, String path);
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
Reference in New Issue
Block a user