Hello
I'm trying to create a folder structure (something similar to "mkdir -p" command) using Java API, but when I create a folder, I cannot create a subfolder in it, because a parent folder does not exist yet.
How can I create a folder, commit transition, and then create a subfolder?
Solved! Go to Solution.
Considering you have root folder known, i would follow steps as (no external transaction handling needed):
1- Using the root folder name, get the path of the root folder.
2- Using the TMDQ as suggested, get the root folder node ref.
3- If subfolder (considering an input are separated by multiple paths (like your mkdir -p case), you can split the path and iterate each subfolder and create subfolder within rootfolder and their sub folders.
3- If subfolder is not separated by path, you can directly create the subfoler within root folder.
Here is an example:
String folderPathQuery = getFolderPathQuery(rootFolderName, siteShortName); //Change the query accordingly if not using sites List<NodeRef> selectedNodes = searchService.selectNodes(nodeService.getRootNode(StoreRef.STORE_REF_WORKSPACE_SPACESSTORE), folderPathQuery, null, namespaceService, false); if (selectedNodes != null && !selectedNodes.isEmpty()) { NodeRef rootFolderRef = selectedNodes.get(0); if(rootFolderRef != null && fileFolderService.exists(rootFolderRef)) { if(subFolderName.contains("/")) { String[] pathTokens = subFolderName.split("/"); NodeRef subRootNodeRef = rootFolderRef; for (String subFolder : pathTokens) { subRootNodeRef = fileFolderService.create(subRootNodeRef, subFolder, ContentModel.TYPE_FOLDER).getNodeRef(); } } else { fileFolderService.create(rootFolderRef, subFolderName, ContentModel.TYPE_FOLDER); } } else { // handle and notify message as needed. ROOT FOLDR NOT FOUND } } else { // handle and notify message as needed. } private String getFolderPathQuery(String folderPath, String siteShortName) { StringBuilder queryBuilder = new StringBuilder("/app:company_home/st:sites/"); queryBuilder.append("cm:").append(ISO9075.encode(siteShortName)) .append("/cm:documentLibrary"); if (null != folderPath && !folderPath.isEmpty()) { String[] pathTokens = folderPath.split("/"); if (!"Document Library".equals(folderPath)) { for (String pathToken : pathTokens) { queryBuilder.append("/cm:").append(ISO9075.encode(pathToken)); } } } return queryBuilder.toString(); }
Can you provide detail how you are creating?Some code snippet.
If you are using lucene to search created node then it will take some time because indexing will take time for making content searchable.
You can use Transactional metadata query
By java api do you mean the embeded java foundation api or remote java api ?
If you mean java fondation api ,you shoud inject the capitalized bean name NodeService into your bean,like following
<property name="nodeService" ref="NodeService"/>
If you mean remote java pai ,you can try createPath method of org.apache.chemistry.opencmis.client.api.Session interface
Sure, I do. The method should create a directory structure given a path (similar to mkdir -p command). I used Lucene (is there another way if I don't have noderef, only the human-readable-path?).
private static void createDirectoryStructure(String parentPath, String childName) { StoreRef storeRef = new StoreRef(StoreRef.PROTOCOL_WORKSPACE, "SpacesStore"); ResultSet rs = searchService.query(storeRef, SearchService.LANGUAGE_LUCENE, "PATH:\"" + parentPath + "\""); if (rs.length() == 0) { logger.warn("Didn't find the parent path, trying to create it..."); createParentPath(parentPath); // very similar code rs = searchService.query(storeRef, SearchService.LANGUAGE_LUCENE, "PATH:\"" + parentPath + "\""); if(rs.length() == 0) { throw new AlfrescoRuntimeException("Parent still does not exist!"); } } NodeRef parentRef = rs.getNodeRef(0);
.... }
(I modified the code a bit to make it more readable)
@kaynezhang I mean Java (foundation?) API, not remote. Getting nodeService is not a problem at all, I'm just trying to create a node, and then create another node inside the previously created one.
Considering you have root folder known, i would follow steps as (no external transaction handling needed):
1- Using the root folder name, get the path of the root folder.
2- Using the TMDQ as suggested, get the root folder node ref.
3- If subfolder (considering an input are separated by multiple paths (like your mkdir -p case), you can split the path and iterate each subfolder and create subfolder within rootfolder and their sub folders.
3- If subfolder is not separated by path, you can directly create the subfoler within root folder.
Here is an example:
String folderPathQuery = getFolderPathQuery(rootFolderName, siteShortName); //Change the query accordingly if not using sites List<NodeRef> selectedNodes = searchService.selectNodes(nodeService.getRootNode(StoreRef.STORE_REF_WORKSPACE_SPACESSTORE), folderPathQuery, null, namespaceService, false); if (selectedNodes != null && !selectedNodes.isEmpty()) { NodeRef rootFolderRef = selectedNodes.get(0); if(rootFolderRef != null && fileFolderService.exists(rootFolderRef)) { if(subFolderName.contains("/")) { String[] pathTokens = subFolderName.split("/"); NodeRef subRootNodeRef = rootFolderRef; for (String subFolder : pathTokens) { subRootNodeRef = fileFolderService.create(subRootNodeRef, subFolder, ContentModel.TYPE_FOLDER).getNodeRef(); } } else { fileFolderService.create(rootFolderRef, subFolderName, ContentModel.TYPE_FOLDER); } } else { // handle and notify message as needed. ROOT FOLDR NOT FOUND } } else { // handle and notify message as needed. } private String getFolderPathQuery(String folderPath, String siteShortName) { StringBuilder queryBuilder = new StringBuilder("/app:company_home/st:sites/"); queryBuilder.append("cm:").append(ISO9075.encode(siteShortName)) .append("/cm:documentLibrary"); if (null != folderPath && !folderPath.isEmpty()) { String[] pathTokens = folderPath.split("/"); if (!"Document Library".equals(folderPath)) { for (String pathToken : pathTokens) { queryBuilder.append("/cm:").append(ISO9075.encode(pathToken)); } } } return queryBuilder.toString(); }
Well, that is even more than I wanted. Thank you very much.
@upforsin Glad to hear that.
Ask for and offer help to other Alfresco Content Services Users and members of the Alfresco team.
Related links:
By using this site, you are agreeing to allow us to collect and use cookies as outlined in Alfresco’s Cookie Statement and Terms of Use (and you have a legitimate interest in Alfresco and our products, authorizing us to contact you in such methods). If you are not ok with these terms, please do not use this website.