Activate a page and its assets programmatically

AEM provides Replicator (com.day.cq.replication.Replicator) service which can be used in order to activate pages programmatically.

All you need to do is to define a field in your service class (or servlet, Sling model, etc.) of the type com.day.cq.replication.Replicator, let OSGi injects the reference to Replicator service and use it on the following way:

import com.day.cq.replication.Replicator;
import org.apache.felix.scr.annotations.Component;
import org.apache.felix.scr.annotations.Service;
import org.apache.felix.scr.annotations.Reference;
import javax.jcr.Session;
import com.day.cq.replication.ReplicationActionType;

@Component
@Service(ReplicationService.class)
public class ReplicationServiceImpl implements ReplicationService {

@Reference
private Replicator replicator;

@Override
public void activatePage(Session session, String path) throws ReplicationException {
replicator.replicate(session, ReplicationActionType.ACTIVATE, path);
}

}

This is not the whole story because DAM assets, referenced by a page will not be published automatically. We have to do the same for all page assets.

Instead of checking a page node structure for ‘fileReference’ property, AEM provides a handful class com.day.cq.dam.commons.util.AssetReferenceSearch. So the final code would look like this one:

// ... class declaration remains unchanged

@Override
public void activatePage(ResourceResolver resourceResolver, String pagePath) throws ReplicationException {
activate(resourceResolver.adaptTo(Session.class), pagePath);
activatePageAssets(resourceResolver, pagePath);
}

private void activatePageAssets(ResourceResolver resourceResolver, String pagePath) throws ReplicationException {
Set<String> pageAssetPaths = getPageAssetPaths(pagePath, resourceResolver);
if(pageAssetPaths.isEmpty()) {
return;
}
Session session = resourceResolver.adaptTo(Session.class);
for (String assetPath : pageAssetPaths) {
activate(session, assetPath);
}
}

private Set<String> getPageAssetPaths(ResourceResolver resourceResolver, String pagePath) {
PageManager pm = resourceResolver.adaptTo(PageManager.class);
Page page = pm.getPage(pagePath);
if(page == null) {
return new HashSet<>();
}
Resource contentResource = page.getContentResource();
AssetReferenceSearch arSearch = new AssetReferenceSearch(contentResource.adaptTo(Node.class), DamConstants.MOUNTPOINT_ASSETS, resourceResolver);
Map<String, Asset> assetMap = arSearch.search();
return assetMap.keySet();
}

private void activate(Session session, String path) throws ReplicationException {
replicator.replicate(session, ReplicationActionType.ACTIVATE, path);
}