The problem I am facing here that If I move the node from one path to another by creating the same hirearchy and if we move the parent of parent node then I am facing issues like some pages are not moving means the pages whoes child or child of childs are already moved,
I am moving and iterating the node using PageManager API
Example if we pass payload to our workflow : [/content/project/websites/en-us/c/cfolder/cfolder-relateddocs/elevated/super-parent-1/parent-b/child-b/child-of-child-b/grand-child-b]
So we can see our code perfectly moved the grand-child-b to /content/archived/websites/en-us/c/cfolder/cfolder-relateddocs/elevated/super-parent-1/parent-b/child-b/child-of-child-b/grand-child-b:
But Now if we want to move parent-b [/content/archived/websites/en-us/c/cfolder/cfolder-relateddocs/elevated/super-parent-1/parent-b]
the expectation will be it should move all the node from source and retain the already moved node :
But it is moving its child of childs of first child page and returns out of loop:
Archived like only chid of child-b moved and it came out of loop:
and we can see in source : in the child-b jcr:content and childs are are moved and rest didn't moved
Can Anyone please guide here the optimized approach to achive this issue:
here is the sample code I have written for this
@Override
public void execute(WorkItem workItem, WorkflowSession workflowSession, MetaDataMap metaDataMap) throws WorkflowException {
String payload = workItem.getWorkflowData().getPayload().toString();
ResourceResolver resourceResolver = resourceResolverUtil.getResourceResolver();
Session session = resourceResolver.adaptTo(Session.class);
Page rootPage = Objects.requireNonNull(resourceResolver.getResource(payload)).adaptTo(Page.class);
Resource resource = resourceResolver.getResource(payload);
PageManager pageManager = resourceResolver.adaptTo(PageManager.class);
if (rootPage != null) {
List<String> list = new ArrayList<>();
list.add(payload);
Iterator<Page> childPages;
childPages = rootPage.listChildren(new PublishedPageFilter(), true);
if (childPages != null) {
while (childPages.hasNext()) {
Page page1 = childPages.next();
list.add(page1.getPath());
}
}
String[] paths = list.toArray(new String[0]);
try {
assert resource != null;
Page page = resource.adaptTo(Page.class);
String archivePath = StringUtils.substringAfter(payload, ROOT_PATH);
archivePath = StringUtils.substringBeforeLast(archivePath, DELIMITER_SLASH);
archivePath = StringUtils.join("/content/archived", archivePath);
Node archived = JcrUtils.getOrCreateByPath(archivePath, "cq:Page", session);
String targetPath = archived.getPath() + "/" + rootPage.getName();
if (session.nodeExists(targetPath)) {
callingChildOc(pageManager, rootPage, session);
} else {
if (pageManager != null) {
pageManager.move(page, targetPath, null, false, true, null);
}
}
if (!session.nodeExists(targetPath + "/jcr:content") && session.nodeExists(rootPage.getPath() + "/jcr:content")) {
Node jcr = session.getNode(rootPage.getPath() + "/jcr:content");
String targetJcr = jcr.getPath().replace("/content/project", "/content/archived");
session.move(jcr.getPath(), targetJcr);
pageManager.delete(rootPage, true);
//session.save();
}
session.save();
} catch (RepositoryException | WCMException e) {
loggerService.postLog(LogLevel.ERROR, "RepositoryException exception occurred at :: {}" + Arrays.toString(paths));
} catch (Exception e) {
throw new RuntimeException(e);
} finally {
if (resourceResolver.isLive()) {
resourceResolver.close();
}
}
} else {
String workflowId = workItem.getWorkflow().getId();
Workflow workflow = workflowSession.getWorkflow(workflowId);
workflowSession.terminateWorkflow(workflow);
loggerService.postLog(LogLevel.ERROR, "Workflow Terminated as path does not start with /content/wem-content :: {}" + workflowId + " or payload is having more than one level of child pages ");
}
}
private static void callingChildOc(PageManager pageManager, Page rootPath, Session session) throws WCMException, RepositoryException, InterruptedException {
Iterator<Page> childIterators = rootPath.listChildren();
LOG.debug("1 :: " + rootPath.getName());
if (childIterators != null) {
while (childIterators.hasNext()) {
Page innerPage = childIterators.next();
callingChildOc(pageManager, innerPage, session);
}
}
String rootPathPayload = rootPath.getPath();
LOG.debug("2 :: {}" + rootPathPayload);
String childOfChildPathTarget = rootPathPayload.replace("/content/wem-content", "/content/wem-archived");
if (!session.nodeExists(childOfChildPathTarget)) {
LOG.debug("3 archive ::{}" + childOfChildPathTarget);
pageManager.move(rootPath, childOfChildPathTarget, null, false, true, null);
} else {
if (!session.nodeExists(rootPathPayload.replace("/content/wem-content", "/content/wem-archived") + "/jcr:content")
&& session.nodeExists(rootPathPayload + "/jcr:content")) {
Node jcr = session.getNode(rootPath.getPath() + "/jcr:content");
String childOfChildPathTargets = jcr.getPath().replace("/content/wem-content", "/content/wem-archived");
LOG.debug("4 final jcr move :: {}" + childOfChildPathTargets);
session.move(jcr.getPath(), childOfChildPathTargets);
pageManager.delete(rootPath, true);
//session.save();
}
}
}
}
Thanks
@arunpatidar @kautuk_sahni @lukasz-m @Tanika02
Solved! Go to Solution.
Views
Replies
Total Likes
Hope below solution helps for recursive movement of child nodes from source to the target.
private static void callingChildOc(PageManager pageManager, Page rootPage, Session session) throws WCMException {
Iterator<Page> childIterators = rootPage.listChildren();
if (childIterators != null) {
while (childIterators.hasNext()) {
Page childPage = childIterators.next();
String childPath = childPage.getPath();
String childArchivePath = StringUtils.replace(childPath, "/content/project", "/content/archived");
if (!session.nodeExists(childArchivePath)) {
pageManager.move(childPage, childArchivePath, null, false, true, null);
} else{
callingChildOc(pageManager, childPage, session);
}
}
}
True, similar implementation is done on above code but
This issue here is if we move the parent of parent node then I am getting ItemExistException or IllegaleArgumentException shallow not possible on empty page aem
Example if I move page from child-1 [/content/project/partent/sub-parent/child-1]
/content
/project
/partent
/sub-parent
/child-1
/child-2
So our code will move it to [/content/archived/parent/sub-parent/child-1]
But Getting exception when I am moving Parent page [/content/archived/parent] {ItemExistException or shallow not possible on empty page aem.
ItemExistException is thrown because you already have page with same name at location where you trying to move a page and shallow not possible on empty page is thrown when there is no jcr:content node under a page and you try that page move with shallow option as 'true'.
Can you try this below code? I have tested it in my local and it works.
public void execute(WorkItem item, WorkflowSession session, MetaDataMap args)
throws WorkflowException {
final WorkflowData workflowData = item.getWorkflowData();
String payload = workflowData.getPayload().toString();
PageManager pageManager = resourceResolver.adaptTo(PageManager.class);
Page pageTreeToMove = pageManager.getPage(payload);
// Assuming /content/archived hierarchy already exists (This needs to be created manually)
String[] strArray = StringUtils.split(pageTreeToMove.getPath(), "/");
String targetRootPath = "/content/archived";
String sourceRootPath = "/" + strArray[0] + "/" + strArray[1];
String sourcePath = sourceRootPath;
String targetPath = targetRootPath;
for (int i = 2; i < strArray.length; i++) { // Skipping /content/project
sourcePath = sourcePath + "/" + strArray[i];
targetPath = targetPath + "/" + strArray[i];
Page sourcePage = pageManager.getPage(sourcePath);
Page targetPage = pageManager.getPage(targetPath);
if (Objects.isNull(targetPage)) {
try {
pageManager.move(sourcePage, targetPath, null, true, false, new String[] {});
} catch (WCMException e) {
log.error("error occured while moving parent pages: ", e);
}
}
}
Iterator<Page> childPagesIterator = pageTreeToMove.listChildren();
while (childPagesIterator.hasNext()) {
Page childPage = childPagesIterator.next();
String childPageArchivePath =
StringUtils.replace(childPage.getPath(), sourceRootPath, "/content/archived");
if (Objects.isNull(pageManager.getPage(childPageArchivePath))) {
try {
pageManager.move(childPage, childPageArchivePath, null, false, false, new String[] {});
} catch (WCMException e) {
log.error("error occured while moving child pages: ", e);
}
}
}
}
Here I am first moving whole parent pages hierarchy by checking each page in hierarchy if its exist or not in archived path. Please note here that shallow option is set to true. After moving parent hierarchy I am moving all child pages by setting shallow option as false.
Hi @salamswapnil ,
I tried with the approach you suggested it is still breaking for me I have updated the above question with my working code, the only thing is it is breaking for some hirearchy which is already present in moved path.
Could you please review the above and provide your guidance
Thanks
As per my understanding :
Possible Solution :
Thankyou @kautuk_sahni
Hope below solution helps for recursive movement of child nodes from source to the target.
private static void callingChildOc(PageManager pageManager, Page rootPage, Session session) throws WCMException {
Iterator<Page> childIterators = rootPage.listChildren();
if (childIterators != null) {
while (childIterators.hasNext()) {
Page childPage = childIterators.next();
String childPath = childPage.getPath();
String childArchivePath = StringUtils.replace(childPath, "/content/project", "/content/archived");
if (!session.nodeExists(childArchivePath)) {
pageManager.move(childPage, childArchivePath, null, false, true, null);
} else{
callingChildOc(pageManager, childPage, session);
}
}
}