10-07-2016 12:00 PM
The following groovy demonstrates the problem I'm having:
import org.apache.chemistry.opencmis.commons.*
import org.apache.chemistry.opencmis.commons.data.*
import org.apache.chemistry.opencmis.commons.enums.*
import org.apache.chemistry.opencmis.client.api.*
def cmis = new scripts.CMIS(session)
Folder folder = cmis.getFolder("/Shared")
final String textFileName = "test.txt"
Document doc
try{
doc = (Document) session.getObjectByPath(folder.getPath()+"/"+textFileName)
}catch(Err){}
if (doc != null){
doc.delete(true)
}
String mimetype = "text/plain; charset=UTF-8"
String content = "This is some test content"
String filename = textFileName
byte[] buf = content.getBytes("UTF-8")
ByteArrayInputStream input = new ByteArrayInputStream(buf)
ContentStream contentStream = session.getObjectFactory().createContentStream(filename, buf.length, mimetype, input)
Map<String, Object> props = new HashMap<String, Object>()
props.put(PropertyIds.OBJECT_TYPE_ID, "cmis:document")
props.put(PropertyIds.NAME, filename)
doc = folder.createDocument(props, contentStream, VersioningState.MAJOR)
List<String> aspects = doc.getPropertyValue("cmis:secondaryObjectTypeIds")
println(aspects)
List<String> toAdd
props.clear()
if (!aspects.contains("R:ncsrel:related")) {
toAdd = ["P:ncsrel:related"]
doc = doc.updateProperties(props, toAdd, null)
}
aspects = doc.getPropertyValue("cmis:secondaryObjectTypeIds")
println(aspects)
//problem, adding this aspect removes the R:ncsrel:related
if (!aspects.contains("P:cm:dublincore")) {
toAdd = ["P:cm:dublincore"]
doc = doc.updateProperties(props, toAdd, null)
}
aspects = doc.getPropertyValue("cmis:secondaryObjectTypeIds")
println(aspects)
The output is:
[P:cm:titled, P:sys:localized, P:cm:author]
[P:cm:titled, R:ncsrel:related, P:sys:localized, P:cm:author]
[P:cm:titled, P:cm:dublincore, P:sys:localized, P:cm:author]
Adding P:cm:dublincore deleted R:ncsrel:related.
The R:ncsrel:related aspect definition:
<aspects>
<aspect name="ncsrel:related">
<title>NCS Related</title>
<associations>
<association name="ncsrel:related">
<title>Related Content</title>
<source>
<mandatory>false</mandatory>
<many>true</many>
</source>
<target>
<class>cm:content</class>
<mandatory>false</mandatory>
<many>true</many>
</target>
</association>
</associations>
</aspect>
</aspects>c
cts>
Has anyone any thoughts?
10-08-2016 04:05 AM
In fact the "aspectsToAdd" is a detail of the CMIS client library and is not transmitted to Alfresco that way. The CMIS specification only provides an updateProperties operation where ALL secondaryTypes / aspects need to be included that should still be applied after the operation (current + new). In case the client library does not correctly merge the existing and aspects to add, Alfresco may remove those aspects that are not in the cmis:secondaryObjectTypeIds list. This is implemented in the CMISConnector.processSecondaryTypes operation.
I would check the HTTP request the client library sends to Alfresco if it contains all the aspects that were applied before PLUS the aspects you want to add.
10-07-2016 02:06 PM
This is indeed the established behaviour that Alfresco has had the entire time I have been working with it (~6 years). Alfresco may automatically remove aspects when they define associations and/or properties of which none is currently being used on the node or the last of which has just been removed (e.g. if you delete the value of a property defined by an aspect and it was the last property of that aspect, it may be removed). Alfresco will not remove aspects that do not define any properties / associations at all (which can be used for semantic marking).
There are some variations on this behaviour depending on which API is used - I would assume the CMIS integration is built in a way that triggers this automatic removal.
10-07-2016 11:44 PM
It seems alfresco will remove aspects that are already in item'existing aspects list but not in aspectsToAdd list in cmis implementation.
To avoid this problem ,you can get all existing aspects first and append them to the aspectsToAdd list.
10-08-2016 04:05 AM
In fact the "aspectsToAdd" is a detail of the CMIS client library and is not transmitted to Alfresco that way. The CMIS specification only provides an updateProperties operation where ALL secondaryTypes / aspects need to be included that should still be applied after the operation (current + new). In case the client library does not correctly merge the existing and aspects to add, Alfresco may remove those aspects that are not in the cmis:secondaryObjectTypeIds list. This is implemented in the CMISConnector.processSecondaryTypes operation.
I would check the HTTP request the client library sends to Alfresco if it contains all the aspects that were applied before PLUS the aspects you want to add.
10-08-2016 04:47 AM
What I means is that alfresco server cmis implementation does not correctly merge the existing and aspects to add
It removes the aspects that are in existing aspects list but not contained in secondaryTypes in the parameter.
So to avoid the error deleting,in the client we can get all existing aspects first and append it to secondaryTypes List we are going to add.
10-08-2016 04:50 AM
As I said, merging existing and aspects to add is the responsiblity of the client library before sending the CMIS request. Alfresco is not allowed to override the request data from the client because that would effectively result in users not being able to remove aspects again...
10-08-2016 05:09 AM
I got your point alfresco server should design that way .
10-10-2016 09:12 AM
I've checked the HTTP request and the existing aspects are indeed missing. I therefore conclude that there is a bug in the opencims client 1.0.0 for the function
CmisObject updateProperties(Map<String,?> properties,
List<String> addSecondaryTypeIds,
List<String> removeSecondaryTypeIds)
It seem sensible to use CmisObject updateProperties(Map<String,?> properties), however, when the aspect list is retrieved using getPropertyValue("cmis:secondaryObjectTypeIds") association type aspects are prefixed with "R:". If this is passed to updateProperties the opencmis library throws the error "Secondary types property contains a type that is not a secondary type: R:ncsrel:related". Changing the R: prefix to P: fixes the error, but feels wrong. Is this another problem with the opencmis client?
10-10-2016 09:18 AM
I fear the second part about the R: prefix might be a mapping bug inside of Alfresco. You have named the aspect and the association identically. I assume internally Alfresco is mapping Alfresco QNames to CMIS type IDs. The association ncsrel:related is mapped to the CMIS type ID R:ncsrel:related, overriding any prior mapping for the aspect. When Alfresco needs to map the aspect QName back to the CMIS secondary object type ID it picks up the relationship type ID instead.
10-10-2016 10:30 AM
Spot on, I've rename the association and all is working.
Thank you very much
Tags
Find what you came for
We want to make your experience in Hyland Connect as valuable as possible, so we put together some helpful links.