Get Alfresco NodeRef by path (real-time, race cond

2019-09-14 18:08发布

I want to get the NodeRef of a document (or space) stored in Alfresco.

My code is in Java, running within Alfresco (for instance in an AMP).

My code needs to be safe against race conditions, for instance it must find nodes that have been created a second before. In this context, the usual methods (search-based) can not be used.

How to do?

标签: java alfresco
3条回答
Explosion°爆炸
2楼-- · 2019-09-14 18:25

You need to avoid anything that touches SOLR, as those APIs are only Eventually Consistent

Specifically, you need an API that's based on canned queries. The main ones for your use-case are NodeService.getChildAssocs and NodeService.getChildByName. Some of FileFolderService will work immediately too

Your best bet would be to split a path into components, then do a recursive / looping descent through it. Depending on if you want it by Name (cm:name) or QName (based on the assoc), you'd use one of the two NodeService methods

eg (not fully tested...)

String[] parts = path.split("\\/");
NodeRef nodeRef = nodeService.getRootNode(StoreRef.STORE_REF_WORKSPACE_SPACESSTORE);
for (String name : parts) {
   NodeRef child = nodeService.getChildByName(nodeRef, ContentModel.ASSOC_CONTAINS, name);
   if (child == null) 
      throw new Exception("Path part not found "+name+" in "+path+" at "+nodeRef);
   nodeRef = child;
}
return nodeRef;
查看更多
兄弟一词,经得起流年.
3楼-- · 2019-09-14 18:38

Transactional queries are supported, at least to some extent. http://docs.alfresco.com/5.2/concepts/intrans-metadata-overview.html

查看更多
Rolldiameter
4楼-- · 2019-09-14 18:43

This method gets the company home NodeRef, which is always available (at least from an Alfresco-based application's point of view), then uses FileFolderService.resolveNamePath which is not search-based.

Syntax example of expected path: /Company Home/Shared/My Folder/123.txt

public NodeRef getNode(String path) {

    // Get company home NodeRef. No race condition because it is always exists.
    NodeRef companyHomeNode = nodeService.getRootNode(StoreRef.STORE_REF_WORKSPACE_SPACESSTORE);

    // Get NodeRef for the path using path elements and resolveNamePath.
    List<String> pathElements = new LinkedList<>(Arrays.asList(path.split("/")));
    pathElements.remove(0); // Remove leading empty element before first slash
    pathElements.remove(0); // Remove Company Home element
    try {
        FileInfo fileInfo = fileFolderService.resolveNamePath(
                companyHomeNode, pathElements);
        return fileInfo.getNodeRef();
    } catch (FileNotFoundException e) {
        return null; // No node with such a path.
    }
}

Public domain, feel free to edit and improve :-)

查看更多
登录 后发表回答