
Alfresco: resolve node path programmatically in Java
by Stanislav on Thursday Nov 19, 2015
If you have a requirement to retrieve a particular Node path within an Alfresco repository by means of Java then this article for you. Also I’ll show how to get a subpath of this path and use it in Lucene search queries.
To get a node path by its NodeRef is pretty simple, just use org.alfresco.service.cmr.repository.NodeService.getPath(NodeRef nodeRef). This method returns a result of type Path. Though this type is really useful, in most cases we need node path presentation as standard Java String. To do this we can use org.alfresco.service.cmr.repository.Path.toPrefixString(NamespacePrefixResolver resolver) method which gives back a string path consisting of node names each prefixed with its namespace (e.g. “app:company_home/st:sites/cm:test/cm:documentLibrary”). This string representation is very handy when we need to execute search queries within Alfresco repository. So NamespacePrefixResolver variable as a parameter should be passed, here DynamicNamespacePrefixResolver implementation can be used, having all namespaces registered (those that persist in current path). As an example let’s consider a Folder node in some site Document library, NamespacePrefixResolver method for it will look:
import org.alfresco.service.namespace.DynamicNamespacePrefixResolver; import org.alfresco.service.namespace.NamespaceService; import org.alfresco.repo.site.SiteModel; private static DynamicNamespacePrefixResolver getNamespaceResolver() { DynamicNamespacePrefixResolver resolver = new DynamicNamespacePrefixResolver(null); resolver.registerNamespace(NamespaceService.CONTENT_MODEL_PREFIX, NamespaceService.CONTENT_MODEL_1_0_URI); resolver.registerNamespace(NamespaceService.APP_MODEL_PREFIX, NamespaceService.APP_MODEL_1_0_URI); resolver.registerNamespace(SiteModel.SITE_MODEL_PREFIX, SiteModel.SITE_MODEL_URL); return resolver; }
The final method to get node path (including subpath retrieval example) will look as following:
public static String getPathWithoutLastNode(NodeRef nr) { Path fullPath = nodeService.getPath(nr); Path path = fullPath.subPath(4, fullPath.size()); String pathStr = path.toPrefixString(getNamespaceResolver()); return pathStr; }
Here should be mentioned that subPath() method has start node number and end node number as a first and second parameter respectively. So for some folder that persist in root level of the cm:test site document library (test is the name of site), fullPath will “app:company_home/st:sites/cm:test/cm:documentLibrary/cm:FAQ_x0020_CT_x0020_standart”, and subPath “cm:documentLibrary/cm:FAQ_x0020_CT_x0020_standart”. Also folder name is “FAQ CT Standart”, where spaces escaped with “_x0020_”, other special symbols are also escaped by toPrefixString() method. Using this string path we can built some Lucene search query, for example:
public static List<NodeRef> getTargetFolderPaths(NodeRef nr) { List<NodeRef> res = new ArrayList<NodeRef>(); if (!nodeService.exists(nr)) { System.out.println("WARN. node is not exists: " + nr); return res; } String pathStr = getPathWithoutLastNode(nr); ResultSet resultSet = searchService.query(new StoreRef(StoreRef.PROTOCOL_WORKSPACE, "SpacesStore"), SearchService.LANGUAGE_LUCENE, MessageFormat.format("PATH:\"//{0}\"", pathStr)); for (ResultSetRow row : resultSet) { NodeRef remoteFolder = row.getNodeRef(); if (!siteService.getSite(remoteFolder).getShortName() .equals(Utils.getSiteShortName(Constants.MANAGER_SITE))) { res.add(remoteFolder); } } resultSet.close(); return res; }
This method searches for a root folder by its name within document libraries of each site. If it is found, then further action performed.
Tags: alfresco