Expand my Community achievements bar.

SOLVED

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

Avatar

Level 6

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 6

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.