11-08-2020 09:09 AM
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?
11-09-2020 11:24 AM
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(); }
11-08-2020 10:33 PM
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
11-09-2020 09:32 AM
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.
11-09-2020 11:24 AM
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(); }
11-09-2020 12:49 PM
Well, that is even more than I wanted. Thank you very much.
11-09-2020 12:55 PM
@upforsin Glad to hear that.
11-09-2020 02:02 AM
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
Explore our Alfresco products with the links below. Use labels to filter content by product module.