Expand my Community achievements bar.

July 31st AEM Gems Webinar: Elevate your AEM development to master the integration of private GitHub repositories within AEM Cloud Manager.
SOLVED

How to restrict workflow at different dept of pages in AEM 6.5

Avatar

Level 7

Hi All,

 

I have written a workflow which will unpublsih and move node and it's children from payload path to "/content/archived" path. I am successfully able to do,

 

but the challenge I am facing here or the modification is required here is:

 

1- All the unpublish and move action should be proformed after some hirearchy, example

/content/project/websites/../...

/content/project/location/../../../..

 

it should only perform after level4/--- if the hirearchy like /content/leve1/leve2/level3/level4____ for [/content/project/websites/en-us/a/authors/ {list of author pages and their sub childs}

&& 

it should only perform after level3/--- if the hirearchy like /content/leve1/leve2/level3/____ for [/content/project/location/en-us/a/location_test/ {list of location pages and their sub childs}

 

where as in my workflow I have first restricted to rome root path "/content/project" now how to accomodate for the above level..

 

@Override
    public void execute(WorkItem workItem, WorkflowSession workflowSession, MetaDataMap metaDataMap) throws WorkflowException {
        String payload = workItem.getWorkflowData().getPayload().toString();
        LOG.debug("payload :: {}", payload);
        String workflowInitiator = workItem.getWorkflow().getInitiator();
        if (payload.startsWith("/content/project-content")) {
            ResourceResolver resourceResolver = resourceResolverUtil.getResourceResolver();
            Session session = resourceResolver.adaptTo(Session.class);

            List<String> list = new ArrayList<String>();
            list.add(payload);

            Page rootPage = resourceResolver.getResource(payload).adaptTo(Page.class);
            //LOG.debug("Level :: {}" + rootPage.getAbsoluteParent(4).toString());
            Iterator<Page> childPages = null;
            if (rootPage != null) {
                childPages = rootPage.listChildren(new PublishedPageFilter(), true);
            }
            if (childPages != null) {
                while (childPages.hasNext()) {
                    Page page = childPages.next();
                    list.add(page.getPath());
                }
            }

            String[] paths = list.toArray(new String[0]);

            try {
                replicator.replicate(session, ReplicationActionType.DEACTIVATE, paths, null);
            } catch (ReplicationException e) {
                LOG.debug("Replication exception occurred at :: {}" + Arrays.toString(paths));
            }
            try {
                Node payloadNode = null;
                if (session != null) {
                    payloadNode = session.getNode(payload);
                    String payloadName = null;
                    if (payloadNode != null) {
                        payloadName = payloadNode.getName();
                        String archivePath = DESTINATION_PATH + payload.substring(ROOT_PATH.length(), payload.lastIndexOf("/"));
                        Node archived = JcrUtils.getOrCreateByPath(archivePath, "cq:Page", session);
                        session.move(payloadNode.getPath(), archived.getPath() + "/" + payloadName);
                        setPropertyForNodeAndChildNodes(archived.getNode(payloadName), "archivedBy", workflowInitiator);
                    }
                    session.save();
                }

            } catch (Exception e) {
                LOG.debug("PersistenceException exception occurred at :: {}" + Arrays.toString(paths));
            }
        } else {
            String workflowId = workItem.getWorkflow().getId();
            Workflow workflow = workflowSession.getWorkflow(workflowId);
            workflowSession.terminateWorkflow(workflow);
            LOG.error("Workflow Terminated as path does not start with /content/wem-content : " + workflowId);
        }

 

Thanks.

 

@kautuk_sahni  @lukasz-m  @arunpatidar  @Avinash_Gupta_ 

1 Accepted Solution

Avatar

Correct answer by
Community Advisor

Hi @tushaar_srivastava,

In my opinion you can use combination of getDepth() method from Page object inside PublishPageFilter class. This method returns level of specific page in content hierarchy like that:

For path /content/project/location/en-us/a/location_test you will get:

 | level | returned                                        |
 |     1 | /content                                        |
 |     2 | /content/project                                |
 |     3 | /content/project/location                       |
 |     4 | /content/project/location/en-us                 |
 |     5 | /content/project/location/en-us/a/location_test |

Base on above you should be able to calculate what depth for level 3 and 4.

Moving forward I would try this kind of code:

    private class PublishedPageFilter implements Filter<Page> {

        @Override
        public boolean includes(Page page) {
            return (page != null &&
                    page.adaptTo(ReplicationStatus.class).isActivated() &&
                    (isUnderPathAndLevel(page, "/content/project/websites", 6) ||
                     isUnderPathAndLevel(page, "/content/project/location", 5)));
        }

        private boolean isUnderPathAndLevel(Page page, String path, int level) {
            return page.getPath().startsWith(path) && page.getDepth() > level;
        }
    }

 You will need to adjust value of level and paths. As a result below part of code

rootPage.listChildren(new PublishedPageFilter(), true);

it will return only pages that are published, and are located under specific level in content structure.

View solution in original post

3 Replies

Avatar

Community Advisor

Hi @tushaar_srivastava 
The logic is very simple, I would suggest you to put a debugger and find the issues.

Use https://developer.adobe.com/experience-manager/reference-materials/6-4/javadoc/com/day/cq/wcm/api/Pa... API for page move.

 



Arun Patidar

Avatar

Level 7

Thank you @arunpatidar  for your guidance,

The above code works perfectly fine, the only thing is I want to restrict the author on certiaon leve on pages, means the workflow condition will work on certain level :

/content/project/websites/../...

/content/project/location/../../../..

 

it should only perform after level4/--- if the hirearchy like /content/leve1/leve2/level3/level4____ for [/content/project/websites/en-us/a/authors/ {list of author pages and their sub childs}

&& 

it should only perform after level3/--- if the hirearchy like /content/leve1/leve2/level3/____ for [/content/project/

/content/project/websites/../... [restrict till level4]

/content/project/location/../../../.. [restrict till level3]

 

it should only perform after level4/--- if the hirearchy like /content/leve1/leve2/level3/level4____ for [/content/project/websites/en-us/a/authors/ {list of author pages and their sub childs}

&& 

it should only perform after level3/--- if the hirearchy like /content/leve1/leve2/level3/____ for [/content/project/location/en-us/a/location_test/ {list of location pages and their sub childs}

/en-us/a/location_test/ {list of location pages and their sub childs}

Avatar

Correct answer by
Community Advisor

Hi @tushaar_srivastava,

In my opinion you can use combination of getDepth() method from Page object inside PublishPageFilter class. This method returns level of specific page in content hierarchy like that:

For path /content/project/location/en-us/a/location_test you will get:

 | level | returned                                        |
 |     1 | /content                                        |
 |     2 | /content/project                                |
 |     3 | /content/project/location                       |
 |     4 | /content/project/location/en-us                 |
 |     5 | /content/project/location/en-us/a/location_test |

Base on above you should be able to calculate what depth for level 3 and 4.

Moving forward I would try this kind of code:

    private class PublishedPageFilter implements Filter<Page> {

        @Override
        public boolean includes(Page page) {
            return (page != null &&
                    page.adaptTo(ReplicationStatus.class).isActivated() &&
                    (isUnderPathAndLevel(page, "/content/project/websites", 6) ||
                     isUnderPathAndLevel(page, "/content/project/location", 5)));
        }

        private boolean isUnderPathAndLevel(Page page, String path, int level) {
            return page.getPath().startsWith(path) && page.getDepth() > level;
        }
    }

 You will need to adjust value of level and paths. As a result below part of code

rootPage.listChildren(new PublishedPageFilter(), true);

it will return only pages that are published, and are located under specific level in content structure.