mirror of
https://github.com/Alfresco/alfresco-community-repo.git
synced 2025-08-14 17:58:59 +00:00
Merging BRANCHES/DEV/CMIS_10 to HEAD (phase 2 - currently up-to-date with branch):
18717: SAIL-166: Refactor CMIS to use shared services and resolve objectIds and error codes consistently 18731: SAIL-169: CMIS REST versioning compliance 18732: Fix failing change log test. 18768: Add displayName and queryName attributes to rendered properties (in CMIS AtomPub binding). 18775: Fix exception reporting when retrieving items that do not exist (in CMIS AtomPub binding). 18784: Fix CMIS REST change logging 18785: SAIL-174: CMIS Relationship lookup by association ID 18812: SAIL-183: Support orderBy argument for getChildren and getCheckedOutDocs in CMIS REST and Web Service bindings 18823: CMIS WS Bindings were moved to 1.0 cd07 schema. 18838: Update to latest Chemistry TCK. git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/alfresco/HEAD/root@18847 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261
This commit is contained in:
@@ -280,6 +280,7 @@
|
||||
<value>dmDiscoveryService</value>
|
||||
<value>dmRelationshipService</value>
|
||||
<value>dmPolicyService</value>
|
||||
<value>dmAclService</value>
|
||||
</list>
|
||||
</property>
|
||||
<property name="interceptorNames">
|
||||
@@ -305,25 +306,12 @@
|
||||
|
||||
<bean id="exceptionPointcutAdvisor" class="org.springframework.aop.support.DefaultPointcutAdvisor">
|
||||
<property name="advice">
|
||||
<bean class="org.alfresco.repo.cmis.ws.DMServicePortThrowsAdvice">
|
||||
<property name="cmisObjectsUtils" ref="cmisObjectsUtils" />
|
||||
</bean>
|
||||
<bean class="org.alfresco.repo.cmis.ws.DMServicePortThrowsAdvice" />
|
||||
</property>
|
||||
</bean>
|
||||
|
||||
<bean id="cmisObjectsUtils" class="org.alfresco.repo.cmis.ws.utils.CmisObjectsUtils">
|
||||
<property name="lockService" ref="LockService" />
|
||||
<property name="checkOutCheckInService" ref="CheckoutCheckinService" />
|
||||
<property name="authorityService" ref="AuthorityService" />
|
||||
<property name="versionService" ref="VersionService" />
|
||||
<property name="cmisDictionaryService" ref="CMISDictionaryService" />
|
||||
<property name="fileFolderService" ref="FileFolderService" />
|
||||
<property name="nodeService" ref="NodeService" />
|
||||
</bean>
|
||||
|
||||
<bean id="propertiesUtils" class="org.alfresco.repo.cmis.ws.utils.PropertyUtil">
|
||||
<property name="cmisDictionaryService" ref="CMISDictionaryService" />
|
||||
<property name="cmisObjectsUtils" ref="cmisObjectsUtils" />
|
||||
<property name="cmisService" ref="CMISService" />
|
||||
<property name="nodeService" ref="NodeService" />
|
||||
<property name="dictionaryService" ref="DictionaryService" />
|
||||
@@ -341,15 +329,11 @@
|
||||
|
||||
<bean id="dmMultiFilingService" parent="dmAbstractService" class="org.alfresco.repo.cmis.ws.DMMultiFilingServicePort" />
|
||||
|
||||
<bean id="dmVersioningService" parent="dmAbstractService" class="org.alfresco.repo.cmis.ws.DMVersioningServicePort">
|
||||
<property name="lockService" ref="LockService" />
|
||||
</bean>
|
||||
<bean id="dmVersioningService" parent="dmAbstractService" class="org.alfresco.repo.cmis.ws.DMVersioningServicePort" />
|
||||
|
||||
<bean id="dmDiscoveryService" parent="dmAbstractService" class="org.alfresco.repo.cmis.ws.DMDiscoveryServicePort" />
|
||||
|
||||
<bean id="dmRelationshipService" parent="dmAbstractService" class="org.alfresco.repo.cmis.ws.DMRelationshipServicePort" >
|
||||
<property name="dictionaryService" ref="DictionaryService" />
|
||||
</bean>
|
||||
<bean id="dmRelationshipService" parent="dmAbstractService" class="org.alfresco.repo.cmis.ws.DMRelationshipServicePort" />
|
||||
|
||||
<bean id="dmPolicyService" parent="dmAbstractService" class="org.alfresco.repo.cmis.ws.DMPolicyServicePort" />
|
||||
|
||||
@@ -358,20 +342,16 @@
|
||||
<bean id="dmAbstractService" abstract="true" class="org.alfresco.repo.cmis.ws.DMAbstractServicePort">
|
||||
<property name="cmisService" ref="CMISService" />
|
||||
<property name="cmisQueryService" ref="CMISQueryService" />
|
||||
<property name="cmisDictionaryService" ref="CMISDictionaryService" />
|
||||
<property name="cmisRenditionService" ref="CMISRenditionService" />
|
||||
<property name="cmisChangeLogService" ref="CMISChangeLogService" />
|
||||
<property name="cmisAclService" ref="CMISAccessControlService" />
|
||||
|
||||
<property name="descriptorService" ref="DescriptorService" />
|
||||
<property name="nodeService" ref="NodeService" />
|
||||
<property name="versionService" ref="VersionService" />
|
||||
<property name="fileFolderService" ref="FileFolderService" />
|
||||
<property name="checkOutCheckInService" ref="CheckoutCheckinService" />
|
||||
<property name="searchService" ref="SearchService" />
|
||||
<property name="permissionService" ref="PermissionService" />
|
||||
|
||||
<property name="cmisObjectsUtils" ref="cmisObjectsUtils" />
|
||||
<property name="propertiesUtil" ref="propertiesUtils" />
|
||||
</bean>
|
||||
|
||||
|
@@ -30,33 +30,8 @@ script:
|
||||
}
|
||||
model.node = object.node;
|
||||
|
||||
// ensure node can be checked-out
|
||||
if (!model.node.isDocument)
|
||||
{
|
||||
status.code = 400;
|
||||
status.message = "Cannot checkout node " + object.ref + " as it is not a document";
|
||||
status.redirect = true;
|
||||
break script;
|
||||
}
|
||||
|
||||
// TODO: need to test for isCheckedOut not isLocked
|
||||
if (model.node.isLocked || model.node.hasAspect("cm:workingCopy"))
|
||||
{
|
||||
status.code = 400;
|
||||
status.message = "Cannot checkout node " + object.ref + " as it is already checked-out";
|
||||
status.redirect = true;
|
||||
break script;
|
||||
}
|
||||
|
||||
// switch on versioning
|
||||
if (!model.node.hasAspect("cm:versionable"))
|
||||
{
|
||||
// create an initial version of the current document
|
||||
model.node.createVersion("Initial Version", true);
|
||||
}
|
||||
|
||||
// checkout
|
||||
model.pwc = model.node.checkout();
|
||||
model.pwc = cmis.checkOut(objectId);
|
||||
|
||||
// setup for 201 Created response
|
||||
// TODO: set Content-Location
|
||||
|
@@ -36,14 +36,14 @@ If no “maxItems” value is provided, then the Repository will determine an ap
|
||||
</description>
|
||||
|
||||
<!-- by object id -->
|
||||
<url>/cmis/i/{id}/children?types={types}&filter={filter?}&skipCount={skipCount?}&maxItems={maxItems?}&includeAllowableActions={includeAllowableActions?}&renditionFilter={renditionFilter?}</url>
|
||||
<url>/cmis/s/{store}/i/{id}/children?types={types}&filter={filter?}&skipCount={skipCount?}&maxItems={maxItems?}&includeAllowableActions={includeAllowableActions?}&renditionFilter={renditionFilter?}</url>
|
||||
<url>/cmis/i/{id}/children?types={types}&filter={filter?}&skipCount={skipCount?}&maxItems={maxItems?}&includeAllowableActions={includeAllowableActions?}&renditionFilter={renditionFilter?}&orderBy={orderBy?}</url>
|
||||
<url>/cmis/s/{store}/i/{id}/children?types={types}&filter={filter?}&skipCount={skipCount?}&maxItems={maxItems?}&includeAllowableActions={includeAllowableActions?}&renditionFilter={renditionFilter?}&orderBy={orderBy?}</url>
|
||||
<!-- by path -->
|
||||
<url>/cmis/p{path}/children?types={types}&filter={filter?}&skipCount={skipCount?}&maxItems={maxItems?}&includeAllowableActions={includeAllowableActions?}&renditionFilter={renditionFilter?}</url>
|
||||
<url>/cmis/s/{store}/p{path}/children?types={types}&filter={filter?}&skipCount={skipCount?}&maxItems={maxItems?}&includeAllowableActions={includeAllowableActions?}&renditionFilter={renditionFilter?}</url>
|
||||
<url>/cmis/p{path}/children?types={types}&filter={filter?}&skipCount={skipCount?}&maxItems={maxItems?}&includeAllowableActions={includeAllowableActions?}&renditionFilter={renditionFilter?}&orderBy={orderBy?}</url>
|
||||
<url>/cmis/s/{store}/p{path}/children?types={types}&filter={filter?}&skipCount={skipCount?}&maxItems={maxItems?}&includeAllowableActions={includeAllowableActions?}&renditionFilter={renditionFilter?}&orderBy={orderBy?}</url>
|
||||
<!-- alfresco style -->
|
||||
<url>/api/node/{store_type}/{store_id}/{id}/children?types={types}&filter={filter?}&skipCount={skipCount?}&maxItems={maxItems?}&includeAllowableActions={includeAllowableActions?}&renditionFilter={renditionFilter?}</url>
|
||||
<url>/api/path/{store_type}/{store_id}/{path}/children?types={types}&filter={filter?}&skipCount={skipCount?}&maxItems={maxItems?}&includeAllowableActions={includeAllowableActions?}&renditionFilter={renditionFilter?}</url>
|
||||
<url>/api/node/{store_type}/{store_id}/{id}/children?types={types}&filter={filter?}&skipCount={skipCount?}&maxItems={maxItems?}&includeAllowableActions={includeAllowableActions?}&renditionFilter={renditionFilter?}&orderBy={orderBy?}</url>
|
||||
<url>/api/path/{store_type}/{store_id}/{path}/children?types={types}&filter={filter?}&skipCount={skipCount?}&maxItems={maxItems?}&includeAllowableActions={includeAllowableActions?}&renditionFilter={renditionFilter?}&orderBy={orderBy?}</url>
|
||||
|
||||
<authentication>guest</authentication>
|
||||
<transaction allow="readonly"/>
|
||||
|
@@ -34,13 +34,16 @@ script:
|
||||
model.renditionFilter = "cmis:none";
|
||||
}
|
||||
|
||||
// order by
|
||||
var orderBy = args[cmis.ARG_ORDER_BY];
|
||||
|
||||
// include allowable actions
|
||||
var includeAllowableActions = args[cmis.ARG_INCLUDE_ALLOWABLE_ACTIONS];
|
||||
model.includeAllowableActions = (includeAllowableActions == "true" ? true : false);
|
||||
|
||||
// retrieve children
|
||||
var page = paging.createPageOrWindow(args);
|
||||
var paged = cmis.queryChildren(model.node, model.types, page);
|
||||
var paged = cmis.queryChildren(model.node, model.types, orderBy, page);
|
||||
model.results = paged.results;
|
||||
model.cursor = paged.cursor;
|
||||
}
|
||||
|
@@ -21,24 +21,33 @@ script:
|
||||
}
|
||||
model.parent = parent.node;
|
||||
|
||||
// versioning state
|
||||
var versioningState = args[cmis.ARG_VERSIONING_STATE];
|
||||
if (versioningState === null || versioningState.length == 0)
|
||||
{
|
||||
versioningState = "major";
|
||||
}
|
||||
|
||||
// is this a create or move?
|
||||
var object = entry.getExtension(atom.names.cmisra_object);
|
||||
var objectIdProp = (object !== null) ? object.objectId : null;
|
||||
var objectId = (objectIdProp !== null) ? objectIdProp.nativeValue : null;
|
||||
var sourceFolderId = args[cmis.ARG_SOURCE_FOLDER_ID];
|
||||
var node = null;
|
||||
|
||||
if (objectId == null)
|
||||
{
|
||||
// create node
|
||||
node = createNode(model.parent, entry, slug);
|
||||
node = createNode(model.parent, entry, slug, versioningState);
|
||||
if (node == null)
|
||||
{
|
||||
break script;
|
||||
}
|
||||
node.save();
|
||||
}
|
||||
else
|
||||
else if (sourceFolderId == null || sourceFolderId.length == 0)
|
||||
{
|
||||
// locate node and its source folder
|
||||
// Add node
|
||||
var object = getObjectFromObjectId(objectId);
|
||||
if (object.node == null)
|
||||
{
|
||||
@@ -46,44 +55,25 @@ script:
|
||||
}
|
||||
node = object.node;
|
||||
|
||||
cmis.addObjectToFolder(node, model.parent);
|
||||
}
|
||||
else
|
||||
{
|
||||
// move node
|
||||
var sourceFolderId = args[cmis.ARG_SOURCE_FOLDER_ID];
|
||||
if (sourceFolderId == null)
|
||||
{
|
||||
status.code = 400;
|
||||
status.message = "Move of object " + object.ref + " requires sourceFolderId argument";
|
||||
status.redirect = true;
|
||||
break script;
|
||||
}
|
||||
|
||||
var sourceFolderObject = getObjectFromObjectId(sourceFolderId);
|
||||
if (sourceFolderObject.node == null)
|
||||
// locate node
|
||||
var object = getObjectFromObjectId(objectId);
|
||||
if (object.node == null)
|
||||
{
|
||||
status.code = 400;
|
||||
break script;
|
||||
}
|
||||
if (!sourceFolderObject.node.nodeRef.equals(node.parent.nodeRef))
|
||||
{
|
||||
status.code = 400;
|
||||
status.message = "Source Folder " + sourceFolderObject.ref + " is not parent of object " + object.ref;
|
||||
status.redirect = true;
|
||||
break script;
|
||||
}
|
||||
var sourceFolder = sourceFolderObject.node;
|
||||
node = object.node;
|
||||
|
||||
// perform move
|
||||
var success = node.move(model.parent);
|
||||
if (!success)
|
||||
{
|
||||
status.code = 500;
|
||||
status.message = "Failed to move object " + object.ref + " from folder " + sourceFolderObject.ref + " to folder " + parent.ref;
|
||||
status.redirect = true;
|
||||
break script;
|
||||
}
|
||||
cmis.moveObject(node, model.parent, sourceFolderId);
|
||||
}
|
||||
|
||||
// success
|
||||
node.save();
|
||||
model.node = node;
|
||||
// TODO: set Content-Location
|
||||
status.code = 201;
|
||||
|
@@ -42,14 +42,14 @@ Root folder can not be created using this service.<br>
|
||||
]]>
|
||||
</description>
|
||||
|
||||
<url>/cmis/i/{id}/children?sourceFolderId={sourceFolderId}</url>
|
||||
<url>/cmis/s/{store}/i/{id}/children?sourceFolderId={sourceFolderId}</url>
|
||||
<url>/cmis/i/{id}/children?sourceFolderId={sourceFolderId}&versioningState={versioningState?}</url>
|
||||
<url>/cmis/s/{store}/i/{id}/children?sourceFolderId={sourceFolderId}&versioningState={versioningState?}</url>
|
||||
<!-- by path -->
|
||||
<url>/cmis/p{path}/children?sourceFolderId={sourceFolderId}</url>
|
||||
<url>/cmis/s/{store}/p{path}/children?sourceFolderId={sourceFolderId}</url>
|
||||
<url>/cmis/p{path}/children?sourceFolderId={sourceFolderId}&versioningState={versioningState?}</url>
|
||||
<url>/cmis/s/{store}/p{path}/children?sourceFolderId={sourceFolderId}&versioningState={versioningState?}</url>
|
||||
<!-- alfresco style -->
|
||||
<url>/api/node/{store_type}/{store_id}/{id}/children?sourceFolderId={sourceFolderId}</url>
|
||||
<url>/api/path/{store_type}/{store_id}/{path}/children?sourceFolderId={sourceFolderId}</url>
|
||||
<url>/api/node/{store_type}/{store_id}/{id}/children?sourceFolderId={sourceFolderId}&versioningState={versioningState?}</url>
|
||||
<url>/api/path/{store_type}/{store_id}/{path}/children?sourceFolderId={sourceFolderId}&versioningState={versioningState?}</url>
|
||||
|
||||
<authentication>user</authentication>
|
||||
<format default="atomentry"/>
|
||||
|
@@ -8,38 +8,9 @@ script:
|
||||
{
|
||||
break script;
|
||||
}
|
||||
node = object.node;
|
||||
var node = object.node;
|
||||
|
||||
if (!node.hasPermission("Delete"))
|
||||
{
|
||||
status.code = 403;
|
||||
status.message = "Permission to delete is denied";
|
||||
status.redirect = true;
|
||||
break script;
|
||||
}
|
||||
|
||||
// if deleting a folder, only delete when the folder is empty or
|
||||
// a force delete has been specified
|
||||
// NOTE: force delete is not part of CMIS specification
|
||||
if (node.isFolder)
|
||||
{
|
||||
if (node.children.length > 0 && !args.includeChildren)
|
||||
{
|
||||
status.code = 403;
|
||||
status.message = "Cannot delete folder " + pathSegments[2] + " " + reference.join("/") + " as it's not empty";
|
||||
status.redirect = true;
|
||||
break script;
|
||||
}
|
||||
}
|
||||
|
||||
// Note: checked-out documents are automatically unlocked if a private working copy is deleted
|
||||
if (!node.remove())
|
||||
{
|
||||
status.code = 500;
|
||||
status.message = "Failed to delete node " + pathSegments[2] + " " + reference.join("/");
|
||||
status.redirect = true;
|
||||
break script;
|
||||
}
|
||||
cmis.deleteContentStream(node);
|
||||
|
||||
status.code = 204; // Success, but no response content
|
||||
status.redirect = true;
|
||||
|
@@ -10,36 +10,8 @@ script:
|
||||
}
|
||||
var node = object.node;
|
||||
|
||||
if (!node.hasPermission("Delete"))
|
||||
{
|
||||
status.code = 403;
|
||||
status.message = "Permission to delete object " + object.ref + " is denied";
|
||||
status.redirect = true;
|
||||
break script;
|
||||
}
|
||||
|
||||
// if deleting a folder, only delete when the folder is empty or
|
||||
// a force delete has been specified
|
||||
// NOTE: force delete is not part of CMIS specification
|
||||
if (node.isFolder)
|
||||
{
|
||||
if (node.children.length > 0 && !args.includeChildren)
|
||||
{
|
||||
status.code = 403;
|
||||
status.message = "Cannot delete folder " + object.ref + " as it's not empty";
|
||||
status.redirect = true;
|
||||
break script;
|
||||
}
|
||||
}
|
||||
|
||||
// Note: checked-out documents are automatically unlocked if a private working copy is deleted
|
||||
if (!node.remove())
|
||||
{
|
||||
status.code = 500;
|
||||
status.message = "Failed to delete object " + object.ref;
|
||||
status.redirect = true;
|
||||
break script;
|
||||
}
|
||||
// Intentionally pass false as allVersions flag for now. There is no binding.
|
||||
cmis.deleteObject(node, false);
|
||||
|
||||
status.code = 204; // Success, but no response content
|
||||
status.redirect = true;
|
||||
|
@@ -25,7 +25,6 @@ Does not return the content-stream of a document<br>
|
||||
PropertyCollection includes changeToken (if applicable to repository)<br>
|
||||
]]>
|
||||
</description>
|
||||
<!-- TODO: spec issue: returnVersion or returnCurrent? -->
|
||||
|
||||
<!-- by object id -->
|
||||
<url>/cmis/i/{id}?filter={filter?}&returnVersion={returnVersion?}&includeAllowableActions={includeAllowableActions?}&includeACL={includeACL?}&renditionFilter={renditionFilter?}</url>
|
||||
|
@@ -9,7 +9,13 @@ script:
|
||||
}
|
||||
model.node = object.node;
|
||||
|
||||
// TODO: handle version??
|
||||
// return version
|
||||
var returnVersion = args[cmis.ARG_RETURN_VERSION];
|
||||
if (returnVersion === null || returnVersion.length == 0)
|
||||
{
|
||||
returnVersion = "this";
|
||||
}
|
||||
model.node = cmis.getReturnVersion(model.node, returnVersion);
|
||||
|
||||
// property filter
|
||||
model.filter = args[cmis.ARG_FILTER];
|
||||
|
@@ -15,7 +15,7 @@
|
||||
[#assign typedef = cmistype(object)]
|
||||
|
||||
[#list typedef.propertyDefinitions?values as propdef]
|
||||
[@filter propfilter propdef.queryName][@prop propdef.propertyId.id object propdef.dataType.label/][/@filter]
|
||||
[@filter propfilter propdef.queryName][@prop object propdef/][/@filter]
|
||||
[/#list]
|
||||
</cmis:properties>
|
||||
[/#macro]
|
||||
@@ -69,7 +69,7 @@
|
||||
[#-- ATOM Entry for Version --]
|
||||
[#-- --]
|
||||
|
||||
[#macro version node version propfilter="*" ns=""]
|
||||
[#macro version node propfilter="*" ns=""]
|
||||
[@entry ns]
|
||||
<author><name>${node.properties.creator!""}</name></author>
|
||||
[@contentstream node/]
|
||||
@@ -263,10 +263,19 @@
|
||||
[#assign rowvalues = row.values]
|
||||
[#list rowvalues?keys as colname]
|
||||
[#assign coltype = row.getColumnType(colname)]
|
||||
[#assign propdef = row.getPropertyDefinition(colname)]
|
||||
[#if rowvalues[colname]??]
|
||||
[@propvalue colname rowvalues[colname] coltype/]
|
||||
[#if propdef??]
|
||||
[@propvalue rowvalues[colname] coltype colname propdef.displayName propdef.queryName propdef.propertyId.localName/]
|
||||
[#else]
|
||||
[@propnull colname coltype/]
|
||||
[@propvalue rowvalues[colname] coltype colname/]
|
||||
[/#if]
|
||||
[#else]
|
||||
[#if propdef??]
|
||||
[@propnull coltype colname propdef.displayName propdef.queryName propdef.propertyId.localName/]
|
||||
[#else]
|
||||
[@propnull coltype colname/]
|
||||
[/#if]
|
||||
[/#if]
|
||||
[/#list]
|
||||
</cmis:properties>
|
||||
@@ -289,7 +298,7 @@
|
||||
<updated>${xmldate(event.changeTime)}</updated>
|
||||
<cmisra:object>
|
||||
<cmis:properties>
|
||||
[@propvalue "cmis:objectId" node.nodeRef?string cmisconstants.DATATYPE_ID/]
|
||||
[@propvalue event.objectId cmisconstants.DATATYPE_ID "cmis:objectId"/]
|
||||
</cmis:properties>
|
||||
<cmis:changeEventInfo>
|
||||
<cmis:changeType>${event.changeType.label}</cmis:changeType>
|
||||
@@ -309,54 +318,63 @@
|
||||
[#if filter == "*" || filter?index_of(value) != -1 || filter?matches(value,'i')][#nested][/#if]
|
||||
[/#macro]
|
||||
|
||||
[#macro prop name object type]
|
||||
[#assign value=cmisproperty(object, name)/]
|
||||
[#macro prop object propdef]
|
||||
[#assign value=cmisproperty(object, propdef.propertyId.id)/]
|
||||
[#if value?is_string || value?is_number || value?is_boolean || value?is_date || value?is_enumerable]
|
||||
[@propvalue name value type/]
|
||||
[@propvaluedef value propdef/]
|
||||
[#elseif value.class.canonicalName?ends_with("NULL")]
|
||||
[@propnull name type/]
|
||||
[@propnulldef propdef/]
|
||||
[/#if]
|
||||
[/#macro]
|
||||
|
||||
[#macro propvalue name value type]
|
||||
[#macro propvaluedef value propdef]
|
||||
[@propvalue value propdef.dataType.label propdef.propertyId.id propdef.displayName propdef.queryName propdef.propertyId.localName/]
|
||||
[/#macro]
|
||||
|
||||
[#macro propvalue value type name displayname="" queryname="" localname=""]
|
||||
[#if type == cmisconstants.DATATYPE_STRING]
|
||||
<cmis:propertyString propertyDefinitionId="${name}">[@values value;v]<cmis:value>[@stringvalue v/]</cmis:value>[/@values]</cmis:propertyString>
|
||||
<cmis:propertyString [@propargs name displayname queryname localname/]>[@values value;v]<cmis:value>[@stringvalue v/]</cmis:value>[/@values]</cmis:propertyString>
|
||||
[#elseif type == cmisconstants.DATATYPE_INTEGER]
|
||||
<cmis:propertyInteger propertyDefinitionId="${name}">[@values value;v]<cmis:value>[@integervalue v/]</cmis:value>[/@values]</cmis:propertyInteger>
|
||||
<cmis:propertyInteger [@propargs name displayname queryname localname/]>[@values value;v]<cmis:value>[@integervalue v/]</cmis:value>[/@values]</cmis:propertyInteger>
|
||||
[#elseif type == cmisconstants.DATATYPE_DECIMAL]
|
||||
<cmis:propertyDecimal propertyDefinitionId="${name}">[@values value;v]<cmis:value>[@decimalvalue v/]</cmis:value>[/@values]</cmis:propertyDecimal>
|
||||
<cmis:propertyDecimal [@propargs name displayname queryname localname/]>[@values value;v]<cmis:value>[@decimalvalue v/]</cmis:value>[/@values]</cmis:propertyDecimal>
|
||||
[#elseif type == cmisconstants.DATATYPE_BOOLEAN]
|
||||
<cmis:propertyBoolean propertyDefinitionId="${name}">[@values value;v]<cmis:value>[@booleanvalue v/]</cmis:value>[/@values]</cmis:propertyBoolean>
|
||||
<cmis:propertyBoolean [@propargs name displayname queryname localname/]>[@values value;v]<cmis:value>[@booleanvalue v/]</cmis:value>[/@values]</cmis:propertyBoolean>
|
||||
[#elseif type == cmisconstants.DATATYPE_DATETIME]
|
||||
<cmis:propertyDateTime propertyDefinitionId="${name}">[@values value;v]<cmis:value>[@datetimevalue v/]</cmis:value>[/@values]</cmis:propertyDateTime>
|
||||
<cmis:propertyDateTime [@propargs name displayname queryname localname/]>[@values value;v]<cmis:value>[@datetimevalue v/]</cmis:value>[/@values]</cmis:propertyDateTime>
|
||||
[#elseif type == cmisconstants.DATATYPE_URI]
|
||||
[#-- TODO: check validity of abs url prefix --]
|
||||
<cmis:propertyUri propertyDefinitionId="${name}">[@values value;v]<cmis:value>[@urivalue absurl(url.serviceContext) + v/]</cmis:value>[/@values]</cmis:propertyUri>
|
||||
<cmis:propertyUri [@propargs name displayname queryname localname/]>[@values value;v]<cmis:value>[@urivalue absurl(url.serviceContext) + v/]</cmis:value>[/@values]</cmis:propertyUri>
|
||||
[#elseif type == cmisconstants.DATATYPE_ID]
|
||||
<cmis:propertyId propertyDefinitionId="${name}">[@values value;v]<cmis:value>[@idvalue v/]</cmis:value>[/@values]</cmis:propertyId>
|
||||
<cmis:propertyId [@propargs name displayname queryname localname/]>[@values value;v]<cmis:value>[@idvalue v/]</cmis:value>[/@values]</cmis:propertyId>
|
||||
[#-- TODO: remaining property types --]
|
||||
[/#if]
|
||||
[/#macro]
|
||||
|
||||
[#macro propnull name type]
|
||||
[#macro propnulldef propdef]
|
||||
[@propnull propdef.dataType.label propdef.propertyId.id propdef.displayName propdef.queryName propdef.propertyId.localName/]
|
||||
[/#macro]
|
||||
|
||||
[#macro propnull type name displayname="" queryname="" localname=""]
|
||||
[#if type == cmisconstants.DATATYPE_STRING]
|
||||
<cmis:propertyString propertyDefinitionId="${name}"/>
|
||||
<cmis:propertyString [@propargs name displayname queryname localname/]/>
|
||||
[#elseif type == cmisconstants.DATATYPE_INTEGER]
|
||||
<cmis:propertyInteger propertyDefinitionId="${name}"/>
|
||||
<cmis:propertyInteger [@propargs name displayname queryname localname/]/>
|
||||
[#elseif type == cmisconstants.DATATYPE_DECIMAL]
|
||||
<cmis:propertyDecimal propertyDefinitionId="${name}"/>
|
||||
<cmis:propertyDecimal [@propargs name displayname queryname localname/]/>
|
||||
[#elseif type == cmisconstants.DATATYPE_BOOLEAN]
|
||||
<cmis:propertyBoolean propertyDefinitionId="${name}"/>
|
||||
<cmis:propertyBoolean [@propargs name displayname queryname localname/]/>
|
||||
[#elseif type == cmisconstants.DATATYPE_DATETIME]
|
||||
<cmis:propertyDateTime propertyDefinitionId="${name}"/>
|
||||
<cmis:propertyDateTime [@propargs name displayname queryname localname/]/>
|
||||
[#elseif type == cmisconstants.DATATYPE_URI]
|
||||
<cmis:propertyUri propertyDefinitionId="${name}"/>
|
||||
<cmis:propertyUri [@propargs name displayname queryname localname/]/>
|
||||
[#elseif type == cmisconstants.DATATYPE_ID]
|
||||
<cmis:propertyId propertyDefinitionId="${name}"/>
|
||||
<cmis:propertyId [@propargs name displayname queryname localname/]/>
|
||||
[#-- TODO: remaining property types --]
|
||||
[/#if]
|
||||
[/#macro]
|
||||
|
||||
[#macro propargs name displayname="" queryname="" localname=""]propertyDefinitionId="${name}"[#if displayname != ""] displayName="${displayname}"[/#if][#if queryname != ""] queryName="${queryname}"[/#if][/#macro]
|
||||
|
||||
[#-- --]
|
||||
[#-- CMIS Values --]
|
||||
|
@@ -158,7 +158,7 @@
|
||||
[#macro nodeuri node]/cmis/[@noderef node/][/#macro]
|
||||
|
||||
[#-- Helper to render Alfresco Assoc uri --]
|
||||
[#macro assocuri assoc]/cmis/rel/[@noderef assoc.source/]/type/${cmistype(assoc).typeId.id!"undefined"}/target/[@noderef assoc.target/][/#macro]
|
||||
[#macro assocuri assoc]/cmis/rel/${assoc.associationRef.id}[/#macro]
|
||||
|
||||
[#-- Helper to render Alfresco Type uri --]
|
||||
[#macro typeuri typedef]/cmis/type/${typedef.typeId.id}[/#macro]
|
||||
|
@@ -6,7 +6,7 @@
|
||||
// @param slug (optional) node name
|
||||
// @return created node (or null, in case of error)
|
||||
//
|
||||
function createNode(parent, entry, slug)
|
||||
function createNode(parent, entry, slug, versioningState)
|
||||
{
|
||||
var object = entry.getExtension(atom.names.cmisra_object);
|
||||
var typeId = (object !== null) ? object.objectTypeId.nativeValue : null;
|
||||
@@ -29,7 +29,10 @@ function createNode(parent, entry, slug)
|
||||
if (baseType == DOCUMENT_TYPE_ID)
|
||||
{
|
||||
node = parent.createFile(name);
|
||||
// TODO: versioningState argument (CheckedOut/CheckedInMinor/CheckedInMajor)
|
||||
if (versioningState != null)
|
||||
{
|
||||
node = cmis.applyVersioningState(node, versioningState);
|
||||
}
|
||||
}
|
||||
else if (baseType == FOLDER_TYPE_ID)
|
||||
{
|
||||
|
@@ -9,15 +9,7 @@ script:
|
||||
}
|
||||
var node = object.node;
|
||||
|
||||
if (!node.hasPermission("CancelCheckOut"))
|
||||
{
|
||||
status.code = 403;
|
||||
status.message = "Permission to cancel checkout of " + object.ref + " is denied";
|
||||
status.redirect = true;
|
||||
break script;
|
||||
}
|
||||
|
||||
node.cancelCheckout();
|
||||
cmis.cancelCheckOut(node);
|
||||
|
||||
status.code = 204; // Success, but no response content
|
||||
status.redirect = true;
|
||||
|
@@ -6,21 +6,9 @@ script:
|
||||
{
|
||||
// locate node
|
||||
var object = getObjectFromUrl();
|
||||
if (object.node == null)
|
||||
{
|
||||
break script;
|
||||
}
|
||||
model.node = object.node;
|
||||
|
||||
// check permissions
|
||||
model.checkin = args[cmis.ARG_CHECKIN] == "true" ? true : false;
|
||||
if (model.checkin && !model.node.hasPermission("CheckIn"))
|
||||
{
|
||||
status.code = 403;
|
||||
status.message = "Permission to checkin " + object.ref + " is denied";
|
||||
status.redirect = true;
|
||||
break script;
|
||||
}
|
||||
|
||||
if (entry !== null)
|
||||
{
|
||||
@@ -42,6 +30,6 @@ script:
|
||||
var comment = args[cmis.ARG_CHECKIN_COMMENT];
|
||||
var major = args[cmis.ARG_MAJOR];
|
||||
major = (major === null || major == "true") ? true : false;
|
||||
model.node = model.node.checkin(comment === null ? "" : comment, major);
|
||||
model.node = cmis.checkIn(model.node, comment, major);
|
||||
}
|
||||
}
|
||||
|
@@ -6,21 +6,9 @@ script:
|
||||
{
|
||||
// locate node
|
||||
var object = getObjectFromUrl();
|
||||
if (object.node === null || !object.node.hasAspect("cm:workingcopy"))
|
||||
{
|
||||
break script;
|
||||
}
|
||||
model.node = object.node;
|
||||
|
||||
// check permissions
|
||||
model.checkin = args[cmis.ARG_CHECKIN] == "true" ? true : false;
|
||||
if (model.checkin && !model.node.hasPermission("CheckIn"))
|
||||
{
|
||||
status.code = 403;
|
||||
status.message = "Permission to checkin is denied";
|
||||
status.redirect = true;
|
||||
break script;
|
||||
}
|
||||
|
||||
if (entry !== null)
|
||||
{
|
||||
@@ -42,6 +30,6 @@ script:
|
||||
var comment = args[cmis.ARG_CHECKIN_COMMENT];
|
||||
var major = args[cmis.ARG_MAJOR];
|
||||
major = (major === null || major == "true") ? true : false;
|
||||
model.node = model.node.checkin(comment === null ? "" : comment, major);
|
||||
model.node = cmis.checkIn(model.node, comment, major);
|
||||
}
|
||||
}
|
||||
|
@@ -3,7 +3,7 @@
|
||||
<description>
|
||||
</description>
|
||||
|
||||
<url>/cmis/rel/s/{store}/i/{id}/type/{rel_type}/target/s/{target_store}/i/{target_id}</url>
|
||||
<url>/cmis/rel/{assoc_id}</url>
|
||||
|
||||
<authentication>user</authentication>
|
||||
<format default="atomentry"/>
|
||||
|
@@ -10,15 +10,7 @@ script:
|
||||
}
|
||||
var assoc = rel.assoc;
|
||||
|
||||
// TODO: check permission
|
||||
// if (!assoc.source.hasPermission("DeleteAssociations"))
|
||||
// {
|
||||
// status.setCode(403, "Permission to delete is denied");
|
||||
// break script;
|
||||
// }
|
||||
|
||||
// delete
|
||||
assoc.source.removeAssociation(assoc.target, assoc.type);
|
||||
cmis.deleteObject(assoc);
|
||||
|
||||
status.code = 204; // Success, but no response content
|
||||
status.redirect = true;
|
||||
|
@@ -3,7 +3,7 @@
|
||||
<description>
|
||||
</description>
|
||||
|
||||
<url>/cmis/rel/s/{store}/i/{id}/type/{rel_type}/target/s/{target_store}/i/{target_id}?filter={filter?}&includeAllowableActions={includeAllowableActions?}</url>
|
||||
<url>/cmis/rel/{assoc_id}?filter={filter?}&includeAllowableActions={includeAllowableActions?}</url>
|
||||
|
||||
<authentication>guest</authentication>
|
||||
<transaction allow="readonly"/>
|
||||
|
@@ -4,14 +4,14 @@
|
||||
</description>
|
||||
|
||||
<!-- by object id -->
|
||||
<url>/cmis/i/{id}/tree?continueOnFailure={continueOnFailure?}&unfileMultiFiledDocuments={unfileMultiFiledDocuments}</url>
|
||||
<url>/cmis/s/{store}/i/{id}/tree?continueOnFailure={continueOnFailure?}&unfileMultiFiledDocuments={unfileMultiFiledDocuments}</url>
|
||||
<url>/cmis/i/{id}/tree?continueOnFailure={continueOnFailure?}&unfileObjects={unfileObjects}</url>
|
||||
<url>/cmis/s/{store}/i/{id}/tree?continueOnFailure={continueOnFailure?}&unfileObjects={unfileObjects}</url>
|
||||
<!-- by path -->
|
||||
<url>/cmis/p{path}/tree?continueOnFailure={continueOnFailure?}&unfileMultiFiledDocuments={unfileMultiFiledDocuments}</url>
|
||||
<url>/cmis/s/{store}/p{path}/tree?continueOnFailure={continueOnFailure?}&unfileMultiFiledDocuments={unfileMultiFiledDocuments}</url>
|
||||
<url>/cmis/p{path}/tree?continueOnFailure={continueOnFailure?}&unfileObjects={unfileObjects}</url>
|
||||
<url>/cmis/s/{store}/p{path}/tree?continueOnFailure={continueOnFailure?}&unfileObjects={unfileObjects}</url>
|
||||
<!-- alfresco style -->
|
||||
<url>/api/node/{store_type}/{store_id}/{id}/tree?continueOnFailure={continueOnFailure?}&unfileMultiFiledDocuments={unfileMultiFiledDocuments}</url>
|
||||
<url>/api/path/{store_type}/{store_id}/{path}/tree?continueOnFailure={continueOnFailure?}&unfileMultiFiledDocuments={unfileMultiFiledDocuments}</url>
|
||||
<url>/api/node/{store_type}/{store_id}/{id}/tree?continueOnFailure={continueOnFailure?}&unfileObjects={unfileObjects}</url>
|
||||
<url>/api/path/{store_type}/{store_id}/{path}/tree?continueOnFailure={continueOnFailure?}&unfileObjects={unfileObjects}</url>
|
||||
|
||||
<authentication>user</authentication>
|
||||
<format default="atomfeed"/>
|
||||
|
@@ -10,27 +10,24 @@ script:
|
||||
}
|
||||
var node = object.node;
|
||||
|
||||
// NOTE: Ignore continueOnDelete as complete tree is deleted in single transaction
|
||||
// TODO: Throw error on invalid unfileMultiFiledDocuments error
|
||||
|
||||
if (!node.hasPermission("Delete"))
|
||||
// unfileObjects
|
||||
var unfileObjects = args[cmis.ARG_UNFILE_OBJECTS];
|
||||
if (unfileObjects === null || unfileObjects.length == 0)
|
||||
{
|
||||
status.code = 403;
|
||||
status.message = "Permission to delete is denied";
|
||||
unfileObjects = "delete";
|
||||
}
|
||||
|
||||
// We only support delete and deletesinglefiled
|
||||
if (unfileObjects == "unfile")
|
||||
{
|
||||
status.code = 405;
|
||||
status.message = "Unfiling is not supported";
|
||||
status.redirect = true;
|
||||
break script;
|
||||
}
|
||||
|
||||
// TODO: Checked-out documents - are they automatically cancelled?
|
||||
var continueOnFailure = (args[cmis.ARG_CONTINUE_ON_FAILURE] == "true");
|
||||
|
||||
if (!node.remove())
|
||||
{
|
||||
status.code = 500;
|
||||
status.message = "Failed to delete object " + object.ref;
|
||||
status.redirect = true;
|
||||
break script;
|
||||
}
|
||||
|
||||
status.code = 204; // Success, but no response content
|
||||
status.redirect = true;
|
||||
// Intentionally pass allVersions=false, even though this isn't the default!
|
||||
cmis.deleteTree(node, status, continueOnFailure, unfileObjects != "delete", false);
|
||||
}
|
||||
|
@@ -17,7 +17,7 @@
|
||||
[/@feedLib.generic]
|
||||
|
||||
[#list nodes as version]
|
||||
[@entryLib.version version versions[version_index]/]
|
||||
[@entryLib.version version/]
|
||||
[/#list]
|
||||
|
||||
</feed>
|
||||
|
@@ -4,7 +4,7 @@ script:
|
||||
{
|
||||
// NOTE: version series is identified by noderef (as this is constant during lifetime of node)
|
||||
var object = getObjectFromUrl();
|
||||
if (object.node == null || !object.node.isVersioned)
|
||||
if (object.node == null)
|
||||
{
|
||||
status.message = "Versions series " + object.ref + " not found";
|
||||
break script;
|
||||
@@ -19,10 +19,5 @@ script:
|
||||
}
|
||||
|
||||
// retrieve versions
|
||||
model.versions = model.node.versionHistory;
|
||||
model.nodes = new Array(model.versions.length);
|
||||
for (i = 0; i < model.versions.length; i++)
|
||||
{
|
||||
model.nodes[i] = model.versions[i].node;
|
||||
}
|
||||
model.nodes = cmis.getAllVersions(model.node);
|
||||
}
|
||||
|
@@ -269,6 +269,10 @@
|
||||
</bean>
|
||||
|
||||
<!-- CMIS Javsascript API -->
|
||||
<bean id="CMISReferenceFactory" class="org.alfresco.repo.cmis.reference.ReferenceFactory">
|
||||
<property name="CMISService" ref="CMISService" />
|
||||
</bean>
|
||||
|
||||
<bean id="webscripts.js.cmis" parent="baseJavaScriptExtension" class="org.alfresco.repo.cmis.rest.CMISScript">
|
||||
<property name="extensionName"><value>cmis</value></property>
|
||||
<property name="serviceRegistry" ref="ServiceRegistry" />
|
||||
@@ -299,7 +303,7 @@
|
||||
<property name="referenceFactory" ref="CMISReferenceFactory" />
|
||||
<property name="dictionaryService" ref="DictionaryService" />
|
||||
<property name="namespaceService" ref="NamespaceService" />
|
||||
<property name="contentService" ref="ContentService" />
|
||||
<property name="cmisService" ref="CMISService" />
|
||||
<property name="mimetypeService" ref="MimetypeService" />
|
||||
</bean>
|
||||
|
||||
|
@@ -49,7 +49,6 @@ import org.w3c.dom.Element;
|
||||
* <element name="canCreateDocument" type="{http://www.w3.org/2001/XMLSchema}boolean" minOccurs="0"/>
|
||||
* <element name="canCreateFolder" type="{http://www.w3.org/2001/XMLSchema}boolean" minOccurs="0"/>
|
||||
* <element name="canCreateRelationship" type="{http://www.w3.org/2001/XMLSchema}boolean" minOccurs="0"/>
|
||||
* <element name="canCreatePolicy" type="{http://www.w3.org/2001/XMLSchema}boolean" minOccurs="0"/>
|
||||
* <element name="canDeleteTree" type="{http://www.w3.org/2001/XMLSchema}boolean" minOccurs="0"/>
|
||||
* <element name="canGetRenditions" type="{http://www.w3.org/2001/XMLSchema}boolean" minOccurs="0"/>
|
||||
* <element name="canGetACL" type="{http://www.w3.org/2001/XMLSchema}boolean" minOccurs="0"/>
|
||||
@@ -91,7 +90,6 @@ import org.w3c.dom.Element;
|
||||
"canCreateDocument",
|
||||
"canCreateFolder",
|
||||
"canCreateRelationship",
|
||||
"canCreatePolicy",
|
||||
"canDeleteTree",
|
||||
"canGetRenditions",
|
||||
"canGetACL",
|
||||
@@ -125,7 +123,6 @@ public class CmisAllowableActionsType {
|
||||
protected Boolean canCreateDocument;
|
||||
protected Boolean canCreateFolder;
|
||||
protected Boolean canCreateRelationship;
|
||||
protected Boolean canCreatePolicy;
|
||||
protected Boolean canDeleteTree;
|
||||
protected Boolean canGetRenditions;
|
||||
protected Boolean canGetACL;
|
||||
@@ -735,30 +732,6 @@ public class CmisAllowableActionsType {
|
||||
this.canCreateRelationship = value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the value of the canCreatePolicy property.
|
||||
*
|
||||
* @return
|
||||
* possible object is
|
||||
* {@link Boolean }
|
||||
*
|
||||
*/
|
||||
public Boolean isCanCreatePolicy() {
|
||||
return canCreatePolicy;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the value of the canCreatePolicy property.
|
||||
*
|
||||
* @param value
|
||||
* allowed object is
|
||||
* {@link Boolean }
|
||||
*
|
||||
*/
|
||||
public void setCanCreatePolicy(Boolean value) {
|
||||
this.canCreatePolicy = value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the value of the canDeleteTree property.
|
||||
*
|
||||
@@ -873,8 +846,8 @@ public class CmisAllowableActionsType {
|
||||
*
|
||||
* <p>
|
||||
* Objects of the following type(s) are allowed in the list
|
||||
* {@link Object }
|
||||
* {@link Element }
|
||||
* {@link Object }
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
@@ -30,7 +30,7 @@ import java.util.regex.Pattern;
|
||||
|
||||
import org.alfresco.repo.cmis.ws.CmisException;
|
||||
import org.alfresco.repo.cmis.ws.EnumServiceException;
|
||||
import org.alfresco.repo.cmis.ws.utils.CmisObjectsUtils;
|
||||
import org.alfresco.repo.cmis.ws.utils.ExceptionUtil;
|
||||
|
||||
/**
|
||||
* Property filter supporting CMIS filter expression
|
||||
@@ -56,11 +56,11 @@ public class PropertyFilter
|
||||
* @param filter filter value (case insensitive)
|
||||
* @throws FilterNotValidException if filter string isn't valid
|
||||
*/
|
||||
public PropertyFilter(String filter, CmisObjectsUtils cmisObjectsUtils) throws CmisException
|
||||
public PropertyFilter(String filter) throws CmisException
|
||||
{
|
||||
if (filter == null || filter.length() < MINIMAL_ALLOWED_STRUCTURE_SIZE ? false : !PROPERTY_FILTER_REGEX.matcher(filter).matches())
|
||||
{
|
||||
throw cmisObjectsUtils.createCmisException(("\"" + filter + "\" filter value is invalid"), EnumServiceException.FILTER_NOT_VALID);
|
||||
throw ExceptionUtil.createCmisException(("\"" + filter + "\" filter value is invalid"), EnumServiceException.FILTER_NOT_VALID);
|
||||
}
|
||||
|
||||
if (!filter.equals(MATCH_ALL_FILTER) && filter.length() >= MINIMAL_ALLOWED_STRUCTURE_SIZE)
|
||||
|
@@ -28,7 +28,6 @@ import junit.framework.TestCase;
|
||||
|
||||
import org.alfresco.repo.cmis.ws.CmisException;
|
||||
import org.alfresco.repo.cmis.ws.EnumServiceException;
|
||||
import org.alfresco.repo.cmis.ws.utils.CmisObjectsUtils;
|
||||
|
||||
/**
|
||||
* @author Dmitry Velichkevich
|
||||
@@ -59,23 +58,21 @@ public class PropertyFilterTest extends TestCase
|
||||
private static final String INVALID_FILTER_WITH_DENIED_SYMBOL = "ObjectId; name";
|
||||
private static final String INVALID_FILTER_WITH_LAST_INVALID_SYMBOL = "ObjectId, name*";
|
||||
|
||||
private CmisObjectsUtils cmisObjectsUtils = new CmisObjectsUtils();
|
||||
|
||||
public void testValidFilters() throws Exception
|
||||
{
|
||||
try
|
||||
{
|
||||
allTokensValidAssertion(new PropertyFilter());
|
||||
allTokensValidAssertion(new PropertyFilter(VALID_MATCHE_ALL_EMPTY_FILTER, cmisObjectsUtils));
|
||||
allTokensValidAssertion(new PropertyFilter(VALID_MATCHE_ALL_FILTER, cmisObjectsUtils));
|
||||
allTokensValidAssertion(new PropertyFilter(VALID_MATCHE_ALL_EMPTY_FILTER));
|
||||
allTokensValidAssertion(new PropertyFilter(VALID_MATCHE_ALL_FILTER));
|
||||
|
||||
onlyNameTokensAssertionValid(new PropertyFilter(VALID_FILTER_WITH_NAME, cmisObjectsUtils));
|
||||
onlyNameTokensAssertionValid(new PropertyFilter(VALID_FILTER_WITH_NAME));
|
||||
|
||||
nameAndObjectIdTokensAssertionValid(new PropertyFilter(VALID_FILTER_WITH_SEVERAL_TOKENS, cmisObjectsUtils));
|
||||
nameAndObjectIdTokensAssertionValid(new PropertyFilter(LONG_VALID_FILTER_WITH_SEVERAL_TOKENS, cmisObjectsUtils));
|
||||
nameAndObjectIdTokensAssertionValid(new PropertyFilter(VALID_FILTER_WITH_SEVERAL_TOKENS_WITHOUT_BREAKS, cmisObjectsUtils));
|
||||
nameAndObjectIdTokensAssertionValid(new PropertyFilter(VALID_FILTER_WITH_SEVERAL_TOKENS_AND_WITH_BREAKS_IN_SOME_PLACES, cmisObjectsUtils));
|
||||
nameAndObjectIdTokensAssertionValid(new PropertyFilter(VALID_FILTER_WITH_SEVERAL_TOKENS_AND_WITH_SEVERAL_BREAKS_IN_SOME_PLACES, cmisObjectsUtils));
|
||||
nameAndObjectIdTokensAssertionValid(new PropertyFilter(VALID_FILTER_WITH_SEVERAL_TOKENS));
|
||||
nameAndObjectIdTokensAssertionValid(new PropertyFilter(LONG_VALID_FILTER_WITH_SEVERAL_TOKENS));
|
||||
nameAndObjectIdTokensAssertionValid(new PropertyFilter(VALID_FILTER_WITH_SEVERAL_TOKENS_WITHOUT_BREAKS));
|
||||
nameAndObjectIdTokensAssertionValid(new PropertyFilter(VALID_FILTER_WITH_SEVERAL_TOKENS_AND_WITH_BREAKS_IN_SOME_PLACES));
|
||||
nameAndObjectIdTokensAssertionValid(new PropertyFilter(VALID_FILTER_WITH_SEVERAL_TOKENS_AND_WITH_SEVERAL_BREAKS_IN_SOME_PLACES));
|
||||
}
|
||||
catch (Throwable e)
|
||||
{
|
||||
@@ -144,7 +141,7 @@ public class PropertyFilterTest extends TestCase
|
||||
{
|
||||
try
|
||||
{
|
||||
new PropertyFilter(filterValue, cmisObjectsUtils);
|
||||
new PropertyFilter(filterValue);
|
||||
|
||||
fail("Invalid filter \"" + filterValue + "\" was interpreted as valid");
|
||||
}
|
||||
|
@@ -0,0 +1,66 @@
|
||||
/*
|
||||
* Copyright (C) 2005-2007 Alfresco Software Limited.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
|
||||
* As a special exception to the terms and conditions of version 2.0 of
|
||||
* the GPL, you may redistribute this Program in connection with Free/Libre
|
||||
* and Open Source Software ("FLOSS") applications as described in Alfresco's
|
||||
* FLOSS exception. You should have recieved a copy of the text describing
|
||||
* the FLOSS exception, and it is also available here:
|
||||
* http://www.alfresco.com/legal/licensing"
|
||||
*/
|
||||
package org.alfresco.repo.cmis.reference;
|
||||
|
||||
import org.alfresco.cmis.CMISRepositoryReference;
|
||||
import org.alfresco.cmis.CMISServices;
|
||||
import org.alfresco.service.cmr.repository.NodeRef;
|
||||
|
||||
|
||||
/**
|
||||
* AVM Path Reference
|
||||
*
|
||||
* @author davidc
|
||||
*/
|
||||
public class AVMPathReference extends ObjectPathReference
|
||||
{
|
||||
/**
|
||||
* Construct
|
||||
*
|
||||
* @param cmisServices
|
||||
* @param repo
|
||||
* @param path
|
||||
*/
|
||||
public AVMPathReference(CMISServices cmisServices, CMISRepositoryReference repo, String path)
|
||||
{
|
||||
super(cmisServices, repo, path);
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.alfresco.cmis.reference.ObjectPathReference#getNodeRef()
|
||||
*/
|
||||
public NodeRef getNodeRef()
|
||||
{
|
||||
return cmisServices.getNode("avmpath", reference);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString()
|
||||
{
|
||||
return "AVMPathReference[storeRef=" + repo.getStoreRef() + ",path=" + path + "]";
|
||||
}
|
||||
|
||||
}
|
@@ -0,0 +1,62 @@
|
||||
/*
|
||||
* Copyright (C) 2005-2010 Alfresco Software Limited.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
|
||||
* As a special exception to the terms and conditions of version 2.0 of
|
||||
* the GPL, you may redistribute this Program in connection with Free/Libre
|
||||
* and Open Source Software ("FLOSS") applications as described in Alfresco's
|
||||
* FLOSS exception. You should have received a copy of the text describing
|
||||
* the FLOSS exception, and it is also available here:
|
||||
* http://www.alfresco.com/legal/licensing"
|
||||
*/
|
||||
package org.alfresco.repo.cmis.reference;
|
||||
|
||||
import org.alfresco.cmis.CMISObjectReference;
|
||||
import org.alfresco.cmis.CMISRepositoryReference;
|
||||
import org.alfresco.cmis.CMISServices;
|
||||
|
||||
|
||||
/**
|
||||
* Abstract Object Reference
|
||||
*
|
||||
* @author davidc
|
||||
*/
|
||||
public abstract class AbstractObjectReference implements CMISObjectReference
|
||||
{
|
||||
protected CMISServices cmisServices;
|
||||
protected CMISRepositoryReference repo;
|
||||
|
||||
/**
|
||||
* Construct
|
||||
*
|
||||
* @param cmisServices
|
||||
* @param repo
|
||||
*/
|
||||
public AbstractObjectReference(CMISServices cmisServices, CMISRepositoryReference repo)
|
||||
{
|
||||
this.cmisServices = cmisServices;
|
||||
this.repo = repo;
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.alfresco.cmis.CMISObjectReference#getRepositoryReference()
|
||||
*/
|
||||
public CMISRepositoryReference getRepositoryReference()
|
||||
{
|
||||
return repo;
|
||||
}
|
||||
}
|
@@ -0,0 +1,56 @@
|
||||
/*
|
||||
* Copyright (C) 2005-2007 Alfresco Software Limited.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
|
||||
* As a special exception to the terms and conditions of version 2.0 of
|
||||
* the GPL, you may redistribute this Program in connection with Free/Libre
|
||||
* and Open Source Software ("FLOSS") applications as described in Alfresco's
|
||||
* FLOSS exception. You should have recieved a copy of the text describing
|
||||
* the FLOSS exception, and it is also available here:
|
||||
* http://www.alfresco.com/legal/licensing"
|
||||
*/
|
||||
package org.alfresco.repo.cmis.reference;
|
||||
|
||||
import org.alfresco.cmis.CMISRepositoryReference;
|
||||
import org.alfresco.cmis.CMISServices;
|
||||
|
||||
|
||||
/**
|
||||
* Abstract Repository Reference
|
||||
*
|
||||
* @author davidc
|
||||
*/
|
||||
public abstract class AbstractRepositoryReference implements CMISRepositoryReference
|
||||
{
|
||||
protected CMISServices cmisServices;
|
||||
|
||||
/**
|
||||
* Construct
|
||||
*
|
||||
* @param cmisServices
|
||||
*/
|
||||
public AbstractRepositoryReference(CMISServices cmisServices)
|
||||
{
|
||||
this.cmisServices = cmisServices;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString()
|
||||
{
|
||||
return getStoreRef().toString();
|
||||
}
|
||||
|
||||
}
|
@@ -0,0 +1,93 @@
|
||||
/*
|
||||
* Copyright (C) 2005-2010 Alfresco Software Limited.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
|
||||
* As a special exception to the terms and conditions of version 2.0 of
|
||||
* the GPL, you may redistribute this Program in connection with Free/Libre
|
||||
* and Open Source Software ("FLOSS") applications as described in Alfresco's
|
||||
* FLOSS exception. You should have received a copy of the text describing
|
||||
* the FLOSS exception, and it is also available here:
|
||||
* http://www.alfresco.com/legal/licensing"
|
||||
*/
|
||||
package org.alfresco.repo.cmis.reference;
|
||||
|
||||
import org.alfresco.cmis.CMISRelationshipReference;
|
||||
import org.alfresco.cmis.CMISRepositoryReference;
|
||||
import org.alfresco.cmis.CMISServiceException;
|
||||
import org.alfresco.cmis.CMISServices;
|
||||
import org.alfresco.service.cmr.repository.AssociationRef;
|
||||
import org.alfresco.service.cmr.repository.StoreRef;
|
||||
import org.springframework.extensions.webscripts.WebScriptException;
|
||||
|
||||
/**
|
||||
* Association ID relationship reference. An association ID can be resolved to an {@link AssociationRef}.
|
||||
*
|
||||
* @author dward
|
||||
*/
|
||||
public class AssociationIdRelationshipReference implements CMISRelationshipReference
|
||||
{
|
||||
private CMISServices cmisServices;
|
||||
private String assocId;
|
||||
|
||||
/**
|
||||
* Construct
|
||||
*
|
||||
* @param cmisServices
|
||||
* @param assocId
|
||||
*/
|
||||
public AssociationIdRelationshipReference(CMISServices cmisServices, String assocId)
|
||||
{
|
||||
this.cmisServices = cmisServices;
|
||||
this.assocId = assocId;
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.alfresco.cmis.CMISRelationshipReference#getAssocRef()
|
||||
*/
|
||||
public AssociationRef getAssocRef()
|
||||
{
|
||||
try
|
||||
{
|
||||
return cmisServices.getReadableObject(CMISServices.ASSOC_ID_PREFIX + this.assocId, AssociationRef.class);
|
||||
}
|
||||
catch (CMISServiceException e)
|
||||
{
|
||||
throw new WebScriptException(e.getStatusCode(), e.getMessage(), e);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.alfresco.cmis.CMISObjectReference#getRepositoryReference()
|
||||
*/
|
||||
public CMISRepositoryReference getRepositoryReference()
|
||||
{
|
||||
return new AbstractRepositoryReference(cmisServices)
|
||||
{
|
||||
public StoreRef getStoreRef()
|
||||
{
|
||||
return getAssocRef().getSourceRef().getStoreRef();
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString()
|
||||
{
|
||||
return "AssociationIdRelationshipReference[assocId=" + this.assocId + "]";
|
||||
}
|
||||
}
|
@@ -0,0 +1,57 @@
|
||||
/*
|
||||
* Copyright (C) 2005-2007 Alfresco Software Limited.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
|
||||
* As a special exception to the terms and conditions of version 2.0 of
|
||||
* the GPL, you may redistribute this Program in connection with Free/Libre
|
||||
* and Open Source Software ("FLOSS") applications as described in Alfresco's
|
||||
* FLOSS exception. You should have recieved a copy of the text describing
|
||||
* the FLOSS exception, and it is also available here:
|
||||
* http://www.alfresco.com/legal/licensing"
|
||||
*/
|
||||
package org.alfresco.repo.cmis.reference;
|
||||
|
||||
import org.alfresco.cmis.CMISServices;
|
||||
import org.alfresco.service.cmr.repository.StoreRef;
|
||||
|
||||
|
||||
/**
|
||||
* Default Repository Reference
|
||||
*
|
||||
* @author davidc
|
||||
*/
|
||||
public class DefaultRepositoryReference extends AbstractRepositoryReference
|
||||
{
|
||||
/**
|
||||
* Construct
|
||||
*
|
||||
* @param cmisServices
|
||||
*/
|
||||
public DefaultRepositoryReference(CMISServices cmisServices)
|
||||
{
|
||||
super(cmisServices);
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.alfresco.cmis.CMISRepositoryReference#getStoreRef()
|
||||
*/
|
||||
public StoreRef getStoreRef()
|
||||
{
|
||||
return cmisServices.getDefaultRootStoreRef();
|
||||
}
|
||||
|
||||
}
|
@@ -0,0 +1,87 @@
|
||||
/*
|
||||
* Copyright (C) 2005-2010 Alfresco Software Limited.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
|
||||
* As a special exception to the terms and conditions of version 2.0 of
|
||||
* the GPL, you may redistribute this Program in connection with Free/Libre
|
||||
* and Open Source Software ("FLOSS") applications as described in Alfresco's
|
||||
* FLOSS exception. You should have received a copy of the text describing
|
||||
* the FLOSS exception, and it is also available here:
|
||||
* http://www.alfresco.com/legal/licensing"
|
||||
*/
|
||||
package org.alfresco.repo.cmis.reference;
|
||||
|
||||
import org.alfresco.cmis.CMISRepositoryReference;
|
||||
import org.alfresco.cmis.CMISServices;
|
||||
import org.alfresco.service.cmr.repository.NodeRef;
|
||||
import org.alfresco.service.cmr.repository.StoreRef;
|
||||
|
||||
/**
|
||||
* GUID Object Reference. This class decodes node 'paths' generated by links.lib.atom.ftl. These are not the same as
|
||||
* CMIS object IDs.
|
||||
*
|
||||
* @author davidc
|
||||
*/
|
||||
public class NodeIdReference extends AbstractObjectReference
|
||||
{
|
||||
private String id;
|
||||
private String[] reference;
|
||||
|
||||
/**
|
||||
* Construct
|
||||
*
|
||||
* @param cmisServices
|
||||
* @param repo
|
||||
* @param id
|
||||
*/
|
||||
public NodeIdReference(CMISServices cmisServices, CMISRepositoryReference repo, String id)
|
||||
{
|
||||
super(cmisServices, repo);
|
||||
|
||||
this.id = id;
|
||||
|
||||
StoreRef storeRef = repo.getStoreRef();
|
||||
String[] idParts = this.id.split("/");
|
||||
reference = new String[2 + idParts.length];
|
||||
reference[0] = storeRef.getProtocol();
|
||||
reference[1] = storeRef.getIdentifier();
|
||||
System.arraycopy(idParts, 0, reference, 2, idParts.length);
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.alfresco.cmis.CMISObjectReference#getNodeRef()
|
||||
*/
|
||||
public NodeRef getNodeRef()
|
||||
{
|
||||
return cmisServices.getNode("node", reference);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return id
|
||||
*/
|
||||
public String getId()
|
||||
{
|
||||
return id;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString()
|
||||
{
|
||||
return "NodeIdReference[storeRef=" + repo.getStoreRef() + ",id=" + id + "]";
|
||||
}
|
||||
|
||||
}
|
@@ -0,0 +1,94 @@
|
||||
/*
|
||||
* Copyright (C) 2005-2010 Alfresco Software Limited.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
|
||||
* As a special exception to the terms and conditions of version 2.0 of
|
||||
* the GPL, you may redistribute this Program in connection with Free/Libre
|
||||
* and Open Source Software ("FLOSS") applications as described in Alfresco's
|
||||
* FLOSS exception. You should have received a copy of the text describing
|
||||
* the FLOSS exception, and it is also available here:
|
||||
* http://www.alfresco.com/legal/licensing"
|
||||
*/
|
||||
package org.alfresco.repo.cmis.reference;
|
||||
|
||||
import org.alfresco.cmis.CMISObjectReference;
|
||||
import org.alfresco.cmis.CMISRepositoryReference;
|
||||
import org.alfresco.cmis.CMISServiceException;
|
||||
import org.alfresco.cmis.CMISServices;
|
||||
import org.alfresco.service.cmr.repository.NodeRef;
|
||||
import org.alfresco.service.cmr.repository.StoreRef;
|
||||
import org.springframework.extensions.webscripts.WebScriptException;
|
||||
|
||||
/**
|
||||
* CMIS Object ID reference. A CMIS object ID encapsulates both a store and a node and identifies a specific version.
|
||||
*
|
||||
* @author dward
|
||||
*/
|
||||
public class ObjectIdReference implements CMISObjectReference
|
||||
{
|
||||
private CMISServices cmisServices;
|
||||
private String objectId;
|
||||
|
||||
/**
|
||||
* Construct
|
||||
*
|
||||
* @param cmisServices
|
||||
* @param storeRef
|
||||
*/
|
||||
public ObjectIdReference(CMISServices cmisServices, String objectId)
|
||||
{
|
||||
this.cmisServices = cmisServices;
|
||||
this.objectId = objectId;
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.alfresco.cmis.CMISObjectReference#getNodeRef()
|
||||
*/
|
||||
public NodeRef getNodeRef()
|
||||
{
|
||||
try
|
||||
{
|
||||
return cmisServices.getReadableObject(this.objectId, NodeRef.class);
|
||||
}
|
||||
catch (CMISServiceException e)
|
||||
{
|
||||
throw new WebScriptException(e.getStatusCode(), e.getMessage(), e);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.alfresco.cmis.CMISObjectReference#getRepositoryReference()
|
||||
*/
|
||||
public CMISRepositoryReference getRepositoryReference()
|
||||
{
|
||||
return new AbstractRepositoryReference(cmisServices)
|
||||
{
|
||||
public StoreRef getStoreRef()
|
||||
{
|
||||
return getNodeRef().getStoreRef();
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString()
|
||||
{
|
||||
return "ObjectIdReference[objectId=" + this.objectId + "]";
|
||||
}
|
||||
|
||||
}
|
@@ -0,0 +1,88 @@
|
||||
/*
|
||||
* Copyright (C) 2005-2010 Alfresco Software Limited.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
|
||||
* As a special exception to the terms and conditions of version 2.0 of
|
||||
* the GPL, you may redistribute this Program in connection with Free/Libre
|
||||
* and Open Source Software ("FLOSS") applications as described in Alfresco's
|
||||
* FLOSS exception. You should have received a copy of the text describing
|
||||
* the FLOSS exception, and it is also available here:
|
||||
* http://www.alfresco.com/legal/licensing"
|
||||
*/
|
||||
package org.alfresco.repo.cmis.reference;
|
||||
|
||||
import org.alfresco.cmis.CMISRepositoryReference;
|
||||
import org.alfresco.cmis.CMISServices;
|
||||
import org.alfresco.service.cmr.repository.NodeRef;
|
||||
import org.alfresco.service.cmr.repository.StoreRef;
|
||||
|
||||
|
||||
/**
|
||||
* Path Object Reference
|
||||
*
|
||||
* @author davidc
|
||||
*/
|
||||
public class ObjectPathReference extends AbstractObjectReference
|
||||
{
|
||||
protected String path;
|
||||
protected String[] reference;
|
||||
|
||||
/**
|
||||
* Construct
|
||||
*
|
||||
* @param cmisServices
|
||||
* @param repo
|
||||
* @param path
|
||||
*/
|
||||
public ObjectPathReference(CMISServices cmisServices, CMISRepositoryReference repo, String path)
|
||||
{
|
||||
super(cmisServices, repo);
|
||||
this.path = path.startsWith("/") ? path : "/" + path;
|
||||
this.path = (!cmisServices.getDefaultRootPath().equals("/")) ? cmisServices.getDefaultRootPath() + this.path : this.path;
|
||||
String[] splitPath = this.path.split("/");
|
||||
String[] pathSegments = new String[splitPath.length -1];
|
||||
System.arraycopy(splitPath, 1, pathSegments, 0, splitPath.length -1);
|
||||
this.reference = new String[2 + pathSegments.length];
|
||||
StoreRef storeRef = repo.getStoreRef();
|
||||
reference[0] = storeRef.getProtocol();
|
||||
reference[1] = storeRef.getIdentifier();
|
||||
System.arraycopy(pathSegments, 0, reference, 2, pathSegments.length);
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.alfresco.cmis.CMISObjectReference#getNodeRef()
|
||||
*/
|
||||
public NodeRef getNodeRef()
|
||||
{
|
||||
return cmisServices.getNode("path", reference);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return path
|
||||
*/
|
||||
public String getPath()
|
||||
{
|
||||
return path;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString()
|
||||
{
|
||||
return "ObjectPathReference[storeRef=" + repo.getStoreRef() + ",path=" + path + "]";
|
||||
}
|
||||
|
||||
}
|
@@ -0,0 +1,145 @@
|
||||
/*
|
||||
* Copyright (C) 2005-2010 Alfresco Software Limited.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
|
||||
* As a special exception to the terms and conditions of version 2.0 of
|
||||
* the GPL, you may redistribute this Program in connection with Free/Libre
|
||||
* and Open Source Software ("FLOSS") applications as described in Alfresco's
|
||||
* FLOSS exception. You should have recieved a copy of the text describing
|
||||
* the FLOSS exception, and it is also available here:
|
||||
* http://www.alfresco.com/legal/licensing"
|
||||
*/
|
||||
package org.alfresco.repo.cmis.reference;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
import org.alfresco.cmis.CMISDictionaryService;
|
||||
import org.alfresco.cmis.CMISObjectReference;
|
||||
import org.alfresco.cmis.CMISRelationshipReference;
|
||||
import org.alfresco.cmis.CMISRepositoryReference;
|
||||
import org.alfresco.cmis.CMISServices;
|
||||
|
||||
|
||||
/**
|
||||
* Reference Factory
|
||||
*
|
||||
* @author davidc
|
||||
*/
|
||||
public class ReferenceFactory
|
||||
{
|
||||
private CMISServices cmisService;
|
||||
|
||||
/**
|
||||
* @param cmisService
|
||||
*/
|
||||
public void setCMISService(CMISServices cmisService)
|
||||
{
|
||||
this.cmisService = cmisService;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create CMIS Repository Reference from URL segments
|
||||
*
|
||||
* @param args url arguments
|
||||
* @param templateArgs url template arguments
|
||||
* @return Repository Reference (or null, in case of bad url)
|
||||
*/
|
||||
public CMISRepositoryReference createRepoReferenceFromUrl(Map<String, String> args, Map<String, String> templateArgs)
|
||||
{
|
||||
String store_type = templateArgs.get("store_type");
|
||||
String store_id = templateArgs.get("store_id");
|
||||
if (store_type != null && store_id != null)
|
||||
{
|
||||
return new StoreRepositoryReference(cmisService, store_type + ":" + store_id);
|
||||
}
|
||||
|
||||
String store = templateArgs.get("store");
|
||||
if (store != null)
|
||||
{
|
||||
return new StoreRepositoryReference(cmisService, store);
|
||||
}
|
||||
|
||||
// TODO: repository id
|
||||
// String repoId = templateArgs.get("repo");
|
||||
// else if (repoId != null)
|
||||
// {
|
||||
// }
|
||||
|
||||
return new DefaultRepositoryReference(cmisService);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create CMIS Object Reference from URL segments
|
||||
*
|
||||
* @param args url arguments
|
||||
* @param templateArgs url template arguments
|
||||
* @return Repository Reference (or null, in case of bad url)
|
||||
*/
|
||||
public CMISObjectReference createObjectReferenceFromUrl(Map<String, String> args, Map<String, String> templateArgs)
|
||||
{
|
||||
// Despite the name of this argument, it is included in the "Object by ID" URL template and actually accepts a
|
||||
// value in object ID format (including version label suffix) so should be parsed as an object ID rather than a
|
||||
// NodeRef
|
||||
String objectId = args.get("noderef");
|
||||
if (objectId != null)
|
||||
{
|
||||
return new ObjectIdReference(cmisService, objectId);
|
||||
}
|
||||
|
||||
CMISRepositoryReference repo = createRepoReferenceFromUrl(args, templateArgs);
|
||||
String id = templateArgs.get("id");
|
||||
if (id != null)
|
||||
{
|
||||
return new NodeIdReference(cmisService, repo, id);
|
||||
}
|
||||
|
||||
String path = templateArgs.get("path");
|
||||
if (path == null)
|
||||
{
|
||||
path = args.get("path");
|
||||
}
|
||||
if (path != null)
|
||||
{
|
||||
return new ObjectPathReference(cmisService, repo, path);
|
||||
}
|
||||
|
||||
String avmPath = templateArgs.get("avmpath");
|
||||
if (avmPath != null)
|
||||
{
|
||||
return new AVMPathReference(cmisService, repo, avmPath);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create CMIS Relationship Reference from URL segments
|
||||
*
|
||||
* @param args url arguments
|
||||
* @param templateArgs url template arguments
|
||||
* @return Repository Reference (or null, in case of bad url)
|
||||
*/
|
||||
public CMISRelationshipReference createRelationshipReferenceFromUrl(Map<String, String> args, Map<String, String> templateArgs)
|
||||
{
|
||||
String assocId = templateArgs.get("assoc_id");
|
||||
if (assocId != null)
|
||||
{
|
||||
return new AssociationIdRelationshipReference(cmisService, assocId);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
@@ -0,0 +1,93 @@
|
||||
/*
|
||||
* Copyright (C) 2005-2007 Alfresco Software Limited.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
|
||||
* As a special exception to the terms and conditions of version 2.0 of
|
||||
* the GPL, you may redistribute this Program in connection with Free/Libre
|
||||
* and Open Source Software ("FLOSS") applications as described in Alfresco's
|
||||
* FLOSS exception. You should have recieved a copy of the text describing
|
||||
* the FLOSS exception, and it is also available here:
|
||||
* http://www.alfresco.com/legal/licensing"
|
||||
*/
|
||||
package org.alfresco.repo.cmis.reference;
|
||||
|
||||
import org.alfresco.cmis.CMISRelationshipReference;
|
||||
import org.alfresco.cmis.CMISRepositoryReference;
|
||||
import org.alfresco.cmis.CMISServices;
|
||||
import org.alfresco.cmis.CMISTypeDefinition;
|
||||
import org.alfresco.service.cmr.repository.AssociationRef;
|
||||
import org.alfresco.service.cmr.repository.NodeRef;
|
||||
|
||||
|
||||
/**
|
||||
* Source Node / Rel Type / Target Node Relationship Reference
|
||||
*
|
||||
* @author davidc
|
||||
*/
|
||||
public class SourceTypeTargetRelationshipReference implements CMISRelationshipReference
|
||||
{
|
||||
protected CMISServices cmisServices;
|
||||
protected StoreRepositoryReference repo;
|
||||
protected CMISTypeDefinition type;
|
||||
protected NodeRef source;
|
||||
protected NodeRef target;
|
||||
|
||||
|
||||
/**
|
||||
* Construct
|
||||
*
|
||||
* @param cmisServices
|
||||
* @param type
|
||||
* @param srcStore
|
||||
* @param srcId
|
||||
* @param tgtStore
|
||||
* @param tgtId
|
||||
*/
|
||||
public SourceTypeTargetRelationshipReference(CMISServices cmisServices, CMISTypeDefinition type, String srcStore, String srcId, String tgtStore, String tgtId)
|
||||
{
|
||||
this.cmisServices = cmisServices;
|
||||
this.repo = new StoreRepositoryReference(cmisServices, srcStore);
|
||||
this.type = type;
|
||||
this.source = new NodeRef(repo.getStoreRef(), srcId);
|
||||
StoreRepositoryReference tgtStoreRef = new StoreRepositoryReference(cmisServices, tgtStore);
|
||||
this.target = new NodeRef(tgtStoreRef.getStoreRef(), tgtId);
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.alfresco.cmis.CMISRelationshipReference#getRepositoryReference()
|
||||
*/
|
||||
public CMISRepositoryReference getRepositoryReference()
|
||||
{
|
||||
return repo;
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.alfresco.cmis.CMISRelationshipReference#getAssocRef()
|
||||
*/
|
||||
public AssociationRef getAssocRef()
|
||||
{
|
||||
return cmisServices.getRelationship(type, source, target);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString()
|
||||
{
|
||||
return "SourceTypeTargetRelationshipReference[type=" + type.getTypeId().getId() + ",source=" + source.toString() + ",target=" + target.toString() + "]";
|
||||
}
|
||||
|
||||
}
|
@@ -0,0 +1,86 @@
|
||||
/*
|
||||
* Copyright (C) 2005-2007 Alfresco Software Limited.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
|
||||
* As a special exception to the terms and conditions of version 2.0 of
|
||||
* the GPL, you may redistribute this Program in connection with Free/Libre
|
||||
* and Open Source Software ("FLOSS") applications as described in Alfresco's
|
||||
* FLOSS exception. You should have recieved a copy of the text describing
|
||||
* the FLOSS exception, and it is also available here:
|
||||
* http://www.alfresco.com/legal/licensing"
|
||||
*/
|
||||
package org.alfresco.repo.cmis.reference;
|
||||
|
||||
import org.alfresco.cmis.CMISServices;
|
||||
import org.alfresco.service.cmr.repository.StoreRef;
|
||||
|
||||
|
||||
/**
|
||||
* Store Ref Repository Reference
|
||||
*
|
||||
* @author davidc
|
||||
*/
|
||||
public class StoreRepositoryReference extends AbstractRepositoryReference
|
||||
{
|
||||
private StoreRef storeRef;
|
||||
|
||||
/**
|
||||
* Construct
|
||||
*
|
||||
* @param cmisServices
|
||||
* @param storeRef
|
||||
*/
|
||||
public StoreRepositoryReference(CMISServices cmisServices, StoreRef storeRef)
|
||||
{
|
||||
super(cmisServices);
|
||||
this.storeRef = storeRef;
|
||||
}
|
||||
|
||||
/**
|
||||
* Construct
|
||||
*
|
||||
* @param cmisServices
|
||||
* @param store accept storeType://storeId, storeType:storeId, storeId
|
||||
*/
|
||||
public StoreRepositoryReference(CMISServices cmisServices, String store)
|
||||
{
|
||||
super(cmisServices);
|
||||
|
||||
if (store.indexOf(StoreRef.URI_FILLER) != -1)
|
||||
{
|
||||
storeRef = new StoreRef(store);
|
||||
}
|
||||
else if (store.indexOf(':') != -1)
|
||||
{
|
||||
String[] storeParts = store.split(":");
|
||||
storeRef = new StoreRef(storeParts[0], storeParts[1]);
|
||||
}
|
||||
else
|
||||
{
|
||||
storeRef = new StoreRef(StoreRef.PROTOCOL_WORKSPACE, store);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.alfresco.cmis.CMISRepositoryReference#getStoreRef()
|
||||
*/
|
||||
public StoreRef getStoreRef()
|
||||
{
|
||||
return storeRef;
|
||||
}
|
||||
|
||||
}
|
@@ -26,6 +26,7 @@ package org.alfresco.repo.cmis.rest;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.alfresco.cmis.CMISInvalidArgumentException;
|
||||
import org.alfresco.cmis.CMISServices;
|
||||
import org.alfresco.cmis.CMISTypesFilterEnum;
|
||||
import org.alfresco.repo.template.TemplateNode;
|
||||
@@ -33,6 +34,7 @@ import org.alfresco.repo.web.scripts.RepositoryImageResolver;
|
||||
import org.alfresco.service.ServiceRegistry;
|
||||
import org.alfresco.service.cmr.repository.NodeRef;
|
||||
import org.alfresco.service.cmr.repository.TemplateImageResolver;
|
||||
import org.springframework.extensions.webscripts.WebScriptException;
|
||||
|
||||
import freemarker.ext.beans.BeanModel;
|
||||
import freemarker.template.TemplateMethodModelEx;
|
||||
@@ -98,7 +100,15 @@ public class CMISChildrenMethod implements TemplateMethodModelEx
|
||||
}
|
||||
|
||||
// query children
|
||||
NodeRef[] childNodeRefs = cmisService.getChildren(nodeRef, typesFilter);
|
||||
NodeRef[] childNodeRefs;
|
||||
try
|
||||
{
|
||||
childNodeRefs = cmisService.getChildren(nodeRef, typesFilter, null);
|
||||
}
|
||||
catch (CMISInvalidArgumentException e)
|
||||
{
|
||||
throw new WebScriptException(e.getStatusCode(), e.getMessage(), e);
|
||||
}
|
||||
children = new TemplateNode[childNodeRefs.length];
|
||||
for (int i = 0; i < childNodeRefs.length; i++)
|
||||
{
|
||||
|
@@ -26,9 +26,11 @@ package org.alfresco.repo.cmis.rest;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.alfresco.cmis.CMISInvalidArgumentException;
|
||||
import org.alfresco.cmis.CMISServices;
|
||||
import org.alfresco.repo.template.TemplateAssociation;
|
||||
import org.alfresco.repo.template.TemplateNode;
|
||||
import org.springframework.extensions.webscripts.WebScriptException;
|
||||
|
||||
import freemarker.ext.beans.BeanModel;
|
||||
import freemarker.ext.beans.BeansWrapper;
|
||||
@@ -90,8 +92,15 @@ public final class CMISPropertyValueMethod implements TemplateMethodModelEx
|
||||
if (wrapped != null && wrapped instanceof TemplateNode)
|
||||
{
|
||||
// retrieve property value from node
|
||||
try
|
||||
{
|
||||
result = cmisService.getProperty(((TemplateNode)wrapped).getNodeRef(), propertyName);
|
||||
}
|
||||
catch (CMISInvalidArgumentException e)
|
||||
{
|
||||
throw new WebScriptException(e.getStatusCode(), e.getMessage(), e);
|
||||
}
|
||||
}
|
||||
else if (wrapped != null && wrapped instanceof TemplateAssociation)
|
||||
{
|
||||
// retrieve property value from node
|
||||
|
@@ -27,12 +27,14 @@ package org.alfresco.repo.cmis.rest;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import org.alfresco.cmis.CMISFilterNotValidException;
|
||||
import org.alfresco.cmis.CMISServices;
|
||||
import org.alfresco.repo.template.TemplateNode;
|
||||
import org.alfresco.repo.web.scripts.RepositoryImageResolver;
|
||||
import org.alfresco.service.cmr.repository.NodeRef;
|
||||
import org.alfresco.service.cmr.repository.TemplateImageResolver;
|
||||
import org.alfresco.service.cmr.repository.TemplateValueConverter;
|
||||
import org.springframework.extensions.webscripts.WebScriptException;
|
||||
|
||||
import freemarker.ext.beans.BeanModel;
|
||||
import freemarker.template.TemplateMethodModelEx;
|
||||
@@ -102,7 +104,15 @@ public class CMISRenditionsMethod implements TemplateMethodModelEx
|
||||
// query renditions
|
||||
if (nodeRef != null)
|
||||
{
|
||||
Map<String, Object> renditions = cmisService.getRenditions(nodeRef, renditionFilter);
|
||||
Map<String, Object> renditions;
|
||||
try
|
||||
{
|
||||
renditions = cmisService.getRenditions(nodeRef, renditionFilter);
|
||||
}
|
||||
catch (CMISFilterNotValidException e)
|
||||
{
|
||||
throw new WebScriptException(e.getStatusCode(), e.getMessage(), e);
|
||||
}
|
||||
return templateValueConverter.convertValue(renditions, imageResolver);
|
||||
}
|
||||
|
||||
|
@@ -41,7 +41,10 @@ import org.alfresco.cmis.CMISCapabilityChanges;
|
||||
import org.alfresco.cmis.CMISChangeEvent;
|
||||
import org.alfresco.cmis.CMISChangeLog;
|
||||
import org.alfresco.cmis.CMISChangeLogService;
|
||||
import org.alfresco.cmis.CMISConstraintException;
|
||||
import org.alfresco.cmis.CMISDictionaryModel;
|
||||
import org.alfresco.cmis.CMISDictionaryService;
|
||||
import org.alfresco.cmis.CMISInvalidArgumentException;
|
||||
import org.alfresco.cmis.CMISJoinEnum;
|
||||
import org.alfresco.cmis.CMISObjectReference;
|
||||
import org.alfresco.cmis.CMISPermissionDefinition;
|
||||
@@ -54,14 +57,15 @@ import org.alfresco.cmis.CMISRelationshipDirectionEnum;
|
||||
import org.alfresco.cmis.CMISRelationshipReference;
|
||||
import org.alfresco.cmis.CMISRepositoryReference;
|
||||
import org.alfresco.cmis.CMISResultSet;
|
||||
import org.alfresco.cmis.CMISServiceException;
|
||||
import org.alfresco.cmis.CMISServices;
|
||||
import org.alfresco.cmis.CMISTypeDefinition;
|
||||
import org.alfresco.cmis.CMISTypesFilterEnum;
|
||||
import org.alfresco.cmis.CMISVersioningStateEnum;
|
||||
import org.alfresco.cmis.CMISQueryOptions.CMISQueryMode;
|
||||
import org.alfresco.cmis.acl.CMISAccessControlEntryImpl;
|
||||
import org.alfresco.cmis.reference.NodeRefReference;
|
||||
import org.alfresco.cmis.reference.ReferenceFactory;
|
||||
import org.alfresco.error.AlfrescoRuntimeException;
|
||||
import org.alfresco.repo.cmis.reference.ObjectIdReference;
|
||||
import org.alfresco.repo.cmis.reference.ReferenceFactory;
|
||||
import org.alfresco.repo.jscript.Association;
|
||||
import org.alfresco.repo.jscript.BaseScopableProcessorExtension;
|
||||
import org.alfresco.repo.jscript.ScriptNode;
|
||||
@@ -73,16 +77,18 @@ import org.alfresco.repo.web.util.paging.Paging;
|
||||
import org.alfresco.service.ServiceRegistry;
|
||||
import org.alfresco.service.cmr.repository.AssociationRef;
|
||||
import org.alfresco.service.cmr.repository.NodeRef;
|
||||
import org.alfresco.service.namespace.QName;
|
||||
import org.mozilla.javascript.Context;
|
||||
import org.mozilla.javascript.Scriptable;
|
||||
import org.mozilla.javascript.ScriptableObject;
|
||||
import org.springframework.extensions.webscripts.Status;
|
||||
import org.springframework.extensions.webscripts.WebScriptException;
|
||||
|
||||
|
||||
/**
|
||||
* CMIS Javascript API
|
||||
* CMIS Javascript API.
|
||||
*
|
||||
* @author davic
|
||||
* @author davidc
|
||||
* @author dward
|
||||
*/
|
||||
public class CMISScript extends BaseScopableProcessorExtension
|
||||
{
|
||||
@@ -117,12 +123,13 @@ public class CMISScript extends BaseScopableProcessorExtension
|
||||
public static final String ARG_THIS_VERSION = "thisVersion";
|
||||
public static final String ARG_TYPE_ID = "typeId";
|
||||
public static final String ARG_TYPES = "types";
|
||||
public static final String ARG_UNFILE_MULTIFILE_DOCUMENTS = "unfileMultiFiledDocuments";
|
||||
public static final String ARG_UNFILE_OBJECTS = "unfileObjects";
|
||||
public static final String ARG_VERSIONING_STATE = "versioningState";
|
||||
public static final String ARG_SOURCE_FOLDER_ID = "sourceFolderId";
|
||||
public static final String ARG_INCLUDE_ACL = "includeACL";
|
||||
public static final String ARG_RENDITION_FILTER = "renditionFilter";
|
||||
public static final String ARG_CHANGE_LOG_TOKEN = "changeLogToken";
|
||||
public static final String ARG_ORDER_BY = "orderBy";
|
||||
|
||||
// service dependencies
|
||||
private ServiceRegistry services;
|
||||
@@ -147,9 +154,10 @@ public class CMISScript extends BaseScopableProcessorExtension
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the paging helper
|
||||
* Set the paging helper.
|
||||
*
|
||||
* @param paging
|
||||
* the paging helper
|
||||
*/
|
||||
public void setPaging(Paging paging)
|
||||
{
|
||||
@@ -157,9 +165,10 @@ public class CMISScript extends BaseScopableProcessorExtension
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the CMIS Service
|
||||
* Set the CMIS Service.
|
||||
*
|
||||
* @param cmisService
|
||||
* the cmis service
|
||||
*/
|
||||
public void setCMISService(CMISServices cmisService)
|
||||
{
|
||||
@@ -167,9 +176,10 @@ public class CMISScript extends BaseScopableProcessorExtension
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the CMIS Dictionary Service
|
||||
* Set the CMIS Dictionary Service.
|
||||
*
|
||||
* @param cmisDictionaryService
|
||||
* the cmis dictionary service
|
||||
*/
|
||||
public void setCMISDictionaryService(CMISDictionaryService cmisDictionaryService)
|
||||
{
|
||||
@@ -177,9 +187,10 @@ public class CMISScript extends BaseScopableProcessorExtension
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the CMIS Query Service
|
||||
* Set the CMIS Query Service.
|
||||
*
|
||||
* @param cmisQueryService
|
||||
* the cmis query service
|
||||
*/
|
||||
public void setCMISQueryService(CMISQueryService cmisQueryService)
|
||||
{
|
||||
@@ -208,9 +219,10 @@ public class CMISScript extends BaseScopableProcessorExtension
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the CMIS Reference Factory
|
||||
* Set the CMIS Reference Factory.
|
||||
*
|
||||
* @param referenceFactory
|
||||
* the reference factory
|
||||
*/
|
||||
public void setCMISReferenceFactory(ReferenceFactory referenceFactory)
|
||||
{
|
||||
@@ -337,7 +349,7 @@ public class CMISScript extends BaseScopableProcessorExtension
|
||||
*/
|
||||
public CMISObjectReference createObjectIdReference(String objectId)
|
||||
{
|
||||
return new NodeRefReference(cmisService, objectId);
|
||||
return new ObjectIdReference(cmisService, objectId);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -375,15 +387,29 @@ public class CMISScript extends BaseScopableProcessorExtension
|
||||
/**
|
||||
* Query for node children
|
||||
*
|
||||
* @param parent node to query children for
|
||||
* @param typesFilter types filter
|
||||
* @param page page to query for
|
||||
* @param parent
|
||||
* node to query children for
|
||||
* @param typesFilter
|
||||
* types filter
|
||||
* @param orderBy
|
||||
* comma-separated list of query names and the ascending modifier "ASC" or the descending modifier "DESC"
|
||||
* for each query name
|
||||
* @param page
|
||||
* page to query for
|
||||
* @return paged result set of children
|
||||
*/
|
||||
public PagedResults queryChildren(ScriptNode parent, String typesFilter, Page page)
|
||||
public PagedResults queryChildren(ScriptNode parent, String typesFilter, String orderBy, Page page)
|
||||
{
|
||||
CMISTypesFilterEnum filter = resolveTypesFilter(typesFilter);
|
||||
NodeRef[] children = cmisService.getChildren(parent.getNodeRef(), filter);
|
||||
NodeRef[] children;
|
||||
try
|
||||
{
|
||||
children = cmisService.getChildren(parent.getNodeRef(), filter, orderBy);
|
||||
}
|
||||
catch (CMISInvalidArgumentException e)
|
||||
{
|
||||
throw new WebScriptException(e.getStatusCode(), e.getMessage(), e);
|
||||
}
|
||||
|
||||
Cursor cursor = paging.createCursor(children.length, page);
|
||||
ScriptNode[] nodes = new ScriptNode[cursor.getRowCount()];
|
||||
@@ -408,7 +434,15 @@ public class CMISScript extends BaseScopableProcessorExtension
|
||||
*/
|
||||
public PagedResults queryRelationships(ScriptNode node, CMISTypeDefinition relDef, boolean includeSubTypes, CMISRelationshipDirectionEnum direction, Page page)
|
||||
{
|
||||
AssociationRef[] relationships = cmisService.getRelationships(node.getNodeRef(), relDef, includeSubTypes, direction);
|
||||
AssociationRef[] relationships;
|
||||
try
|
||||
{
|
||||
relationships = cmisService.getRelationships(node.getNodeRef(), relDef, includeSubTypes, direction);
|
||||
}
|
||||
catch (CMISInvalidArgumentException e)
|
||||
{
|
||||
throw new WebScriptException(e.getStatusCode(), e.getMessage(), e);
|
||||
}
|
||||
|
||||
Cursor cursor = paging.createCursor(relationships.length, page);
|
||||
Association[] assocs = new Association[cursor.getRowCount()];
|
||||
@@ -421,31 +455,6 @@ public class CMISScript extends BaseScopableProcessorExtension
|
||||
return results;
|
||||
}
|
||||
|
||||
/**
|
||||
* Query for items checked-out to user
|
||||
*
|
||||
* @param username user
|
||||
* @param page
|
||||
* @return paged result set of checked-out items
|
||||
*/
|
||||
public PagedResults queryCheckedOut(String username, Page page)
|
||||
{
|
||||
return queryCheckedOut(username, null, false, page);
|
||||
}
|
||||
|
||||
/**
|
||||
* Query for items checked-out to user within folder
|
||||
*
|
||||
* @param username user
|
||||
* @param folder folder
|
||||
* @param page
|
||||
* @return paged result set of checked-out items
|
||||
*/
|
||||
public PagedResults queryCheckedOut(String username, ScriptNode folder, Page page)
|
||||
{
|
||||
return queryCheckedOut(username, folder, false, page);
|
||||
}
|
||||
|
||||
/**
|
||||
* Query for items checked-out to user within folder (and possibly descendants)
|
||||
*
|
||||
@@ -457,7 +466,15 @@ public class CMISScript extends BaseScopableProcessorExtension
|
||||
*/
|
||||
public PagedResults queryCheckedOut(String username, ScriptNode folder, boolean includeDescendants, Page page)
|
||||
{
|
||||
NodeRef[] checkedout = cmisService.getCheckedOut(username, (folder == null) ? null : folder.getNodeRef(), includeDescendants);
|
||||
NodeRef[] checkedout;
|
||||
try
|
||||
{
|
||||
checkedout = cmisService.getCheckedOut(username, (folder == null) ? null : folder.getNodeRef(), includeDescendants, null);
|
||||
}
|
||||
catch (CMISInvalidArgumentException e)
|
||||
{
|
||||
throw new WebScriptException(e.getStatusCode(), e.getMessage(), e);
|
||||
}
|
||||
Cursor cursor = paging.createCursor(checkedout.length, page);
|
||||
ScriptNode[] nodes = new ScriptNode[cursor.getRowCount()];
|
||||
for (int i = cursor.getStartRow(); i <= cursor.getEndRow(); i++)
|
||||
@@ -470,15 +487,18 @@ public class CMISScript extends BaseScopableProcessorExtension
|
||||
}
|
||||
|
||||
/**
|
||||
* Query for child types (of a given type), or the base types (if no type given)
|
||||
* Query for child types (of a given type), or the base types (if no type given).
|
||||
*
|
||||
* @param typeDef
|
||||
* the type def
|
||||
* @param page
|
||||
* @return
|
||||
* the page
|
||||
* @return the paged results
|
||||
*/
|
||||
public PagedResults queryTypeChildren(CMISTypeDefinition typeDef, Page page)
|
||||
{
|
||||
Collection<CMISTypeDefinition> children = (typeDef == null) ? cmisDictionaryService.getBaseTypes() : typeDef.getSubTypes(false);
|
||||
Collection<CMISTypeDefinition> children = (typeDef == null) ? cmisService.getBaseTypes() : typeDef
|
||||
.getSubTypes(false);
|
||||
Cursor cursor = paging.createCursor(children.size(), page);
|
||||
|
||||
// skip
|
||||
@@ -500,47 +520,49 @@ public class CMISScript extends BaseScopableProcessorExtension
|
||||
}
|
||||
|
||||
/**
|
||||
* Query for a Type Definition given a CMIS Type Id
|
||||
* Query for a Type Definition given a CMIS Type Id.
|
||||
*
|
||||
* @param page
|
||||
* @param typeId
|
||||
* the type id
|
||||
* @return CMIS Type Definition
|
||||
*/
|
||||
public CMISTypeDefinition queryType(String typeId)
|
||||
{
|
||||
try
|
||||
{
|
||||
return cmisDictionaryService.findType(typeId);
|
||||
return cmisService.getTypeDefinition(typeId);
|
||||
}
|
||||
catch(AlfrescoRuntimeException e)
|
||||
catch (CMISInvalidArgumentException e)
|
||||
{
|
||||
return null;
|
||||
throw new WebScriptException(e.getStatusCode(), e.getMessage(), e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Query the Type Definition for the given Node
|
||||
* Query the Type Definition for the given Node.
|
||||
*
|
||||
* @param node
|
||||
* the node
|
||||
* @return CMIS Type Definition
|
||||
*/
|
||||
public CMISTypeDefinition queryType(ScriptNode node)
|
||||
{
|
||||
try
|
||||
{
|
||||
QName typeQName = node.getQNameType();
|
||||
return cmisDictionaryService.findTypeForClass(typeQName);
|
||||
return cmisService.getTypeDefinition(node.getNodeRef());
|
||||
}
|
||||
catch(AlfrescoRuntimeException e)
|
||||
catch (CMISInvalidArgumentException e)
|
||||
{
|
||||
return null;
|
||||
throw new WebScriptException(e.getStatusCode(), e.getMessage(), e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Query the Property Definition for the given Property
|
||||
* Query the Property Definition for the given Property.
|
||||
*
|
||||
* @param propertyName
|
||||
* @return
|
||||
* the property name
|
||||
* @return the CMIS property definition
|
||||
*/
|
||||
public CMISPropertyDefinition queryProperty(String propertyName)
|
||||
{
|
||||
@@ -554,7 +576,7 @@ public class CMISScript extends BaseScopableProcessorExtension
|
||||
/**
|
||||
* Can you query the private working copy of a document.
|
||||
*
|
||||
* @return
|
||||
* @return is the PWC searchable?
|
||||
*/
|
||||
public boolean getPwcSearchable()
|
||||
{
|
||||
@@ -576,7 +598,7 @@ public class CMISScript extends BaseScopableProcessorExtension
|
||||
/**
|
||||
* Get the query support level.
|
||||
*
|
||||
* @return
|
||||
* @return the query support level
|
||||
*/
|
||||
public CMISQueryEnum getQuerySupport()
|
||||
{
|
||||
@@ -586,7 +608,7 @@ public class CMISScript extends BaseScopableProcessorExtension
|
||||
/**
|
||||
* Get the join support level in queries.
|
||||
*
|
||||
* @return
|
||||
* @return the join support level
|
||||
*/
|
||||
public CMISJoinEnum getJoinSupport()
|
||||
{
|
||||
@@ -594,11 +616,12 @@ public class CMISScript extends BaseScopableProcessorExtension
|
||||
}
|
||||
|
||||
/**
|
||||
* Issue query
|
||||
* Issue query.
|
||||
*
|
||||
* @param statement query statement
|
||||
* @param statement
|
||||
* query statement
|
||||
* @param page
|
||||
*
|
||||
* the page
|
||||
* @return paged result set
|
||||
*/
|
||||
public PagedResults query(String statement, Page page)
|
||||
@@ -624,7 +647,7 @@ public class CMISScript extends BaseScopableProcessorExtension
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the supported permission types
|
||||
* Gets the supported permission types.
|
||||
*
|
||||
* @return the supported permission types
|
||||
*/
|
||||
@@ -645,6 +668,7 @@ public class CMISScript extends BaseScopableProcessorExtension
|
||||
|
||||
/**
|
||||
* Get all the permissions defined by the repository.
|
||||
*
|
||||
* @return a list of permissions
|
||||
*/
|
||||
public List<CMISPermissionDefinition> getRepositoryPermissions()
|
||||
@@ -655,6 +679,7 @@ public class CMISScript extends BaseScopableProcessorExtension
|
||||
|
||||
/**
|
||||
* Get the list of permission mappings.
|
||||
*
|
||||
* @return get the permission mapping as defined by the CMIS specification.
|
||||
*/
|
||||
public List<? extends CMISPermissionMapping> getPermissionMappings()
|
||||
@@ -684,6 +709,16 @@ public class CMISScript extends BaseScopableProcessorExtension
|
||||
return cmisAccessControlService.getPrincipalAnyone();
|
||||
}
|
||||
|
||||
/**
|
||||
* Applies an ACL to a node.
|
||||
*
|
||||
* @param node
|
||||
* the node
|
||||
* @param principalIds
|
||||
* the principal IDs
|
||||
* @param permissions
|
||||
* the permissions for each principal ID
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
public void applyACL(ScriptNode node, Serializable principalIds, Serializable permissions)
|
||||
{
|
||||
@@ -694,8 +729,16 @@ public class CMISScript extends BaseScopableProcessorExtension
|
||||
{
|
||||
acesToApply.add(new CMISAccessControlEntryImpl(principalList.get(i), permissionList.get(i)));
|
||||
}
|
||||
try
|
||||
{
|
||||
cmisAccessControlService.applyAcl(node.getNodeRef(), acesToApply);
|
||||
}
|
||||
catch (CMISConstraintException e)
|
||||
{
|
||||
// Force the appropriate status code on error
|
||||
throw new WebScriptException(e.getStatusCode(), e.getMessage(), e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the change log capability.
|
||||
@@ -779,7 +822,7 @@ public class CMISScript extends BaseScopableProcessorExtension
|
||||
Scriptable changeNodes = cx.newArray(scope, size);
|
||||
for (int i = 0; i < size; i++)
|
||||
{
|
||||
ScriptableObject.putProperty(changeNodes, i, new ScriptNode(changeEvents.get(i).getNode(), services,
|
||||
ScriptableObject.putProperty(changeNodes, i, new ScriptNode(changeEvents.get(i).getChangedNode(), services,
|
||||
scope));
|
||||
}
|
||||
ScriptableObject.putProperty(changeLogMap, "changeNodes", changeNodes);
|
||||
@@ -811,9 +854,298 @@ public class CMISScript extends BaseScopableProcessorExtension
|
||||
}
|
||||
return changeLogMap;
|
||||
}
|
||||
catch (CMISInvalidArgumentException e)
|
||||
{
|
||||
throw new WebScriptException(e.getStatusCode(), e.getMessage(), e);
|
||||
}
|
||||
finally
|
||||
{
|
||||
Context.exit();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Applies a versioning state to a new node, potentially resulting in a new node.
|
||||
*
|
||||
* @param source
|
||||
* the source
|
||||
* @param versioningState
|
||||
* the versioning state
|
||||
* @return the node to write changes to
|
||||
* @throws CMISConstraintException
|
||||
*/
|
||||
public ScriptNode applyVersioningState(ScriptNode source, String versioningState)
|
||||
{
|
||||
CMISVersioningStateEnum versioningStateEnum = CMISVersioningStateEnum.FACTORY.fromLabel(versioningState);
|
||||
try
|
||||
{
|
||||
return new ScriptNode(cmisService.applyVersioningState(source.getNodeRef(), versioningStateEnum), services,
|
||||
getScope());
|
||||
}
|
||||
catch (CMISServiceException e)
|
||||
{
|
||||
throw new WebScriptException(e.getStatusCode(), e.getMessage(), e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks out an object by ID.
|
||||
*
|
||||
* @param objectId
|
||||
* the object id
|
||||
* @return the private working copy node
|
||||
*/
|
||||
public ScriptNode checkOut(String objectId)
|
||||
{
|
||||
try
|
||||
{
|
||||
return new ScriptNode(cmisService.checkOut(objectId), services, getScope());
|
||||
}
|
||||
catch (CMISServiceException e)
|
||||
{
|
||||
throw new WebScriptException(e.getStatusCode(), e.getMessage(), e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks in a given private working copy node.
|
||||
*
|
||||
* @param source
|
||||
* the node
|
||||
* @param checkinComment
|
||||
* the checkin comment
|
||||
* @param isMajor
|
||||
* is this a major version?
|
||||
* @return the checked-in node
|
||||
*/
|
||||
public ScriptNode checkIn(ScriptNode source, String checkinComment, boolean isMajor)
|
||||
{
|
||||
try
|
||||
{
|
||||
return new ScriptNode(cmisService.checkIn((String) cmisService.getProperty(source.getNodeRef(), CMISDictionaryModel.PROP_OBJECT_ID), checkinComment, isMajor), services,
|
||||
getScope());
|
||||
}
|
||||
catch (CMISServiceException e)
|
||||
{
|
||||
throw new WebScriptException(e.getStatusCode(), e.getMessage(), e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Cancels a check out.
|
||||
*
|
||||
* @param source
|
||||
* the private working copy
|
||||
*/
|
||||
public void cancelCheckOut(ScriptNode source)
|
||||
{
|
||||
try
|
||||
{
|
||||
cmisService.cancelCheckOut((String) cmisService.getProperty(source.getNodeRef(),
|
||||
CMISDictionaryModel.PROP_OBJECT_ID));
|
||||
}
|
||||
catch (CMISServiceException e)
|
||||
{
|
||||
throw new WebScriptException(e.getStatusCode(), e.getMessage(), e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets all the versions of a node.
|
||||
*
|
||||
* @param source
|
||||
* the node
|
||||
* @return a Javascript array of all the versions
|
||||
*/
|
||||
public Scriptable getAllVersions(ScriptNode source)
|
||||
{
|
||||
Scriptable scope = getScope();
|
||||
Context cx = Context.enter();
|
||||
try
|
||||
{
|
||||
List<NodeRef> allVersions = cmisService.getAllVersions((String) cmisService.getProperty(
|
||||
source.getNodeRef(), CMISDictionaryModel.PROP_OBJECT_ID));
|
||||
// Wrap the version
|
||||
int size = allVersions.size();
|
||||
Scriptable allVersionsArr = cx.newArray(scope, size);
|
||||
for (int i = 0; i < size; i++)
|
||||
{
|
||||
ScriptableObject.putProperty(allVersionsArr, i, new ScriptNode(allVersions.get(i), services, scope));
|
||||
}
|
||||
return allVersionsArr;
|
||||
}
|
||||
catch (CMISServiceException e)
|
||||
{
|
||||
throw new WebScriptException(e.getStatusCode(), e.getMessage(), e);
|
||||
}
|
||||
finally
|
||||
{
|
||||
Context.exit();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the required version of a node
|
||||
*
|
||||
* @param source
|
||||
* the node
|
||||
* @param returnVersion
|
||||
* value indicating version required
|
||||
* @return the version
|
||||
*/
|
||||
public ScriptNode getReturnVersion(ScriptNode source, String returnVersion)
|
||||
{
|
||||
if (returnVersion == null || returnVersion.equals("this"))
|
||||
{
|
||||
return source;
|
||||
}
|
||||
try
|
||||
{
|
||||
return new ScriptNode(cmisService.getLatestVersion((String) cmisService.getProperty(source.getNodeRef(),
|
||||
CMISDictionaryModel.PROP_OBJECT_ID), returnVersion.equals("latestmajor")), services, getScope());
|
||||
}
|
||||
catch (CMISServiceException e)
|
||||
{
|
||||
throw new WebScriptException(e.getStatusCode(), e.getMessage(), e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Attempts to delete a folder and all of its children, recording the status in the given status object.
|
||||
*
|
||||
* @param source
|
||||
* the folder node
|
||||
* @param status
|
||||
* the status
|
||||
* @param continueOnFailure
|
||||
* should we continue if an error occurs with one of the children?
|
||||
* @param unfile
|
||||
* should we remove non-primary associations to nodes rather than delete them?
|
||||
* @param deleteAllVersions
|
||||
* should we delete all the versions of the nodes we delete?
|
||||
*/
|
||||
public void deleteTree(ScriptNode source, Status status, boolean continueOnFailure, boolean unfile,
|
||||
boolean deleteAllVersions)
|
||||
{
|
||||
// Let's avoid all deletions getting rolled back by catching the exception and setting the status ourselves
|
||||
try
|
||||
{
|
||||
cmisService.deleteTreeReportLastError((String) cmisService.getProperty(source.getNodeRef(),
|
||||
CMISDictionaryModel.PROP_OBJECT_ID), continueOnFailure, unfile, deleteAllVersions);
|
||||
// Success, but no response content
|
||||
status.setCode(Status.STATUS_NO_CONTENT);
|
||||
status.setRedirect(true);
|
||||
}
|
||||
catch (CMISServiceException e)
|
||||
{
|
||||
status.setCode(e.getStatusCode());
|
||||
status.setMessage(e.getMessage());
|
||||
status.setRedirect(true);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Deletes a node's content stream.
|
||||
*
|
||||
* @param source
|
||||
* the node
|
||||
*/
|
||||
public void deleteContentStream(ScriptNode source)
|
||||
{
|
||||
try
|
||||
{
|
||||
cmisService.deleteContentStream((String) cmisService.getProperty(source.getNodeRef(),
|
||||
CMISDictionaryModel.PROP_OBJECT_ID));
|
||||
}
|
||||
catch (CMISServiceException e)
|
||||
{
|
||||
throw new WebScriptException(e.getStatusCode(), e.getMessage(), e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Deletes a node.
|
||||
*
|
||||
* @param source
|
||||
* the node
|
||||
* @param allVersions
|
||||
* should we delete all the versions of the node?
|
||||
*/
|
||||
public void deleteObject(ScriptNode source, boolean allVersions)
|
||||
{
|
||||
try
|
||||
{
|
||||
cmisService.deleteObject((String) cmisService.getProperty(source.getNodeRef(),
|
||||
CMISDictionaryModel.PROP_OBJECT_ID), allVersions);
|
||||
}
|
||||
catch (CMISServiceException e)
|
||||
{
|
||||
throw new WebScriptException(e.getStatusCode(), e.getMessage(), e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Deletes an association.
|
||||
*
|
||||
* @param assoc
|
||||
* the association
|
||||
*/
|
||||
public void deleteObject(Association assoc)
|
||||
{
|
||||
try
|
||||
{
|
||||
cmisService.deleteObject((String) cmisService.getProperty(assoc.getAssociationRef(),
|
||||
CMISDictionaryModel.PROP_OBJECT_ID), true);
|
||||
}
|
||||
catch (CMISServiceException e)
|
||||
{
|
||||
throw new WebScriptException(e.getStatusCode(), e.getMessage(), e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds an object to a folder.
|
||||
*
|
||||
* @param child
|
||||
* the object to add
|
||||
* @param parent
|
||||
* the folder
|
||||
*/
|
||||
public void addObjectToFolder(ScriptNode child, ScriptNode parent)
|
||||
{
|
||||
try
|
||||
{
|
||||
cmisService.addObjectToFolder((String) cmisService.getProperty(child.getNodeRef(),
|
||||
CMISDictionaryModel.PROP_OBJECT_ID), (String) cmisService.getProperty(parent.getNodeRef(),
|
||||
CMISDictionaryModel.PROP_OBJECT_ID));
|
||||
}
|
||||
catch (CMISServiceException e)
|
||||
{
|
||||
throw new WebScriptException(e.getStatusCode(), e.getMessage(), e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Moves an object from a source folder to a target folder.
|
||||
*
|
||||
* @param child
|
||||
* the object to move
|
||||
* @param targetFolder
|
||||
* the target folder
|
||||
* @param sourceFolderId
|
||||
* the source folder object ID
|
||||
*/
|
||||
public void moveObject(ScriptNode child, ScriptNode targetFolder, String sourceFolderId)
|
||||
{
|
||||
try
|
||||
{
|
||||
cmisService.moveObject((String) cmisService.getProperty(child.getNodeRef(),
|
||||
CMISDictionaryModel.PROP_OBJECT_ID), (String) cmisService.getProperty(targetFolder.getNodeRef(),
|
||||
CMISDictionaryModel.PROP_OBJECT_ID), sourceFolderId);
|
||||
}
|
||||
catch (CMISServiceException e)
|
||||
{
|
||||
throw new WebScriptException(e.getStatusCode(), e.getMessage(), e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -31,6 +31,7 @@ import java.util.HashMap;
|
||||
import java.util.Iterator;
|
||||
import java.util.Map;
|
||||
|
||||
import org.alfresco.cmis.CMISPropertyDefinition;
|
||||
import org.alfresco.cmis.CMISResultSet;
|
||||
import org.alfresco.cmis.CMISResultSetColumn;
|
||||
import org.alfresco.cmis.CMISResultSetMetaData;
|
||||
@@ -234,6 +235,18 @@ public class CMISTemplateResultSet implements Serializable
|
||||
return col == null ? null : col.getCMISDataType().getLabel();
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets property definition for specified column name
|
||||
*
|
||||
* @param colName column name
|
||||
* @return property definition (or null, if not applicable)
|
||||
*/
|
||||
public CMISPropertyDefinition getPropertyDefinition(String colName)
|
||||
{
|
||||
CMISResultSetColumn col = resultSet.getMetaData().getColumn(colName);
|
||||
return col == null ? null : col.getCMISPropertyDefinition();
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets node for specified selector
|
||||
*
|
||||
|
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2005-2009 Alfresco Software Limited.
|
||||
* Copyright (C) 2005-2010 Alfresco Software Limited.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
@@ -18,57 +18,58 @@
|
||||
* As a special exception to the terms and conditions of version 2.0 of
|
||||
* the GPL, you may redistribute this Program in connection with Free/Libre
|
||||
* and Open Source Software ("FLOSS") applications as described in Alfresco's
|
||||
* FLOSS exception. You should have recieved a copy of the text describing
|
||||
* FLOSS exception. You should have received a copy of the text describing
|
||||
* the FLOSS exception, and it is also available here:
|
||||
* http://www.alfresco.com/legal/licensing"
|
||||
*/
|
||||
package org.alfresco.repo.cmis.ws;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.beans.IntrospectionException;
|
||||
import java.beans.Introspector;
|
||||
import java.beans.PropertyDescriptor;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.math.BigInteger;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
|
||||
import javax.xml.bind.JAXBElement;
|
||||
import javax.xml.ws.Holder;
|
||||
|
||||
import org.alfresco.cmis.CMISAccessControlEntry;
|
||||
import org.alfresco.cmis.CMISAccessControlFormatEnum;
|
||||
import org.alfresco.cmis.CMISAccessControlReport;
|
||||
import org.alfresco.cmis.CMISAccessControlService;
|
||||
import org.alfresco.cmis.CMISAclPropagationEnum;
|
||||
import org.alfresco.cmis.CMISActionEvaluator;
|
||||
import org.alfresco.cmis.CMISAllowedActionEnum;
|
||||
import org.alfresco.cmis.CMISChangeLogService;
|
||||
import org.alfresco.cmis.CMISDictionaryModel;
|
||||
import org.alfresco.cmis.CMISDictionaryService;
|
||||
import org.alfresco.cmis.CMISConstraintException;
|
||||
import org.alfresco.cmis.CMISFilterNotValidException;
|
||||
import org.alfresco.cmis.CMISInvalidArgumentException;
|
||||
import org.alfresco.cmis.CMISQueryService;
|
||||
import org.alfresco.cmis.CMISRendition;
|
||||
import org.alfresco.cmis.CMISRenditionService;
|
||||
import org.alfresco.cmis.CMISServices;
|
||||
import org.alfresco.cmis.CMISTypeDefinition;
|
||||
import org.alfresco.model.ContentModel;
|
||||
import org.alfresco.cmis.acl.CMISAccessControlEntryImpl;
|
||||
import org.alfresco.error.AlfrescoRuntimeException;
|
||||
import org.alfresco.repo.cmis.PropertyFilter;
|
||||
import org.alfresco.repo.cmis.ws.utils.AlfrescoObjectType;
|
||||
import org.alfresco.repo.cmis.ws.utils.CmisObjectsUtils;
|
||||
import org.alfresco.repo.cmis.ws.utils.ExceptionUtil;
|
||||
import org.alfresco.repo.cmis.ws.utils.PropertyUtil;
|
||||
import org.alfresco.repo.security.authentication.AuthenticationUtil;
|
||||
import org.alfresco.repo.version.VersionModel;
|
||||
import org.alfresco.repo.web.util.paging.Cursor;
|
||||
import org.alfresco.repo.web.util.paging.Page;
|
||||
import org.alfresco.repo.web.util.paging.Paging;
|
||||
import org.alfresco.service.cmr.coci.CheckOutCheckInService;
|
||||
import org.alfresco.service.cmr.model.FileFolderService;
|
||||
import org.alfresco.service.cmr.repository.AssociationRef;
|
||||
import org.alfresco.service.cmr.repository.NodeRef;
|
||||
import org.alfresco.service.cmr.repository.NodeService;
|
||||
import org.alfresco.service.cmr.search.SearchService;
|
||||
import org.alfresco.service.cmr.security.AccessStatus;
|
||||
import org.alfresco.service.cmr.security.PermissionService;
|
||||
import org.alfresco.service.cmr.version.Version;
|
||||
import org.alfresco.service.cmr.version.VersionService;
|
||||
import org.alfresco.service.cmr.version.VersionType;
|
||||
import org.alfresco.service.descriptor.DescriptorService;
|
||||
|
||||
/**
|
||||
@@ -81,24 +82,41 @@ import org.alfresco.service.descriptor.DescriptorService;
|
||||
*/
|
||||
public class DMAbstractServicePort
|
||||
{
|
||||
protected static final String INITIAL_VERSION_DESCRIPTION = "Initial version";
|
||||
private static final String CMIS_USER = "cmis:user";
|
||||
|
||||
private static final String INVALID_REPOSITORY_ID_MESSAGE = "Invalid repository id";
|
||||
private static final String INVALID_FOLDER_OBJECT_ID_MESSAGE = "OID for non-existent object or not folder object";
|
||||
|
||||
private static final Map<EnumACLPropagation, CMISAclPropagationEnum> ACL_PROPAGATION_ENUM_MAPPGIN;
|
||||
private static final Map<CMISAllowedActionEnum, PropertyDescriptor> ALLOWED_ACTION_ENUM_MAPPING;
|
||||
static
|
||||
{
|
||||
ACL_PROPAGATION_ENUM_MAPPGIN = new HashMap<EnumACLPropagation, CMISAclPropagationEnum>();
|
||||
ACL_PROPAGATION_ENUM_MAPPGIN.put(EnumACLPropagation.OBJECTONLY, CMISAclPropagationEnum.OBJECT_ONLY);
|
||||
ACL_PROPAGATION_ENUM_MAPPGIN.put(EnumACLPropagation.PROPAGATE, CMISAclPropagationEnum.PROPAGATE);
|
||||
ACL_PROPAGATION_ENUM_MAPPGIN.put(EnumACLPropagation.REPOSITORYDETERMINED, CMISAclPropagationEnum.REPOSITORY_DETERMINED);
|
||||
|
||||
try
|
||||
{
|
||||
ALLOWED_ACTION_ENUM_MAPPING = new HashMap<CMISAllowedActionEnum, PropertyDescriptor>(97);
|
||||
for (PropertyDescriptor propertyDescriptor : Introspector.getBeanInfo(CmisAllowableActionsType.class, Object.class).getPropertyDescriptors())
|
||||
{
|
||||
String label = propertyDescriptor.getName();
|
||||
CMISAllowedActionEnum allowedActionEnum = CMISAllowedActionEnum.FACTORY.fromLabel(label);
|
||||
if (allowedActionEnum != null)
|
||||
{
|
||||
ALLOWED_ACTION_ENUM_MAPPING.put(allowedActionEnum, propertyDescriptor);
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (IntrospectionException e)
|
||||
{
|
||||
throw new ExceptionInInitializerError(e);
|
||||
}
|
||||
}
|
||||
|
||||
private Paging paging = new Paging();
|
||||
|
||||
protected ObjectFactory cmisObjectFactory = new ObjectFactory();
|
||||
protected CMISDictionaryService cmisDictionaryService;
|
||||
protected CMISQueryService cmisQueryService;
|
||||
protected CMISServices cmisService;
|
||||
protected CMISChangeLogService cmisChangeLogService;
|
||||
@@ -107,11 +125,8 @@ public class DMAbstractServicePort
|
||||
|
||||
protected DescriptorService descriptorService;
|
||||
protected NodeService nodeService;
|
||||
protected VersionService versionService;
|
||||
protected FileFolderService fileFolderService;
|
||||
protected CheckOutCheckInService checkOutCheckInService;
|
||||
protected SearchService searchService;
|
||||
protected CmisObjectsUtils cmisObjectsUtils;
|
||||
protected PropertyUtil propertiesUtil;
|
||||
protected PermissionService permissionService;
|
||||
|
||||
@@ -120,11 +135,6 @@ public class DMAbstractServicePort
|
||||
this.cmisService = cmisService;
|
||||
}
|
||||
|
||||
public void setCmisDictionaryService(CMISDictionaryService cmisDictionaryService)
|
||||
{
|
||||
this.cmisDictionaryService = cmisDictionaryService;
|
||||
}
|
||||
|
||||
public void setCmisQueryService(CMISQueryService cmisQueryService)
|
||||
{
|
||||
this.cmisQueryService = cmisQueryService;
|
||||
@@ -155,27 +165,11 @@ public class DMAbstractServicePort
|
||||
this.nodeService = nodeService;
|
||||
}
|
||||
|
||||
public void setVersionService(VersionService versionService)
|
||||
{
|
||||
this.versionService = versionService;
|
||||
}
|
||||
|
||||
public void setFileFolderService(FileFolderService fileFolderService)
|
||||
{
|
||||
this.fileFolderService = fileFolderService;
|
||||
}
|
||||
|
||||
public void setCheckOutCheckInService(CheckOutCheckInService checkOutCheckInService)
|
||||
{
|
||||
|
||||
this.checkOutCheckInService = checkOutCheckInService;
|
||||
}
|
||||
|
||||
public void setCmisObjectsUtils(CmisObjectsUtils cmisObjectsUtils)
|
||||
{
|
||||
this.cmisObjectsUtils = cmisObjectsUtils;
|
||||
}
|
||||
|
||||
public void setPropertiesUtil(PropertyUtil propertiesUtil)
|
||||
{
|
||||
this.propertiesUtil = propertiesUtil;
|
||||
@@ -193,7 +187,7 @@ public class DMAbstractServicePort
|
||||
|
||||
protected PropertyFilter createPropertyFilter(String filter) throws CmisException
|
||||
{
|
||||
return (filter == null) ? (new PropertyFilter()) : (new PropertyFilter(filter, cmisObjectsUtils));
|
||||
return (filter == null) ? (new PropertyFilter()) : (new PropertyFilter(filter));
|
||||
}
|
||||
|
||||
protected PropertyFilter createPropertyFilter(JAXBElement<String> element) throws CmisException
|
||||
@@ -239,7 +233,7 @@ public class DMAbstractServicePort
|
||||
protected CmisObjectType createCmisObject(Object identifier, PropertyFilter filter, boolean includeAllowableActions, String renditionFilter) throws CmisException
|
||||
{
|
||||
CmisObjectType result = new CmisObjectType();
|
||||
result.setProperties(propertiesUtil.getPropertiesType(identifier.toString(), filter));
|
||||
result.setProperties(propertiesUtil.getProperties(identifier, filter));
|
||||
if (includeAllowableActions)
|
||||
{
|
||||
result.setAllowableActions(determineObjectAllowableActions(identifier));
|
||||
@@ -255,20 +249,6 @@ public class DMAbstractServicePort
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Asserts "Folder with folderNodeRef exists"
|
||||
*
|
||||
* @param folderNodeRef node reference
|
||||
* @throws FolderNotValidException folderNodeRef doesn't exist or folderNodeRef isn't for folder object
|
||||
*/
|
||||
protected void assertExistFolder(NodeRef folderNodeRef) throws CmisException
|
||||
{
|
||||
if (!this.cmisObjectsUtils.isFolder(folderNodeRef))
|
||||
{
|
||||
throw new CmisException(INVALID_FOLDER_OBJECT_ID_MESSAGE, cmisObjectsUtils.createCmisException(INVALID_FOLDER_OBJECT_ID_MESSAGE, EnumServiceException.INVALID_ARGUMENT));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks specified in CMIS request parameters repository Id.
|
||||
*
|
||||
@@ -279,54 +259,29 @@ public class DMAbstractServicePort
|
||||
{
|
||||
if (!this.descriptorService.getCurrentRepositoryDescriptor().getId().equals(repositoryId))
|
||||
{
|
||||
throw cmisObjectsUtils.createCmisException(INVALID_REPOSITORY_ID_MESSAGE, EnumServiceException.INVALID_ARGUMENT);
|
||||
throw ExceptionUtil.createCmisException(INVALID_REPOSITORY_ID_MESSAGE, EnumServiceException.INVALID_ARGUMENT);
|
||||
}
|
||||
}
|
||||
|
||||
protected Map<String, Serializable> createVersionProperties(String versionDescription, VersionType versionType)
|
||||
{
|
||||
Map<String, Serializable> result = new HashMap<String, Serializable>();
|
||||
result.put(Version.PROP_DESCRIPTION, versionDescription);
|
||||
result.put(VersionModel.PROP_VERSION_TYPE, versionType);
|
||||
return result;
|
||||
}
|
||||
|
||||
protected NodeRef checkoutNode(NodeRef documentNodeReference)
|
||||
{
|
||||
if (!this.nodeService.hasAspect(documentNodeReference, ContentModel.ASPECT_VERSIONABLE))
|
||||
{
|
||||
this.versionService.createVersion(documentNodeReference, createVersionProperties(INITIAL_VERSION_DESCRIPTION, VersionType.MAJOR));
|
||||
}
|
||||
return checkOutCheckInService.checkout(documentNodeReference);
|
||||
}
|
||||
|
||||
protected CMISTypeDefinition getCmisTypeDefinition(String typeId) throws CmisException
|
||||
{
|
||||
try
|
||||
{
|
||||
return cmisDictionaryService.findType(typeId);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
throw new CmisException(("Invalid typeId " + typeId), cmisObjectsUtils.createCmisException(("Invalid typeId " + typeId), EnumServiceException.INVALID_ARGUMENT));
|
||||
}
|
||||
}
|
||||
|
||||
protected List<CmisRenditionType> getRenditions(Object objectId, String renditionFilter) throws CmisException
|
||||
protected List<CmisRenditionType> getRenditions(Object object, String renditionFilter) throws CmisException
|
||||
{
|
||||
List<CmisRenditionType> result = null;
|
||||
if (NodeRef.isNodeRef(objectId.toString()))
|
||||
if (object instanceof Version)
|
||||
{
|
||||
NodeRef document = new NodeRef(objectId.toString());
|
||||
object = ((Version) object).getFrozenStateNodeRef();
|
||||
}
|
||||
if (object instanceof NodeRef)
|
||||
{
|
||||
NodeRef document = (NodeRef) object;
|
||||
|
||||
List<CMISRendition> renditions = null;
|
||||
try
|
||||
{
|
||||
renditions = cmisRenditionService.getRenditions(document, renditionFilter);
|
||||
}
|
||||
catch (Exception e)
|
||||
catch (CMISFilterNotValidException e)
|
||||
{
|
||||
throw cmisObjectsUtils.createCmisException("Invalid rendition filter", EnumServiceException.FILTER_NOT_VALID);
|
||||
throw ExceptionUtil.createCmisException(e);
|
||||
}
|
||||
if (renditions != null && !renditions.isEmpty())
|
||||
{
|
||||
@@ -372,127 +327,41 @@ public class DMAbstractServicePort
|
||||
{
|
||||
return null;
|
||||
}
|
||||
String typeId = propertiesUtil.getProperty(object, CMISDictionaryModel.PROP_OBJECT_TYPE_ID, null);
|
||||
CMISTypeDefinition objectType = (null == typeId) ? (null) : (cmisDictionaryService.findType(typeId));
|
||||
if (null == objectType)
|
||||
try
|
||||
{
|
||||
throw cmisObjectsUtils.createCmisException("Type Definition for specified Object was not found", EnumServiceException.STORAGE);
|
||||
}
|
||||
if (!objectType.isControllableACL())
|
||||
{
|
||||
throw cmisObjectsUtils.createCmisException("Object that was specified is not ACL Controllable", EnumServiceException.CONSTRAINT);
|
||||
}
|
||||
CMISAclPropagationEnum propagation = (null == aclPropagation) ? (CMISAclPropagationEnum.PROPAGATE) : (ACL_PROPAGATION_ENUM_MAPPGIN.get(aclPropagation));
|
||||
List<CMISAccessControlEntry> acesToAdd = (null == addACEs) ? (null) : (convertToAlfrescoAceEntriesList(addACEs.getPermission()));
|
||||
List<CMISAccessControlEntry> acesToRemove = (null == removeACEs) ? (null) : (convertToAlfrescoAceEntriesList(removeACEs.getPermission()));
|
||||
CMISAccessControlReport aclReport = null;
|
||||
try
|
||||
{
|
||||
aclReport = cmisAclService.applyAcl(object, acesToRemove, acesToAdd, propagation, CMISAccessControlFormatEnum.REPOSITORY_SPECIFIC_PERMISSIONS);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
throw cmisObjectsUtils.createCmisException(("Can't perform updating of Object Permissions. Error cause message: " + e.toString()), EnumServiceException.CONSTRAINT);
|
||||
}
|
||||
CmisACLType result = convertAclReportToCmisAclType(aclReport);
|
||||
return result;
|
||||
}
|
||||
catch (CMISConstraintException e)
|
||||
{
|
||||
throw ExceptionUtil.createCmisException(e);
|
||||
}
|
||||
}
|
||||
|
||||
private List<CMISAccessControlEntry> convertToAlfrescoAceEntriesList(List<CmisAccessControlEntryType> source)
|
||||
private List<CMISAccessControlEntry> convertToAlfrescoAceEntriesList(List<CmisAccessControlEntryType> source) throws CmisException
|
||||
{
|
||||
List<CMISAccessControlEntry> result = new LinkedList<CMISAccessControlEntry>();
|
||||
for (CmisAccessControlEntryType cmisEntry : source)
|
||||
{
|
||||
result.add(convertToAlfrescoAceEntry(cmisEntry));
|
||||
if (!cmisEntry.isDirect())
|
||||
{
|
||||
throw ExceptionUtil.createCmisException("Inherited Permissions can't be updated or deleted from Object", EnumServiceException.NOT_SUPPORTED);
|
||||
}
|
||||
return result;
|
||||
String principalId = cmisEntry.getPrincipal().getPrincipalId();
|
||||
if (CMIS_USER.equals(principalId))
|
||||
{
|
||||
principalId = AuthenticationUtil.getFullyAuthenticatedUser();
|
||||
}
|
||||
|
||||
private CMISAccessControlEntry convertToAlfrescoAceEntry(final CmisAccessControlEntryType entry)
|
||||
for (String permission : cmisEntry.getPermission())
|
||||
{
|
||||
final Holder<String> correctPrincipalId = new Holder<String>(entry.getPrincipal().getPrincipalId());
|
||||
if ("cmis:user".equals(correctPrincipalId))
|
||||
{
|
||||
correctPrincipalId.value = AuthenticationUtil.getFullyAuthenticatedUser();
|
||||
}
|
||||
CMISAccessControlEntry result = new CMISAccessControlEntry() // FIXME: It is better to use already implemented class of this interface
|
||||
{
|
||||
private String principalId;
|
||||
private String permission; // FIXME: [BUG] It MUST BE a List of permissions!!!
|
||||
private boolean direct;
|
||||
{
|
||||
|
||||
principalId = correctPrincipalId.value;
|
||||
permission = entry.getPermission().iterator().next(); // FIXME: See line 66
|
||||
direct = entry.isDirect();
|
||||
}
|
||||
|
||||
public String getPrincipalId()
|
||||
{
|
||||
return principalId;
|
||||
}
|
||||
|
||||
public String getPermission()
|
||||
{
|
||||
return permission;
|
||||
}
|
||||
|
||||
public boolean getDirect()
|
||||
{
|
||||
return direct;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode()
|
||||
{
|
||||
final int prime = 31;
|
||||
int result = 1;
|
||||
result = prime * result + ((permission == null) ? 0 : permission.hashCode());
|
||||
result = prime * result + ((principalId == null) ? 0 : principalId.hashCode());
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj)
|
||||
{
|
||||
if (this == obj)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
if (obj == null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
if (getClass() != obj.getClass())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
final CMISAccessControlEntry other = (CMISAccessControlEntry) obj;
|
||||
if (permission == null)
|
||||
{
|
||||
if (other.getPermission() != null)
|
||||
{
|
||||
return false;
|
||||
result.add(new CMISAccessControlEntryImpl(principalId, permission));
|
||||
}
|
||||
}
|
||||
else if (!permission.equals(other.getPermission()))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
if (principalId == null)
|
||||
{
|
||||
if (other.getPrincipalId() != null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else if (!principalId.equals(other.getPrincipalId()))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
};
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -515,90 +384,54 @@ public class DMAbstractServicePort
|
||||
return result;
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
protected CmisAllowableActionsType determineObjectAllowableActions(Object objectIdentifier) throws CmisException
|
||||
{
|
||||
if (objectIdentifier instanceof String)
|
||||
CMISTypeDefinition typeDef;
|
||||
try
|
||||
{
|
||||
objectIdentifier = cmisObjectsUtils.getIdentifierInstance(objectIdentifier.toString(), AlfrescoObjectType.ANY_OBJECT);
|
||||
}
|
||||
if (objectIdentifier instanceof AssociationRef)
|
||||
{
|
||||
return determineRelationshipAllowableActions((AssociationRef) objectIdentifier);
|
||||
typeDef = cmisService.getTypeDefinition((AssociationRef) objectIdentifier);
|
||||
}
|
||||
|
||||
switch (cmisObjectsUtils.determineObjectType(objectIdentifier.toString()))
|
||||
else
|
||||
{
|
||||
case CMIS_DOCUMENT:
|
||||
if (objectIdentifier instanceof Version)
|
||||
{
|
||||
return determineDocumentAllowableActions((NodeRef) objectIdentifier);
|
||||
objectIdentifier = ((Version) objectIdentifier).getFrozenStateNodeRef();
|
||||
}
|
||||
case CMIS_FOLDER:
|
||||
typeDef = cmisService.getTypeDefinition((NodeRef) objectIdentifier);
|
||||
}
|
||||
}
|
||||
catch (CMISInvalidArgumentException e)
|
||||
{
|
||||
return determineFolderAllowableActions((NodeRef) objectIdentifier);
|
||||
throw ExceptionUtil.createCmisException(e);
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: determinePolicyAllowableActions() when Policy functionality is ready
|
||||
throw cmisObjectsUtils.createCmisException("It is impossible to get Allowable actions for the specified Object", EnumServiceException.NOT_SUPPORTED);
|
||||
}
|
||||
|
||||
private CmisAllowableActionsType determineBaseAllowableActions(NodeRef objectNodeReference)
|
||||
{
|
||||
CmisAllowableActionsType result = new CmisAllowableActionsType();
|
||||
result.setCanGetProperties(this.permissionService.hasPermission(objectNodeReference, PermissionService.READ_PROPERTIES) == AccessStatus.ALLOWED);
|
||||
result.setCanUpdateProperties(this.permissionService.hasPermission(objectNodeReference, PermissionService.WRITE_PROPERTIES) == AccessStatus.ALLOWED);
|
||||
result.setCanDeleteObject(this.permissionService.hasPermission(objectNodeReference, PermissionService.DELETE) == AccessStatus.ALLOWED);
|
||||
|
||||
// TODO: response.setCanAddPolicy(value);
|
||||
// TODO: response.setCanRemovePolicy(value);
|
||||
// TODO: response.setCanGetAppliedPolicies(value);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
private CmisAllowableActionsType determineDocumentAllowableActions(NodeRef objectNodeReference)
|
||||
for (Entry<CMISAllowedActionEnum, CMISActionEvaluator<? extends Object>> entry : typeDef.getActionEvaluators().entrySet())
|
||||
{
|
||||
CmisAllowableActionsType result = determineBaseAllowableActions(objectNodeReference);
|
||||
determineCommonFolderDocumentAllowableActions(objectNodeReference, result);
|
||||
result.setCanGetObjectParents(this.permissionService.hasPermission(objectNodeReference, PermissionService.READ_ASSOCIATIONS) == AccessStatus.ALLOWED);
|
||||
result.setCanGetContentStream(this.permissionService.hasPermission(objectNodeReference, PermissionService.READ_CONTENT) == AccessStatus.ALLOWED);
|
||||
result.setCanSetContentStream(this.permissionService.hasPermission(objectNodeReference, PermissionService.WRITE_CONTENT) == AccessStatus.ALLOWED);
|
||||
result.setCanCheckOut(this.permissionService.hasPermission(objectNodeReference, PermissionService.CHECK_OUT) == AccessStatus.ALLOWED);
|
||||
result.setCanCheckIn(this.permissionService.hasPermission(objectNodeReference, PermissionService.CHECK_IN) == AccessStatus.ALLOWED);
|
||||
result.setCanCancelCheckOut(this.permissionService.hasPermission(objectNodeReference, PermissionService.CANCEL_CHECK_OUT) == AccessStatus.ALLOWED);
|
||||
result.setCanDeleteContentStream(result.isCanUpdateProperties() && result.isCanSetContentStream());
|
||||
return result;
|
||||
}
|
||||
|
||||
private CmisAllowableActionsType determineFolderAllowableActions(NodeRef objectNodeReference)
|
||||
PropertyDescriptor propertyDescriptor = ALLOWED_ACTION_ENUM_MAPPING.get(entry.getKey());
|
||||
if (propertyDescriptor != null)
|
||||
{
|
||||
CmisAllowableActionsType result = determineBaseAllowableActions(objectNodeReference);
|
||||
determineCommonFolderDocumentAllowableActions(objectNodeReference, result);
|
||||
|
||||
result.setCanGetChildren(this.permissionService.hasPermission(objectNodeReference, PermissionService.READ_CHILDREN) == AccessStatus.ALLOWED);
|
||||
result.setCanCreateDocument(this.permissionService.hasPermission(objectNodeReference, PermissionService.ADD_CHILDREN) == AccessStatus.ALLOWED);
|
||||
result.setCanGetDescendants(result.isCanGetChildren() && (this.permissionService.hasPermission(objectNodeReference, PermissionService.READ) == AccessStatus.ALLOWED));
|
||||
result.setCanDeleteTree(this.permissionService.hasPermission(objectNodeReference, PermissionService.DELETE_CHILDREN) == AccessStatus.ALLOWED);
|
||||
result.setCanGetFolderParent(result.isCanGetObjectRelationships());
|
||||
result.setCanCreateFolder(result.isCanCreateDocument());
|
||||
// TODO: response.setCanCreatePolicy(value);
|
||||
return result;
|
||||
}
|
||||
|
||||
private void determineCommonFolderDocumentAllowableActions(NodeRef objectNodeReference, CmisAllowableActionsType allowableActions)
|
||||
// Let's assume that the evaluator will accept the object
|
||||
try
|
||||
{
|
||||
allowableActions.setCanAddObjectToFolder(this.permissionService.hasPermission(objectNodeReference, PermissionService.CREATE_ASSOCIATIONS) == AccessStatus.ALLOWED);
|
||||
allowableActions.setCanGetObjectRelationships(this.permissionService.hasPermission(objectNodeReference, PermissionService.READ_ASSOCIATIONS) == AccessStatus.ALLOWED);
|
||||
allowableActions.setCanMoveObject(allowableActions.isCanUpdateProperties() && allowableActions.isCanAddObjectToFolder());
|
||||
allowableActions.setCanRemoveObjectFromFolder(allowableActions.isCanUpdateProperties());
|
||||
allowableActions.setCanCreateRelationship(allowableActions.isCanAddObjectToFolder());
|
||||
propertyDescriptor.getWriteMethod().invoke(result, new Boolean(((CMISActionEvaluator) entry.getValue()).isAllowed(objectIdentifier)));
|
||||
}
|
||||
|
||||
private CmisAllowableActionsType determineRelationshipAllowableActions(AssociationRef association)
|
||||
catch (IllegalArgumentException e)
|
||||
{
|
||||
CmisAllowableActionsType result = new CmisAllowableActionsType();
|
||||
result.setCanDeleteObject(this.permissionService.hasPermission(association.getSourceRef(), PermissionService.DELETE_ASSOCIATIONS) == AccessStatus.ALLOWED);
|
||||
result.setCanGetObjectRelationships(this.permissionService.hasPermission(association.getSourceRef(), PermissionService.READ_ASSOCIATIONS) == AccessStatus.ALLOWED);
|
||||
throw new AlfrescoRuntimeException("Exception setting allowable actions", e);
|
||||
}
|
||||
catch (IllegalAccessException e)
|
||||
{
|
||||
throw new AlfrescoRuntimeException("Exception setting allowable actions", e);
|
||||
}
|
||||
catch (InvocationTargetException e)
|
||||
{
|
||||
throw new AlfrescoRuntimeException("Exception setting allowable actions", e.getTargetException());
|
||||
}
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
@@ -26,7 +26,8 @@ package org.alfresco.repo.cmis.ws;
|
||||
|
||||
import org.alfresco.cmis.CMISAccessControlFormatEnum;
|
||||
import org.alfresco.cmis.CMISAccessControlReport;
|
||||
import org.alfresco.repo.cmis.ws.utils.AlfrescoObjectType;
|
||||
import org.alfresco.cmis.CMISServiceException;
|
||||
import org.alfresco.repo.cmis.ws.utils.ExceptionUtil;
|
||||
import org.alfresco.service.cmr.repository.NodeRef;
|
||||
|
||||
/**
|
||||
@@ -42,7 +43,15 @@ public class DMAclServicePort extends DMAbstractServicePort implements ACLServic
|
||||
CmisExtensionType extension) throws CmisException
|
||||
{
|
||||
checkRepositoryId(repositoryId);
|
||||
NodeRef object = cmisObjectsUtils.getIdentifierInstance(objectId, AlfrescoObjectType.ANY_OBJECT);
|
||||
NodeRef object;
|
||||
try
|
||||
{
|
||||
object = cmisService.getObject(objectId, NodeRef.class, true, false, false);
|
||||
}
|
||||
catch (CMISServiceException e)
|
||||
{
|
||||
throw ExceptionUtil.createCmisException(e);
|
||||
}
|
||||
return applyAclCarefully(object, addACEs, removeACEs, aclPropagation);
|
||||
}
|
||||
|
||||
@@ -52,10 +61,18 @@ public class DMAclServicePort extends DMAbstractServicePort implements ACLServic
|
||||
public CmisACLType getACL(String repositoryId, String objectId, Boolean onlyBasicPermissions, CmisExtensionType extension) throws CmisException
|
||||
{
|
||||
checkRepositoryId(repositoryId);
|
||||
NodeRef object = cmisObjectsUtils.getIdentifierInstance(objectId, AlfrescoObjectType.ANY_OBJECT);
|
||||
NodeRef nodeRef;
|
||||
try
|
||||
{
|
||||
nodeRef = cmisService.getReadableObject(objectId, NodeRef.class);
|
||||
}
|
||||
catch (CMISServiceException e)
|
||||
{
|
||||
throw ExceptionUtil.createCmisException(e);
|
||||
}
|
||||
CMISAccessControlFormatEnum permissionsKind = ((null == onlyBasicPermissions) || onlyBasicPermissions) ? (CMISAccessControlFormatEnum.CMIS_BASIC_PERMISSIONS)
|
||||
: (CMISAccessControlFormatEnum.REPOSITORY_SPECIFIC_PERMISSIONS);
|
||||
CMISAccessControlReport aclReport = cmisAclService.getAcl(object, permissionsKind);
|
||||
CMISAccessControlReport aclReport = cmisAclService.getAcl(nodeRef, permissionsKind);
|
||||
return convertAclReportToCmisAclType(aclReport);
|
||||
}
|
||||
}
|
||||
|
@@ -26,7 +26,6 @@ package org.alfresco.repo.cmis.ws;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.math.BigInteger;
|
||||
import java.util.Date;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
@@ -43,8 +42,9 @@ import org.alfresco.cmis.CMISQueryOptions;
|
||||
import org.alfresco.cmis.CMISResultSet;
|
||||
import org.alfresco.cmis.CMISResultSetColumn;
|
||||
import org.alfresco.cmis.CMISResultSetRow;
|
||||
import org.alfresco.cmis.CMISServiceException;
|
||||
import org.alfresco.repo.cmis.PropertyFilter;
|
||||
import org.alfresco.repo.cmis.ws.utils.AlfrescoObjectType;
|
||||
import org.alfresco.repo.cmis.ws.utils.ExceptionUtil;
|
||||
|
||||
/**
|
||||
* Port for Discovery service.
|
||||
@@ -118,7 +118,15 @@ public class DMDiscoveryServicePort extends DMAbstractServicePort implements Dis
|
||||
|
||||
CmisObjectType object = new CmisObjectType();
|
||||
object.setProperties(properties);
|
||||
Object identifier = cmisObjectsUtils.getIdentifierInstance((String) values.get(CMISDictionaryModel.PROP_OBJECT_ID), AlfrescoObjectType.DOCUMENT_OR_FOLDER_OBJECT);
|
||||
Object identifier;
|
||||
try
|
||||
{
|
||||
identifier = cmisService.getReadableObject((String) values.get(CMISDictionaryModel.PROP_OBJECT_ID), Object.class);
|
||||
}
|
||||
catch (CMISServiceException e)
|
||||
{
|
||||
throw ExceptionUtil.createCmisException(e);
|
||||
}
|
||||
if (includeAllowableActions)
|
||||
{
|
||||
object.setAllowableActions(determineObjectAllowableActions(identifier));
|
||||
@@ -175,26 +183,14 @@ public class DMDiscoveryServicePort extends DMAbstractServicePort implements Dis
|
||||
filter = CMISDictionaryModel.PROP_OBJECT_ID;
|
||||
}
|
||||
|
||||
if (changeToken != null)
|
||||
{
|
||||
try
|
||||
{
|
||||
Long.parseLong(changeToken);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
throw cmisObjectsUtils.createCmisException("Invalid changeLogToken was specified", EnumServiceException.INVALID_ARGUMENT);
|
||||
}
|
||||
}
|
||||
|
||||
CMISChangeLog changeLog = null;
|
||||
try
|
||||
{
|
||||
changeLog = cmisChangeLogService.getChangeLogEvents(changeToken, maxAmount);
|
||||
}
|
||||
catch (Exception e)
|
||||
catch (CMISServiceException e)
|
||||
{
|
||||
throw cmisObjectsUtils.createCmisException(e.getMessage(), EnumServiceException.STORAGE);
|
||||
throw ExceptionUtil.createCmisException(e);
|
||||
}
|
||||
if (null == objects.value)
|
||||
{
|
||||
@@ -230,10 +226,10 @@ public class DMDiscoveryServicePort extends DMAbstractServicePort implements Dis
|
||||
CmisObjectType object = new CmisObjectType();
|
||||
CmisPropertiesType propertiesType = new CmisPropertiesType();
|
||||
object.setProperties(propertiesType);
|
||||
propertiesType.getProperty().add(propertiesUtil.createProperty(CMISDictionaryModel.PROP_OBJECT_ID, CMISDataTypeEnum.ID, event.getNode()));
|
||||
if (nodeService.exists(event.getNode()) && includeAce)
|
||||
propertiesType.getProperty().add(propertiesUtil.createProperty(CMISDictionaryModel.PROP_OBJECT_ID, CMISDataTypeEnum.ID, event.getObjectId()));
|
||||
if (nodeService.exists(event.getChangedNode()) && includeAce)
|
||||
{
|
||||
appendWithAce(event.getNode(), object);
|
||||
appendWithAce(event.getChangedNode(), object);
|
||||
}
|
||||
CmisChangeEventType changeInfo = new CmisChangeEventType();
|
||||
XMLGregorianCalendar modificationDate = propertiesUtil.convert(event.getChangeTime());
|
||||
|
@@ -26,10 +26,8 @@ package org.alfresco.repo.cmis.ws;
|
||||
|
||||
import javax.xml.ws.Holder;
|
||||
|
||||
import org.alfresco.cmis.CMISDictionaryModel;
|
||||
import org.alfresco.cmis.CMISTypeDefinition;
|
||||
import org.alfresco.repo.cmis.ws.utils.AlfrescoObjectType;
|
||||
import org.alfresco.service.cmr.repository.NodeRef;
|
||||
import org.alfresco.cmis.CMISServiceException;
|
||||
import org.alfresco.repo.cmis.ws.utils.ExceptionUtil;
|
||||
|
||||
/**
|
||||
* Port for Multi-Filing service.
|
||||
@@ -51,25 +49,13 @@ public class DMMultiFilingServicePort extends DMAbstractServicePort implements M
|
||||
public void addObjectToFolder(String repositoryId, String objectId, String folderId, Boolean allVersions, Holder<CmisExtensionType> extension) throws CmisException
|
||||
{
|
||||
checkRepositoryId(repositoryId);
|
||||
NodeRef objectNodeRef = cmisObjectsUtils.getIdentifierInstance(objectId, AlfrescoObjectType.DOCUMENT_OBJECT);
|
||||
NodeRef parentFolderNodeRef = cmisObjectsUtils.getIdentifierInstance(folderId, AlfrescoObjectType.FOLDER_OBJECT);
|
||||
CMISTypeDefinition objectType = cmisDictionaryService.findType(propertiesUtil.getProperty(objectNodeRef, CMISDictionaryModel.PROP_OBJECT_TYPE_ID, (String) null));
|
||||
CMISTypeDefinition folderType = cmisDictionaryService.findType(propertiesUtil.getProperty(parentFolderNodeRef, CMISDictionaryModel.PROP_OBJECT_TYPE_ID, (String) null));
|
||||
if (folderType == null)
|
||||
try
|
||||
{
|
||||
throw cmisObjectsUtils.createCmisException("Type of the specified parent folder can't be resovled", EnumServiceException.RUNTIME);
|
||||
cmisService.addObjectToFolder(objectId, folderId);
|
||||
}
|
||||
// FIXME [BUG]: folderType.getAllowedTargetTypes() MUST be changed on folderType.getAllowedChildObjectTypeIds()
|
||||
if (!folderType.getAllowedTargetTypes().isEmpty() && !folderType.getAllowedTargetTypes().contains(objectType))
|
||||
catch (CMISServiceException e)
|
||||
{
|
||||
throw cmisObjectsUtils.createCmisException(("The Object of '" + objectType.getTypeId() + "' Type can't be child of Folder of '" + folderType.getTypeId() + "' Type"),
|
||||
EnumServiceException.CONSTRAINT);
|
||||
}
|
||||
if (!cmisObjectsUtils.addObjectToFolder(objectNodeRef, parentFolderNodeRef))
|
||||
{
|
||||
Throwable exception = cmisObjectsUtils.getLastOperationException();
|
||||
throw cmisObjectsUtils.createCmisException(("Can't add specified Object to specified Folder. Cause exception message: " + exception.toString()),
|
||||
EnumServiceException.STORAGE, exception);
|
||||
throw ExceptionUtil.createCmisException(e);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -84,43 +70,13 @@ public class DMMultiFilingServicePort extends DMAbstractServicePort implements M
|
||||
public void removeObjectFromFolder(String repositoryId, String objectId, String folderId, Holder<CmisExtensionType> extension) throws CmisException
|
||||
{
|
||||
checkRepositoryId(repositoryId);
|
||||
NodeRef objectNodeReference = cmisObjectsUtils.getIdentifierInstance(objectId, AlfrescoObjectType.DOCUMENT_OBJECT);
|
||||
NodeRef folderNodeReference = checkAndReceiveFolderIdentifier(folderId);
|
||||
// FIXME [BUG]: if Document is Multi-Filled then removing this Object from Primary Parent Folder MUST treat to determine Primary Parent for Document from other Parent
|
||||
// Folders
|
||||
checkObjectChildParentRelationships(objectNodeReference, folderNodeReference);
|
||||
if (!cmisObjectsUtils.removeObject(objectNodeReference, folderNodeReference))
|
||||
{
|
||||
Throwable exception = cmisObjectsUtils.getLastOperationException();
|
||||
if (null != exception)
|
||||
{
|
||||
throw cmisObjectsUtils.createCmisException(("Can't remove specified Object from specified Folder. Cause exception message: " + exception.toString()),
|
||||
EnumServiceException.STORAGE, exception);
|
||||
}
|
||||
else
|
||||
{
|
||||
throw cmisObjectsUtils.createCmisException("Can't remove specified Object from specified Folder", EnumServiceException.STORAGE, exception);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private NodeRef checkAndReceiveFolderIdentifier(String folderIdentifier) throws CmisException
|
||||
{
|
||||
try
|
||||
{
|
||||
return cmisObjectsUtils.getIdentifierInstance(folderIdentifier, AlfrescoObjectType.FOLDER_OBJECT);
|
||||
cmisService.removeObjectFromFolder(objectId, folderId);
|
||||
}
|
||||
catch (Throwable e)
|
||||
catch (CMISServiceException e)
|
||||
{
|
||||
throw cmisObjectsUtils.createCmisException("Unfiling is not supported. An Object can't be deleted from all Folders", EnumServiceException.NOT_SUPPORTED, e);
|
||||
}
|
||||
}
|
||||
|
||||
private void checkObjectChildParentRelationships(NodeRef objectNodeReference, NodeRef folderNodeReference) throws CmisException
|
||||
{
|
||||
if (cmisObjectsUtils.isPrimaryObjectParent(folderNodeReference, objectNodeReference))
|
||||
{
|
||||
throw cmisObjectsUtils.createCmisException("Unfiling is not supported. Use deleteObject() Service instead", EnumServiceException.NOT_SUPPORTED);
|
||||
throw ExceptionUtil.createCmisException(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2005-2008 Alfresco Software Limited.
|
||||
* Copyright (C) 2005-2010 Alfresco Software Limited.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
@@ -18,7 +18,7 @@
|
||||
* As a special exception to the terms and conditions of version 2.0 of
|
||||
* the GPL, you may redistribute this Program in connection with Free/Libre
|
||||
* and Open Source Software ("FLOSS") applications as described in Alfresco's
|
||||
* FLOSS exception. You should have recieved a copy of the text describing
|
||||
* FLOSS exception. You should have received a copy of the text describing
|
||||
* the FLOSS exception, and it is also available here:
|
||||
* http://www.alfresco.com/legal/licensing"
|
||||
*/
|
||||
@@ -29,17 +29,16 @@ import java.util.ArrayList;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.Stack;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import org.alfresco.cmis.CMISDictionaryModel;
|
||||
import org.alfresco.cmis.CMISServiceException;
|
||||
import org.alfresco.cmis.CMISTypesFilterEnum;
|
||||
import org.alfresco.repo.cmis.PropertyFilter;
|
||||
import org.alfresco.repo.cmis.ws.utils.AlfrescoObjectType;
|
||||
import org.alfresco.repo.cmis.ws.utils.ExceptionUtil;
|
||||
import org.alfresco.repo.security.authentication.AuthenticationUtil;
|
||||
import org.alfresco.repo.web.util.paging.Cursor;
|
||||
import org.alfresco.service.cmr.repository.ChildAssociationRef;
|
||||
import org.alfresco.service.cmr.repository.NodeRef;
|
||||
import org.springframework.extensions.surf.util.Pair;
|
||||
|
||||
/**
|
||||
* Port for navigation service
|
||||
@@ -55,9 +54,6 @@ public class DMNavigationServicePort extends DMAbstractServicePort implements Na
|
||||
|
||||
private static final String FILTER_TOKENS_DELIMETER = ", ";
|
||||
|
||||
private static final Pattern ORDER_BY_CLAUSE_MASK = Pattern.compile("^( )*([\\p{Alnum}_]+(( )+((ASC)|(DESC))){1}){1}((,){1}( )*[\\p{Alnum}_]+(( )+((ASC)|(DESC))){1})*( )*$",
|
||||
Pattern.CASE_INSENSITIVE);
|
||||
|
||||
/**
|
||||
* Gets the private working copies of checked-out objects that the user is allowed to update.
|
||||
*
|
||||
@@ -71,21 +67,16 @@ public class DMNavigationServicePort extends DMAbstractServicePort implements Na
|
||||
checkRepositoryId(repositoryId);
|
||||
PropertyFilter propertyFilter = createPropertyFilter(filter);
|
||||
|
||||
try
|
||||
{
|
||||
NodeRef folderRef = null;
|
||||
if ((folderId != null) && !folderId.equals(""))
|
||||
{
|
||||
folderRef = cmisObjectsUtils.getIdentifierInstance(folderId, AlfrescoObjectType.FOLDER_OBJECT);
|
||||
folderRef = cmisService.getFolder(folderId);
|
||||
}
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
List<Pair<String, Boolean>> orderingFields = null;
|
||||
if ((orderBy != null) && !orderBy.equals(""))
|
||||
{
|
||||
orderingFields = checkAndParseOrderByClause(orderBy);
|
||||
}
|
||||
|
||||
// TODO: Ordering functionality SHOULD be moved to getChildren service method
|
||||
NodeRef[] nodeRefs = cmisService.getCheckedOut(AuthenticationUtil.getFullyAuthenticatedUser(), folderRef, (folderRef == null));
|
||||
NodeRef[] nodeRefs = cmisService.getCheckedOut(AuthenticationUtil.getFullyAuthenticatedUser(), folderRef,
|
||||
(folderRef == null), orderBy);
|
||||
Cursor cursor = createCursor(nodeRefs.length, skipCount, maxItems);
|
||||
|
||||
CmisObjectListType result = new CmisObjectListType();
|
||||
@@ -93,7 +84,8 @@ public class DMNavigationServicePort extends DMAbstractServicePort implements Na
|
||||
|
||||
for (int index = cursor.getStartRow(); index <= cursor.getEndRow(); index++)
|
||||
{
|
||||
resultListing.add(createCmisObject(nodeRefs[index].toString(), propertyFilter, includeAllowableActions, renditionFilter));
|
||||
resultListing.add(createCmisObject(nodeRefs[index], propertyFilter, includeAllowableActions,
|
||||
renditionFilter));
|
||||
}
|
||||
result.setHasMoreItems(new Boolean(cursor.getEndRow() < (nodeRefs.length - 1)));
|
||||
|
||||
@@ -101,6 +93,11 @@ public class DMNavigationServicePort extends DMAbstractServicePort implements Na
|
||||
|
||||
return result;
|
||||
}
|
||||
catch (CMISServiceException e)
|
||||
{
|
||||
throw ExceptionUtil.createCmisException(e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the list of child objects contained in the specified folder. Only the filter-selected properties associated with each object are returned. The content-streams of
|
||||
@@ -111,24 +108,19 @@ public class DMNavigationServicePort extends DMAbstractServicePort implements Na
|
||||
* @return collection of CmisObjectType and boolean hasMoreItems
|
||||
* @throws CmisException (with following {@link EnumServiceException} : INVALID_ARGUMENT, OBJECT_NOT_FOUND, NOT_SUPPORTED, PERMISSION_DENIED, RUNTIME, FILTER_NOT_VALID)
|
||||
*/
|
||||
public CmisObjectInFolderListType getChildren(String repositoryId, String folderId, String filter, String orderBy, Boolean includeAllowableActions,
|
||||
EnumIncludeRelationships includeRelationships, String renditionFilter, Boolean includePathSegments, BigInteger maxItems, BigInteger skipCount,
|
||||
CmisExtensionType extension) throws CmisException
|
||||
public CmisObjectInFolderListType getChildren(String repositoryId, String folderId, String filter, String orderBy,
|
||||
Boolean includeAllowableActions, EnumIncludeRelationships includeRelationships, String renditionFilter,
|
||||
Boolean includePathSegments, BigInteger maxItems, BigInteger skipCount, CmisExtensionType extension)
|
||||
throws CmisException
|
||||
{
|
||||
checkRepositoryId(repositoryId);
|
||||
PropertyFilter propertyFilter = createPropertyFilter(filter);
|
||||
|
||||
NodeRef folderNodeRef = cmisObjectsUtils.getIdentifierInstance(folderId, AlfrescoObjectType.FOLDER_OBJECT);
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
List<Pair<String, Boolean>> orderingFields = null;
|
||||
if ((orderBy != null) && !orderBy.equals(""))
|
||||
try
|
||||
{
|
||||
orderingFields = checkAndParseOrderByClause(orderBy);
|
||||
}
|
||||
NodeRef folderNodeRef = cmisService.getFolder(folderId);
|
||||
|
||||
// TODO: Ordering functionality SHOULD be moved to getChildren service method
|
||||
NodeRef[] listing = cmisService.getChildren(folderNodeRef, CMISTypesFilterEnum.ANY);
|
||||
NodeRef[] listing = cmisService.getChildren(folderNodeRef, CMISTypesFilterEnum.ANY, orderBy);
|
||||
|
||||
CmisObjectInFolderListType result = new CmisObjectInFolderListType();
|
||||
|
||||
@@ -136,12 +128,14 @@ public class DMNavigationServicePort extends DMAbstractServicePort implements Na
|
||||
|
||||
for (int index = cursor.getStartRow(); index <= cursor.getEndRow(); index++)
|
||||
{
|
||||
CmisObjectType cmisObject = createCmisObject(listing[index].toString(), propertyFilter, includeAllowableActions, renditionFilter);
|
||||
CmisObjectType cmisObject = createCmisObject(listing[index], propertyFilter, includeAllowableActions,
|
||||
renditionFilter);
|
||||
CmisObjectInFolderType cmisObjectInFolder = new CmisObjectInFolderType();
|
||||
cmisObjectInFolder.setObject(cmisObject);
|
||||
if (includePathSegments != null && includePathSegments)
|
||||
{
|
||||
cmisObjectInFolder.setPathSegment(propertiesUtil.getProperty(listing[index], CMISDictionaryModel.PROP_NAME, ""));
|
||||
cmisObjectInFolder.setPathSegment(propertiesUtil.getProperty(listing[index],
|
||||
CMISDictionaryModel.PROP_NAME, ""));
|
||||
}
|
||||
result.getObjects().add(cmisObjectInFolder);
|
||||
}
|
||||
@@ -152,6 +146,11 @@ public class DMNavigationServicePort extends DMAbstractServicePort implements Na
|
||||
// TODO: Process includeRelationships, includeACL
|
||||
return result;
|
||||
}
|
||||
catch (CMISServiceException e)
|
||||
{
|
||||
throw ExceptionUtil.createCmisException(e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the list of descendant objects contained at one or more levels in the tree rooted at the specified folder. Only the filter-selected properties associated with each
|
||||
@@ -165,7 +164,7 @@ public class DMNavigationServicePort extends DMAbstractServicePort implements Na
|
||||
public List<CmisObjectInFolderContainerType> getDescendants(String repositoryId, String folderId, BigInteger depth, String filter, Boolean includeAllowableActions,
|
||||
EnumIncludeRelationships includeRelationships, String renditionFilter, Boolean includePathSegments, CmisExtensionType extension) throws CmisException
|
||||
{
|
||||
CmisObjectInFolderContainerType objectInFolderContainerType = getDescedantsTree(repositoryId, folderId, depth, filter, includeAllowableActions, includeRelationships,
|
||||
CmisObjectInFolderContainerType objectInFolderContainerType = getDescendantsTree(repositoryId, folderId, depth, filter, includeAllowableActions, includeRelationships,
|
||||
renditionFilter, includePathSegments, CMISTypesFilterEnum.ANY);
|
||||
return objectInFolderContainerType.getChildren();
|
||||
}
|
||||
@@ -182,7 +181,7 @@ public class DMNavigationServicePort extends DMAbstractServicePort implements Na
|
||||
public List<CmisObjectInFolderContainerType> getFolderTree(String repositoryId, String folderId, BigInteger depth, String filter, Boolean includeAllowableActions,
|
||||
EnumIncludeRelationships includeRelationships, String renditionFilter, Boolean includePathSegments, CmisExtensionType extension) throws CmisException
|
||||
{
|
||||
CmisObjectInFolderContainerType objectInFolderContainerType = getDescedantsTree(repositoryId, folderId, depth, filter, includeAllowableActions, includeRelationships,
|
||||
CmisObjectInFolderContainerType objectInFolderContainerType = getDescendantsTree(repositoryId, folderId, depth, filter, includeAllowableActions, includeRelationships,
|
||||
renditionFilter, includePathSegments, CMISTypesFilterEnum.FOLDERS);
|
||||
return objectInFolderContainerType.getChildren();
|
||||
}
|
||||
@@ -211,9 +210,17 @@ public class DMNavigationServicePort extends DMAbstractServicePort implements Na
|
||||
}
|
||||
}
|
||||
PropertyFilter propertyFilter = createPropertyFilter(filter);
|
||||
NodeRef parentRef = receiveParent(folderId);
|
||||
NodeRef parentRef;
|
||||
try
|
||||
{
|
||||
parentRef = cmisService.getFolderParent(folderId);
|
||||
}
|
||||
catch (CMISServiceException e)
|
||||
{
|
||||
throw ExceptionUtil.createCmisException(e);
|
||||
}
|
||||
|
||||
CmisObjectType result = createCmisObject(parentRef, propertyFilter, false, null);
|
||||
// TODO: It is not clear whether ACL etc should be returned
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -231,7 +238,15 @@ public class DMNavigationServicePort extends DMAbstractServicePort implements Na
|
||||
checkRepositoryId(repositoryId);
|
||||
PropertyFilter propertyFilter = createPropertyFilter(filter);
|
||||
|
||||
NodeRef childNode = (NodeRef) cmisObjectsUtils.getIdentifierInstance(objectId, AlfrescoObjectType.DOCUMENT_OBJECT);
|
||||
NodeRef childNode;
|
||||
try
|
||||
{
|
||||
childNode = (NodeRef) cmisService.getReadableObject(objectId, NodeRef.class);
|
||||
}
|
||||
catch (CMISServiceException e)
|
||||
{
|
||||
throw ExceptionUtil.createCmisException(e);
|
||||
}
|
||||
List<NodeRef> parents = receiveObjectParents(childNode);
|
||||
|
||||
List<CmisObjectParentsType> result = new ArrayList<CmisObjectParentsType>();
|
||||
@@ -252,7 +267,7 @@ public class DMNavigationServicePort extends DMAbstractServicePort implements Na
|
||||
return result;
|
||||
}
|
||||
|
||||
private CmisObjectInFolderContainerType getDescedantsTree(String repositoryId, String folderId, BigInteger depth, String filter, Boolean includeAllowableActions,
|
||||
private CmisObjectInFolderContainerType getDescendantsTree(String repositoryId, String folderId, BigInteger depth, String filter, Boolean includeAllowableActions,
|
||||
EnumIncludeRelationships includeRelationships, String renditionFilter, Boolean includePathSegments, CMISTypesFilterEnum types) throws CmisException
|
||||
{
|
||||
checkRepositoryId(repositoryId);
|
||||
@@ -262,11 +277,13 @@ public class DMNavigationServicePort extends DMAbstractServicePort implements Na
|
||||
long maxDepth = depth.longValue();
|
||||
checkDepthParameter(depth);
|
||||
|
||||
NodeRef folderNodeRef = cmisObjectsUtils.getIdentifierInstance(folderId, AlfrescoObjectType.FOLDER_OBJECT);
|
||||
try
|
||||
{
|
||||
NodeRef folderNodeRef = cmisService.getFolder(folderId);
|
||||
Stack<RecursiveElement> descedantsStack = new Stack<RecursiveElement>();
|
||||
CmisObjectInFolderContainerType objectInFolderContainer = createObjectInFolderContainer(folderNodeRef, propertyFilter, includeAllowableActions, includeRelationships,
|
||||
renditionFilter, includePathSegments);
|
||||
NodeRef[] children = cmisService.getChildren(folderNodeRef, types);
|
||||
CmisObjectInFolderContainerType objectInFolderContainer = createObjectInFolderContainer(folderNodeRef,
|
||||
propertyFilter, includeAllowableActions, includeRelationships, renditionFilter, includePathSegments);
|
||||
NodeRef[] children = cmisService.getChildren(folderNodeRef, types, null);
|
||||
for (NodeRef childRef : children)
|
||||
{
|
||||
descedantsStack.push(new RecursiveElement(objectInFolderContainer, 1, childRef));
|
||||
@@ -274,23 +291,30 @@ public class DMNavigationServicePort extends DMAbstractServicePort implements Na
|
||||
while (!descedantsStack.isEmpty())
|
||||
{
|
||||
RecursiveElement element = descedantsStack.pop();
|
||||
CmisObjectInFolderContainerType currentContainer = createObjectInFolderContainer(element.getCurrentNodeRef(), propertyFilter, includeAllowableActions,
|
||||
includeRelationships, renditionFilter, includePathSegments);
|
||||
CmisObjectInFolderContainerType currentContainer = createObjectInFolderContainer(element
|
||||
.getCurrentNodeRef(), propertyFilter, includeAllowableActions, includeRelationships,
|
||||
renditionFilter, includePathSegments);
|
||||
element.getParentContainerType().getChildren().add(currentContainer);
|
||||
if (element.getDepth() <= maxDepth)
|
||||
{
|
||||
children = cmisService.getChildren(element.getCurrentNodeRef(), types);
|
||||
children = cmisService.getChildren(element.getCurrentNodeRef(), types, null);
|
||||
if (children != null)
|
||||
{
|
||||
for (NodeRef childRef : children)
|
||||
{
|
||||
descedantsStack.push(new RecursiveElement(currentContainer, element.getDepth() + 1, childRef));
|
||||
descedantsStack.push(new RecursiveElement(currentContainer, element.getDepth() + 1,
|
||||
childRef));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return objectInFolderContainer;
|
||||
}
|
||||
catch (CMISServiceException e)
|
||||
{
|
||||
throw ExceptionUtil.createCmisException(e);
|
||||
}
|
||||
}
|
||||
|
||||
private CmisObjectInFolderContainerType createObjectInFolderContainer(NodeRef nodeRef, PropertyFilter filter, Boolean includeAllowableActions,
|
||||
EnumIncludeRelationships includeRelationships, String renditionFilter, Boolean includePathSegments) throws CmisException
|
||||
@@ -311,56 +335,15 @@ public class DMNavigationServicePort extends DMAbstractServicePort implements Na
|
||||
return result;
|
||||
}
|
||||
|
||||
private List<Pair<String, Boolean>> checkAndParseOrderByClause(String orderByClause) throws CmisException
|
||||
{
|
||||
List<Pair<String, Boolean>> result = new LinkedList<Pair<String, Boolean>>();
|
||||
|
||||
if (!ORDER_BY_CLAUSE_MASK.matcher(orderByClause).matches())
|
||||
{
|
||||
throw cmisObjectsUtils.createCmisException(("\"" + orderByClause + "\" Order By Clause is invalid!"), EnumServiceException.INVALID_ARGUMENT);
|
||||
}
|
||||
|
||||
for (String token : orderByClause.split(","))
|
||||
{
|
||||
token = token.trim();
|
||||
|
||||
String[] direction = token.split(" ");
|
||||
String fieldName = direction[0];
|
||||
result.add(new Pair<String, Boolean>(fieldName, direction[direction.length - 1].toLowerCase().equals("asc")));
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
private NodeRef receiveParent(String targetChildIdentifier) throws CmisException
|
||||
{
|
||||
if (cmisService.getDefaultRootNodeRef().toString().equals(targetChildIdentifier))
|
||||
{
|
||||
throw cmisObjectsUtils.createCmisException("Root Folder has no parents", EnumServiceException.INVALID_ARGUMENT);
|
||||
}
|
||||
NodeRef identifierInstance = (NodeRef) cmisObjectsUtils.getIdentifierInstance(targetChildIdentifier, AlfrescoObjectType.FOLDER_OBJECT);
|
||||
return receiveNextParentNodeReference(identifierInstance, new LinkedList<NodeRef>());
|
||||
}
|
||||
|
||||
private void checkDepthParameter(BigInteger depth) throws CmisException
|
||||
{
|
||||
if (depth.equals(BigInteger.ZERO) || (depth.compareTo(FULL_DESCENDANTS_HIERARCHY_CONDITION) < EQUALS_CONDITION_VALUE))
|
||||
{
|
||||
throw cmisObjectsUtils.createCmisException("The specified descendants depth is not valid. Valid depth values are: -1 (full hierarchy), N > 0",
|
||||
throw ExceptionUtil.createCmisException("The specified descendants depth is not valid. Valid depth values are: -1 (full hierarchy), N > 0",
|
||||
EnumServiceException.INVALID_ARGUMENT);
|
||||
}
|
||||
}
|
||||
|
||||
private NodeRef receiveNextParentNodeReference(NodeRef currentParent, List<NodeRef> parents)
|
||||
{
|
||||
currentParent = nodeService.getPrimaryParent(currentParent).getParentRef();
|
||||
if (currentParent != null)
|
||||
{
|
||||
parents.add(currentParent);
|
||||
}
|
||||
return currentParent;
|
||||
}
|
||||
|
||||
private List<NodeRef> receiveObjectParents(NodeRef objectId) throws CmisException
|
||||
{
|
||||
List<NodeRef> parents = new LinkedList<NodeRef>();
|
||||
|
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2005-2009 Alfresco Software Limited.
|
||||
* Copyright (C) 2005-2010 Alfresco Software Limited.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
@@ -18,7 +18,7 @@
|
||||
* As a special exception to the terms and conditions of version 2.0 of
|
||||
* the GPL, you may redistribute this Program in connection with Free/Libre
|
||||
* and Open Source Software ("FLOSS") applications as described in Alfresco's
|
||||
* FLOSS exception. You should have recieved a copy of the text describing
|
||||
* FLOSS exception. You should have received a copy of the text describing
|
||||
* the FLOSS exception, and it is also available here:
|
||||
* http://www.alfresco.com/legal/licensing"
|
||||
*/
|
||||
@@ -29,39 +29,36 @@ import java.io.InputStream;
|
||||
import java.math.BigInteger;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import javax.activation.DataHandler;
|
||||
import javax.xml.ws.Holder;
|
||||
|
||||
import org.alfresco.cmis.CMISConstraintException;
|
||||
import org.alfresco.cmis.CMISContentStreamAllowedEnum;
|
||||
import org.alfresco.cmis.CMISDictionaryModel;
|
||||
import org.alfresco.cmis.CMISInvalidArgumentException;
|
||||
import org.alfresco.cmis.CMISRenditionKind;
|
||||
import org.alfresco.cmis.CMISScope;
|
||||
import org.alfresco.cmis.CMISServiceException;
|
||||
import org.alfresco.cmis.CMISTypeDefinition;
|
||||
import org.alfresco.cmis.dictionary.CMISFolderTypeDefinition;
|
||||
import org.alfresco.model.ContentModel;
|
||||
import org.alfresco.cmis.CMISVersioningStateEnum;
|
||||
import org.alfresco.repo.cmis.PropertyFilter;
|
||||
import org.alfresco.repo.cmis.ws.DeleteTreeResponse.FailedToDelete;
|
||||
import org.alfresco.repo.cmis.ws.utils.AlfrescoObjectType;
|
||||
import org.alfresco.repo.cmis.ws.utils.CmisObjectsUtils;
|
||||
import org.alfresco.repo.security.permissions.AccessDeniedException;
|
||||
import org.alfresco.repo.cmis.ws.utils.ExceptionUtil;
|
||||
import org.alfresco.repo.web.util.paging.Cursor;
|
||||
import org.alfresco.service.cmr.dictionary.AssociationDefinition;
|
||||
import org.alfresco.service.cmr.dictionary.DictionaryService;
|
||||
import org.alfresco.service.cmr.dictionary.TypeDefinition;
|
||||
import org.alfresco.service.cmr.lock.NodeLockedException;
|
||||
import org.alfresco.service.cmr.model.FileExistsException;
|
||||
import org.alfresco.service.cmr.model.FileInfo;
|
||||
import org.alfresco.service.cmr.model.FileNotFoundException;
|
||||
import org.alfresco.service.cmr.repository.AssociationRef;
|
||||
import org.alfresco.service.cmr.repository.ContentReader;
|
||||
import org.alfresco.service.cmr.repository.ContentWriter;
|
||||
import org.alfresco.service.cmr.repository.FileTypeImageSize;
|
||||
import org.alfresco.service.cmr.repository.InvalidNodeRefException;
|
||||
import org.alfresco.service.cmr.repository.NodeRef;
|
||||
import org.alfresco.service.cmr.version.VersionType;
|
||||
import org.alfresco.service.namespace.QName;
|
||||
|
||||
/**
|
||||
@@ -73,12 +70,21 @@ import org.alfresco.service.namespace.QName;
|
||||
@javax.jws.WebService(name = "ObjectServicePort", serviceName = "ObjectService", portName = "ObjectServicePort", targetNamespace = "http://docs.oasis-open.org/ns/cmis/ws/200908/", endpointInterface = "org.alfresco.repo.cmis.ws.ObjectServicePort")
|
||||
public class DMObjectServicePort extends DMAbstractServicePort implements ObjectServicePort
|
||||
{
|
||||
private static final String VERSION_DELIMETER = ".";
|
||||
private static final Map<EnumVersioningState, CMISVersioningStateEnum> VERSIONING_STATE_ENUM_MAPPING;
|
||||
|
||||
private DictionaryService dictionaryService;
|
||||
|
||||
private FileTypeIconRetriever iconRetriever;
|
||||
|
||||
static
|
||||
{
|
||||
VERSIONING_STATE_ENUM_MAPPING = new HashMap<EnumVersioningState, CMISVersioningStateEnum>(7);
|
||||
VERSIONING_STATE_ENUM_MAPPING.put(EnumVersioningState.NONE, CMISVersioningStateEnum.NONE);
|
||||
VERSIONING_STATE_ENUM_MAPPING.put(EnumVersioningState.CHECKEDOUT, CMISVersioningStateEnum.CHECKED_OUT);
|
||||
VERSIONING_STATE_ENUM_MAPPING.put(EnumVersioningState.MAJOR, CMISVersioningStateEnum.MAJOR);
|
||||
VERSIONING_STATE_ENUM_MAPPING.put(EnumVersioningState.MINOR, CMISVersioningStateEnum.MINOR);
|
||||
}
|
||||
|
||||
public void setDictionaryService(DictionaryService dictionaryService)
|
||||
{
|
||||
this.dictionaryService = dictionaryService;
|
||||
@@ -101,14 +107,12 @@ public class DMObjectServicePort extends DMAbstractServicePort implements Object
|
||||
throws CmisException
|
||||
{
|
||||
checkRepositoryId(repositoryId);
|
||||
NodeRef parentNodeRef = safeGetFolderNodeRef(folderId);
|
||||
if (null == properties)
|
||||
try
|
||||
{
|
||||
throw cmisObjectsUtils.createCmisException("Properties input parameter is Mandatory", EnumServiceException.INVALID_ARGUMENT);
|
||||
}
|
||||
NodeRef parentNodeRef = cmisService.getFolder(folderId);
|
||||
Map<String, Object> propertiesMap = propertiesUtil.getPropertiesMap(properties);
|
||||
String typeId = extractAndAssertTypeId(propertiesMap);
|
||||
CMISTypeDefinition typeDef = cmisDictionaryService.findType(typeId);
|
||||
CMISTypeDefinition typeDef = cmisService.getTypeDefinition(typeId);
|
||||
String documentName = checkConstraintsAndGetName(typeId, typeDef, parentNodeRef, contentStream, propertiesMap, versioningState);
|
||||
NodeRef newDocumentNodeRef = fileFolderService.create(parentNodeRef, documentName, typeDef.getTypeId().getQName()).getNodeRef();
|
||||
|
||||
@@ -123,7 +127,7 @@ public class DMObjectServicePort extends DMAbstractServicePort implements Object
|
||||
}
|
||||
else
|
||||
{
|
||||
throw cmisObjectsUtils.createCmisException("Content Stream Mime Type was not specified", EnumServiceException.STORAGE);
|
||||
throw ExceptionUtil.createCmisException("Content Stream Mime Type was not specified", EnumServiceException.INVALID_ARGUMENT);
|
||||
}
|
||||
InputStream inputstream = null;
|
||||
try
|
||||
@@ -132,13 +136,22 @@ public class DMObjectServicePort extends DMAbstractServicePort implements Object
|
||||
}
|
||||
catch (IOException e)
|
||||
{
|
||||
throw cmisObjectsUtils.createCmisException(e.toString(), EnumServiceException.CONSTRAINT);
|
||||
throw ExceptionUtil.createCmisException(e.getMessage(), EnumServiceException.RUNTIME, e);
|
||||
}
|
||||
writer.putContent(inputstream);
|
||||
}
|
||||
PropertyFilter propertyFilter = createPropertyFilter(createIgnoringFilter(new String[] { CMISDictionaryModel.PROP_NAME, CMISDictionaryModel.PROP_OBJECT_TYPE_ID }));
|
||||
appendDataToDocument(newDocumentNodeRef, properties, versioningState, policies, addACEs, removeACEs, objectId, propertyFilter);
|
||||
}
|
||||
catch (CMISServiceException e)
|
||||
{
|
||||
throw ExceptionUtil.createCmisException(e);
|
||||
}
|
||||
if (null == properties)
|
||||
{
|
||||
throw ExceptionUtil.createCmisException("Properties input parameter is Mandatory", EnumServiceException.INVALID_ARGUMENT);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a document object as a copy of the given source document in the specified location
|
||||
@@ -157,8 +170,10 @@ public class DMObjectServicePort extends DMAbstractServicePort implements Object
|
||||
throws CmisException
|
||||
{
|
||||
checkRepositoryId(repositoryId);
|
||||
NodeRef folderNodeRef = cmisObjectsUtils.getIdentifierInstance(folderId, AlfrescoObjectType.FOLDER_OBJECT);
|
||||
NodeRef sourceNodeRef = cmisObjectsUtils.getIdentifierInstance(sourceId, AlfrescoObjectType.DOCUMENT_OR_FOLDER_OBJECT);
|
||||
try
|
||||
{
|
||||
NodeRef folderNodeRef = cmisService.getFolder(folderId);
|
||||
NodeRef sourceNodeRef = cmisService.getReadableObject(sourceId, NodeRef.class);
|
||||
String name = propertiesUtil.getProperty(sourceNodeRef, CMISDictionaryModel.PROP_NAME, null);
|
||||
NodeRef newDocumentNodeRef;
|
||||
try
|
||||
@@ -167,15 +182,20 @@ public class DMObjectServicePort extends DMAbstractServicePort implements Object
|
||||
}
|
||||
catch (FileExistsException e)
|
||||
{
|
||||
throw cmisObjectsUtils.createCmisException("Document already exists", EnumServiceException.CONTENT_ALREADY_EXISTS);
|
||||
throw ExceptionUtil.createCmisException("Document already exists", EnumServiceException.CONTENT_ALREADY_EXISTS);
|
||||
}
|
||||
catch (FileNotFoundException e)
|
||||
{
|
||||
throw cmisObjectsUtils.createCmisException("Source document not found", EnumServiceException.INVALID_ARGUMENT);
|
||||
throw ExceptionUtil.createCmisException("Source document not found", EnumServiceException.INVALID_ARGUMENT);
|
||||
}
|
||||
PropertyFilter propertyFilter = createPropertyFilter(createIgnoringFilter(new String[] { CMISDictionaryModel.PROP_OBJECT_TYPE_ID }));
|
||||
appendDataToDocument(newDocumentNodeRef, properties, versioningState, policies, addACEs, removeACEs, objectId, propertyFilter);
|
||||
}
|
||||
catch (CMISServiceException e)
|
||||
{
|
||||
throw ExceptionUtil.createCmisException(e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a folder object of the specified type.
|
||||
@@ -193,24 +213,16 @@ public class DMObjectServicePort extends DMAbstractServicePort implements Object
|
||||
// TODO: process Policies
|
||||
|
||||
checkRepositoryId(repositoryId);
|
||||
NodeRef folderNodeRef = null;
|
||||
try
|
||||
{
|
||||
folderNodeRef = cmisObjectsUtils.getIdentifierInstance(folderId, AlfrescoObjectType.FOLDER_OBJECT);
|
||||
}
|
||||
catch (CmisException e)
|
||||
{
|
||||
e.getFaultInfo().setType(EnumServiceException.CONSTRAINT);
|
||||
throw e;
|
||||
}
|
||||
assertExistFolder(folderNodeRef);
|
||||
NodeRef folderNodeRef = cmisService.getFolder(folderId);
|
||||
Map<String, Object> propertiesMap = propertiesUtil.getPropertiesMap(properties);
|
||||
String typeId = extractAndAssertTypeId(propertiesMap);
|
||||
CMISTypeDefinition type = getCmisTypeDefinition(typeId);
|
||||
CMISTypeDefinition type = cmisService.getTypeDefinition(typeId);
|
||||
TypeDefinition nativeType = dictionaryService.getType(nodeService.getType(folderNodeRef));
|
||||
if (type == null || type.getTypeId() == null || type.getTypeId().getScope() != CMISScope.FOLDER)
|
||||
{
|
||||
throw cmisObjectsUtils.createCmisException("The typeID is not an Object-Type whose baseType is 'Folder': " + typeId, EnumServiceException.CONSTRAINT);
|
||||
throw ExceptionUtil.createCmisException("The typeID is not an Object-Type whose baseType is 'Folder': " + typeId, EnumServiceException.CONSTRAINT);
|
||||
}
|
||||
|
||||
String name = propertiesUtil.getCmisPropertyValue(properties, CMISDictionaryModel.PROP_NAME, null);
|
||||
@@ -226,7 +238,12 @@ public class DMObjectServicePort extends DMAbstractServicePort implements Object
|
||||
}
|
||||
catch (FileExistsException e)
|
||||
{
|
||||
throw cmisObjectsUtils.createCmisException("Folder already exists", EnumServiceException.CONTENT_ALREADY_EXISTS);
|
||||
throw ExceptionUtil.createCmisException("Folder already exists", EnumServiceException.CONTENT_ALREADY_EXISTS);
|
||||
}
|
||||
}
|
||||
catch (CMISServiceException e)
|
||||
{
|
||||
throw ExceptionUtil.createCmisException(e);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -242,7 +259,7 @@ public class DMObjectServicePort extends DMAbstractServicePort implements Object
|
||||
public void createPolicy(String repositoryId, CmisPropertiesType properties, String folderId, List<String> policies, CmisAccessControlListType addACEs,
|
||||
CmisAccessControlListType removeACEs, Holder<CmisExtensionType> extension, Holder<String> objectId) throws CmisException
|
||||
{
|
||||
throw cmisObjectsUtils.createCmisException("Policy objects not supported", EnumServiceException.NOT_SUPPORTED);
|
||||
throw ExceptionUtil.createCmisException("Policy objects not supported", EnumServiceException.NOT_SUPPORTED);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -267,27 +284,29 @@ public class DMObjectServicePort extends DMAbstractServicePort implements Object
|
||||
|
||||
checkRepositoryId(repositoryId);
|
||||
|
||||
NodeRef sourceNodeRef = cmisObjectsUtils.getIdentifierInstance(sourceObjectId, AlfrescoObjectType.ANY_OBJECT);
|
||||
NodeRef targetNodeRef = cmisObjectsUtils.getIdentifierInstance(targetObjectId, AlfrescoObjectType.ANY_OBJECT);
|
||||
try
|
||||
{
|
||||
NodeRef sourceNodeRef = cmisService.getObject(sourceObjectId, NodeRef.class, true, false, false);
|
||||
NodeRef targetNodeRef = cmisService.getObject(targetObjectId, NodeRef.class, true, false, false);
|
||||
|
||||
String typeId = (String) propertiesMap.get(CMISDictionaryModel.PROP_OBJECT_TYPE_ID);
|
||||
|
||||
CMISTypeDefinition relationshipType = cmisDictionaryService.findType(typeId);
|
||||
CMISTypeDefinition relationshipType = cmisService.getTypeDefinition(typeId);
|
||||
if (relationshipType == null || relationshipType.getTypeId() == null || relationshipType.getTypeId().getScope() != CMISScope.RELATIONSHIP)
|
||||
{
|
||||
throw cmisObjectsUtils.createCmisException(typeId, EnumServiceException.INVALID_ARGUMENT);
|
||||
throw ExceptionUtil.createCmisException(typeId, EnumServiceException.INVALID_ARGUMENT);
|
||||
}
|
||||
|
||||
CMISTypeDefinition sourceType = cmisDictionaryService.findType(propertiesUtil.getProperty(sourceNodeRef, CMISDictionaryModel.PROP_OBJECT_TYPE_ID, (String) null));
|
||||
CMISTypeDefinition targetType = cmisDictionaryService.findType(propertiesUtil.getProperty(targetNodeRef, CMISDictionaryModel.PROP_OBJECT_TYPE_ID, (String) null));
|
||||
CMISTypeDefinition sourceType = cmisService.getTypeDefinition(sourceNodeRef);
|
||||
CMISTypeDefinition targetType = cmisService.getTypeDefinition(targetNodeRef);
|
||||
|
||||
if ((null != relationshipType.getAllowedSourceTypes()) && !relationshipType.getAllowedSourceTypes().contains(sourceType))
|
||||
{
|
||||
throw cmisObjectsUtils.createCmisException(("Source object type is not allowed for \"" + typeId + "\" Relationship type"), EnumServiceException.CONSTRAINT);
|
||||
throw ExceptionUtil.createCmisException(("Source object type is not allowed for \"" + typeId + "\" Relationship type"), EnumServiceException.CONSTRAINT);
|
||||
}
|
||||
if ((null != relationshipType.getAllowedTargetTypes()) && !relationshipType.getAllowedTargetTypes().contains(targetType))
|
||||
{
|
||||
throw cmisObjectsUtils.createCmisException(("Target object type is not allowed for \"" + typeId + "\" Relationship type"), EnumServiceException.CONSTRAINT);
|
||||
throw ExceptionUtil.createCmisException(("Target object type is not allowed for \"" + typeId + "\" Relationship type"), EnumServiceException.CONSTRAINT);
|
||||
}
|
||||
|
||||
QName relationshipTypeQName = relationshipType.getTypeId().getQName();
|
||||
@@ -296,18 +315,23 @@ public class DMObjectServicePort extends DMAbstractServicePort implements Object
|
||||
{
|
||||
if (!dictionaryService.isSubClass(nodeService.getType(sourceNodeRef), associationDef.getSourceClass().getName()))
|
||||
{
|
||||
throw cmisObjectsUtils.createCmisException("Source object type isn't allowed as source type", EnumServiceException.CONSTRAINT);
|
||||
throw ExceptionUtil.createCmisException("Source object type isn't allowed as source type", EnumServiceException.CONSTRAINT);
|
||||
}
|
||||
if (!dictionaryService.isSubClass(nodeService.getType(targetNodeRef), associationDef.getTargetClass().getName()))
|
||||
{
|
||||
throw cmisObjectsUtils.createCmisException("Target object type isn't allowed as target type", EnumServiceException.CONSTRAINT);
|
||||
throw ExceptionUtil.createCmisException("Target object type isn't allowed as target type", EnumServiceException.CONSTRAINT);
|
||||
}
|
||||
String createdId = nodeService.createAssociation(sourceNodeRef, targetNodeRef, relationshipTypeQName).toString();
|
||||
objectId.value = createdId;
|
||||
}
|
||||
else
|
||||
{
|
||||
throw cmisObjectsUtils.createCmisException((relationshipType.getTypeId().getQName() + " Relationship type not found"), EnumServiceException.INVALID_ARGUMENT);
|
||||
throw ExceptionUtil.createCmisException((relationshipType.getTypeId().getQName() + " Relationship type not found"), EnumServiceException.INVALID_ARGUMENT);
|
||||
}
|
||||
}
|
||||
catch (CMISServiceException e)
|
||||
{
|
||||
throw ExceptionUtil.createCmisException(e);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -324,16 +348,14 @@ public class DMObjectServicePort extends DMAbstractServicePort implements Object
|
||||
{
|
||||
// TODO: Process changeToken
|
||||
checkRepositoryId(repositoryId);
|
||||
NodeRef currentNode = cmisObjectsUtils.getIdentifierInstance(objectId.value, AlfrescoObjectType.DOCUMENT_OBJECT);
|
||||
|
||||
CMISTypeDefinition typeDef = cmisDictionaryService.findType(propertiesUtil.getProperty(currentNode, CMISDictionaryModel.PROP_OBJECT_TYPE_ID, (String) null));
|
||||
if (CMISContentStreamAllowedEnum.REQUIRED.equals(typeDef.getContentStreamAllowed()))
|
||||
try
|
||||
{
|
||||
throw cmisObjectsUtils.createCmisException("The 'contentStreamAllowed' attribute of the specified Object-Type definition is set to 'required'.",
|
||||
EnumServiceException.CONSTRAINT);
|
||||
cmisService.deleteContentStream(objectId.value);
|
||||
}
|
||||
catch (CMISServiceException e)
|
||||
{
|
||||
throw ExceptionUtil.createCmisException(e);
|
||||
}
|
||||
|
||||
safeDeleteContentStream(currentNode);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -346,44 +368,14 @@ public class DMObjectServicePort extends DMAbstractServicePort implements Object
|
||||
*/
|
||||
public void deleteObject(String repositoryId, String objectId, Boolean allVersions, Holder<CmisExtensionType> extension) throws CmisException
|
||||
{
|
||||
// TODO: Process flag allVersions
|
||||
|
||||
checkRepositoryId(repositoryId);
|
||||
|
||||
Object identifier = cmisObjectsUtils.getIdentifierInstance(objectId, AlfrescoObjectType.ANY_OBJECT);
|
||||
NodeRef objectNodeReference = null;
|
||||
if (identifier instanceof AssociationRef)
|
||||
{
|
||||
AssociationRef assocRef = (AssociationRef) identifier;
|
||||
try
|
||||
{
|
||||
nodeService.removeAssociation(assocRef.getSourceRef(), assocRef.getTargetRef(), assocRef.getTypeQName());
|
||||
cmisService.deleteObject(objectId, allVersions == null || allVersions);
|
||||
}
|
||||
catch (InvalidNodeRefException e)
|
||||
catch (CMISServiceException e)
|
||||
{
|
||||
throw cmisObjectsUtils.createCmisException("Invalid object identifier", EnumServiceException.INVALID_ARGUMENT);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
objectNodeReference = (NodeRef) identifier;
|
||||
checkForRootObject(repositoryId, objectId);
|
||||
checkObjectTypeAndAppropriateStates(objectNodeReference);
|
||||
QName type = nodeService.getType(objectNodeReference);
|
||||
CMISTypeDefinition typeDef = (null != type) ? (cmisDictionaryService.findTypeForClass(type)) : (null);
|
||||
if (null == typeDef)
|
||||
{
|
||||
throw cmisObjectsUtils.createCmisException("Specified Object has invalid Type", EnumServiceException.INVALID_ARGUMENT);
|
||||
}
|
||||
if (!cmisObjectsUtils.isFolder(objectNodeReference) && typeDef.isVersionable() && (null != allVersions) && allVersions)
|
||||
{
|
||||
deleteAllVersions(repositoryId, objectId);
|
||||
}
|
||||
if (!cmisObjectsUtils.deleteObject(objectNodeReference))
|
||||
{
|
||||
throw cmisObjectsUtils.createCmisException("Currently authenticated User has no appropriate Permissions to delete specified Object",
|
||||
EnumServiceException.PERMISSION_DENIED);
|
||||
}
|
||||
throw ExceptionUtil.createCmisException(e);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -405,14 +397,19 @@ public class DMObjectServicePort extends DMAbstractServicePort implements Object
|
||||
// TODO: Process allVersions
|
||||
checkRepositoryId(repositoryId);
|
||||
checkUnfilingIsNotRequested(unfileObject);
|
||||
checkForRootObject(repositoryId, folderId);
|
||||
|
||||
NodeRef folderNodeReference = cmisObjectsUtils.getIdentifierInstance(folderId, AlfrescoObjectType.FOLDER_OBJECT);
|
||||
FailedToDelete responce = new FailedToDelete();
|
||||
allVersions = allVersions == null ? Boolean.FALSE : allVersions;
|
||||
responce.getObjectIds().addAll(cmisObjectsUtils.deleteFolder(folderNodeReference, continueOnFailure, unfileObject, allVersions));
|
||||
|
||||
return responce;
|
||||
List<String> failedToDelete;
|
||||
try
|
||||
{
|
||||
failedToDelete = cmisService.deleteTree(folderId, continueOnFailure, unfileObject != EnumUnfileObject.DELETE, allVersions == null || allVersions);
|
||||
}
|
||||
catch (CMISServiceException e)
|
||||
{
|
||||
throw ExceptionUtil.createCmisException(e);
|
||||
}
|
||||
FailedToDelete response = new FailedToDelete();
|
||||
response.getObjectIds().addAll(failedToDelete);
|
||||
return response;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -430,21 +427,29 @@ public class DMObjectServicePort extends DMAbstractServicePort implements Object
|
||||
{
|
||||
checkRepositoryId(repositoryId);
|
||||
|
||||
Object identifierInstance = cmisObjectsUtils.getIdentifierInstance(objectId, AlfrescoObjectType.ANY_OBJECT);
|
||||
try
|
||||
{
|
||||
NodeRef object = cmisService.getReadableObject(objectId, NodeRef.class);
|
||||
PropertyFilter propertyFilter = createPropertyFilter(filter);
|
||||
boolean includeActions = (null != includeAllowableActions) ? (includeAllowableActions.booleanValue()) : (false);
|
||||
CmisObjectType object = createCmisObject(identifierInstance, propertyFilter, includeActions, renditionFilter);
|
||||
CmisObjectType cmisObject = createCmisObject(object, propertyFilter, includeActions, renditionFilter);
|
||||
|
||||
// TODO: process relationships
|
||||
// TODO: process policyIds
|
||||
|
||||
Object versionSeries = cmisService.getVersionSeries(objectId, Object.class, false);
|
||||
boolean includeAcl = (null != includeACL) ? (includeACL.booleanValue()) : (false);
|
||||
if (includeAcl && (identifierInstance instanceof NodeRef))
|
||||
if (includeAcl && (versionSeries instanceof NodeRef))
|
||||
{
|
||||
appendWithAce((NodeRef) identifierInstance, object);
|
||||
appendWithAce((NodeRef) versionSeries, cmisObject);
|
||||
}
|
||||
|
||||
return object;
|
||||
return cmisObject;
|
||||
}
|
||||
catch (CMISServiceException e)
|
||||
{
|
||||
throw ExceptionUtil.createCmisException(e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -463,11 +468,12 @@ public class DMObjectServicePort extends DMAbstractServicePort implements Object
|
||||
NodeRef objectNodeRef = resolvePathInfo(path);
|
||||
if (null == objectNodeRef)
|
||||
{
|
||||
throw cmisObjectsUtils.createCmisException("Path to Folder was not specified or Folder Path is invalid", EnumServiceException.INVALID_ARGUMENT);
|
||||
throw ExceptionUtil.createCmisException("Path to Folder was not specified or Folder Path is invalid", EnumServiceException.INVALID_ARGUMENT);
|
||||
}
|
||||
PropertyFilter propertyFilter = createPropertyFilter(filter);
|
||||
CmisObjectType object = createCmisObject(objectNodeRef, propertyFilter, includeAllowableActions, renditionFilter);
|
||||
if (includeACL)
|
||||
boolean includeAcl = (null != includeACL) ? (includeACL.booleanValue()) : (false);
|
||||
if (includeAcl)
|
||||
{
|
||||
appendWithAce(objectNodeRef, object);
|
||||
}
|
||||
@@ -488,7 +494,16 @@ public class DMObjectServicePort extends DMAbstractServicePort implements Object
|
||||
public CmisAllowableActionsType getAllowableActions(String repositoryId, String objectId, CmisExtensionType extension) throws CmisException
|
||||
{
|
||||
checkRepositoryId(repositoryId);
|
||||
return determineObjectAllowableActions(cmisObjectsUtils.getIdentifierInstance(objectId, AlfrescoObjectType.ANY_OBJECT));
|
||||
Object object;
|
||||
try
|
||||
{
|
||||
object = cmisService.getReadableObject(objectId, Object.class);
|
||||
}
|
||||
catch (CMISServiceException e)
|
||||
{
|
||||
throw ExceptionUtil.createCmisException(e);
|
||||
}
|
||||
return determineObjectAllowableActions(object);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -503,12 +518,13 @@ public class DMObjectServicePort extends DMAbstractServicePort implements Object
|
||||
throws CmisException
|
||||
{
|
||||
checkRepositoryId(repositoryId);
|
||||
NodeRef nodeRef = cmisObjectsUtils.getIdentifierInstance(objectId, AlfrescoObjectType.DOCUMENT_OBJECT);
|
||||
|
||||
CMISTypeDefinition typeDefinition = cmisDictionaryService.findType(propertiesUtil.getProperty(nodeRef, CMISDictionaryModel.PROP_OBJECT_TYPE_ID, (String) null));
|
||||
try
|
||||
{
|
||||
NodeRef nodeRef = cmisService.getReadableObject(objectId, NodeRef.class);
|
||||
CMISTypeDefinition typeDefinition = cmisService.getTypeDefinition(nodeRef);
|
||||
if (CMISContentStreamAllowedEnum.NOT_ALLOWED == typeDefinition.getContentStreamAllowed())
|
||||
{
|
||||
throw cmisObjectsUtils.createCmisException("Content stream not allowed", EnumServiceException.STREAM_NOT_SUPPORTED);
|
||||
throw ExceptionUtil.createCmisException("Content stream not allowed", EnumServiceException.STREAM_NOT_SUPPORTED);
|
||||
}
|
||||
|
||||
String filename = propertiesUtil.getProperty(nodeRef, CMISDictionaryModel.PROP_NAME, null);
|
||||
@@ -536,7 +552,7 @@ public class DMObjectServicePort extends DMAbstractServicePort implements Object
|
||||
}
|
||||
else
|
||||
{
|
||||
NodeRef renditionNodeRef = cmisObjectsUtils.getIdentifierInstance(streamId, AlfrescoObjectType.DOCUMENT_OBJECT);
|
||||
NodeRef renditionNodeRef = new NodeRef(streamId);
|
||||
ContentReader reader = safeGetContentReader(renditionNodeRef);
|
||||
dataSource = new ContentReaderDataSource(reader, filename, offset, length, reader.getSize());
|
||||
}
|
||||
@@ -560,6 +576,11 @@ public class DMObjectServicePort extends DMAbstractServicePort implements Object
|
||||
|
||||
return response;
|
||||
}
|
||||
catch (CMISServiceException e)
|
||||
{
|
||||
throw ExceptionUtil.createCmisException(e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Moves the specified filed object from one folder to another
|
||||
@@ -574,40 +595,13 @@ public class DMObjectServicePort extends DMAbstractServicePort implements Object
|
||||
public void moveObject(String repositoryId, Holder<String> objectId, String targetFolderId, String sourceFolderId, Holder<CmisExtensionType> extension) throws CmisException
|
||||
{
|
||||
checkRepositoryId(repositoryId);
|
||||
NodeRef objectNodeRef = cmisObjectsUtils.getIdentifierInstance(objectId.value, AlfrescoObjectType.DOCUMENT_OR_FOLDER_OBJECT);
|
||||
// TODO: maybe this check will be need in terms of document version instead of final document (version specific filing is not supported)
|
||||
// checkOnLatestVersion(objectNodeRef);
|
||||
|
||||
NodeRef sourceFolderNodeRef = cmisObjectsUtils.getIdentifierInstance(sourceFolderId, AlfrescoObjectType.FOLDER_OBJECT);
|
||||
if (!cmisObjectsUtils.isChildOfThisFolder(objectNodeRef, sourceFolderNodeRef))
|
||||
try
|
||||
{
|
||||
throw cmisObjectsUtils.createCmisException("The Docuemnt is not a Child of Source Forlder that was specified", EnumServiceException.INVALID_ARGUMENT);
|
||||
cmisService.moveObject(objectId.value, targetFolderId, sourceFolderId);
|
||||
}
|
||||
NodeRef targetFolderNodeRef = cmisObjectsUtils.getIdentifierInstance(targetFolderId, AlfrescoObjectType.FOLDER_OBJECT);
|
||||
String objectType = propertiesUtil.getProperty(objectNodeRef, CMISDictionaryModel.PROP_OBJECT_TYPE_ID, null);
|
||||
String targetType = propertiesUtil.getProperty(targetFolderNodeRef, CMISDictionaryModel.PROP_OBJECT_TYPE_ID, null);
|
||||
CMISFolderTypeDefinition targetTypeDef = (CMISFolderTypeDefinition) ((null != targetType) ? (cmisDictionaryService.findType(targetType)) : (null));
|
||||
if (null == targetTypeDef)
|
||||
catch (CMISServiceException e)
|
||||
{
|
||||
throw cmisObjectsUtils.createCmisException("Type Definition for Target Folder was not found", EnumServiceException.RUNTIME);
|
||||
}
|
||||
|
||||
// TODO: cmis:allowedChildObjectTypes
|
||||
// FIXME: targetTypeDef.getAllowedTargetTypes() should be changed to something like targetTypeDef.getAllowedChildTypes()
|
||||
CMISTypeDefinition objectTypeDef = (null != objectType) ? (cmisDictionaryService.findType(objectType)) : (null);
|
||||
if (!targetTypeDef.getAllowedTargetTypes().isEmpty() && !targetTypeDef.getAllowedTargetTypes().contains(objectTypeDef))
|
||||
{
|
||||
throw cmisObjectsUtils.createCmisException(("Object with '" + objectType + "' Type can't be moved to Folder with '" + targetType + "' Type"),
|
||||
EnumServiceException.CONSTRAINT);
|
||||
}
|
||||
if (!cmisObjectsUtils.isPrimaryObjectParent(sourceFolderNodeRef, objectNodeRef))
|
||||
{
|
||||
changeObjectParentAssociation(objectNodeRef, targetFolderNodeRef, sourceFolderNodeRef);
|
||||
}
|
||||
else
|
||||
{
|
||||
// FIXME: it is necessary to reconsider how to convert TransactionRollback exception to nameConstraintViolation
|
||||
safeMove(objectNodeRef, targetFolderNodeRef);
|
||||
throw ExceptionUtil.createCmisException(e);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -626,44 +620,18 @@ public class DMObjectServicePort extends DMAbstractServicePort implements Object
|
||||
Holder<CmisExtensionType> extension) throws CmisException
|
||||
{
|
||||
checkRepositoryId(repositoryId);
|
||||
|
||||
// TODO:Process changeToken
|
||||
|
||||
NodeRef nodeRef = cmisObjectsUtils.getIdentifierInstance(objectId.value, AlfrescoObjectType.DOCUMENT_OBJECT);
|
||||
|
||||
CMISTypeDefinition typeDef = cmisDictionaryService.findType(propertiesUtil.getProperty(nodeRef, CMISDictionaryModel.PROP_OBJECT_TYPE_ID, (String) null));
|
||||
if (CMISContentStreamAllowedEnum.NOT_ALLOWED.equals(typeDef.getContentStreamAllowed()))
|
||||
{
|
||||
throw cmisObjectsUtils.createCmisException("The Object's Object-Type definition 'contentStreamAllowed' attribute is set to 'notAllowed'.",
|
||||
EnumServiceException.CONSTRAINT);
|
||||
}
|
||||
|
||||
if ((null == contentStream) || (contentStream.getStream() == null))
|
||||
{
|
||||
throw cmisObjectsUtils.createCmisException("New Content Stream was not provided", EnumServiceException.STORAGE);
|
||||
}
|
||||
|
||||
ContentReader reader = fileFolderService.getReader(nodeRef);
|
||||
if ((null != reader) && !overwriteFlag)
|
||||
{
|
||||
throw cmisObjectsUtils.createCmisException("Content already exists", EnumServiceException.CONTENT_ALREADY_EXISTS);
|
||||
}
|
||||
|
||||
ContentWriter writer = fileFolderService.getWriter(nodeRef);
|
||||
InputStream inputstream = null;
|
||||
try
|
||||
{
|
||||
inputstream = contentStream.getStream().getInputStream();
|
||||
cmisService.setContentStream(objectId.value, null, overwriteFlag == null || overwriteFlag, contentStream.getStream().getInputStream(), contentStream.getMimeType());
|
||||
}
|
||||
catch (IOException e)
|
||||
catch (CMISServiceException e)
|
||||
{
|
||||
throw cmisObjectsUtils.createCmisException(e.getMessage(), EnumServiceException.UPDATE_CONFLICT);
|
||||
throw ExceptionUtil.createCmisException(e);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
throw ExceptionUtil.createCmisException(e.getMessage(), EnumServiceException.RUNTIME, e);
|
||||
}
|
||||
|
||||
writer.setMimetype(contentStream.getMimeType());
|
||||
writer.putContent(inputstream);
|
||||
|
||||
objectId.value = propertiesUtil.getProperty(cmisObjectsUtils.getLatestNode(nodeRef, false), CMISDictionaryModel.PROP_OBJECT_ID, objectId.value);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -679,14 +647,18 @@ public class DMObjectServicePort extends DMAbstractServicePort implements Object
|
||||
public void updateProperties(String repositoryId, Holder<String> objectId, Holder<String> changeToken, CmisPropertiesType properties, Holder<CmisExtensionType> extension)
|
||||
throws CmisException
|
||||
{
|
||||
// TODO: Process changeToken
|
||||
checkRepositoryId(repositoryId);
|
||||
|
||||
NodeRef objectNodeRef = cmisObjectsUtils.getIdentifierInstance(objectId.value, AlfrescoObjectType.DOCUMENT_OR_FOLDER_OBJECT);
|
||||
NodeRef objectNodeRef;
|
||||
try
|
||||
{
|
||||
objectNodeRef = cmisService.getObject(objectId.value, NodeRef.class, true, false, false);
|
||||
}
|
||||
catch (CMISServiceException e)
|
||||
{
|
||||
throw ExceptionUtil.createCmisException(e);
|
||||
}
|
||||
propertiesUtil.setProperties(objectNodeRef, properties, null);
|
||||
|
||||
// no new version
|
||||
objectId.value = propertiesUtil.getProperty(objectNodeRef, CMISDictionaryModel.PROP_OBJECT_ID, objectId.value);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -702,10 +674,16 @@ public class DMObjectServicePort extends DMAbstractServicePort implements Object
|
||||
|
||||
PropertyFilter propertyFilter = createPropertyFilter(filter);
|
||||
|
||||
Object identifierInstance = cmisObjectsUtils.getIdentifierInstance(objectId, AlfrescoObjectType.ANY_OBJECT);
|
||||
String identifier = identifierInstance.toString();
|
||||
|
||||
CmisPropertiesType result = propertiesUtil.getPropertiesType(identifier, propertyFilter);
|
||||
Object identifierInstance;
|
||||
try
|
||||
{
|
||||
identifierInstance = cmisService.getReadableObject(objectId, Object.class);
|
||||
}
|
||||
catch (CMISServiceException e)
|
||||
{
|
||||
throw ExceptionUtil.createCmisException(e);
|
||||
}
|
||||
CmisPropertiesType result = propertiesUtil.getProperties(identifierInstance, propertyFilter);
|
||||
|
||||
return result;
|
||||
}
|
||||
@@ -721,7 +699,15 @@ public class DMObjectServicePort extends DMAbstractServicePort implements Object
|
||||
CmisExtensionType extension) throws CmisException
|
||||
{
|
||||
checkRepositoryId(repositoryId);
|
||||
NodeRef objectNodeRef = cmisObjectsUtils.getIdentifierInstance(objectId, AlfrescoObjectType.DOCUMENT_OR_FOLDER_OBJECT);
|
||||
NodeRef objectNodeRef;
|
||||
try
|
||||
{
|
||||
objectNodeRef = cmisService.getReadableObject(objectId, NodeRef.class);
|
||||
}
|
||||
catch (CMISServiceException e)
|
||||
{
|
||||
throw ExceptionUtil.createCmisException(e);
|
||||
}
|
||||
List<CmisRenditionType> result = new ArrayList<CmisRenditionType>();
|
||||
List<CmisRenditionType> renditions = getRenditions(objectNodeRef, renditionFilter);
|
||||
if (renditions != null)
|
||||
@@ -736,37 +722,23 @@ public class DMObjectServicePort extends DMAbstractServicePort implements Object
|
||||
}
|
||||
|
||||
private void appendDataToDocument(NodeRef targetDocumentNodeRef, CmisPropertiesType properties, EnumVersioningState versioningState, List<String> policies,
|
||||
CmisAccessControlListType addACEs, CmisAccessControlListType removeACEs, Holder<String> objectId, PropertyFilter propertyFilter) throws CmisException
|
||||
CmisAccessControlListType addACEs, CmisAccessControlListType removeACEs, Holder<String> objectId, PropertyFilter propertyFilter) throws CMISConstraintException,
|
||||
CmisException, CMISInvalidArgumentException
|
||||
{
|
||||
// TODO: process Policies
|
||||
|
||||
propertiesUtil.setProperties(targetDocumentNodeRef, properties, propertyFilter);
|
||||
|
||||
String versionLabel = null;
|
||||
// Apply the ACL before potentially creating a PWC
|
||||
applyAclCarefully(targetDocumentNodeRef, addACEs, removeACEs, EnumACLPropagation.PROPAGATE);
|
||||
|
||||
// FIXME: change condition below to "typeDef.isVersionable()" when dictionary problem will be fixed
|
||||
if (true)
|
||||
if (versioningState == null)
|
||||
{
|
||||
versioningState = (null == versioningState) ? (EnumVersioningState.MINOR) : (versioningState);
|
||||
switch (versioningState)
|
||||
{
|
||||
case CHECKEDOUT:
|
||||
targetDocumentNodeRef = checkoutNode(targetDocumentNodeRef);
|
||||
break;
|
||||
case MAJOR:
|
||||
this.versionService.createVersion(targetDocumentNodeRef, createVersionProperties(INITIAL_VERSION_DESCRIPTION, VersionType.MAJOR));
|
||||
break;
|
||||
case MINOR:
|
||||
this.versionService.createVersion(targetDocumentNodeRef, createVersionProperties(INITIAL_VERSION_DESCRIPTION, VersionType.MINOR));
|
||||
break;
|
||||
versioningState = EnumVersioningState.MAJOR;
|
||||
}
|
||||
versionLabel = propertiesUtil.getProperty(targetDocumentNodeRef, CMISDictionaryModel.PROP_VERSION_LABEL, "");
|
||||
}
|
||||
String createdObjectId = ((null != versionLabel) && versionLabel.contains(VERSION_DELIMETER)) ? (targetDocumentNodeRef.toString()
|
||||
+ CmisObjectsUtils.NODE_REFERENCE_ID_DELIMITER + versionLabel) : (targetDocumentNodeRef.toString());
|
||||
NodeRef objectNodeRef = cmisObjectsUtils.getIdentifierInstance(createdObjectId, AlfrescoObjectType.DOCUMENT_OBJECT);
|
||||
applyAclCarefully(objectNodeRef, addACEs, removeACEs, EnumACLPropagation.PROPAGATE);
|
||||
objectId.value = createdObjectId;
|
||||
|
||||
targetDocumentNodeRef = cmisService.applyVersioningState(targetDocumentNodeRef, VERSIONING_STATE_ENUM_MAPPING.get(versioningState));
|
||||
objectId.value = targetDocumentNodeRef.toString();
|
||||
}
|
||||
|
||||
private String createIgnoringFilter(String[] propertyNames)
|
||||
@@ -795,7 +767,7 @@ public class DMObjectServicePort extends DMAbstractServicePort implements Object
|
||||
String typeId = (String) propertiesMap.get(CMISDictionaryModel.PROP_OBJECT_TYPE_ID);
|
||||
if ((null == typeId) || "".equals(typeId))
|
||||
{
|
||||
throw cmisObjectsUtils.createCmisException("Type Id property required", EnumServiceException.INVALID_ARGUMENT);
|
||||
throw ExceptionUtil.createCmisException("Type Id property required", EnumServiceException.INVALID_ARGUMENT);
|
||||
}
|
||||
return typeId;
|
||||
}
|
||||
@@ -805,60 +777,58 @@ public class DMObjectServicePort extends DMAbstractServicePort implements Object
|
||||
{
|
||||
if ((null == typeDef) || (null == typeDef.getTypeId()))
|
||||
{
|
||||
throw cmisObjectsUtils.createCmisException(("Type with " + documentTypeId + "typeId was not found"), EnumServiceException.RUNTIME);
|
||||
throw ExceptionUtil.createCmisException(("Type with " + documentTypeId + "typeId was not found"), EnumServiceException.RUNTIME);
|
||||
}
|
||||
|
||||
if ((CMISScope.DOCUMENT != typeDef.getTypeId().getScope()) || !typeDef.isCreatable())
|
||||
{
|
||||
throw cmisObjectsUtils.createCmisException(("Invalid document type \"" + documentTypeId + "\". This type is not a Creatable Document type"),
|
||||
throw ExceptionUtil.createCmisException(("Invalid document type \"" + documentTypeId + "\". This type is not a Creatable Document type"),
|
||||
EnumServiceException.CONSTRAINT);
|
||||
}
|
||||
|
||||
if ((null != contentStream) && CMISContentStreamAllowedEnum.NOT_ALLOWED == typeDef.getContentStreamAllowed())
|
||||
{
|
||||
throw cmisObjectsUtils.createCmisException(("Content stream not allowed for \"" + documentTypeId + "\" document object type"),
|
||||
EnumServiceException.STREAM_NOT_SUPPORTED);
|
||||
throw ExceptionUtil.createCmisException(("Content stream not allowed for \"" + documentTypeId + "\" document object type"), EnumServiceException.STREAM_NOT_SUPPORTED);
|
||||
}
|
||||
else
|
||||
{
|
||||
if ((CMISContentStreamAllowedEnum.REQUIRED == typeDef.getContentStreamAllowed()) && (null == contentStream))
|
||||
{
|
||||
throw cmisObjectsUtils.createCmisException("Content stream for document object of " + documentTypeId + " type is required", EnumServiceException.CONSTRAINT);
|
||||
throw ExceptionUtil.createCmisException("Content stream for document object of " + documentTypeId + " type is required", EnumServiceException.CONSTRAINT);
|
||||
}
|
||||
}
|
||||
|
||||
// FIXME: change condition below to "!typeDef.isVersionable() && (null != versioningState)" when dictionary problem will be fixed
|
||||
if (false)
|
||||
{
|
||||
throw cmisObjectsUtils.createCmisException(("Verioning for \"" + documentTypeId + "\" document type is not allowed"), EnumServiceException.CONSTRAINT);
|
||||
throw ExceptionUtil.createCmisException(("Verioning for \"" + documentTypeId + "\" document type is not allowed"), EnumServiceException.CONSTRAINT);
|
||||
}
|
||||
|
||||
String folderTypeId = propertiesUtil.getProperty(parentNodeRef, CMISDictionaryModel.PROP_OBJECT_TYPE_ID, null);
|
||||
CMISTypeDefinition folderTypeDefinition = cmisDictionaryService.findType(folderTypeId);
|
||||
CMISTypeDefinition folderTypeDefinition;
|
||||
try
|
||||
{
|
||||
folderTypeDefinition = cmisService.getTypeDefinition(parentNodeRef);
|
||||
}
|
||||
catch (CMISInvalidArgumentException e)
|
||||
{
|
||||
throw ExceptionUtil.createCmisException(e.getMessage(), EnumServiceException.INVALID_ARGUMENT, e);
|
||||
}
|
||||
if ((null != folderTypeDefinition.getAllowedTargetTypes()) && !folderTypeDefinition.getAllowedTargetTypes().isEmpty()
|
||||
&& !folderTypeDefinition.getAllowedTargetTypes().contains(typeDef))
|
||||
{
|
||||
throw cmisObjectsUtils.createCmisException(("Children of \"" + documentTypeId + "\" type are not allowed for specified folder"), EnumServiceException.CONSTRAINT);
|
||||
throw ExceptionUtil.createCmisException(("Children of \"" + documentTypeId + "\" type are not allowed for specified folder"), EnumServiceException.CONSTRAINT);
|
||||
}
|
||||
|
||||
String result = (String) propertiesMap.get(CMISDictionaryModel.PROP_NAME);
|
||||
if (null == result)
|
||||
{
|
||||
throw cmisObjectsUtils.createCmisException("Name property not found", EnumServiceException.INVALID_ARGUMENT);
|
||||
throw ExceptionUtil.createCmisException("Name property not found", EnumServiceException.INVALID_ARGUMENT);
|
||||
}
|
||||
propertiesUtil.checkProperty(null, typeDef, CMISDictionaryModel.PROP_NAME, result, (EnumVersioningState.CHECKEDOUT == versioningState));
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
private void changeObjectParentAssociation(NodeRef objectNodeRef, NodeRef targetFolderNodeRef, NodeRef sourceFolderNodeReference) throws CmisException
|
||||
{
|
||||
if (!cmisObjectsUtils.removeObject(objectNodeRef, sourceFolderNodeReference) || !cmisObjectsUtils.addObjectToFolder(objectNodeRef, targetFolderNodeRef))
|
||||
{
|
||||
determineException(cmisObjectsUtils.getLastOperationException());
|
||||
}
|
||||
}
|
||||
|
||||
private NodeRef resolvePathInfo(String folderPath) throws CmisException
|
||||
{
|
||||
NodeRef result = null;
|
||||
@@ -886,100 +856,24 @@ public class DMObjectServicePort extends DMAbstractServicePort implements Object
|
||||
return result;
|
||||
}
|
||||
|
||||
private void safeMove(NodeRef objectNodeRef, NodeRef targetFolderNodeRef) throws CmisException
|
||||
{
|
||||
try
|
||||
{
|
||||
fileFolderService.move(objectNodeRef, targetFolderNodeRef, null);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
determineException(e);
|
||||
}
|
||||
}
|
||||
|
||||
private void safeDeleteContentStream(NodeRef documentNodeReference) throws CmisException
|
||||
{
|
||||
try
|
||||
{
|
||||
nodeService.setProperty(documentNodeReference, ContentModel.PROP_CONTENT, null);
|
||||
}
|
||||
catch (NodeLockedException e)
|
||||
{
|
||||
throw cmisObjectsUtils.createCmisException("Content Stream Deletion is not allowed for specified Object", EnumServiceException.UPDATE_CONFLICT);
|
||||
}
|
||||
}
|
||||
|
||||
private void deleteAllVersions(String repositoryId, String versionSeriesId) throws CmisException
|
||||
{
|
||||
checkRepositoryId(repositoryId);
|
||||
NodeRef documentNodeRef = cmisObjectsUtils.getIdentifierInstance(versionSeriesId, AlfrescoObjectType.DOCUMENT_OBJECT);
|
||||
NodeRef workingCopyRef = (cmisObjectsUtils.isWorkingCopy(documentNodeRef)) ? (documentNodeRef) : (checkOutCheckInService.getWorkingCopy(documentNodeRef));
|
||||
if ((null != workingCopyRef) && cmisObjectsUtils.isWorkingCopy(workingCopyRef))
|
||||
{
|
||||
documentNodeRef = checkOutCheckInService.cancelCheckout(workingCopyRef);
|
||||
}
|
||||
|
||||
versionService.deleteVersionHistory(documentNodeRef);
|
||||
}
|
||||
|
||||
private ContentReader safeGetContentReader(NodeRef objectNodeReference) throws CmisException
|
||||
{
|
||||
ContentReader reader = fileFolderService.getReader(objectNodeReference);
|
||||
if (reader == null)
|
||||
{
|
||||
throw cmisObjectsUtils.createCmisException("The specified Document has no Content Stream", EnumServiceException.CONSTRAINT);
|
||||
throw ExceptionUtil.createCmisException("The specified Document has no Content Stream", EnumServiceException.CONSTRAINT);
|
||||
}
|
||||
return reader;
|
||||
}
|
||||
|
||||
private NodeRef safeGetFolderNodeRef(String folderId) throws CmisException
|
||||
{
|
||||
try
|
||||
{
|
||||
return this.cmisObjectsUtils.getIdentifierInstance(folderId, AlfrescoObjectType.FOLDER_OBJECT);
|
||||
}
|
||||
catch (CmisException e)
|
||||
{
|
||||
throw cmisObjectsUtils.createCmisException("Unfiling is not suppoerted. Each Document must have existent parent Folder", EnumServiceException.CONSTRAINT, e);
|
||||
}
|
||||
}
|
||||
|
||||
private void checkObjectTypeAndAppropriateStates(NodeRef objectNodeReference) throws CmisException
|
||||
{
|
||||
if (cmisObjectsUtils.isFolder(objectNodeReference) && (nodeService.getChildAssocs(objectNodeReference).size() > 0))
|
||||
{
|
||||
throw cmisObjectsUtils.createCmisException("Could not delete folder with at least one Child", EnumServiceException.CONSTRAINT);
|
||||
}
|
||||
}
|
||||
|
||||
private void checkUnfilingIsNotRequested(EnumUnfileObject unfileNonfolderObjects) throws CmisException
|
||||
{
|
||||
if (unfileNonfolderObjects == EnumUnfileObject.UNFILE)
|
||||
{
|
||||
throw cmisObjectsUtils.createCmisException("Unfiling is not supported", EnumServiceException.NOT_SUPPORTED);
|
||||
throw ExceptionUtil.createCmisException("Unfiling is not supported", EnumServiceException.NOT_SUPPORTED);
|
||||
}
|
||||
}
|
||||
|
||||
private void checkForRootObject(String repositoryId, String objectId) throws CmisException
|
||||
{
|
||||
if (this.cmisService.getDefaultRootNodeRef().toString().equals(objectId) || repositoryId.equals(objectId))
|
||||
{
|
||||
throw cmisObjectsUtils.createCmisException("Could not delete Repository object or Root Folder object - operation is not allowed or not supported",
|
||||
EnumServiceException.NOT_SUPPORTED);
|
||||
}
|
||||
}
|
||||
|
||||
private void determineException(Throwable lastException) throws CmisException
|
||||
{
|
||||
if (lastException instanceof AccessDeniedException)
|
||||
{
|
||||
throw cmisObjectsUtils.createCmisException(lastException.toString(), EnumServiceException.PERMISSION_DENIED);
|
||||
}
|
||||
|
||||
throw cmisObjectsUtils.createCmisException("Couldn't to relocate multi-filed Object", EnumServiceException.UPDATE_CONFLICT);
|
||||
}
|
||||
|
||||
public void setFileTypeIconRetriever(FileTypeIconRetriever iconRetriever)
|
||||
{
|
||||
this.iconRetriever = iconRetriever;
|
||||
|
@@ -28,6 +28,8 @@ import java.util.List;
|
||||
|
||||
import javax.xml.ws.Holder;
|
||||
|
||||
import org.alfresco.repo.cmis.ws.utils.ExceptionUtil;
|
||||
|
||||
@javax.jws.WebService(name = "PolicyServicePort", serviceName = "PolicyServicePort", portName = "PolicyServicePort", targetNamespace = "http://docs.oasis-open.org/ns/cmis/ws/200908/", endpointInterface = "org.alfresco.repo.cmis.ws.PolicyServicePort")
|
||||
public class DMPolicyServicePort extends DMAbstractServicePort implements PolicyServicePort
|
||||
{
|
||||
@@ -43,7 +45,7 @@ public class DMPolicyServicePort extends DMAbstractServicePort implements Policy
|
||||
*/
|
||||
public void applyPolicy(String repositoryId, String policyId, String objectId, Holder<CmisExtensionType> extension) throws CmisException
|
||||
{
|
||||
throw cmisObjectsUtils.createCmisException(POLICY_NOT_SUPPORTED_MESSAGE, EnumServiceException.RUNTIME);
|
||||
throw ExceptionUtil.createCmisException(POLICY_NOT_SUPPORTED_MESSAGE, EnumServiceException.RUNTIME);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -54,7 +56,7 @@ public class DMPolicyServicePort extends DMAbstractServicePort implements Policy
|
||||
*/
|
||||
public List<CmisObjectType> getAppliedPolicies(String repositoryId, String objectId, String filter, CmisExtensionType extension) throws CmisException
|
||||
{
|
||||
throw cmisObjectsUtils.createCmisException(POLICY_NOT_SUPPORTED_MESSAGE, EnumServiceException.RUNTIME);
|
||||
throw ExceptionUtil.createCmisException(POLICY_NOT_SUPPORTED_MESSAGE, EnumServiceException.RUNTIME);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -67,6 +69,6 @@ public class DMPolicyServicePort extends DMAbstractServicePort implements Policy
|
||||
*/
|
||||
public void removePolicy(String repositoryId, String policyId, String objectId, Holder<CmisExtensionType> extension) throws CmisException
|
||||
{
|
||||
throw cmisObjectsUtils.createCmisException(POLICY_NOT_SUPPORTED_MESSAGE, EnumServiceException.RUNTIME);
|
||||
throw ExceptionUtil.createCmisException(POLICY_NOT_SUPPORTED_MESSAGE, EnumServiceException.RUNTIME);
|
||||
}
|
||||
}
|
||||
|
@@ -25,18 +25,17 @@
|
||||
package org.alfresco.repo.cmis.ws;
|
||||
|
||||
import java.math.BigInteger;
|
||||
import java.util.List;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import org.alfresco.cmis.CMISScope;
|
||||
import org.alfresco.cmis.CMISRelationshipDirectionEnum;
|
||||
import org.alfresco.cmis.CMISServiceException;
|
||||
import org.alfresco.cmis.CMISTypeDefinition;
|
||||
import org.alfresco.repo.cmis.PropertyFilter;
|
||||
import org.alfresco.repo.cmis.ws.utils.AlfrescoObjectType;
|
||||
import org.alfresco.repo.cmis.ws.utils.ExceptionUtil;
|
||||
import org.alfresco.repo.web.util.paging.Cursor;
|
||||
import org.alfresco.service.cmr.dictionary.DictionaryService;
|
||||
import org.alfresco.service.cmr.repository.AssociationRef;
|
||||
import org.alfresco.service.cmr.repository.NodeRef;
|
||||
import org.alfresco.service.namespace.QName;
|
||||
import org.alfresco.service.namespace.QNamePattern;
|
||||
|
||||
/**
|
||||
* Port for relationship service
|
||||
@@ -46,11 +45,13 @@ import org.alfresco.service.namespace.QNamePattern;
|
||||
@javax.jws.WebService(name = "RelationshipServicePort", serviceName = "RelationshipService", portName = "RelationshipServicePort", targetNamespace = "http://docs.oasis-open.org/ns/cmis/ws/200908/", endpointInterface = "org.alfresco.repo.cmis.ws.RelationshipServicePort")
|
||||
public class DMRelationshipServicePort extends DMAbstractServicePort implements RelationshipServicePort
|
||||
{
|
||||
private DictionaryService dictionaryService;
|
||||
|
||||
public void setDictionaryService(DictionaryService dictionaryService)
|
||||
private static final Map<EnumRelationshipDirection, CMISRelationshipDirectionEnum> RELATIONSHIP_DIRECTION_MAPPING;
|
||||
static
|
||||
{
|
||||
this.dictionaryService = dictionaryService;
|
||||
RELATIONSHIP_DIRECTION_MAPPING = new HashMap<EnumRelationshipDirection, CMISRelationshipDirectionEnum>(5);
|
||||
RELATIONSHIP_DIRECTION_MAPPING.put(EnumRelationshipDirection.SOURCE, CMISRelationshipDirectionEnum.SOURCE);
|
||||
RELATIONSHIP_DIRECTION_MAPPING.put(EnumRelationshipDirection.TARGET, CMISRelationshipDirectionEnum.TARGET);
|
||||
RELATIONSHIP_DIRECTION_MAPPING.put(EnumRelationshipDirection.EITHER, CMISRelationshipDirectionEnum.BOTH);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -66,31 +67,25 @@ public class DMRelationshipServicePort extends DMAbstractServicePort implements
|
||||
String typeId, String filter, Boolean includeAllowableActions, BigInteger maxItems, BigInteger skipCount, CmisExtensionType extension) throws CmisException
|
||||
{
|
||||
checkRepositoryId(repositoryId);
|
||||
NodeRef objectNodeRef = cmisObjectsUtils.getIdentifierInstance(objectId, AlfrescoObjectType.DOCUMENT_OR_FOLDER_OBJECT);
|
||||
if (null == includeSubRelationshipTypes)
|
||||
if ((null == objectId) || "".equals(objectId) || !NodeRef.isNodeRef(objectId))
|
||||
{
|
||||
throw cmisObjectsUtils.createCmisException("includeSubRelationshipTypes input parameter is required", EnumServiceException.INVALID_ARGUMENT);
|
||||
throw ExceptionUtil.createCmisException(("Object with Id='" + objectId + "' is not exist!"), EnumServiceException.OBJECT_NOT_FOUND);
|
||||
}
|
||||
relationshipDirection = (null != relationshipDirection) ? relationshipDirection : EnumRelationshipDirection.SOURCE;
|
||||
skipCount = (null != skipCount) ? skipCount : BigInteger.ZERO;
|
||||
maxItems = (null != maxItems) ? maxItems : BigInteger.ZERO;
|
||||
QName associationType = null;
|
||||
if ((null != typeId) && !"".equals(typeId))
|
||||
{
|
||||
CMISTypeDefinition cmisTypeDef = cmisDictionaryService.findType(typeId);
|
||||
associationType = cmisTypeDef.getTypeId().getQName();
|
||||
}
|
||||
PropertyFilter propertyFilter = createPropertyFilter(filter);
|
||||
List<AssociationRef> assocs = null;
|
||||
try
|
||||
{
|
||||
assocs = cmisObjectsUtils.receiveAssociations(objectNodeRef, new RelationshipTypeFilter(associationType, includeSubRelationshipTypes), relationshipDirection);
|
||||
CMISTypeDefinition relDef = (null != typeId) ? (cmisService.getTypeDefinition(typeId)):(null);
|
||||
NodeRef nodeRef = cmisService.getReadableObject(objectId, NodeRef.class);
|
||||
AssociationRef[] assocs = cmisService.getRelationships(nodeRef, relDef, includeSubRelationshipTypes != null && includeSubRelationshipTypes,
|
||||
relationshipDirection == null ? CMISRelationshipDirectionEnum.SOURCE : RELATIONSHIP_DIRECTION_MAPPING.get(relationshipDirection));
|
||||
skipCount = (null != skipCount) ? skipCount : BigInteger.ZERO;
|
||||
maxItems = (null != maxItems) ? maxItems : BigInteger.ZERO;
|
||||
PropertyFilter propertyFilter = createPropertyFilter(filter);
|
||||
return createResult(propertyFilter, includeAllowableActions, assocs, skipCount, maxItems);
|
||||
}
|
||||
catch (Exception e)
|
||||
catch (CMISServiceException e)
|
||||
{
|
||||
throw cmisObjectsUtils.createCmisException("Can't receive associations", e);
|
||||
throw ExceptionUtil.createCmisException(e);
|
||||
}
|
||||
return createResult(propertyFilter, includeAllowableActions, assocs.toArray(), skipCount, maxItems);
|
||||
}
|
||||
|
||||
private CmisObjectListType createResult(PropertyFilter filter, boolean includeAllowableActions, Object[] sourceArray, BigInteger skipCount, BigInteger maxItems)
|
||||
@@ -100,39 +95,10 @@ public class DMRelationshipServicePort extends DMAbstractServicePort implements
|
||||
CmisObjectListType result = new CmisObjectListType();
|
||||
for (int i = cursor.getStartRow(); i <= cursor.getEndRow(); i++)
|
||||
{
|
||||
result.getObjects().add(createCmisObject(sourceArray[i].toString(), filter, includeAllowableActions, null));
|
||||
result.getObjects().add(createCmisObject(sourceArray[i], filter, includeAllowableActions, null));
|
||||
}
|
||||
result.setHasMoreItems(cursor.getEndRow() < sourceArray.length);
|
||||
result.setNumItems(BigInteger.valueOf(cursor.getPageSize()));
|
||||
return result;
|
||||
}
|
||||
|
||||
private class RelationshipTypeFilter implements QNamePattern
|
||||
{
|
||||
private boolean includeSubtypes;
|
||||
private QName relationshipType;
|
||||
|
||||
public RelationshipTypeFilter(QName ralationshipType, boolean includeSubtypes)
|
||||
{
|
||||
this.relationshipType = ralationshipType;
|
||||
this.includeSubtypes = includeSubtypes;
|
||||
}
|
||||
|
||||
public boolean isMatch(QName qname)
|
||||
{
|
||||
if (relationshipType == null)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
else if (includeSubtypes)
|
||||
{
|
||||
return null != dictionaryService.getAssociation(qname);
|
||||
}
|
||||
else
|
||||
{
|
||||
CMISTypeDefinition typeDef = cmisDictionaryService.findTypeForClass(qname, CMISScope.RELATIONSHIP);
|
||||
return typeDef != null && relationshipType.equals(qname);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -33,7 +33,6 @@ import java.util.Iterator;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Queue;
|
||||
|
||||
import org.alfresco.cmis.CMISAclCapabilityEnum;
|
||||
import org.alfresco.cmis.CMISAclPropagationEnum;
|
||||
@@ -50,8 +49,10 @@ import org.alfresco.cmis.CMISPermissionDefinition;
|
||||
import org.alfresco.cmis.CMISPermissionMapping;
|
||||
import org.alfresco.cmis.CMISPropertyDefinition;
|
||||
import org.alfresco.cmis.CMISQueryEnum;
|
||||
import org.alfresco.cmis.CMISServiceException;
|
||||
import org.alfresco.cmis.CMISTypeDefinition;
|
||||
import org.alfresco.cmis.CMISUpdatabilityEnum;
|
||||
import org.alfresco.repo.cmis.ws.utils.ExceptionUtil;
|
||||
import org.alfresco.repo.web.util.paging.Cursor;
|
||||
import org.alfresco.service.descriptor.Descriptor;
|
||||
|
||||
@@ -324,7 +325,7 @@ public class DMRepositoryServicePort extends DMAbstractServicePort implements Re
|
||||
}
|
||||
default:
|
||||
{
|
||||
throw cmisObjectsUtils.createCmisException(type.getLabel(), EnumServiceException.OBJECT_NOT_FOUND);
|
||||
throw ExceptionUtil.createCmisException(type.getLabel(), EnumServiceException.OBJECT_NOT_FOUND);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -379,7 +380,7 @@ public class DMRepositoryServicePort extends DMAbstractServicePort implements Re
|
||||
{
|
||||
if (typeDef == null)
|
||||
{
|
||||
throw cmisObjectsUtils.createCmisException("Type not found", EnumServiceException.OBJECT_NOT_FOUND);
|
||||
throw ExceptionUtil.createCmisException("Type not found", EnumServiceException.OBJECT_NOT_FOUND);
|
||||
}
|
||||
|
||||
CmisTypeDefinitionType result = null;
|
||||
@@ -439,7 +440,7 @@ public class DMRepositoryServicePort extends DMAbstractServicePort implements Re
|
||||
result = relationshipDefinitionType;
|
||||
break;
|
||||
case UNKNOWN:
|
||||
throw cmisObjectsUtils.createCmisException("Unknown CMIS Type", EnumServiceException.INVALID_ARGUMENT);
|
||||
throw ExceptionUtil.createCmisException("Unknown CMIS Type", EnumServiceException.INVALID_ARGUMENT);
|
||||
}
|
||||
|
||||
return result;
|
||||
@@ -572,7 +573,15 @@ public class DMRepositoryServicePort extends DMAbstractServicePort implements Re
|
||||
CmisExtensionType extension) throws CmisException
|
||||
{
|
||||
checkRepositoryId(repositoryId);
|
||||
Collection<CMISTypeDefinition> typeDefs = getBaseTypesCollection(typeId, true);
|
||||
Collection<CMISTypeDefinition> typeDefs;
|
||||
try
|
||||
{
|
||||
typeDefs = typeId == null ? cmisService.getBaseTypes() : cmisService.getTypeDefinition(typeId).getSubTypes(false);
|
||||
}
|
||||
catch (CMISServiceException e)
|
||||
{
|
||||
throw ExceptionUtil.createCmisException(e);
|
||||
}
|
||||
// skip
|
||||
Cursor cursor = createCursor(typeDefs.size(), skipCount, maxItems);
|
||||
Iterator<CMISTypeDefinition> iterTypeDefs = typeDefs.iterator();
|
||||
@@ -593,7 +602,7 @@ public class DMRepositoryServicePort extends DMAbstractServicePort implements Re
|
||||
}
|
||||
else
|
||||
{
|
||||
throw cmisObjectsUtils.createCmisException(("Subtypes collection is corrupted. Type id: " + typeId), EnumServiceException.STORAGE);
|
||||
throw ExceptionUtil.createCmisException(("Subtypes collection is corrupted. Type id: " + typeId), EnumServiceException.STORAGE);
|
||||
}
|
||||
}
|
||||
result.setHasMoreItems(((maxItems == null) || (0 == maxItems.intValue())) ? (false) : ((cursor.getEndRow() < (typeDefs.size() - 1))));
|
||||
@@ -614,11 +623,11 @@ public class DMRepositoryServicePort extends DMAbstractServicePort implements Re
|
||||
CMISTypeDefinition typeDef;
|
||||
try
|
||||
{
|
||||
typeDef = cmisDictionaryService.findType(typeId);
|
||||
typeDef = cmisService.getTypeDefinition(typeId);
|
||||
}
|
||||
catch (Exception e)
|
||||
catch (CMISServiceException e)
|
||||
{
|
||||
throw cmisObjectsUtils.createCmisException(e.toString(), EnumServiceException.INVALID_ARGUMENT);
|
||||
throw ExceptionUtil.createCmisException(e);
|
||||
}
|
||||
return getCmisTypeDefinition(typeDef, true);
|
||||
}
|
||||
@@ -634,111 +643,45 @@ public class DMRepositoryServicePort extends DMAbstractServicePort implements Re
|
||||
throws CmisException
|
||||
{
|
||||
checkRepositoryId(repositoryId);
|
||||
long depthLong = (null == depth) ? (-1) : (depth.longValue());
|
||||
long depthLong = (null == depth || null == typeId) ? (-1) : (depth.longValue());
|
||||
if (0 == depthLong)
|
||||
{
|
||||
throw cmisObjectsUtils.createCmisException("Depth parameter equal to '0' have no sence", EnumServiceException.INVALID_ARGUMENT);
|
||||
throw ExceptionUtil.createCmisException("Invalid depth '0'", EnumServiceException.INVALID_ARGUMENT);
|
||||
}
|
||||
boolean includePropertyDefsBool = (null == includePropertyDefinitions) ? (false) : (includePropertyDefinitions);
|
||||
List<CmisTypeContainer> result = new LinkedList<CmisTypeContainer>();
|
||||
Queue<TypeElement> typesQueue = new LinkedList<TypeElement>();
|
||||
Collection<CMISTypeDefinition> typeDefs = getBaseTypesCollection(typeId, false);
|
||||
for (CMISTypeDefinition typeDef : typeDefs)
|
||||
CMISTypeDefinition typeDef;
|
||||
try
|
||||
{
|
||||
typesQueue.add(new TypeElement(0L, typeDef, createTypeContainer(typeDef, includePropertyDefsBool)));
|
||||
typeDef = typeId == null ? null : cmisService.getTypeDefinition(typeId);
|
||||
}
|
||||
for (TypeElement element = typesQueue.peek(); !typesQueue.isEmpty(); element = (typeDefs.isEmpty()) ? (null) : (typesQueue.peek()))
|
||||
catch (CMISServiceException e)
|
||||
{
|
||||
typesQueue.poll();
|
||||
result.add(element.getContainer());
|
||||
long nextLevel = element.getLevel() + 1;
|
||||
Collection<CMISTypeDefinition> subTypes = element.getTypeDefinition().getSubTypes(false);
|
||||
if (null != subTypes)
|
||||
{
|
||||
for (CMISTypeDefinition typeDef : subTypes)
|
||||
{
|
||||
CmisTypeContainer childContainer = createTypeContainer(typeDef, includePropertyDefsBool);
|
||||
if ((-1 == depthLong) || (nextLevel <= depthLong))
|
||||
{
|
||||
element.getContainer().getChildren().add(childContainer);
|
||||
typesQueue.add(new TypeElement(nextLevel, typeDef, childContainer));
|
||||
}
|
||||
}
|
||||
}
|
||||
throw ExceptionUtil.createCmisException(e);
|
||||
}
|
||||
getTypeDescendants(typeDef, result, includePropertyDefinitions != null && includePropertyDefinitions, 1, depthLong);
|
||||
return result;
|
||||
}
|
||||
|
||||
private void getTypeDescendants(CMISTypeDefinition parent, List<CmisTypeContainer> result, boolean includePropertyDefs, long depth, long maxDepth) throws CmisException
|
||||
{
|
||||
Collection<CMISTypeDefinition> subtypes = parent == null ? cmisService.getBaseTypes() : parent.getSubTypes(false);
|
||||
for (CMISTypeDefinition typeDef : subtypes)
|
||||
{
|
||||
result.add(createTypeContainer(typeDef, includePropertyDefs));
|
||||
}
|
||||
if (maxDepth == -1 || depth + 1 <= maxDepth)
|
||||
{
|
||||
for (CMISTypeDefinition typeDef : subtypes)
|
||||
{
|
||||
getTypeDescendants(typeDef, result, includePropertyDefs, depth + 1, maxDepth);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private CmisTypeContainer createTypeContainer(CMISTypeDefinition parentType, boolean includeProperties) throws CmisException
|
||||
{
|
||||
CmisTypeContainer result = new CmisTypeContainer();
|
||||
result.setType(getCmisTypeDefinition(parentType, includeProperties));
|
||||
return result;
|
||||
}
|
||||
|
||||
private class TypeElement
|
||||
{
|
||||
private long level;
|
||||
private CMISTypeDefinition typeDefinition;
|
||||
private CmisTypeContainer container;
|
||||
|
||||
public TypeElement(long level, CMISTypeDefinition typeDefinition, CmisTypeContainer container)
|
||||
{
|
||||
this.level = level;
|
||||
this.typeDefinition = typeDefinition;
|
||||
this.container = container;
|
||||
}
|
||||
|
||||
public long getLevel()
|
||||
{
|
||||
return level;
|
||||
}
|
||||
|
||||
public CMISTypeDefinition getTypeDefinition()
|
||||
{
|
||||
return typeDefinition;
|
||||
}
|
||||
|
||||
public CmisTypeContainer getContainer()
|
||||
{
|
||||
return container;
|
||||
}
|
||||
}
|
||||
|
||||
private Collection<CMISTypeDefinition> getBaseTypesCollection(String typeId, boolean includeSubtypes) throws CmisException
|
||||
{
|
||||
Collection<CMISTypeDefinition> typeDefs = new LinkedList<CMISTypeDefinition>();
|
||||
if ((null == typeId) || "".equals(typeId))
|
||||
{
|
||||
typeDefs = cmisDictionaryService.getBaseTypes();
|
||||
}
|
||||
else
|
||||
{
|
||||
CMISTypeDefinition typeDef = null;
|
||||
try
|
||||
{
|
||||
typeDef = cmisDictionaryService.findType(typeId);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
throw cmisObjectsUtils.createCmisException(e.toString(), EnumServiceException.INVALID_ARGUMENT);
|
||||
}
|
||||
|
||||
if (null == typeDef)
|
||||
{
|
||||
throw cmisObjectsUtils.createCmisException(("Invalid type id: \"" + typeId + "\""), EnumServiceException.INVALID_ARGUMENT);
|
||||
}
|
||||
typeDefs.add(typeDef);
|
||||
|
||||
if (includeSubtypes)
|
||||
{
|
||||
Collection<CMISTypeDefinition> subTypes = typeDef.getSubTypes(false);
|
||||
if (null != subTypes)
|
||||
{
|
||||
typeDefs.addAll(subTypes);
|
||||
}
|
||||
}
|
||||
}
|
||||
return typeDefs;
|
||||
}
|
||||
}
|
||||
|
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2005-2008 Alfresco Software Limited.
|
||||
* Copyright (C) 2005-2010 Alfresco Software Limited.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
@@ -18,13 +18,13 @@
|
||||
* As a special exception to the terms and conditions of version 2.0 of
|
||||
* the GPL, you may redistribute this Program in connection with Free/Libre
|
||||
* and Open Source Software ("FLOSS") applications as described in Alfresco's
|
||||
* FLOSS exception. You should have recieved a copy of the text describing
|
||||
* FLOSS exception. You should have received a copy of the text describing
|
||||
* the FLOSS exception, and it is also available here:
|
||||
* http://www.alfresco.com/legal/licensing"
|
||||
*/
|
||||
package org.alfresco.repo.cmis.ws;
|
||||
|
||||
import org.alfresco.repo.cmis.ws.utils.CmisObjectsUtils;
|
||||
import org.alfresco.repo.cmis.ws.utils.ExceptionUtil;
|
||||
import org.alfresco.repo.security.permissions.AccessDeniedException;
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
@@ -40,13 +40,6 @@ public class DMServicePortThrowsAdvice implements ThrowsAdvice
|
||||
{
|
||||
private static final Log LOGGER = LogFactory.getLog("org.alfresco.repo.cmis.ws");
|
||||
|
||||
private CmisObjectsUtils cmisObjectsUtils;
|
||||
|
||||
public void setCmisObjectsUtils(CmisObjectsUtils cmisObjectsUtils)
|
||||
{
|
||||
this.cmisObjectsUtils = cmisObjectsUtils;
|
||||
}
|
||||
|
||||
public void afterThrowing(AccessDeniedException e) throws CmisException
|
||||
{
|
||||
if (LOGGER.isInfoEnabled())
|
||||
@@ -54,7 +47,7 @@ public class DMServicePortThrowsAdvice implements ThrowsAdvice
|
||||
LOGGER.error(e.toString(), e);
|
||||
}
|
||||
|
||||
throw cmisObjectsUtils.createCmisException(("Access denied. Message: " + e.toString()), e);
|
||||
throw ExceptionUtil.createCmisException(("Access denied. Message: " + e.toString()), e);
|
||||
}
|
||||
|
||||
public void afterThrowing(java.lang.RuntimeException e) throws CmisException
|
||||
@@ -64,7 +57,7 @@ public class DMServicePortThrowsAdvice implements ThrowsAdvice
|
||||
LOGGER.error(e.toString(), e);
|
||||
}
|
||||
|
||||
throw cmisObjectsUtils.createCmisException(("Runtime error. Message: " + e.toString()), e);
|
||||
throw ExceptionUtil.createCmisException(("Runtime error. Message: " + e.toString()), e);
|
||||
}
|
||||
|
||||
public void afterThrowing(java.lang.Exception e) throws CmisException
|
||||
@@ -76,7 +69,7 @@ public class DMServicePortThrowsAdvice implements ThrowsAdvice
|
||||
|
||||
if (!(e instanceof CmisException))
|
||||
{
|
||||
throw cmisObjectsUtils.createCmisException(("Some error occured during last service invokation. Message: " + e.toString()), e);
|
||||
throw ExceptionUtil.createCmisException(("Some error occured during last service invokation. Message: " + e.toString()), e);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@@ -31,18 +31,12 @@ import javax.xml.ws.Holder;
|
||||
|
||||
import org.alfresco.cmis.CMISContentStreamAllowedEnum;
|
||||
import org.alfresco.cmis.CMISDictionaryModel;
|
||||
import org.alfresco.cmis.CMISServiceException;
|
||||
import org.alfresco.cmis.CMISTypeDefinition;
|
||||
import org.alfresco.model.ContentModel;
|
||||
import org.alfresco.repo.cmis.PropertyFilter;
|
||||
import org.alfresco.repo.cmis.ws.utils.AlfrescoObjectType;
|
||||
import org.alfresco.repo.security.permissions.AccessDeniedException;
|
||||
import org.alfresco.service.cmr.lock.LockService;
|
||||
import org.alfresco.service.cmr.lock.LockStatus;
|
||||
import org.alfresco.repo.cmis.ws.utils.ExceptionUtil;
|
||||
import org.alfresco.service.cmr.repository.ContentWriter;
|
||||
import org.alfresco.service.cmr.repository.NodeRef;
|
||||
import org.alfresco.service.cmr.version.Version;
|
||||
import org.alfresco.service.cmr.version.VersionHistory;
|
||||
import org.alfresco.service.cmr.version.VersionType;
|
||||
|
||||
/**
|
||||
* Port for versioning service.
|
||||
@@ -53,13 +47,6 @@ import org.alfresco.service.cmr.version.VersionType;
|
||||
@javax.jws.WebService(name = "VersioningServicePort", serviceName = "VersioningService", portName = "VersioningServicePort", targetNamespace = "http://docs.oasis-open.org/ns/cmis/ws/200908/", endpointInterface = "org.alfresco.repo.cmis.ws.VersioningServicePort")
|
||||
public class DMVersioningServicePort extends DMAbstractServicePort implements VersioningServicePort
|
||||
{
|
||||
private LockService lockService;
|
||||
|
||||
public void setLockService(LockService lockService)
|
||||
{
|
||||
this.lockService = lockService;
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverses the effect of a check-out. Removes the private working copy of the checked-out document object, allowing other documents in the version series to be checked out
|
||||
* again.
|
||||
@@ -73,31 +60,14 @@ public class DMVersioningServicePort extends DMAbstractServicePort implements Ve
|
||||
public void cancelCheckOut(String repositoryId, String objectId, Holder<CmisExtensionType> extension) throws CmisException
|
||||
{
|
||||
checkRepositoryId(repositoryId);
|
||||
NodeRef documentNodeRef = cmisObjectsUtils.getIdentifierInstance(objectId, AlfrescoObjectType.DOCUMENT_OBJECT);
|
||||
assertVersionableIsTrue(documentNodeRef);
|
||||
boolean checkedOut = propertiesUtil.getProperty(documentNodeRef, CMISDictionaryModel.PROP_IS_VERSION_SERIES_CHECKED_OUT, false);
|
||||
NodeRef workingCopyNodeRef = definitelyGetWorkingCopy(checkedOut, documentNodeRef);
|
||||
checkOutCheckInService.cancelCheckout(workingCopyNodeRef);
|
||||
}
|
||||
|
||||
private void assertVersionableIsTrue(NodeRef workingCopyNodeRef) throws CmisException
|
||||
try
|
||||
{
|
||||
if (!getTypeDefinition(workingCopyNodeRef).isVersionable())
|
||||
{
|
||||
// FIXME: uncomment this when CMIS dictionary model will be corrected
|
||||
// throw cmisObjectsUtils.createCmisException("Document that was specified is not versionable", EnumServiceException.CONSTRAINT);
|
||||
cmisService.cancelCheckOut(objectId);
|
||||
}
|
||||
}
|
||||
|
||||
private CMISTypeDefinition getTypeDefinition(NodeRef nodeRef) throws CmisException
|
||||
catch (CMISServiceException e)
|
||||
{
|
||||
String typeId = propertiesUtil.getProperty(nodeRef, CMISDictionaryModel.PROP_OBJECT_TYPE_ID, null);
|
||||
CMISTypeDefinition typeDefinition = (null != typeId) ? (cmisDictionaryService.findType(typeId)) : (null);
|
||||
if (null == typeDefinition)
|
||||
{
|
||||
throw cmisObjectsUtils.createCmisException(("Object type property is invalid"), EnumServiceException.RUNTIME);
|
||||
throw ExceptionUtil.createCmisException(e);
|
||||
}
|
||||
return typeDefinition;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -117,16 +87,14 @@ public class DMVersioningServicePort extends DMAbstractServicePort implements Ve
|
||||
List<String> policies, CmisAccessControlListType addACEs, CmisAccessControlListType removeACEs, Holder<CmisExtensionType> extension) throws CmisException
|
||||
{
|
||||
checkRepositoryId(repositoryId);
|
||||
NodeRef workingCopyNodeRef = cmisObjectsUtils.getIdentifierInstance(objectId.value, AlfrescoObjectType.DOCUMENT_OBJECT);
|
||||
assertVersionableIsTrue(workingCopyNodeRef);
|
||||
assertLatestVersion(workingCopyNodeRef, true);
|
||||
|
||||
String versionSeriesId = propertiesUtil.getProperty(workingCopyNodeRef, CMISDictionaryModel.PROP_VERSION_SERIES_ID, null);
|
||||
CMISTypeDefinition seriesObjectTypeDefinition = getTypeDefinition((NodeRef) cmisObjectsUtils.getIdentifierInstance(versionSeriesId, AlfrescoObjectType.DOCUMENT_OBJECT));
|
||||
try
|
||||
{
|
||||
NodeRef workingCopyNodeRef = cmisService.getObject(objectId.value, NodeRef.class, true, true, true);
|
||||
CMISTypeDefinition seriesObjectTypeDefinition = cmisService.getTypeDefinition(workingCopyNodeRef);
|
||||
|
||||
if ((null != contentStream) && (CMISContentStreamAllowedEnum.NOT_ALLOWED == seriesObjectTypeDefinition.getContentStreamAllowed()))
|
||||
{
|
||||
throw cmisObjectsUtils.createCmisException("Content stream is not allowed", EnumServiceException.STREAM_NOT_SUPPORTED);
|
||||
throw ExceptionUtil.createCmisException("Content stream is not allowed", EnumServiceException.STREAM_NOT_SUPPORTED);
|
||||
}
|
||||
|
||||
if (contentStream != null)
|
||||
@@ -139,25 +107,22 @@ public class DMVersioningServicePort extends DMAbstractServicePort implements Ve
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
throw cmisObjectsUtils.createCmisException("Exception while updating content stream", EnumServiceException.UPDATE_CONFLICT, e);
|
||||
throw ExceptionUtil.createCmisException("Exception while updating content stream", EnumServiceException.RUNTIME, e);
|
||||
}
|
||||
}
|
||||
|
||||
NodeRef nodeRef;
|
||||
try
|
||||
{
|
||||
nodeRef = checkOutCheckInService.checkin(workingCopyNodeRef, createVersionProperties(checkinComment, ((null == major) || major) ? (VersionType.MAJOR)
|
||||
: (VersionType.MINOR)));
|
||||
propertiesUtil.setProperties(nodeRef, properties, null);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
throw cmisObjectsUtils.createCmisException("Unable to check in Private Working Copy object that was specified", EnumServiceException.STORAGE, e);
|
||||
}
|
||||
propertiesUtil.setProperties(workingCopyNodeRef, properties, null);
|
||||
NodeRef nodeRef = cmisService.checkIn(objectId.value, checkinComment, major == null || major);
|
||||
|
||||
// TODO: applyPolicies
|
||||
applyAclCarefully(nodeRef, addACEs, removeACEs, EnumACLPropagation.PROPAGATE);
|
||||
objectId.value = propertiesUtil.getProperty(nodeRef, CMISDictionaryModel.PROP_OBJECT_ID, objectId.value);
|
||||
}
|
||||
catch (CMISServiceException e)
|
||||
{
|
||||
throw ExceptionUtil.createCmisException(e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a private working copy of the object, copies the metadata and optionally content.
|
||||
@@ -172,48 +137,18 @@ public class DMVersioningServicePort extends DMAbstractServicePort implements Ve
|
||||
public void checkOut(String repositoryId, Holder<String> objectId, Holder<CmisExtensionType> extension, Holder<Boolean> contentCopied) throws CmisException
|
||||
{
|
||||
checkRepositoryId(repositoryId);
|
||||
NodeRef documentNodeRef = cmisObjectsUtils.getIdentifierInstance(objectId.value, AlfrescoObjectType.DOCUMENT_OBJECT);
|
||||
assertVersionableIsTrue(documentNodeRef);
|
||||
assertLatestVersion(documentNodeRef, false);
|
||||
|
||||
LockStatus lockStatus = lockService.getLockStatus(documentNodeRef);
|
||||
if (lockStatus.equals(LockStatus.LOCKED) || lockStatus.equals(LockStatus.LOCK_OWNER) || nodeService.hasAspect(documentNodeRef, ContentModel.ASPECT_WORKING_COPY))
|
||||
{
|
||||
throw cmisObjectsUtils.createCmisException("Object is locked or already checked out", EnumServiceException.UPDATE_CONFLICT);
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
NodeRef pwcNodeRef = checkoutNode(documentNodeRef);
|
||||
NodeRef pwcNodeRef = cmisService.checkOut(objectId.value);
|
||||
objectId.value = propertiesUtil.getProperty(pwcNodeRef, CMISDictionaryModel.PROP_OBJECT_ID, objectId.value);
|
||||
contentCopied.value = null != fileFolderService.getReader(pwcNodeRef);
|
||||
}
|
||||
catch (Exception e)
|
||||
catch (CMISServiceException e)
|
||||
{
|
||||
throw cmisObjectsUtils.createCmisException(("Unable to execute Check Out services. Cause message: " + e.toString()), EnumServiceException.STORAGE);
|
||||
throw ExceptionUtil.createCmisException(e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Deletes all document versions in the specified version series.
|
||||
*
|
||||
* @param repositoryId repository Id
|
||||
* @param versionSeriesId version series Id
|
||||
* @throws CmisException (with following {@link EnumServiceException} : INVALID_ARGUMENT, OBJECT_NOT_FOUND, NOT_SUPPORTED, PERMISSION_DENIED, RUNTIME)
|
||||
*/
|
||||
public void deleteAllVersions(String repositoryId, String versionSeriesId) throws CmisException
|
||||
{
|
||||
checkRepositoryId(repositoryId);
|
||||
NodeRef documentNodeRef = cmisObjectsUtils.getIdentifierInstance(versionSeriesId, AlfrescoObjectType.DOCUMENT_OBJECT);
|
||||
NodeRef workingCopyRef = (cmisObjectsUtils.isWorkingCopy(documentNodeRef)) ? (documentNodeRef) : (checkOutCheckInService.getWorkingCopy(documentNodeRef));
|
||||
if ((null != workingCopyRef) && cmisObjectsUtils.isWorkingCopy(workingCopyRef))
|
||||
{
|
||||
documentNodeRef = checkOutCheckInService.cancelCheckout(workingCopyRef);
|
||||
}
|
||||
|
||||
versionService.deleteVersionHistory(documentNodeRef);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the list of all document versions for the specified version series.
|
||||
*
|
||||
@@ -225,38 +160,23 @@ public class DMVersioningServicePort extends DMAbstractServicePort implements Ve
|
||||
throws CmisException
|
||||
{
|
||||
checkRepositoryId(repositoryId);
|
||||
NodeRef documentNodeRef = cmisObjectsUtils.getIdentifierInstance(objectId, AlfrescoObjectType.DOCUMENT_OBJECT);
|
||||
documentNodeRef = cmisObjectsUtils.getLatestNode(documentNodeRef, false);
|
||||
PropertyFilter propertyFilter = createPropertyFilter(filter);
|
||||
List<CmisObjectType> objects = new LinkedList<CmisObjectType>();
|
||||
includeAllowableActions = (null == includeAllowableActions) ? (false) : (includeAllowableActions);
|
||||
|
||||
if (includeAllowableActions == null)
|
||||
{
|
||||
includeAllowableActions = false;
|
||||
}
|
||||
try
|
||||
{
|
||||
NodeRef workingCopyNodeReference = cmisObjectsUtils.isWorkingCopy(documentNodeRef) ? documentNodeRef : checkOutCheckInService.getWorkingCopy(documentNodeRef);
|
||||
if (null != workingCopyNodeReference)
|
||||
for (NodeRef nodeRef : cmisService.getAllVersions(objectId))
|
||||
{
|
||||
objects.add(createCmisObject(workingCopyNodeReference, propertyFilter, includeAllowableActions, null));
|
||||
objects.add(createCmisObject(nodeRef, propertyFilter, includeAllowableActions, null));
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
catch (CMISServiceException e)
|
||||
{
|
||||
if (!(e instanceof AccessDeniedException))
|
||||
{
|
||||
throw cmisObjectsUtils.createCmisException(e.toString(), EnumServiceException.RUNTIME);
|
||||
throw ExceptionUtil.createCmisException(e);
|
||||
}
|
||||
}
|
||||
|
||||
VersionHistory versionHistory = versionService.getVersionHistory(documentNodeRef);
|
||||
if (null != versionHistory)
|
||||
{
|
||||
for (Version version = versionService.getCurrentVersion(documentNodeRef); null != version; version = versionHistory.getPredecessor(version))
|
||||
{
|
||||
objects.add(createCmisObject(version.getFrozenStateNodeRef(), propertyFilter, includeAllowableActions, null));
|
||||
}
|
||||
}
|
||||
// TODO: includeRelationships
|
||||
|
||||
return objects;
|
||||
}
|
||||
|
||||
@@ -271,43 +191,17 @@ public class DMVersioningServicePort extends DMAbstractServicePort implements Ve
|
||||
public CmisPropertiesType getPropertiesOfLatestVersion(String repositoryId, String objectId, Boolean major, String filter, CmisExtensionType extension) throws CmisException
|
||||
{
|
||||
checkRepositoryId(repositoryId);
|
||||
NodeRef documentNodeRef = cmisObjectsUtils.getIdentifierInstance(objectId, AlfrescoObjectType.DOCUMENT_OBJECT);
|
||||
NodeRef latestVersionNodeRef;
|
||||
try
|
||||
{
|
||||
latestVersionNodeRef = cmisService.getLatestVersion(objectId, major != null && major);
|
||||
}
|
||||
catch (CMISServiceException e)
|
||||
{
|
||||
throw ExceptionUtil.createCmisException(e);
|
||||
}
|
||||
PropertyFilter propertyFilter = createPropertyFilter(filter);
|
||||
major = (null == major) ? (false) : (major);
|
||||
NodeRef latestVersionNodeRef = getAndCheckLatestNodeRef(documentNodeRef, major);
|
||||
return propertiesUtil.getPropertiesType(latestVersionNodeRef.toString(), propertyFilter);
|
||||
}
|
||||
|
||||
private void assertLatestVersion(NodeRef nodeRef, boolean mustBePwc) throws CmisException
|
||||
{
|
||||
if (mustBePwc)
|
||||
{
|
||||
boolean checkedOut = propertiesUtil.getProperty(nodeRef, CMISDictionaryModel.PROP_IS_VERSION_SERIES_CHECKED_OUT, false);
|
||||
definitelyGetWorkingCopy(checkedOut, nodeRef);
|
||||
}
|
||||
else
|
||||
{
|
||||
Boolean latestVersion = propertiesUtil.getProperty(nodeRef, CMISDictionaryModel.PROP_IS_LATEST_VERSION, false);
|
||||
if (!latestVersion && !cmisObjectsUtils.isWorkingCopy(nodeRef))
|
||||
{
|
||||
throw cmisObjectsUtils.createCmisException("Operation can be executed only on the latest document version", EnumServiceException.VERSIONING);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private NodeRef definitelyGetWorkingCopy(boolean checkedOut, NodeRef nodeRef) throws CmisException
|
||||
{
|
||||
NodeRef workingCopy = null;
|
||||
String workingCopyId = propertiesUtil.getProperty(nodeRef, CMISDictionaryModel.PROP_VERSION_SERIES_CHECKED_OUT_ID, null);
|
||||
if (checkedOut && (null != workingCopyId) && !"".equals(workingCopyId))
|
||||
{
|
||||
workingCopy = cmisObjectsUtils.getIdentifierInstance(workingCopyId, AlfrescoObjectType.DOCUMENT_OBJECT);
|
||||
}
|
||||
if ((null == workingCopy) || !cmisObjectsUtils.isWorkingCopy(workingCopy))
|
||||
{
|
||||
throw cmisObjectsUtils.createCmisException("Object isn't checked out", EnumServiceException.UPDATE_CONFLICT);
|
||||
}
|
||||
return workingCopy;
|
||||
return propertiesUtil.getProperties(latestVersionNodeRef, propertyFilter);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -318,29 +212,23 @@ public class DMVersioningServicePort extends DMAbstractServicePort implements Ve
|
||||
EnumIncludeRelationships includeRelationships, String renditionFilter, Boolean includePolicyIds, Boolean includeACL, CmisExtensionType extension) throws CmisException
|
||||
{
|
||||
checkRepositoryId(repositoryId);
|
||||
NodeRef documentNodeRef = cmisObjectsUtils.getIdentifierInstance(objectId, AlfrescoObjectType.DOCUMENT_OBJECT);
|
||||
PropertyFilter propertyFilter = createPropertyFilter(filter);
|
||||
includeAllowableActions = (null == includeAllowableActions) ? (false) : (includeAllowableActions);
|
||||
major = (null == major) ? (false) : (major);
|
||||
NodeRef latestVersionNodeRef = getAndCheckLatestNodeRef(documentNodeRef, major);
|
||||
try
|
||||
{
|
||||
NodeRef latestVersionNodeRef = cmisService.getLatestVersion(objectId, major != null && major);
|
||||
// TODO: includeRelationships
|
||||
// TODO: includePolicyIds
|
||||
CmisObjectType result = createCmisObject(latestVersionNodeRef.toString(), propertyFilter, includeAllowableActions, renditionFilter);
|
||||
PropertyFilter propertyFilter = createPropertyFilter(filter);
|
||||
CmisObjectType result = createCmisObject(latestVersionNodeRef, propertyFilter, includeAllowableActions, renditionFilter);
|
||||
if (includeACL)
|
||||
{
|
||||
appendWithAce(documentNodeRef, result);
|
||||
}
|
||||
return result;
|
||||
appendWithAce(cmisService.getVersionSeries(objectId, NodeRef.class, false), result);
|
||||
}
|
||||
|
||||
private NodeRef getAndCheckLatestNodeRef(NodeRef documentNodeRef, Boolean major) throws CmisException
|
||||
return result;
|
||||
}
|
||||
catch (CMISServiceException e)
|
||||
{
|
||||
NodeRef latestVersionNodeRef = cmisObjectsUtils.getLatestNode(documentNodeRef, major);
|
||||
Boolean majorVersionProperty = propertiesUtil.getProperty(latestVersionNodeRef, CMISDictionaryModel.PROP_IS_MAJOR_VERSION, false);
|
||||
if (major && !majorVersionProperty)
|
||||
{
|
||||
throw cmisObjectsUtils.createCmisException("Object that was specified has no latest major version", EnumServiceException.OBJECT_NOT_FOUND);
|
||||
}
|
||||
return latestVersionNodeRef;
|
||||
throw ExceptionUtil.createCmisException(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -1,73 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2005-2008 Alfresco Software Limited.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
|
||||
* As a special exception to the terms and conditions of version 2.0 of
|
||||
* the GPL, you may redistribute this Program in connection with Free/Libre
|
||||
* and Open Source Software ("FLOSS") applications as described in Alfresco's
|
||||
* FLOSS exception. You should have recieved a copy of the text describing
|
||||
* the FLOSS exception, and it is also available here:
|
||||
* http://www.alfresco.com/legal/licensing"
|
||||
*/
|
||||
package org.alfresco.repo.cmis.ws.utils;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import org.alfresco.cmis.mapping.CMISMapping;
|
||||
import org.alfresco.model.ContentModel;
|
||||
|
||||
/**
|
||||
* @author Dmitry Velichkevich
|
||||
*/
|
||||
public enum AlfrescoObjectType
|
||||
{
|
||||
DOCUMENT_OBJECT(ContentModel.TYPE_CONTENT.toString()),
|
||||
FOLDER_OBJECT(ContentModel.TYPE_FOLDER.toString()),
|
||||
DOCUMENT_OR_FOLDER_OBJECT("DOCUMENT_OR_FOLDER"),
|
||||
RELATIONSHIP_OBJECT(CMISMapping.RELATIONSHIP_QNAME.toString()),
|
||||
ANY_OBJECT("ANY");
|
||||
|
||||
String value;
|
||||
|
||||
final static Map<String, AlfrescoObjectType> VALUES;
|
||||
static
|
||||
{
|
||||
VALUES = new HashMap<String, AlfrescoObjectType>();
|
||||
VALUES.put(DOCUMENT_OBJECT.getValue(), DOCUMENT_OBJECT);
|
||||
VALUES.put(FOLDER_OBJECT.getValue(), FOLDER_OBJECT);
|
||||
}
|
||||
|
||||
AlfrescoObjectType(String value)
|
||||
{
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
public String getValue()
|
||||
{
|
||||
return this.value;
|
||||
}
|
||||
|
||||
public static AlfrescoObjectType fromValue(String valueName)
|
||||
{
|
||||
AlfrescoObjectType result = VALUES.get(valueName);
|
||||
if (result == null)
|
||||
{
|
||||
result = ANY_OBJECT;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
}
|
@@ -1,364 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2005-2009 Alfresco Software Limited.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
|
||||
* As a special exception to the terms and conditions of version 2.0 of
|
||||
* the GPL, you may redistribute this Program in connection with Free/Libre
|
||||
* and Open Source Software ("FLOSS") applications as described in Alfresco's
|
||||
* FLOSS exception. You should have recieved a copy of the text describing
|
||||
* the FLOSS exception, and it is also available here:
|
||||
* http://www.alfresco.com/legal/licensing"
|
||||
*/
|
||||
package org.alfresco.repo.cmis.ws.utils;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.Date;
|
||||
import java.util.HashMap;
|
||||
import java.util.Iterator;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import org.alfresco.model.ContentModel;
|
||||
import org.alfresco.repo.cmis.ws.EnumUnfileObject;
|
||||
import org.alfresco.repo.model.filefolder.FileInfoImpl;
|
||||
import org.alfresco.service.cmr.coci.CheckOutCheckInService;
|
||||
import org.alfresco.service.cmr.model.FileFolderService;
|
||||
import org.alfresco.service.cmr.model.FileInfo;
|
||||
import org.alfresco.service.cmr.repository.ChildAssociationRef;
|
||||
import org.alfresco.service.cmr.repository.ContentData;
|
||||
import org.alfresco.service.cmr.repository.NodeRef;
|
||||
import org.alfresco.service.cmr.repository.NodeService;
|
||||
import org.alfresco.service.cmr.version.VersionService;
|
||||
import org.alfresco.service.namespace.QName;
|
||||
|
||||
/**
|
||||
* This class enumerates Documents and Folders hierarchy that begins from specified folder. Iterator returns Document or Empty Folder Objects those may be removed or deleted from
|
||||
* repository according to {@link EnumUnfileObject} <b>unfileObject</b> and {@link Boolean} <b>continueOnFailure</b> parameters. After hierarchy enumerating completion iterator may
|
||||
* introduce Object Id(s) {@link List} those were not deleted due to {@link Exception}(s)
|
||||
*
|
||||
* @author Dmitry Velichkevich
|
||||
*/
|
||||
public class CmisObjectIterator implements Iterator<FileInfo>
|
||||
{
|
||||
private EnumUnfileObject unfillingStrategy;
|
||||
private boolean continueOnFailure;
|
||||
|
||||
private NodeService nodeService;
|
||||
private FileFolderService fileFolderService;
|
||||
private VersionService versionService;
|
||||
private CheckOutCheckInService checkOutCheckInService;
|
||||
private CmisObjectsUtils objectsUtils;
|
||||
|
||||
private Map<FileInfo, List<FileInfo>> hierarchy = new HashMap<FileInfo, List<FileInfo>>();
|
||||
private LinkedList<FileInfo> objects = new LinkedList<FileInfo>();
|
||||
private List<String> failToDelete = new LinkedList<String>();
|
||||
|
||||
private FileInfo next;
|
||||
private boolean lastDeleted;
|
||||
private boolean nextFound;
|
||||
private boolean deleteAllVersions;
|
||||
|
||||
/**
|
||||
* Mandatory constructor
|
||||
*
|
||||
* @param rootObject - {@link NodeRef} instance that represents Root folder for hierarchy
|
||||
* @param unfillingStrategy - {@link EnumUnfileObject} value that determines File-able Objects deletion or removing strategy
|
||||
* @param continueOnFailure - {@link Boolean} value that determines whether it is necessary continue deletion after some {@link Exception} occurred
|
||||
* @param nodeService - A {@link NodeService} implementation instance for manipulating with Object Properties
|
||||
* @param fileFolderService - A {@link FileFolderService} implementation instance for manipulating with Objects
|
||||
* @param objectsUtils - {@link CmisObjectsUtils} service instance for simplifying manipulations with Objects and Object Properties
|
||||
*/
|
||||
public CmisObjectIterator(NodeRef rootObject, EnumUnfileObject unfillingStrategy, boolean continueOnFailure, boolean deleteAllVersions, NodeService nodeService,
|
||||
FileFolderService fileFolderService, VersionService versionService, CheckOutCheckInService checkOutCheckInService, CmisObjectsUtils objectsUtils)
|
||||
{
|
||||
this.unfillingStrategy = unfillingStrategy;
|
||||
this.deleteAllVersions = deleteAllVersions;
|
||||
this.continueOnFailure = continueOnFailure;
|
||||
this.nodeService = nodeService;
|
||||
this.fileFolderService = fileFolderService;
|
||||
this.versionService = versionService;
|
||||
this.checkOutCheckInService = checkOutCheckInService;
|
||||
this.objectsUtils = objectsUtils;
|
||||
objects.add(new ParentedFileInfo(fileFolderService.getFileInfo(rootObject), null));
|
||||
}
|
||||
|
||||
/**
|
||||
* This method performs searching for next Object (see {@link CmisObjectIterator})
|
||||
*/
|
||||
public boolean hasNext()
|
||||
{
|
||||
if (nextFound)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
if (objects.isEmpty() || (!failToDelete.isEmpty() && !continueOnFailure))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
for (next = objects.removeFirst(); processFolder() && !objects.isEmpty(); next = objects.removeFirst())
|
||||
{
|
||||
}
|
||||
nextFound = (null != next) && (!next.isFolder() || (null == receiveChildren(next.getNodeRef())));
|
||||
return nextFound;
|
||||
}
|
||||
|
||||
private boolean processFolder()
|
||||
{
|
||||
if (next.isFolder())
|
||||
{
|
||||
List<ChildAssociationRef> children = receiveChildren(next.getNodeRef());
|
||||
if (null != children)
|
||||
{
|
||||
objects.addFirst(next);
|
||||
for (ChildAssociationRef child : children)
|
||||
{
|
||||
FileInfo info = fileFolderService.getFileInfo(child.getChildRef());
|
||||
ParentedFileInfo childInfo = new ParentedFileInfo(info, next);
|
||||
objects.addFirst(childInfo);
|
||||
addChildToParent(next, childInfo);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private void addChildToParent(FileInfo parent, FileInfo child)
|
||||
{
|
||||
if (null != parent)
|
||||
{
|
||||
List<FileInfo> children;
|
||||
if (hierarchy.containsKey(parent))
|
||||
{
|
||||
children = hierarchy.get(parent);
|
||||
}
|
||||
else
|
||||
{
|
||||
children = new LinkedList<FileInfo>();
|
||||
hierarchy.put(parent, children);
|
||||
}
|
||||
children.add(child);
|
||||
}
|
||||
}
|
||||
|
||||
private List<ChildAssociationRef> receiveChildren(NodeRef folderRef)
|
||||
{
|
||||
if (null != folderRef)
|
||||
{
|
||||
List<ChildAssociationRef> result = nodeService.getChildAssocs(folderRef);
|
||||
if ((null != result) && !result.isEmpty())
|
||||
{
|
||||
return result;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* This method returns currently enumerated Object and changes flag to enumerate next Object
|
||||
*
|
||||
* @see CmisObjectIterator
|
||||
* @see CmisObjectIterator#hasNext()
|
||||
* @see CmisObjectIterator#remove()
|
||||
*/
|
||||
public FileInfo next()
|
||||
{
|
||||
nextFound = false;
|
||||
return next;
|
||||
}
|
||||
|
||||
/**
|
||||
* This method removes currently enumerated Object (see {@link CmisObjectIterator}). If Object deletion or removing fails due to {@link Exception} then according to
|
||||
* <b>continueOnFailure</b> parameter current Object Id and (if <b>continueOnFailure</b>="<b>true</b>") current Object Parent(s)' Id(s) will be stored in <b>failedToDelete</b>
|
||||
* {@link List}. Not deleted Object and its Parent(s) never will be enumerated again
|
||||
*
|
||||
* @see CmisObjectIterator
|
||||
* @see CmisObjectIterator#hasNext()
|
||||
* @see CmisObjectIterator#next()
|
||||
*/
|
||||
public void remove()
|
||||
{
|
||||
lastDeleted = false;
|
||||
NodeRef parentRef = null;
|
||||
ParentedFileInfo info = null;
|
||||
if (null != next)
|
||||
{
|
||||
info = (ParentedFileInfo) next;
|
||||
EnumUnfileObject howToDelete = null;
|
||||
parentRef = (null != info.getExactParent()) ? (info.getExactParent().getNodeRef()) : (null);
|
||||
if ((null != parentRef) && ((EnumUnfileObject.DELETESINGLEFILED == unfillingStrategy) || !objectsUtils.isPrimaryObjectParent(parentRef, info.getNodeRef())))
|
||||
{
|
||||
howToDelete = EnumUnfileObject.DELETESINGLEFILED;
|
||||
}
|
||||
else
|
||||
{
|
||||
howToDelete = EnumUnfileObject.DELETE;
|
||||
}
|
||||
if (EnumUnfileObject.DELETESINGLEFILED == howToDelete)
|
||||
{
|
||||
lastDeleted = objectsUtils.removeObject(info.getNodeRef(), parentRef);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (deleteAllVersions)
|
||||
{
|
||||
NodeRef workingCopyRef = (objectsUtils.isWorkingCopy(info.getNodeRef())) ? (info.getNodeRef()) : (checkOutCheckInService.getWorkingCopy(info.getNodeRef()));
|
||||
if (null == workingCopyRef)
|
||||
{
|
||||
versionService.deleteVersionHistory(info.getNodeRef());
|
||||
}
|
||||
}
|
||||
lastDeleted = (objectsUtils.deleteObject(info.getNodeRef()));
|
||||
}
|
||||
}
|
||||
if (!lastDeleted && (null != info))
|
||||
{
|
||||
failToDelete.add(generateId(info));
|
||||
if ((null == info.getExactParent()) && info.isFolder())
|
||||
{
|
||||
removeFolderFromCollections(info);
|
||||
}
|
||||
if (continueOnFailure)
|
||||
{
|
||||
for (; null != info.getExactParent(); info = (ParentedFileInfo) info.getExactParent())
|
||||
{
|
||||
failToDelete.add(generateId(info.getExactParent()));
|
||||
removeFolderFromCollections(info.getExactParent());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void removeFolderFromCollections(FileInfo object)
|
||||
{
|
||||
if (hierarchy.containsKey(object))
|
||||
{
|
||||
hierarchy.remove(object);
|
||||
objects.remove(object);
|
||||
}
|
||||
}
|
||||
|
||||
private String generateId(FileInfo object)
|
||||
{
|
||||
StringBuilder generator = new StringBuilder(object.getNodeRef().toString());
|
||||
Map<QName, Serializable> properties = object.getProperties();
|
||||
String versionLabel = (null != properties) ? ((String) properties.get(ContentModel.PROP_VERSION_LABEL)) : (null);
|
||||
if (null != versionLabel)
|
||||
{
|
||||
generator.append(CmisObjectsUtils.NODE_REFERENCE_ID_DELIMITER).append(versionLabel);
|
||||
}
|
||||
return generator.toString();
|
||||
}
|
||||
|
||||
public boolean wasLastRemoved()
|
||||
{
|
||||
return lastDeleted;
|
||||
}
|
||||
|
||||
public List<String> getFailToDelete()
|
||||
{
|
||||
return failToDelete;
|
||||
}
|
||||
|
||||
/**
|
||||
* This class is {@link org.alfresco.jlan.server.filesys.FileInfo} implementation that uses {@link FileInfoImpl} instances to delegate core functionality. The main target of
|
||||
* this class is extended standard {@link FileInfo} Objects with Parent Object
|
||||
*
|
||||
* @author Dmitry Velichkevich
|
||||
*/
|
||||
private class ParentedFileInfo implements FileInfo, Serializable
|
||||
{
|
||||
private static final long serialVersionUID = -3024276223816623074L;
|
||||
|
||||
private FileInfo delegator;
|
||||
private FileInfo exactParent;
|
||||
|
||||
public ParentedFileInfo(FileInfo delegator, FileInfo exactParent)
|
||||
{
|
||||
this.delegator = delegator;
|
||||
this.exactParent = exactParent;
|
||||
}
|
||||
|
||||
public ContentData getContentData()
|
||||
{
|
||||
return delegator.getContentData();
|
||||
}
|
||||
|
||||
public Date getCreatedDate()
|
||||
{
|
||||
return delegator.getCreatedDate();
|
||||
}
|
||||
|
||||
public NodeRef getLinkNodeRef()
|
||||
{
|
||||
return delegator.getLinkNodeRef();
|
||||
}
|
||||
|
||||
public Date getModifiedDate()
|
||||
{
|
||||
return delegator.getModifiedDate();
|
||||
}
|
||||
|
||||
public String getName()
|
||||
{
|
||||
return delegator.getName();
|
||||
}
|
||||
|
||||
public NodeRef getNodeRef()
|
||||
{
|
||||
return delegator.getNodeRef();
|
||||
}
|
||||
|
||||
public Map<QName, Serializable> getProperties()
|
||||
{
|
||||
return delegator.getProperties();
|
||||
}
|
||||
|
||||
public boolean isFolder()
|
||||
{
|
||||
return delegator.isFolder();
|
||||
}
|
||||
|
||||
public boolean isLink()
|
||||
{
|
||||
return delegator.isLink();
|
||||
}
|
||||
|
||||
public FileInfo getExactParent()
|
||||
{
|
||||
return exactParent;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj)
|
||||
{
|
||||
return delegator.equals(obj);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode()
|
||||
{
|
||||
return delegator.hashCode();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString()
|
||||
{
|
||||
return delegator.toString();
|
||||
}
|
||||
}
|
||||
}
|
@@ -1,566 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2005-2008 Alfresco Software Limited.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
|
||||
* As a special exception to the terms and conditions of version 2.0 of
|
||||
* the GPL, you may redistribute this Program in connection with Free/Libre
|
||||
* and Open Source Software ("FLOSS") applications as described in Alfresco's
|
||||
* FLOSS exception. You should have recieved a copy of the text describing
|
||||
* the FLOSS exception, and it is also available here:
|
||||
* http://www.alfresco.com/legal/licensing"
|
||||
*/
|
||||
package org.alfresco.repo.cmis.ws.utils;
|
||||
|
||||
import java.math.BigInteger;
|
||||
import java.util.Collection;
|
||||
import java.util.HashMap;
|
||||
import java.util.Iterator;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import org.alfresco.cmis.CMISDictionaryService;
|
||||
import org.alfresco.cmis.CMISQueryException;
|
||||
import org.alfresco.cmis.CMISScope;
|
||||
import org.alfresco.cmis.CMISTypeDefinition;
|
||||
import org.alfresco.model.ContentModel;
|
||||
import org.alfresco.repo.cmis.ws.CmisException;
|
||||
import org.alfresco.repo.cmis.ws.CmisFaultType;
|
||||
import org.alfresco.repo.cmis.ws.EnumBaseObjectTypeIds;
|
||||
import org.alfresco.repo.cmis.ws.EnumRelationshipDirection;
|
||||
import org.alfresco.repo.cmis.ws.EnumServiceException;
|
||||
import org.alfresco.repo.cmis.ws.EnumUnfileObject;
|
||||
import org.alfresco.repo.security.authentication.AuthenticationUtil;
|
||||
import org.alfresco.repo.security.permissions.AccessDeniedException;
|
||||
import org.alfresco.service.cmr.coci.CheckOutCheckInService;
|
||||
import org.alfresco.service.cmr.lock.LockService;
|
||||
import org.alfresco.service.cmr.lock.LockStatus;
|
||||
import org.alfresco.service.cmr.model.FileFolderService;
|
||||
import org.alfresco.service.cmr.repository.AssociationRef;
|
||||
import org.alfresco.service.cmr.repository.ChildAssociationRef;
|
||||
import org.alfresco.service.cmr.repository.ContentIOException;
|
||||
import org.alfresco.service.cmr.repository.InvalidNodeRefException;
|
||||
import org.alfresco.service.cmr.repository.NodeRef;
|
||||
import org.alfresco.service.cmr.repository.NodeService;
|
||||
import org.alfresco.service.cmr.security.AuthorityService;
|
||||
import org.alfresco.service.cmr.version.Version;
|
||||
import org.alfresco.service.cmr.version.VersionHistory;
|
||||
import org.alfresco.service.cmr.version.VersionService;
|
||||
import org.alfresco.service.cmr.version.VersionType;
|
||||
import org.alfresco.service.namespace.NamespaceService;
|
||||
import org.alfresco.service.namespace.QName;
|
||||
import org.alfresco.service.namespace.QNamePattern;
|
||||
import org.springframework.extensions.surf.util.Pair;
|
||||
|
||||
/**
|
||||
* @author Dmitry Velichkevich
|
||||
*/
|
||||
public class CmisObjectsUtils
|
||||
{
|
||||
public static final String NODE_REFERENCE_ID_DELIMITER = ";";
|
||||
|
||||
private static final Pattern VERSION_LABEL_MATCHING_COMPILED_PATTERN = Pattern.compile("([\\p{Graph}])+([\\p{Digit}]*)\\.([\\p{Digit}]*)$");
|
||||
|
||||
private static final String INVALID_OBJECT_IDENTIFIER_MESSAGE = "Invalid Object Identifier was specified: Identifier is incorrect or Object with the specified Identifier does not exist";
|
||||
|
||||
private static final List<QName> DOCUMENT_AND_FOLDER_TYPES;
|
||||
static
|
||||
{
|
||||
DOCUMENT_AND_FOLDER_TYPES = new LinkedList<QName>();
|
||||
DOCUMENT_AND_FOLDER_TYPES.add(ContentModel.TYPE_CONTENT);
|
||||
DOCUMENT_AND_FOLDER_TYPES.add(ContentModel.TYPE_FOLDER);
|
||||
}
|
||||
|
||||
private static final Map<String, EnumServiceException> CLASS_TO_ENUM_EXCEPTION_MAPPING;
|
||||
static
|
||||
{
|
||||
CLASS_TO_ENUM_EXCEPTION_MAPPING = new HashMap<String, EnumServiceException>();
|
||||
CLASS_TO_ENUM_EXCEPTION_MAPPING.put(AccessDeniedException.class.getName(), EnumServiceException.PERMISSION_DENIED);
|
||||
CLASS_TO_ENUM_EXCEPTION_MAPPING.put(java.lang.RuntimeException.class.getName(), EnumServiceException.RUNTIME);
|
||||
CLASS_TO_ENUM_EXCEPTION_MAPPING.put(UnsupportedOperationException.class.getName(), EnumServiceException.NOT_SUPPORTED);
|
||||
CLASS_TO_ENUM_EXCEPTION_MAPPING.put(InvalidNodeRefException.class.getName(), EnumServiceException.INVALID_ARGUMENT);
|
||||
CLASS_TO_ENUM_EXCEPTION_MAPPING.put(ContentIOException.class.getName(), EnumServiceException.NOT_SUPPORTED);
|
||||
CLASS_TO_ENUM_EXCEPTION_MAPPING.put(CMISQueryException.class.getName(), EnumServiceException.INVALID_ARGUMENT);
|
||||
// TODO: insert CLASS_TO_ENUM_EXCEPTION_MAPPING.put(<Concreate_Exception_Type>.class.getName(), EnumServiceException.<Appropriate_Enum_value>);
|
||||
}
|
||||
|
||||
private CheckOutCheckInService checkOutCheckInService;
|
||||
private CMISDictionaryService cmisDictionaryService;
|
||||
private FileFolderService fileFolderService;
|
||||
private AuthorityService authorityService;
|
||||
private VersionService versionService;
|
||||
private NodeService nodeService;
|
||||
private LockService lockService;
|
||||
|
||||
private Throwable lastException;
|
||||
|
||||
public void setCmisDictionaryService(CMISDictionaryService cmisDictionaryService)
|
||||
{
|
||||
this.cmisDictionaryService = cmisDictionaryService;
|
||||
}
|
||||
|
||||
public void setNodeService(NodeService nodeService)
|
||||
{
|
||||
this.nodeService = nodeService;
|
||||
}
|
||||
|
||||
public void setFileFolderService(FileFolderService fileFolderService)
|
||||
{
|
||||
this.fileFolderService = fileFolderService;
|
||||
}
|
||||
|
||||
public void setLockService(LockService lockService)
|
||||
{
|
||||
this.lockService = lockService;
|
||||
}
|
||||
|
||||
public void setCheckOutCheckInService(CheckOutCheckInService checkOutCheckInService)
|
||||
{
|
||||
this.checkOutCheckInService = checkOutCheckInService;
|
||||
}
|
||||
|
||||
public void setAuthorityService(AuthorityService authorityService)
|
||||
{
|
||||
this.authorityService = authorityService;
|
||||
}
|
||||
|
||||
public void setVersionService(VersionService versionService)
|
||||
{
|
||||
this.versionService = versionService;
|
||||
}
|
||||
|
||||
public CmisException createCmisException(String message, EnumServiceException exceptionType)
|
||||
{
|
||||
return createCmisException(message, exceptionType, null, 0);
|
||||
}
|
||||
|
||||
public CmisException createCmisException(String message, Throwable cause)
|
||||
{
|
||||
EnumServiceException exceptionType = null;
|
||||
|
||||
if (CLASS_TO_ENUM_EXCEPTION_MAPPING.containsKey(cause.getClass().getName()))
|
||||
{
|
||||
exceptionType = CLASS_TO_ENUM_EXCEPTION_MAPPING.get(cause.getClass().getName());
|
||||
}
|
||||
|
||||
exceptionType = (exceptionType == null) ? (EnumServiceException.RUNTIME) : (exceptionType);
|
||||
|
||||
return createCmisException(message, exceptionType, cause, 0);
|
||||
}
|
||||
|
||||
public CmisException createCmisException(String message, EnumServiceException exceptionType, Throwable cause)
|
||||
{
|
||||
return createCmisException(message, exceptionType, cause, 0);
|
||||
}
|
||||
|
||||
public CmisException createCmisException(String message, EnumServiceException exceptionType, Throwable cause, int errorCode)
|
||||
{
|
||||
CmisFaultType fault = new CmisFaultType();
|
||||
fault.setMessage(message);
|
||||
fault.setType(exceptionType);
|
||||
fault.setCode(BigInteger.valueOf(errorCode));
|
||||
|
||||
return new CmisException(message, fault, cause);
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public <IdentifierType> IdentifierType getIdentifierInstance(String identifier, AlfrescoObjectType expectedType) throws CmisException
|
||||
{
|
||||
if (!(identifier instanceof String))
|
||||
{
|
||||
throw createCmisException("Invalid Object Identifier was specified", EnumServiceException.INVALID_ARGUMENT);
|
||||
}
|
||||
|
||||
IdentifierType result;
|
||||
AlfrescoObjectType actualObjectType;
|
||||
|
||||
if (isRelationship(identifier))
|
||||
{
|
||||
result = (IdentifierType) safeGetAssociationRef(identifier);
|
||||
actualObjectType = AlfrescoObjectType.RELATIONSHIP_OBJECT;
|
||||
}
|
||||
else
|
||||
{
|
||||
NodeRef nodeReference = safeGetNodeRef(identifier);
|
||||
result = (IdentifierType) nodeReference;
|
||||
actualObjectType = determineActualObjectType(expectedType, this.nodeService.getType(nodeReference));
|
||||
}
|
||||
|
||||
if ((AlfrescoObjectType.ANY_OBJECT == expectedType) || (actualObjectType == expectedType))
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
||||
throw createCmisException(("Unexpected object type of the specified Object with \"" + identifier + "\" identifier"), EnumServiceException.INVALID_ARGUMENT);
|
||||
}
|
||||
|
||||
public List<String> deleteFolder(NodeRef folderNodeReference, boolean continueOnFailure, EnumUnfileObject unfillingStrategy, boolean deleteAllVersions) throws CmisException
|
||||
{
|
||||
CmisObjectIterator iterator = new CmisObjectIterator(folderNodeReference, unfillingStrategy, continueOnFailure, deleteAllVersions, nodeService, fileFolderService,
|
||||
versionService, checkOutCheckInService, this);
|
||||
if (iterator.hasNext())
|
||||
{
|
||||
for (; iterator.hasNext(); iterator.next())
|
||||
{
|
||||
iterator.remove();
|
||||
}
|
||||
}
|
||||
return iterator.getFailToDelete();
|
||||
}
|
||||
|
||||
public boolean deleteObject(NodeRef objectNodeReference)
|
||||
{
|
||||
if (null == objectNodeReference)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (versionService.getVersionStoreReference().getIdentifier().equals(objectNodeReference.getStoreRef().getIdentifier()))
|
||||
{
|
||||
String versionLabel = (String) nodeService.getProperty(objectNodeReference, ContentModel.PROP_VERSION_LABEL);
|
||||
|
||||
if ((null != versionLabel) && !versionLabel.equals(""))
|
||||
{
|
||||
Version currentVersion = versionService.getCurrentVersion(objectNodeReference);
|
||||
|
||||
if ((null != currentVersion) && nodeService.exists(currentVersion.getVersionedNodeRef()))
|
||||
{
|
||||
versionService.deleteVersion(currentVersion.getVersionedNodeRef(), currentVersion);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
return canLock(objectNodeReference) && performNodeDeletion(objectNodeReference);
|
||||
}
|
||||
|
||||
public boolean removeObject(NodeRef objectNodeReference, NodeRef folderNodeReference)
|
||||
{
|
||||
if (isChildOfThisFolder(objectNodeReference, folderNodeReference))
|
||||
{
|
||||
try
|
||||
{
|
||||
this.nodeService.removeChild(folderNodeReference, objectNodeReference);
|
||||
}
|
||||
catch (Throwable e)
|
||||
{
|
||||
lastException = e;
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean addObjectToFolder(NodeRef objectNodeRef, NodeRef parentFolderNodeRef)
|
||||
{
|
||||
try
|
||||
{
|
||||
QName name = QName.createQName(NamespaceService.CONTENT_MODEL_1_0_URI, QName.createValidLocalName((String) nodeService.getProperty(objectNodeRef,
|
||||
ContentModel.PROP_NAME)));
|
||||
nodeService.addChild(parentFolderNodeRef, objectNodeRef, ContentModel.ASSOC_CONTAINS, name);
|
||||
return true;
|
||||
}
|
||||
catch (Throwable e)
|
||||
{
|
||||
lastException = e;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public boolean isFolder(NodeRef folderNodeRef)
|
||||
{
|
||||
if (folderNodeRef == null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
QName typeQName = nodeService.getType(folderNodeRef);
|
||||
CMISTypeDefinition typeDef = cmisDictionaryService.findTypeForClass(typeQName, CMISScope.FOLDER);
|
||||
return typeDef != null;
|
||||
}
|
||||
|
||||
public boolean isDocument(NodeRef documentNodeRef)
|
||||
{
|
||||
if (documentNodeRef == null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
QName typeQName = nodeService.getType(documentNodeRef);
|
||||
CMISTypeDefinition typeDef = cmisDictionaryService.findTypeForClass(typeQName, CMISScope.DOCUMENT);
|
||||
return typeDef != null;
|
||||
}
|
||||
|
||||
public boolean isRelationship(String identifier)
|
||||
{
|
||||
try
|
||||
{
|
||||
new AssociationRef(identifier);
|
||||
return true;
|
||||
}
|
||||
catch (Throwable e)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public boolean isPolicy(NodeRef policyNodeRef)
|
||||
{
|
||||
// TODO: Policy
|
||||
return false;
|
||||
}
|
||||
|
||||
public EnumBaseObjectTypeIds determineObjectType(String identifier)
|
||||
{
|
||||
if (isRelationship(identifier))
|
||||
{
|
||||
return EnumBaseObjectTypeIds.CMIS_RELATIONSHIP;
|
||||
}
|
||||
|
||||
NodeRef objectNodeReference = new NodeRef(identifier);
|
||||
if (isFolder(objectNodeReference))
|
||||
{
|
||||
return EnumBaseObjectTypeIds.CMIS_FOLDER;
|
||||
}
|
||||
|
||||
if (isDocument(objectNodeReference))
|
||||
{
|
||||
return EnumBaseObjectTypeIds.CMIS_DOCUMENT;
|
||||
}
|
||||
|
||||
return EnumBaseObjectTypeIds.CMIS_POLICY;
|
||||
}
|
||||
|
||||
public boolean isChildOfThisFolder(NodeRef objectNodeReference, NodeRef folderNodeReference)
|
||||
{
|
||||
NodeRef searchedObjectNodeReference = fileFolderService.searchSimple(folderNodeReference, (String) nodeService.getProperty(objectNodeReference, ContentModel.PROP_NAME));
|
||||
return (searchedObjectNodeReference != null) && searchedObjectNodeReference.equals(objectNodeReference);
|
||||
}
|
||||
|
||||
public boolean isPrimaryObjectParent(NodeRef folderNodeReference, NodeRef objectNodeReference)
|
||||
{
|
||||
NodeRef searchedParentObject = nodeService.getPrimaryParent(objectNodeReference).getParentRef();
|
||||
return (searchedParentObject != null) && searchedParentObject.equals(folderNodeReference);
|
||||
}
|
||||
|
||||
public boolean isWorkingCopy(NodeRef objectIdentifier)
|
||||
{
|
||||
return nodeService.hasAspect(objectIdentifier, ContentModel.ASPECT_WORKING_COPY);
|
||||
}
|
||||
|
||||
public List<AssociationRef> receiveAssociations(NodeRef objectNodeReference, QNamePattern qnameFilter, EnumRelationshipDirection direction)
|
||||
{
|
||||
List<AssociationRef> result = new LinkedList<AssociationRef>();
|
||||
|
||||
if ((direction == EnumRelationshipDirection.EITHER) || (direction == EnumRelationshipDirection.TARGET))
|
||||
{
|
||||
result.addAll(nodeService.getSourceAssocs(objectNodeReference, qnameFilter));
|
||||
}
|
||||
|
||||
if ((direction == EnumRelationshipDirection.EITHER) || (direction == EnumRelationshipDirection.SOURCE))
|
||||
{
|
||||
result.addAll(nodeService.getTargetAssocs(objectNodeReference, qnameFilter));
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns latest minor or major version of document
|
||||
*
|
||||
* @param documentNodeRef document node reference
|
||||
* @param major need latest major version
|
||||
* @return latest version node reference
|
||||
*/
|
||||
public NodeRef getLatestNode(NodeRef documentNodeRef, boolean major)
|
||||
{
|
||||
NodeRef latestVersionNodeRef = documentNodeRef;
|
||||
VersionHistory versionHistory = versionService.getVersionHistory(documentNodeRef);
|
||||
if (null != versionHistory)
|
||||
{
|
||||
Collection<Version> allVersions = versionHistory.getAllVersions();
|
||||
Iterator<Version> versionsIterator = ((null != allVersions) && !allVersions.isEmpty()) ? (allVersions.iterator()) : (null);
|
||||
Version latestVersion = (null == versionsIterator) ? (null) : (versionsIterator.next());
|
||||
String currentVersionLabel = (null != latestVersion) ? (latestVersion.getVersionLabel()) : (null);
|
||||
if (major && (null != latestVersion))
|
||||
{
|
||||
for (; (VersionType.MAJOR != latestVersion.getVersionType()) && versionsIterator.hasNext(); latestVersion = versionsIterator.next())
|
||||
{
|
||||
}
|
||||
latestVersion = (VersionType.MAJOR != latestVersion.getVersionType()) ? (null) : (latestVersion);
|
||||
}
|
||||
if ((null != latestVersion) && (null != latestVersion.getVersionLabel()))
|
||||
{
|
||||
latestVersionNodeRef = (!latestVersion.getVersionLabel().equals(currentVersionLabel) || (null == latestVersion.getVersionedNodeRef()) || !nodeService
|
||||
.exists(latestVersion.getVersionedNodeRef())) ? (latestVersion.getFrozenStateNodeRef()) : (latestVersion.getVersionedNodeRef());
|
||||
}
|
||||
}
|
||||
|
||||
return latestVersionNodeRef;
|
||||
}
|
||||
|
||||
private boolean performNodeDeletion(NodeRef objectNodeReference)
|
||||
{
|
||||
if (nodeService.hasAspect(objectNodeReference, ContentModel.ASPECT_WORKING_COPY))
|
||||
{
|
||||
checkOutCheckInService.cancelCheckout(objectNodeReference);
|
||||
return true;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
List<AssociationRef> associations = receiveAssociations(objectNodeReference, new MatcheAllQNames(), EnumRelationshipDirection.EITHER);
|
||||
for (AssociationRef association : associations)
|
||||
{
|
||||
if ((null != association) && (null != association.getSourceRef()) && (null != association.getTargetRef()) && (null != association.getTypeQName()))
|
||||
{
|
||||
nodeService.removeAssociation(association.getSourceRef(), association.getTargetRef(), association.getTypeQName());
|
||||
}
|
||||
}
|
||||
|
||||
for (ChildAssociationRef parentAssociation : nodeService.getParentAssocs(objectNodeReference))
|
||||
{
|
||||
if (!parentAssociation.isPrimary())
|
||||
{
|
||||
nodeService.removeChildAssociation(parentAssociation);
|
||||
}
|
||||
}
|
||||
|
||||
nodeService.deleteNode(objectNodeReference);
|
||||
}
|
||||
catch (Throwable e)
|
||||
{
|
||||
lastException = e;
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
private boolean canLock(NodeRef objectNodeReference)
|
||||
{
|
||||
String currentUserName = AuthenticationUtil.getFullyAuthenticatedUser();
|
||||
return (this.lockService.getLockStatus(objectNodeReference, currentUserName) != LockStatus.LOCKED) || authorityService.isAdminAuthority(currentUserName);
|
||||
}
|
||||
|
||||
private AssociationRef safeGetAssociationRef(String identifier) throws CmisException
|
||||
{
|
||||
AssociationRef result = new AssociationRef(identifier);
|
||||
|
||||
if (!nodeService.exists(result.getSourceRef()) || !nodeService.exists(result.getTargetRef()))
|
||||
{
|
||||
throw createCmisException(INVALID_OBJECT_IDENTIFIER_MESSAGE, EnumServiceException.INVALID_ARGUMENT);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
private NodeRef safeGetNodeRef(String nodeIdentifier) throws CmisException
|
||||
{
|
||||
Pair<String, String> nodeRefAndVersionLabel = (null != nodeIdentifier) ? (splitOnNodeRefAndVersionLabel(nodeIdentifier)) : (null);
|
||||
if ((null != nodeRefAndVersionLabel) && (null != nodeRefAndVersionLabel.getFirst()) && NodeRef.isNodeRef(nodeRefAndVersionLabel.getFirst()))
|
||||
{
|
||||
NodeRef result = new NodeRef(nodeRefAndVersionLabel.getFirst());
|
||||
if (nodeService.exists(result))
|
||||
{
|
||||
result = getNodeRefFromVersion(result, nodeRefAndVersionLabel.getSecond());
|
||||
|
||||
if ((null != result) && nodeService.exists(result))
|
||||
{
|
||||
return result;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
throw createCmisException(INVALID_OBJECT_IDENTIFIER_MESSAGE, EnumServiceException.OBJECT_NOT_FOUND);
|
||||
}
|
||||
|
||||
private Pair<String, String> splitOnNodeRefAndVersionLabel(String nodeIdentifier)
|
||||
{
|
||||
String versionLabel = null;
|
||||
int versionDelimeterIndex = nodeIdentifier.lastIndexOf(NODE_REFERENCE_ID_DELIMITER);
|
||||
if (versionDelimeterIndex > 0)
|
||||
{
|
||||
versionLabel = nodeIdentifier.substring(versionDelimeterIndex + 1);
|
||||
if ((null != versionLabel) && !versionLabel.equals("") && VERSION_LABEL_MATCHING_COMPILED_PATTERN.matcher(versionLabel).matches())
|
||||
{
|
||||
nodeIdentifier = nodeIdentifier.substring(0, versionDelimeterIndex);
|
||||
}
|
||||
else
|
||||
{
|
||||
versionLabel = null;
|
||||
}
|
||||
}
|
||||
|
||||
return new Pair<String, String>(nodeIdentifier, versionLabel);
|
||||
}
|
||||
|
||||
private NodeRef getNodeRefFromVersion(NodeRef nodeRef, String versionLabel) throws CmisException
|
||||
{
|
||||
NodeRef result = nodeRef;
|
||||
|
||||
NodeRef latestNodeRef = ((null != versionLabel) && (null != nodeRef)) ? (getLatestNode(nodeRef, false)) : (null);
|
||||
if ((null != latestNodeRef) && nodeService.exists(latestNodeRef) && !versionLabel.equals(nodeService.getProperty(latestNodeRef, ContentModel.PROP_VERSION_LABEL)))
|
||||
{
|
||||
VersionHistory versionHistory = versionService.getVersionHistory(latestNodeRef);
|
||||
if (null != versionHistory)
|
||||
{
|
||||
Version version = versionHistory.getVersion(versionLabel);
|
||||
|
||||
if ((null == version) || (null == version.getFrozenStateNodeRef()))
|
||||
{
|
||||
throw createCmisException(("Specified object has no " + versionLabel + " version"), EnumServiceException.INVALID_ARGUMENT);
|
||||
}
|
||||
|
||||
result = version.getFrozenStateNodeRef();
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
private AlfrescoObjectType determineActualObjectType(AlfrescoObjectType expectedType, QName objectType)
|
||||
{
|
||||
CMISTypeDefinition typeDef = cmisDictionaryService.findTypeForClass(objectType);
|
||||
if ((expectedType == AlfrescoObjectType.DOCUMENT_OBJECT || expectedType == AlfrescoObjectType.DOCUMENT_OR_FOLDER_OBJECT)
|
||||
&& typeDef.getTypeId().getScope() == CMISScope.DOCUMENT)
|
||||
{
|
||||
return expectedType;
|
||||
}
|
||||
if ((expectedType == AlfrescoObjectType.FOLDER_OBJECT || expectedType == AlfrescoObjectType.DOCUMENT_OR_FOLDER_OBJECT)
|
||||
&& typeDef.getTypeId().getScope() == CMISScope.FOLDER)
|
||||
{
|
||||
return expectedType;
|
||||
}
|
||||
return AlfrescoObjectType.ANY_OBJECT;
|
||||
}
|
||||
|
||||
private class MatcheAllQNames implements QNamePattern
|
||||
{
|
||||
public boolean isMatch(QName qname)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
public Throwable getLastOperationException()
|
||||
{
|
||||
Throwable result = lastException;
|
||||
lastException = null;
|
||||
return result;
|
||||
}
|
||||
}
|
100
source/java/org/alfresco/repo/cmis/ws/utils/ExceptionUtil.java
Executable file
100
source/java/org/alfresco/repo/cmis/ws/utils/ExceptionUtil.java
Executable file
@@ -0,0 +1,100 @@
|
||||
/*
|
||||
* Copyright (C) 2005-2010 Alfresco Software Limited.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
|
||||
* As a special exception to the terms and conditions of version 2.0 of
|
||||
* the GPL, you may redistribute this Program in connection with Free/Libre
|
||||
* and Open Source Software ("FLOSS") applications as described in Alfresco's
|
||||
* FLOSS exception. You should have received a copy of the text describing
|
||||
* the FLOSS exception, and it is also available here:
|
||||
* http://www.alfresco.com/legal/licensing"
|
||||
*/
|
||||
package org.alfresco.repo.cmis.ws.utils;
|
||||
|
||||
import java.math.BigInteger;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import org.alfresco.cmis.CMISQueryException;
|
||||
import org.alfresco.cmis.CMISServiceException;
|
||||
import org.alfresco.repo.cmis.ws.CmisException;
|
||||
import org.alfresco.repo.cmis.ws.CmisFaultType;
|
||||
import org.alfresco.repo.cmis.ws.EnumServiceException;
|
||||
import org.alfresco.repo.security.permissions.AccessDeniedException;
|
||||
import org.alfresco.service.cmr.repository.ContentIOException;
|
||||
import org.alfresco.service.cmr.repository.InvalidNodeRefException;
|
||||
|
||||
/**
|
||||
* @author Dmitry Velichkevich
|
||||
*/
|
||||
public abstract class ExceptionUtil
|
||||
{
|
||||
private static final Map<String, EnumServiceException> CLASS_TO_ENUM_EXCEPTION_MAPPING;
|
||||
static
|
||||
{
|
||||
CLASS_TO_ENUM_EXCEPTION_MAPPING = new HashMap<String, EnumServiceException>();
|
||||
CLASS_TO_ENUM_EXCEPTION_MAPPING.put(AccessDeniedException.class.getName(), EnumServiceException.PERMISSION_DENIED);
|
||||
CLASS_TO_ENUM_EXCEPTION_MAPPING.put(java.lang.RuntimeException.class.getName(), EnumServiceException.RUNTIME);
|
||||
CLASS_TO_ENUM_EXCEPTION_MAPPING.put(UnsupportedOperationException.class.getName(), EnumServiceException.NOT_SUPPORTED);
|
||||
CLASS_TO_ENUM_EXCEPTION_MAPPING.put(InvalidNodeRefException.class.getName(), EnumServiceException.INVALID_ARGUMENT);
|
||||
CLASS_TO_ENUM_EXCEPTION_MAPPING.put(ContentIOException.class.getName(), EnumServiceException.NOT_SUPPORTED);
|
||||
CLASS_TO_ENUM_EXCEPTION_MAPPING.put(CMISQueryException.class.getName(), EnumServiceException.INVALID_ARGUMENT);
|
||||
}
|
||||
|
||||
public static CmisException createCmisException(String message, EnumServiceException exceptionType)
|
||||
{
|
||||
return createCmisException(message, exceptionType, null, 0);
|
||||
}
|
||||
|
||||
public static CmisException createCmisException(String message, Throwable cause)
|
||||
{
|
||||
EnumServiceException exceptionType = null;
|
||||
|
||||
if (cause instanceof CMISServiceException)
|
||||
{
|
||||
return createCmisException((CMISServiceException)cause);
|
||||
}
|
||||
|
||||
if (CLASS_TO_ENUM_EXCEPTION_MAPPING.containsKey(cause.getClass().getName()))
|
||||
{
|
||||
exceptionType = CLASS_TO_ENUM_EXCEPTION_MAPPING.get(cause.getClass().getName());
|
||||
}
|
||||
|
||||
exceptionType = (exceptionType == null) ? (EnumServiceException.RUNTIME) : (exceptionType);
|
||||
|
||||
return createCmisException(message, exceptionType, cause, 0);
|
||||
}
|
||||
|
||||
public static CmisException createCmisException(String message, EnumServiceException exceptionType, Throwable cause)
|
||||
{
|
||||
return createCmisException(message, exceptionType, cause, 0);
|
||||
}
|
||||
|
||||
public static CmisException createCmisException(CMISServiceException exception)
|
||||
{
|
||||
return createCmisException(exception.getMessage(), EnumServiceException.fromValue(exception.getFaultName()), exception, exception.getStatusCode());
|
||||
}
|
||||
|
||||
public static CmisException createCmisException(String message, EnumServiceException exceptionType, Throwable cause, int errorCode)
|
||||
{
|
||||
CmisFaultType fault = new CmisFaultType();
|
||||
fault.setMessage(message);
|
||||
fault.setType(exceptionType);
|
||||
fault.setCode(BigInteger.valueOf(errorCode));
|
||||
|
||||
return new CmisException(message, fault, cause);
|
||||
}
|
||||
}
|
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2005-2009 Alfresco Software Limited.
|
||||
* Copyright (C) 2005-2010 Alfresco Software Limited.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
@@ -18,7 +18,7 @@
|
||||
* As a special exception to the terms and conditions of version 2.0 of
|
||||
* the GPL, you may redistribute this Program in connection with Free/Libre
|
||||
* and Open Source Software ("FLOSS") applications as described in Alfresco's
|
||||
* FLOSS exception. You should have recieved a copy of the text describing
|
||||
* FLOSS exception. You should have received a copy of the text describing
|
||||
* the FLOSS exception, and it is also available here:
|
||||
* http://www.alfresco.com/legal/licensing"
|
||||
*/
|
||||
@@ -40,6 +40,7 @@ import javax.xml.datatype.XMLGregorianCalendar;
|
||||
import org.alfresco.cmis.CMISDataTypeEnum;
|
||||
import org.alfresco.cmis.CMISDictionaryModel;
|
||||
import org.alfresco.cmis.CMISDictionaryService;
|
||||
import org.alfresco.cmis.CMISInvalidArgumentException;
|
||||
import org.alfresco.cmis.CMISPropertyDefinition;
|
||||
import org.alfresco.cmis.CMISScope;
|
||||
import org.alfresco.cmis.CMISServices;
|
||||
@@ -65,6 +66,7 @@ import org.alfresco.service.cmr.dictionary.TypeDefinition;
|
||||
import org.alfresco.service.cmr.repository.AssociationRef;
|
||||
import org.alfresco.service.cmr.repository.NodeRef;
|
||||
import org.alfresco.service.cmr.repository.NodeService;
|
||||
import org.alfresco.service.cmr.version.Version;
|
||||
import org.alfresco.service.namespace.NamespaceService;
|
||||
import org.alfresco.service.namespace.QName;
|
||||
|
||||
@@ -98,7 +100,6 @@ public class PropertyUtil
|
||||
private NamespaceService namespaceService;
|
||||
private CMISServices cmisService;
|
||||
private CMISDictionaryService cmisDictionaryService;
|
||||
private CmisObjectsUtils cmisObjectsUtils;
|
||||
|
||||
public PropertyUtil()
|
||||
{
|
||||
@@ -129,11 +130,6 @@ public class PropertyUtil
|
||||
this.cmisDictionaryService = cmisDictionaryService;
|
||||
}
|
||||
|
||||
public void setCmisObjectsUtils(CmisObjectsUtils cmisObjectsUtils)
|
||||
{
|
||||
this.cmisObjectsUtils = cmisObjectsUtils;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets property value by its name from Node Reference object
|
||||
*
|
||||
@@ -275,7 +271,7 @@ public class PropertyUtil
|
||||
|
||||
if ((PropertyMultiValueStateEnum.PROPERTY_NOT_MULTIVALUED == state) && (values.size() > 1))
|
||||
{
|
||||
throw cmisObjectsUtils.createCmisException("\"" + propertyName + "\" property is not Multi Valued", EnumServiceException.INVALID_ARGUMENT);
|
||||
throw ExceptionUtil.createCmisException("\"" + propertyName + "\" property is not Multi Valued", EnumServiceException.INVALID_ARGUMENT);
|
||||
}
|
||||
|
||||
return PropertyMultiValueStateEnum.PROPERTY_MULTIVALUED == state;
|
||||
@@ -379,7 +375,7 @@ public class PropertyUtil
|
||||
|
||||
if ((null == cmisObjectType) && (null == nativeObjectType))
|
||||
{
|
||||
throw cmisObjectsUtils.createCmisException(("Can't find type definition for current object with \"" + typeId + "\" type Id"), EnumServiceException.INVALID_ARGUMENT);
|
||||
throw ExceptionUtil.createCmisException(("Can't find type definition for current object with \"" + typeId + "\" type Id"), EnumServiceException.INVALID_ARGUMENT);
|
||||
}
|
||||
|
||||
for (CmisProperty property : properties.getProperty())
|
||||
@@ -406,7 +402,7 @@ public class PropertyUtil
|
||||
}
|
||||
case PROPERTY_NOT_UPDATABLE:
|
||||
{
|
||||
throw cmisObjectsUtils.createCmisException(("\"" + propertyName + "\" property is not updatable by repository for specified Object id"),
|
||||
throw ExceptionUtil.createCmisException(("\"" + propertyName + "\" property is not updatable by repository for specified Object id"),
|
||||
EnumServiceException.CONSTRAINT);
|
||||
}
|
||||
}
|
||||
@@ -479,7 +475,7 @@ public class PropertyUtil
|
||||
|
||||
if (propertyDefinition.isRequired() && (null == value))
|
||||
{
|
||||
throw cmisObjectsUtils.createCmisException((propertyName + " property required"), EnumServiceException.CONSTRAINT);
|
||||
throw ExceptionUtil.createCmisException((propertyName + " property required"), EnumServiceException.CONSTRAINT);
|
||||
}
|
||||
|
||||
switch (propertyDefinition.getDataType())
|
||||
@@ -514,7 +510,7 @@ public class PropertyUtil
|
||||
{
|
||||
if (value != null && (propertyDefinition.getMaximumLength() > 0) && (value.length() > propertyDefinition.getMaximumLength()))
|
||||
{
|
||||
throw cmisObjectsUtils.createCmisException((propertyName + " property value is too long"), EnumServiceException.CONSTRAINT);
|
||||
throw ExceptionUtil.createCmisException((propertyName + " property value is too long"), EnumServiceException.CONSTRAINT);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -525,22 +521,33 @@ public class PropertyUtil
|
||||
* @param filter property filter
|
||||
* @return properties
|
||||
*/
|
||||
public CmisPropertiesType getPropertiesType(String identifier, PropertyFilter filter) throws CmisException
|
||||
public CmisPropertiesType getProperties(Object object, PropertyFilter filter) throws CmisException
|
||||
{
|
||||
try
|
||||
{
|
||||
Map<String, Serializable> properties;
|
||||
if (!identifier.contains("|"))
|
||||
if (object instanceof NodeRef)
|
||||
{
|
||||
properties = cmisService.getProperties(new NodeRef(identifier));
|
||||
properties = cmisService.getProperties((NodeRef) object);
|
||||
}
|
||||
else if (object instanceof Version)
|
||||
{
|
||||
properties = cmisService.getProperties(((Version) object).getFrozenStateNodeRef());
|
||||
}
|
||||
else
|
||||
{
|
||||
properties = createBaseRelationshipProperties(new AssociationRef(identifier));
|
||||
properties = createBaseRelationshipProperties((AssociationRef) object);
|
||||
}
|
||||
|
||||
CmisPropertiesType result = new CmisPropertiesType();
|
||||
convertToCmisProperties(properties, filter, result);
|
||||
return result;
|
||||
}
|
||||
catch (CMISInvalidArgumentException e)
|
||||
{
|
||||
throw ExceptionUtil.createCmisException(e.getMessage(), EnumServiceException.INVALID_ARGUMENT, e);
|
||||
}
|
||||
}
|
||||
|
||||
private Map<String, Serializable> createBaseRelationshipProperties(AssociationRef association)
|
||||
{
|
||||
@@ -562,7 +569,7 @@ public class PropertyUtil
|
||||
|
||||
if (null == type)
|
||||
{
|
||||
throw cmisObjectsUtils.createCmisException(("Type with " + typeId + " typeId was not found"), EnumServiceException.RUNTIME);
|
||||
throw ExceptionUtil.createCmisException(("Type with " + typeId + " typeId was not found"), EnumServiceException.RUNTIME);
|
||||
}
|
||||
|
||||
for (String propertyName : properties.keySet())
|
||||
|
@@ -31,8 +31,8 @@ import java.util.Map;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
import org.alfresco.cmis.CMISObjectReference;
|
||||
import org.alfresco.cmis.reference.ReferenceFactory;
|
||||
import org.alfresco.model.ContentModel;
|
||||
import org.alfresco.repo.cmis.reference.ReferenceFactory;
|
||||
import org.alfresco.service.cmr.repository.ContentData;
|
||||
import org.alfresco.service.cmr.repository.NodeRef;
|
||||
import org.alfresco.service.cmr.repository.NodeService;
|
||||
|
@@ -31,8 +31,8 @@ import java.util.Map;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
import org.alfresco.cmis.CMISObjectReference;
|
||||
import org.alfresco.cmis.reference.ReferenceFactory;
|
||||
import org.alfresco.model.ContentModel;
|
||||
import org.alfresco.repo.cmis.reference.ReferenceFactory;
|
||||
import org.alfresco.service.cmr.repository.NodeRef;
|
||||
import org.alfresco.service.namespace.NamespaceService;
|
||||
import org.alfresco.service.namespace.QName;
|
||||
|
@@ -24,26 +24,22 @@
|
||||
*/
|
||||
package org.alfresco.repo.web.scripts.content;
|
||||
|
||||
import java.io.BufferedInputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.nio.charset.Charset;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
import org.alfresco.cmis.CMISDictionaryModel;
|
||||
import org.alfresco.cmis.CMISObjectReference;
|
||||
import org.alfresco.cmis.reference.ObjectPathReference;
|
||||
import org.alfresco.cmis.reference.ReferenceFactory;
|
||||
import org.alfresco.cmis.CMISServiceException;
|
||||
import org.alfresco.cmis.CMISServices;
|
||||
import org.alfresco.model.ContentModel;
|
||||
import org.alfresco.repo.content.encoding.ContentCharsetFinder;
|
||||
import org.alfresco.repo.cmis.reference.ObjectPathReference;
|
||||
import org.alfresco.repo.cmis.reference.ReferenceFactory;
|
||||
import org.alfresco.service.cmr.dictionary.DataTypeDefinition;
|
||||
import org.alfresco.service.cmr.dictionary.DictionaryService;
|
||||
import org.alfresco.service.cmr.dictionary.PropertyDefinition;
|
||||
import org.alfresco.service.cmr.repository.ContentReader;
|
||||
import org.alfresco.service.cmr.repository.ContentService;
|
||||
import org.alfresco.service.cmr.repository.ContentWriter;
|
||||
import org.alfresco.service.cmr.repository.MimetypeService;
|
||||
import org.alfresco.service.cmr.repository.NodeRef;
|
||||
import org.alfresco.service.namespace.NamespaceService;
|
||||
@@ -74,7 +70,7 @@ public class ContentSet extends AbstractWebScript
|
||||
private ReferenceFactory referenceFactory;
|
||||
private DictionaryService dictionaryService;
|
||||
private NamespaceService namespaceService;
|
||||
private ContentService contentService;
|
||||
private CMISServices cmisService;
|
||||
private MimetypeService mimetypeService;
|
||||
|
||||
/**
|
||||
@@ -102,11 +98,11 @@ public class ContentSet extends AbstractWebScript
|
||||
}
|
||||
|
||||
/**
|
||||
* @param contentService
|
||||
* @param cmisServices
|
||||
*/
|
||||
public void setContentService(ContentService contentService)
|
||||
public void setCmisService(CMISServices cmisService)
|
||||
{
|
||||
this.contentService = contentService;
|
||||
this.cmisService = cmisService;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -168,22 +164,7 @@ public class ContentSet extends AbstractWebScript
|
||||
}
|
||||
|
||||
// ensure content can be overwritten
|
||||
// TODO: check parameter name
|
||||
String overwrite = req.getParameter("overwriteFlag");
|
||||
if (overwrite != null && overwrite.equalsIgnoreCase("false"))
|
||||
{
|
||||
ContentReader reader = contentService.getReader(nodeRef, propertyQName);
|
||||
if (reader != null)
|
||||
{
|
||||
// error code as per CMIS specification
|
||||
throw new WebScriptException(HttpServletResponse.SC_CONFLICT, "Content already exists.");
|
||||
}
|
||||
}
|
||||
|
||||
// setup content writer
|
||||
ContentReader reader = contentService.getReader(nodeRef, propertyQName);
|
||||
boolean isUpdate = (reader != null && reader.exists());
|
||||
ContentWriter writer = contentService.getWriter(nodeRef, propertyQName, true);
|
||||
|
||||
// establish mimetype
|
||||
String mimetype = req.getContentType();
|
||||
@@ -194,24 +175,19 @@ public class ContentSet extends AbstractWebScript
|
||||
mimetype = mimetypeService.guessMimetype(((ObjectPathReference)reference).getPath());
|
||||
}
|
||||
}
|
||||
if (mimetype != null)
|
||||
|
||||
try
|
||||
{
|
||||
writer.setMimetype(mimetype);
|
||||
}
|
||||
|
||||
// get the input stream from the request data
|
||||
InputStream is = req.getContent().getInputStream();
|
||||
is = is.markSupported() ? is : new BufferedInputStream(is);
|
||||
|
||||
// establish content encoding
|
||||
ContentCharsetFinder charsetFinder = mimetypeService.getContentCharsetFinder();
|
||||
Charset encoding = charsetFinder.getCharset(is, mimetype);
|
||||
writer.setEncoding(encoding.name());
|
||||
|
||||
// write the new data
|
||||
writer.putContent(is);
|
||||
boolean isUpdate = cmisService.setContentStream((String) cmisService.getProperty(nodeRef,
|
||||
CMISDictionaryModel.PROP_OBJECT_ID), propertyQName, overwrite == null || overwrite.equals("true"),
|
||||
req.getContent().getInputStream(), mimetype);
|
||||
|
||||
// set status
|
||||
res.setStatus(isUpdate ? Status.STATUS_OK : Status.STATUS_CREATED);
|
||||
}
|
||||
catch (CMISServiceException e)
|
||||
{
|
||||
throw new WebScriptException(e.getStatusCode(), e.getMessage(), e);
|
||||
}
|
||||
}
|
||||
}
|
@@ -82,7 +82,7 @@ public class DMNavigationServiceTest extends AbstractServiceTest
|
||||
helper.versioningServicePort.checkOut(repositoryId, documentIdHolder1, new Holder<CmisExtensionType>(), contentCopied);
|
||||
assertTrue(contentCopied.value);
|
||||
|
||||
List<CmisObjectType> result = getCheckedoutDocs(null, 0, 0);
|
||||
List<CmisObjectType> result = getCheckedoutDocs(null, "cmis:lastModificationDate DESC", 0, 0);
|
||||
|
||||
if (result == null || result.size() < 2)
|
||||
{
|
||||
@@ -90,23 +90,25 @@ public class DMNavigationServiceTest extends AbstractServiceTest
|
||||
helper.versioningServicePort.checkIn(repositoryId, documentIdHolder, false, null, null, null, null, null, null, new Holder<CmisExtensionType>());
|
||||
fail("Not all checkout docs have been found");
|
||||
}
|
||||
|
||||
assertEquals("Wrong order", documentIdHolder1.value, getIdProperty(result.get(0).getProperties(), CMISDictionaryModel.PROP_OBJECT_ID));
|
||||
validateResponse(result);
|
||||
|
||||
result = getCheckedoutDocs(null, 1, 0);
|
||||
result = getCheckedoutDocs(null, "cmis:lastModificationDate DESC", 1, 0);
|
||||
assertNotNull(result);
|
||||
assertTrue(result.size() == 1);
|
||||
|
||||
// check in
|
||||
helper.versioningServicePort.checkIn(repositoryId, documentIdHolder, false, null, null, null, null, null, null, new Holder<CmisExtensionType>());
|
||||
|
||||
result = getCheckedoutDocs(companyHomeId, 0, 0);
|
||||
result = getCheckedoutDocs(companyHomeId, "cmis:lastModificationDate ASC", 0, 0);
|
||||
assertFalse("Wrong results", isExistItemWithProperty(result, CMISDictionaryModel.PROP_NAME, documentName));
|
||||
|
||||
}
|
||||
|
||||
public void testGetChildren() throws Exception
|
||||
{
|
||||
List<CmisObjectInFolderType> response = getChildren(companyHomeId, 100, true);
|
||||
List<CmisObjectInFolderType> response = getChildren(companyHomeId, null, 100, true);
|
||||
|
||||
if (null != response)
|
||||
{
|
||||
@@ -134,10 +136,10 @@ public class DMNavigationServiceTest extends AbstractServiceTest
|
||||
@SuppressWarnings("unused")
|
||||
String documentId1 = helper.createDocument(documentName1, folderId, CMISDictionaryModel.DOCUMENT_TYPE_ID, EnumVersioningState.MAJOR);
|
||||
|
||||
response = getChildren(folderId, 2, false);
|
||||
response = getChildren(folderId, CMISDictionaryModel.PROP_NAME + " ASC", 2, false);
|
||||
assertEquals(2, response.size());
|
||||
assertTrue(getStringProperty(response.get(0).getObject().getProperties(), CMISDictionaryModel.PROP_NAME).equals(folderName1));
|
||||
assertTrue(getStringProperty(response.get(1).getObject().getProperties(), CMISDictionaryModel.PROP_NAME).equals(documentName1));
|
||||
assertTrue(getStringProperty(response.get(0).getObject().getProperties(), CMISDictionaryModel.PROP_NAME).equals(documentName1));
|
||||
assertTrue(getStringProperty(response.get(1).getObject().getProperties(), CMISDictionaryModel.PROP_NAME).equals(folderName1));
|
||||
|
||||
// TODO: not implemented
|
||||
// assertNotNull(response.getObject().get(0).getAllowableActions());
|
||||
@@ -290,9 +292,9 @@ public class DMNavigationServiceTest extends AbstractServiceTest
|
||||
return result;
|
||||
}
|
||||
|
||||
private List<CmisObjectInFolderType> getChildren(String folderId, int maxItems, boolean includePathSegments) throws Exception
|
||||
private List<CmisObjectInFolderType> getChildren(String folderId, String orderBy, int maxItems, boolean includePathSegments) throws Exception
|
||||
{
|
||||
CmisObjectInFolderListType result = ((NavigationServicePort) servicePort).getChildren(repositoryId, folderId, "*", "", false, null, "", includePathSegments, BigInteger
|
||||
CmisObjectInFolderListType result = ((NavigationServicePort) servicePort).getChildren(repositoryId, folderId, "*", orderBy, false, null, "", includePathSegments, BigInteger
|
||||
.valueOf(maxItems), BigInteger.valueOf(0), null);
|
||||
assertNotNull("Get Children response is undefined", result);
|
||||
return result.getObjects();
|
||||
@@ -318,9 +320,9 @@ public class DMNavigationServiceTest extends AbstractServiceTest
|
||||
return response;
|
||||
}
|
||||
|
||||
private List<CmisObjectType> getCheckedoutDocs(String folderId, long maxItems, long skipCount) throws Exception
|
||||
private List<CmisObjectType> getCheckedoutDocs(String folderId, String orderBy, long maxItems, long skipCount) throws Exception
|
||||
{
|
||||
CmisObjectListType result = ((NavigationServicePort) servicePort).getCheckedOutDocs(repositoryId, folderId, "*", null, false, null, "", BigInteger.valueOf(maxItems),
|
||||
CmisObjectListType result = ((NavigationServicePort) servicePort).getCheckedOutDocs(repositoryId, folderId, "*", orderBy, false, null, "", BigInteger.valueOf(maxItems),
|
||||
BigInteger.valueOf(skipCount), null);
|
||||
assertNotNull(result);
|
||||
return result.getObjects();
|
||||
|
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2005-2008 Alfresco Software Limited.
|
||||
* Copyright (C) 2005-2010 Alfresco Software Limited.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
@@ -18,7 +18,7 @@
|
||||
* As a special exception to the terms and conditions of version 2.0 of
|
||||
* the GPL, you may redistribute this Program in connection with Free/Libre
|
||||
* and Open Source Software ("FLOSS") applications as described in Alfresco's
|
||||
* FLOSS exception. You should have recieved a copy of the text describing
|
||||
* FLOSS exception. You should have received a copy of the text describing
|
||||
* the FLOSS exception, and it is also available here:
|
||||
* http://www.alfresco.com/legal/licensing"
|
||||
*/
|
||||
@@ -88,7 +88,7 @@ public class DMVersioningServiceTest extends AbstractServiceTest
|
||||
new Holder<CmisExtensionType>());
|
||||
documentId = documentIdHolder.value;
|
||||
|
||||
assertEquals(checkinComment, getStringProperty(helper.getObjectProperties(documentIdHolder.value).getProperties(), CMISDictionaryModel.PROP_CHECKIN_COMMENT));
|
||||
assertEquals(checkinComment, getStringProperty(((VersioningServicePort) servicePort).getPropertiesOfLatestVersion(repositoryId, documentId, true, null, null), CMISDictionaryModel.PROP_CHECKIN_COMMENT));
|
||||
}
|
||||
|
||||
public void testCheckOutCheckInDefault() throws Exception
|
||||
@@ -139,7 +139,7 @@ public class DMVersioningServiceTest extends AbstractServiceTest
|
||||
}
|
||||
catch (CmisException e)
|
||||
{
|
||||
assertTrue(e.getFaultInfo().getType().equals(EnumServiceException.UPDATE_CONFLICT));
|
||||
assertTrue(e.getFaultInfo().getType().equals(EnumServiceException.VERSIONING));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -154,20 +154,20 @@ public class DMVersioningServiceTest extends AbstractServiceTest
|
||||
}
|
||||
catch (CmisException e)
|
||||
{
|
||||
assertTrue(e.getFaultInfo().getType().equals(EnumServiceException.UPDATE_CONFLICT));
|
||||
assertTrue(e.getFaultInfo().getType().equals(EnumServiceException.VERSIONING));
|
||||
}
|
||||
}
|
||||
|
||||
public void testGetPropertiesOfLatestVersion() throws Exception
|
||||
{
|
||||
CmisPropertiesType objectType = ((VersioningServicePort) servicePort).getPropertiesOfLatestVersion(repositoryId, documentId, true, "*", null);
|
||||
CmisPropertiesType objectType = ((VersioningServicePort) servicePort).getPropertiesOfLatestVersion(repositoryId, documentId, false, "*", null);
|
||||
assertNotNull(objectType);
|
||||
assertTrue(getBooleanProperty(objectType, CMISDictionaryModel.PROP_IS_LATEST_VERSION));
|
||||
}
|
||||
|
||||
public void testGetPropertiesOfLatestVersionDefault() throws Exception
|
||||
{
|
||||
CmisPropertiesType cmisObjectType = ((VersioningServicePort) servicePort).getPropertiesOfLatestVersion(repositoryId, documentId, true, "", null);
|
||||
CmisPropertiesType cmisObjectType = ((VersioningServicePort) servicePort).getPropertiesOfLatestVersion(repositoryId, documentId, false, "", null);
|
||||
assertNotNull(cmisObjectType);
|
||||
assertTrue(getBooleanProperty(cmisObjectType, CMISDictionaryModel.PROP_IS_LATEST_VERSION));
|
||||
}
|
||||
@@ -184,10 +184,10 @@ public class DMVersioningServiceTest extends AbstractServiceTest
|
||||
|
||||
List<CmisObjectType> response = ((VersioningServicePort) servicePort).getAllVersions(repositoryId, documentId, "", null, null);
|
||||
assertNotNull(response);
|
||||
assertFalse(response.isEmpty());
|
||||
CmisObjectType firstElement = response.iterator().next();
|
||||
assertNotNull(firstElement);
|
||||
assertEquals(checkinComment, getStringProperty(firstElement.getProperties(), CMISDictionaryModel.PROP_CHECKIN_COMMENT));
|
||||
assertTrue("Expected three versions", response.size() == 3);
|
||||
CmisObjectType lastVersion = response.get(1);
|
||||
assertNotNull(lastVersion);
|
||||
assertEquals(checkinComment, getStringProperty(lastVersion.getProperties(), CMISDictionaryModel.PROP_CHECKIN_COMMENT));
|
||||
}
|
||||
|
||||
public void testGetAllVersions() throws Exception
|
||||
@@ -202,10 +202,10 @@ public class DMVersioningServiceTest extends AbstractServiceTest
|
||||
|
||||
List<CmisObjectType> response = ((VersioningServicePort) servicePort).getAllVersions(repositoryId, documentId, "*", false, null);
|
||||
assertNotNull(response);
|
||||
assertFalse(response.isEmpty());
|
||||
CmisObjectType firstElement = response.iterator().next();
|
||||
assertNotNull(firstElement);
|
||||
assertEquals(checkinComment, getStringProperty(firstElement.getProperties(), CMISDictionaryModel.PROP_CHECKIN_COMMENT));
|
||||
assertTrue("Expected three versions", response.size() == 3);
|
||||
CmisObjectType lastVersion = response.get(1);
|
||||
assertNotNull(lastVersion);
|
||||
assertEquals(checkinComment, getStringProperty(lastVersion.getProperties(), CMISDictionaryModel.PROP_CHECKIN_COMMENT));
|
||||
}
|
||||
|
||||
public void testGetAllVersionsForNoVersionHistory() throws Exception
|
||||
|
@@ -1,7 +1,7 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!--
|
||||
$Revision: 149 $ $Date: 2009-12-22 08:01:48 -0800 (Tue, 22 Dec 2009) $
|
||||
$Author: fmueller $ $HeadURL:
|
||||
$Revision: 169 $ $Date: 2010-01-25 10:34:39 -0800 (Mon, 25 Jan 2010) $
|
||||
$Author: albertcbrown $ $HeadURL:
|
||||
http://tools.oasis-open.org/version-control/svn/cmis/trunk/SchemaProject/schema/CMIS-Core.xsd
|
||||
$
|
||||
-->
|
||||
@@ -556,8 +556,6 @@
|
||||
minOccurs="0" maxOccurs="1" />
|
||||
<xs:element name="canCreateRelationship" type="xs:boolean"
|
||||
minOccurs="0" maxOccurs="1" />
|
||||
<xs:element name="canCreatePolicy" type="xs:boolean"
|
||||
minOccurs="0" maxOccurs="1" />
|
||||
<xs:element name="canDeleteTree" type="xs:boolean"
|
||||
minOccurs="0" maxOccurs="1" />
|
||||
|
||||
|
Reference in New Issue
Block a user