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?
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;
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 :-)
Transactional queries are supported, at least to some extent.
http://docs.alfresco.com/5.2/concepts/intrans-metadata-overview.html