
com.adobe.forms.foundation.service.util.FormsFoundationUtils Maven / Gradle / Ivy
/*************************************************************************
*
* ADOBE CONFIDENTIAL
* ___________________
*
* Copyright 2015 Adobe Systems Incorporated
* All Rights Reserved.
*
* NOTICE: All information contained herein is, and remains
* the property of Adobe Systems Incorporated and its suppliers,
* if any. The intellectual and technical concepts contained
* herein are proprietary to Adobe Systems Incorporated and its
* suppliers and are protected by trade secret or copyright law.
* Dissemination of this information or reproduction of this material
* is strictly forbidden unless prior written permission is obtained
* from Adobe Systems Incorporated.
**************************************************************************/
package com.adobe.forms.foundation.service.util;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import javax.jcr.Node;
import javax.jcr.NodeIterator;
import javax.jcr.RepositoryException;
import javax.jcr.Session;
import javax.jcr.Value;
import javax.jcr.nodetype.NodeType;
import org.apache.commons.lang3.StringUtils;
import org.apache.felix.scr.annotations.Component;
import org.apache.felix.scr.annotations.Reference;
import org.apache.felix.scr.annotations.Service;
import org.apache.jackrabbit.util.Text;
import org.apache.sling.api.resource.ModifiableValueMap;
import org.apache.sling.api.resource.Resource;
import org.apache.sling.api.resource.ResourceResolver;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.adobe.forms.foundation.service.FormsAssetType;
import com.adobe.forms.foundation.service.FormsFoundationException;
import com.adobe.forms.foundation.transfer.CopiedAssetInfo;
import com.adobe.granite.resourceresolverhelper.ResourceResolverHelper;
import com.day.cq.commons.jcr.JcrConstants;
import com.day.cq.tagging.Tag;
import com.day.cq.tagging.TagManager;
import com.day.cq.wcm.api.Page;
import com.day.cq.wcm.api.PageManager;
import com.day.cq.wcm.commons.ReferenceSearch;
/**
* @author sharoon
* @date Dec 2, 2015
* @time 4:06:52 PM
*/
@Service(value=FormsFoundationUtils.class)
@Component
@org.apache.felix.scr.annotations.Properties({
@org.apache.felix.scr.annotations.Property(name = "connectors.jsoninvoker", boolValue = true),
@org.apache.felix.scr.annotations.Property(name = "connectors.jsoninvoker.alias", value = "ff.FormsFoundationUtils")
})
public class FormsFoundationUtils {
private static final Logger logger = LoggerFactory.getLogger(FormsFoundationUtils.class);
@Reference
private ResourceResolverHelper resourceResolverHelper;
private static final Map cmAssetTypeMap = new HashMap();
private static final List supportedDAMDocumentFormats = new ArrayList();
private static Pattern ptrnAllDigits = Pattern.compile("^\\d+$");
private static final String LCC_CLASSNAME = "lcc:className";
private static final String DAM_ASSET_TYPE = "dam:Asset";
private static final String NT_UNSTRUCTURED_TYPE = "nt:unstructured";
private static final String SLING_FOLDER = "sling:Folder";
private static final String CQ_TEMPLATE_TYPE = "cq:Template";
private static final String SLING_RESOURCE_TYPE = "sling:resourceType";
private static final String CQ_PAGE_TYPE = "cq:Page";
private static final String COPY_STR = "-copy";
private static final String COPY_STR_FOR_DD = "copy";
public static final String STR_SLING_ORDERED_FOLDER = "sling:OrderedFolder";
public static final String STR_NT_FOLDER = "nt:folder";
public static final String CM_MIXIN = "cm:resource";
public static final String FORM_ROOT_PATH = "/content/dam/formsanddocuments";
public static final String FORM_PAGE_ROOT_PATH = "/content/forms/af";
static {
// Populate the CM assets type map
cmAssetTypeMap.put("com.adobe.icc.dbforms.obj.FragmentLayout", FormsAssetType.FRAGMENT_LAYOUT);
cmAssetTypeMap.put("com.adobe.icc.dbforms.obj.Form", FormsAssetType.LETTER_LAYOUT);
cmAssetTypeMap.put("com.adobe.icc.dbforms.obj.TextModule", FormsAssetType.TEXT);
cmAssetTypeMap.put("com.adobe.icc.dbforms.obj.ListDataModule", FormsAssetType.LIST);
cmAssetTypeMap.put("com.adobe.icc.dbforms.obj.ConditionalDataModule", FormsAssetType.CONDITION);
cmAssetTypeMap.put("com.adobe.dct.transfer.DataDictionary", FormsAssetType.DATA_DICTIONARY);
cmAssetTypeMap.put("com.adobe.icc.dbforms.obj.Letter", FormsAssetType.LETTER);
// To support import of old collateral assets in CM
cmAssetTypeMap.put("com.adobe.icc.dbforms.obj.Category", FormsAssetType.CATEGORY);
cmAssetTypeMap.put("com.adobe.icc.dbforms.obj.ImageModule", FormsAssetType.IMAGE);
cmAssetTypeMap.put("com.adobe.icc.dbforms.obj.ContentDataModule", FormsAssetType.CONTENT);
/* Adding supported DAM Document types*/
supportedDAMDocumentFormats.add("application/pdf");
supportedDAMDocumentFormats.add("application/vnd.ms-excel");
supportedDAMDocumentFormats.add("application/vnd.openxmlformats-officedocument.wordprocessingml.document");
supportedDAMDocumentFormats.add("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
supportedDAMDocumentFormats.add("application/vnd.ms-powerpoint");
supportedDAMDocumentFormats.add("application/vnd.openxmlformats-officedocument.presentationml.presentation");
}
public FormsAssetType getAssetType(String assetId) throws FormsFoundationException {
Node node = mapAssetIdToNode(assetId);
return getAssetType(node);
}
public FormsAssetType getAssetType(Node node) throws FormsFoundationException {
if (node == null) {
throw new FormsFoundationException(FormsFoundationException.INVALID_INPUT_PARAMETERS, new Object[]{});
}
FormsAssetType assetType = null;
try {
if (node.isNodeType(NT_UNSTRUCTURED_TYPE)) {
if (node.hasProperty(LCC_CLASSNAME)) {
String propValue = node.getProperty(LCC_CLASSNAME).getString();
assetType = cmAssetTypeMap.get(propValue);
}
} else if (node.isNodeType(DAM_ASSET_TYPE)) {
if (node.hasNode("jcr:content")) {
node = node.getNode("jcr:content");
if (node.hasProperty("xfaForm")) {
assetType = FormsAssetType.XDP;
} else if (node.hasProperty("pdfForm")) {
assetType = FormsAssetType.PDF;
} else if (node.hasProperty("lcResource")) {
assetType = FormsAssetType.FM_RESOURCE;
} else if (node.hasProperty("guide")) {
assetType = FormsAssetType.ADAPTIVE_FORM;
} else if (node.hasProperty("formset")) {
assetType = FormsAssetType.FORMSET;
} else if (node.hasProperty("affragment")) {
assetType = FormsAssetType.ADAPTIVE_FORM_FRAGMENT;
} else if (node.hasProperty("adaptivedocument")) {
assetType = FormsAssetType.ADAPTIVE_DOCUMENT;
} else if (node.hasProperty("theme")) {
assetType = FormsAssetType.THEME;
} else if (node.hasProperty("printForm")) {
assetType = FormsAssetType.PRINT_FORM;
} else if (node.hasProperty("metadata/dc:format")) {
String dcFormat = node.getProperty("metadata/dc:format").getString();
if(dcFormat.startsWith("image/")) {
assetType = FormsAssetType.DAM_IMAGE;
} else if(supportedDAMDocumentFormats.contains(dcFormat)) {
assetType = FormsAssetType.DAM_DOCUMENT;
} else {
assetType = FormsAssetType.EXTERNAL;
}
} else if(node.hasProperty("type")) {
String type = node.getProperty("type").getString();
if(StringUtils.isNotEmpty(type)) {
try{
assetType = FormsAssetType.valueOf(type.toUpperCase());
}catch(Exception e){
// move ahead
}
}
} else {
assetType = FormsAssetType.EXTERNAL;
}
}
} else if (node.isNodeType(CQ_PAGE_TYPE)) {
assetType = FormsAssetType.CQ_PAGE;
} else if (node.isNodeType(SLING_FOLDER)) {
assetType = FormsAssetType.FOLDER;
} else if (node.isNodeType(CQ_TEMPLATE_TYPE)) {
if (node.hasProperty("jcr:content/cq:templateType") && "/libs/settings/wcm/template-types/web-channel-page".equals(node.getProperty("jcr:content/cq:templateType").getString())){
assetType = FormsAssetType.ADAPTIVE_DOCUMENT_TEMPLATE;
} else if (node.hasProperty("initial/jcr:content/guideComponentType")) {// TODO Improve the check - adapt Resource to Template and then checking for structured templates should be enough instead of relying on hardcoded relative path for guidecomponenttype
assetType = FormsAssetType.ADAPTIVE_FORM_TEMPLATE;
}
} else if (node.hasProperty(SLING_RESOURCE_TYPE)
&& "wcm/core/components/policy/policy".equals(node.getProperty(SLING_RESOURCE_TYPE).getString())) {
// TODO Improve the check and adapt Resource to ContentPolicy instead of relying on RT
assetType = FormsAssetType.WCM_CONTENT_POLICY;
}
if (assetType == null) {
throw new FormsFoundationException(FormsFoundationException.UNABLE_TO_DETERMINE_ASSET_TYPE, new Object[]{node.getPath()});
}
} catch (FormsFoundationException e) {
throw e;
} catch (Exception e) {
throw new FormsFoundationException(e);
}
return assetType;
}
public String[] getResolvedAssetTags(Node node) throws FormsFoundationException {
if (node == null) {
throw new FormsFoundationException(FormsFoundationException.INVALID_INPUT_PARAMETERS, new Object[]{});
}
String[] tags = null;
try {
FormsAssetType assetType = getAssetType(node);
if (node.hasProperty(assetType.getTagsProperty())) {
Value[] values = node.getProperty(assetType.getTagsProperty()).getValues();
tags = new String[values.length];
for (int i = 0; i< values.length; i++) {
tags[i] = values[i].getString();
}
}
} catch (FormsFoundationException e) {
throw e;
} catch (Exception e) {
throw new FormsFoundationException(e);
}
if (tags != null)
return resolveTags(tags);
else
return tags;
}
public String[] getResolvedAssetTags(String assetId) throws FormsFoundationException {
Node node = mapAssetIdToNode(assetId);
return getResolvedAssetTags(node);
}
public String[] resolveTags(String[] tagNames) throws FormsFoundationException {
if (tagNames == null) {
throw new FormsFoundationException(FormsFoundationException.INVALID_INPUT_PARAMETERS, new Object[]{});
}
TagManager tagManger = getTagManager();
List resolvedTags = new ArrayList();
for (int i=0; i < tagNames.length; i++) {
Tag tag = tagManger.resolve(tagNames[i]);
if (tag != null) {
resolvedTags.add(tag.getPath());
} else {
logger.warn("Tag named " + tagNames[i] + " does not exists.");
}
}
return resolvedTags.toArray(new String[resolvedTags.size()]);
}
private Node mapAssetIdToNode(String assetId) throws FormsFoundationException {
Node node = null;
try {
if (assetId == null || assetId.trim().isEmpty()) {
throw new FormsFoundationException(FormsFoundationException.INVALID_INPUT_PARAMETERS, new Object[]{});
}
Session session = getCurrentSession();
if (!session.nodeExists(assetId)) {
Object[] params = {assetId};
throw new FormsFoundationException(FormsFoundationException.NODE_DOES_NOT_EXISTS, params);
}
node = session.getNode(assetId);
} catch (FormsFoundationException e) {
throw e;
} catch (Exception e) {
throw new FormsFoundationException(e);
}
return node;
}
public Session getCurrentSession() throws FormsFoundationException {
ResourceResolver resolver = resourceResolverHelper.getResourceResolver();
if (resolver == null) {
throw new FormsFoundationException(FormsFoundationException.UNABLE_TO_CURRENT_USER_SESSION, (Object[])null);
}
return resolver.adaptTo(Session.class);
}
/**
* This function returns the title of the given asset path.
* @param path
* @return a string value
* @throws FormsFoundationException
*/
public String getAssetTitle(String path) throws FormsFoundationException {
String title = null;
try {
Node node = mapAssetIdToNode(path);
FormsAssetType assetType = getAssetType(node);
if (node.hasProperty(assetType.getTitleProperty())) {
title = node.getProperty(assetType.getTitleProperty()).getValue().toString();
}
} catch (FormsFoundationException e) {
throw e;
} catch (Exception e) {
throw new FormsFoundationException(e);
}
return title;
}
/**
* Check whether assetName is present at destinationPath.
* @param assetName
* @param destinationPath
* @return a boolean value
*/
public boolean nodeExists(String assetName, String destinationPath) {
boolean nodeExists = true;
try {
if(StringUtils.isEmpty(assetName)) {
throw new FormsFoundationException(FormsFoundationException.INVALID_INPUT_PARAMETERS, new Object[]{});
}
if(StringUtils.isEmpty(destinationPath)) {
throw new FormsFoundationException(FormsFoundationException.INVALID_INPUT_PARAMETERS, new Object[]{});
}
mapAssetIdToNode(destinationPath+"/"+assetName);
} catch (FormsFoundationException e) {
nodeExists = false;
logger.debug("Exception occured in nodeExists function "+e);
}
return nodeExists;
}
/**
* Calculating index of integer part starting in name after last occurrence of copy string.
* Divide string in two parts prefix(String part) and suffix(Numerical part)
* If name is user generated in bad format prefix should append copy string.
* e.g. 1. name = "Test-copy1", then prefix = "Test-copy" and suffix = "1"
* 2. name = "Test-copy1-copy2", then prefix = "Test-copy1-copy" and suffix = "2"
* 3. name = "Test", then prefix = "Test-copy" and suffix = "0"
* For data dictionaries hypen(-) is not allowed in name.
* @param name
* @param sourceAssetPath
* @return a map with "prefix" & "suffix" as keys
*/
private Map findAssetPrefixAndSuffix (String name, String sourceAssetPath) throws FormsFoundationException {
String suffix = null, prefix = null;
int indexOfSuffix = -1;
Integer versionNumber = 0;
FormsAssetType assetType = getAssetType(sourceAssetPath);
String copy = (assetType == FormsAssetType.DATA_DICTIONARY) ? COPY_STR_FOR_DD : COPY_STR;
Map resultMap = new HashMap();
if(name.lastIndexOf(copy) != -1) {
indexOfSuffix = name.lastIndexOf(copy) + copy.length();
prefix = name.substring(0, indexOfSuffix);
// If valid suffix exists.
if(name.length() > indexOfSuffix) {
suffix = name.substring(indexOfSuffix);
Matcher matcher = ptrnAllDigits.matcher(suffix);
if(matcher.find()) {
versionNumber = Integer.parseInt(suffix);
} else {
prefix = prefix + copy;
}
}
} else {
// append copy if copy string does not exists.
prefix = name + copy;
}
resultMap.put("prefix", prefix);
resultMap.put("suffix", versionNumber.toString());
return resultMap;
}
/**
* Generating default name for single asset.
* @param name
* @param path
* @param sourceAssetPath
* @return a string of generated asset name
* @throws FormsFoundationException
*/
private String generateCopiedAssetName(String name, String path, String sourceAssetPath) throws FormsFoundationException {
try {
Session session = getCurrentSession();
Node node = null;
String prefix = null, copiedAssetName = null;
Map nameInfoMap = new HashMap();
// index of suffix, and maximum integer value of copied asset.
int versionNumber = 0;
//If source asset name is not present at destination path, then copied asset name will be same as source asset name.
//Else divide the source asset name into prefix & suffix(version number) and find the highest version number.
if(!nodeExists(name, path)) {
copiedAssetName = name;
} else {
node = session.getNode(path);
if(node != null) {
Node childNode = null;
String resourceName = null;
String resourceSuffix = null;
Matcher matcher;
int value = 0;
nameInfoMap = findAssetPrefixAndSuffix(name, sourceAssetPath);
prefix = nameInfoMap.get("prefix");
versionNumber = Integer.parseInt(nameInfoMap.get("suffix"));
NodeIterator iterator = node.getNodes(prefix+"*");
while (iterator.hasNext()) {
childNode = iterator.nextNode();
resourceName = childNode.getName();
resourceSuffix = resourceName.substring(prefix.length());
matcher = ptrnAllDigits.matcher(resourceSuffix);
if(matcher.find()) {
value = Integer.parseInt(resourceSuffix);
if(versionNumber < value)
versionNumber = value;
}
}
copiedAssetName = prefix + ++versionNumber;
}
}
return copiedAssetName;
} catch (Exception e) {
throw new FormsFoundationException(e);
}
}
/**
* Generating default name for multiple assets.
* This function uses generateCopiedAssetName function for each asset.
* @param selectedItemsPath
* @param destinationFolderPath
* @return a map of CopiedAssetInfo with key as sourceAssetPath
* @throws FormsFoundationException
*/
public Map generateCopiedAssetNames(String[] selectedItemsPath, String destinationFolderPath) throws FormsFoundationException {
// assetNameMap is used to store prefix as key and versionNumber(suffix) as value
Map assetNameMap = new HashMap();
String prefix = null;
Map nameInfoMap = new HashMap();
// index of suffix, and maximum integer value of copied asset.
int versionNumber = 0;
String sourceAssetName, assetTitle, copiedAssetName;
Map copiedAssetInfoMap = new HashMap();
CopiedAssetInfo copiedAssetInfo = null;
try {
if(selectedItemsPath == null || selectedItemsPath.length <= 0) {
throw new FormsFoundationException(FormsFoundationException.INVALID_INPUT_PARAMETERS, new Object[]{});
}
if(StringUtils.isEmpty(destinationFolderPath)) {
throw new FormsFoundationException(FormsFoundationException.INVALID_INPUT_PARAMETERS, new Object[]{});
}
for(String sourceAssetPath: selectedItemsPath) {
copiedAssetInfo = new CopiedAssetInfo();
sourceAssetName = mapAssetIdToNode(sourceAssetPath).getName();
assetTitle = getAssetTitle(sourceAssetPath);
int version = 0;
//find assetName prefix
nameInfoMap = findAssetPrefixAndSuffix(sourceAssetName, sourceAssetPath);
prefix = nameInfoMap.get("prefix");
//if assetName prefix is present in assetNameMap, then generate copiedAssetName using the information from assetNameMap
//else generate the copiedAssetName using generateCopiedAssetName function and store copiedAssetName prefix and version number(suffix) in assetNameMap.
if (assetNameMap.containsKey(prefix)) {
version = assetNameMap.get(prefix) + 1;
copiedAssetName = prefix + version;
assetNameMap.put(prefix, version);
} else {
copiedAssetName = generateCopiedAssetName(sourceAssetName, destinationFolderPath, sourceAssetPath);
//if asset with same name is not present at destinationPath, then copiedAssetName = assetName.
if(copiedAssetName.equals(sourceAssetName)) {
prefix = copiedAssetName;
versionNumber = version;
} else {
//Find copiedAssetName prefix and version number(suffix) and store this info in assetNameMap.
nameInfoMap = findAssetPrefixAndSuffix(copiedAssetName, sourceAssetPath);
prefix = nameInfoMap.get("prefix");
versionNumber = Integer.parseInt(nameInfoMap.get("suffix"));
}
assetNameMap.put(prefix, versionNumber);
}
copiedAssetInfo.setAssetName(copiedAssetName);
copiedAssetInfo.setAssetTitle(assetTitle);
copiedAssetInfoMap.put(sourceAssetPath, copiedAssetInfo);
}
} catch (FormsFoundationException e) {
throw e;
} catch (Exception e) {
throw new FormsFoundationException(e);
}
return copiedAssetInfoMap;
}
/**
* This function returns list of node path of all child nodes present at folderpath.
* If depth is greater than zero, then the child nodes path up to the depth passed will be included.
* If depth is zero or negative then all child nodes path will be included.
* Folder details will be included depending on includeFolderDetails flag.
* @param folderPath
* @param depth
* @param includeFolderPath
* @return a list of all nodes path present at folderpath
* @throws FormsFoundationException
*/
public List getChildAssetsPath(String folderPath, int depth, boolean includeChildFolderPath) throws FormsFoundationException {
try {
List childNodePathList = new ArrayList();
if(StringUtils.isEmpty(folderPath)) {
throw new FormsFoundationException(FormsFoundationException.INVALID_INPUT_PARAMETERS, new Object[]{});
}
Node node = mapAssetIdToNode(folderPath);
childNodePathList = listChildren(node, 0, depth, includeChildFolderPath);
return childNodePathList;
} catch (FormsFoundationException e) {
throw e;
} catch (Exception e) {
throw new FormsFoundationException(e);
}
}
private List listChildren (Node node, int currentDepth, int desiredDepth, boolean includeChildFolderPath) throws FormsFoundationException {
try {
List childNodePathList = new ArrayList();
String childNodePath = null;
NodeIterator iterator = node.getNodes();
currentDepth++;
Node childNode = null;
while (iterator.hasNext()) {
childNode = iterator.nextNode();
if (childNode != null && (currentDepth <= desiredDepth || desiredDepth <= 0)) {
childNodePath = childNode.getPath();
if(childNode.isNodeType(DAM_ASSET_TYPE) || hasMixin(childNode, CM_MIXIN)){
childNodePathList.add(childNodePath);
} else if (childNode.isNodeType(STR_SLING_ORDERED_FOLDER) || childNode.isNodeType(STR_NT_FOLDER)
|| childNode.isNodeType(SLING_FOLDER)) {
if(includeChildFolderPath) {
childNodePathList.add(childNodePath);
}
childNodePathList.addAll(listChildren(childNode, currentDepth, desiredDepth, includeChildFolderPath));
}
}
}
return childNodePathList;
} catch (FormsFoundationException e) {
throw e;
} catch (Exception e) {
throw new FormsFoundationException(e);
}
}
private boolean hasMixin(Node node,String mixin) throws RepositoryException {
if(node == null || mixin == null)
return false;
NodeType [] nodeTypes =node.getMixinNodeTypes();
if(nodeTypes != null )
{
for(NodeType nodeType:nodeTypes)
{
if(mixin.equals(nodeType.getName()))
return true;
}
}
return false;
}
/**
* update source path to destination path in all references path
* @param sourcePath
* @param destinationPath
* @param referencesPath
* @throws FormsFoundationException
*/
public void updateReferences(String sourcePath, String destinationPath, String[] referencesPath) throws FormsFoundationException {
try {
if(sourcePath == null) {
throw new FormsFoundationException("Source Path is null");
}
if(destinationPath == null) {
throw new FormsFoundationException("Destination Path is null");
}
if(referencesPath != null && referencesPath.length > 0) {
logger.info("Updating references");
List referencesList = new ArrayList();
for(String referencePath: referencesPath) {
if(!referencePath.equals(sourcePath)) {
referencesList.add(referencePath);
FormsAssetType type = getAssetType(referencePath);
switch(type) {
case ADAPTIVE_DOCUMENT:
case ADAPTIVE_FORM:
case ADAPTIVE_FORM_FRAGMENT:
referencesList.add(getCQPagePath(referencePath));
break;
}
}
}
// added moved asset as it may contain path to its node
referencesList.add(destinationPath);
ReferenceSearch refSearch = new ReferenceSearch();
refSearch.adjustReferences(resourceResolverHelper.getResourceResolver(), sourcePath, destinationPath, (String[]) referencesList.toArray(new String[0]));
}
} catch (FormsFoundationException e) {
throw e;
} catch(Exception e) {
throw new FormsFoundationException(e);
}
}
public String getCQPagePath(String assetPath) {
assetPath = assetPath.replace(FORM_ROOT_PATH, FORM_PAGE_ROOT_PATH);
return assetPath;
}
private TagManager getTagManager() throws FormsFoundationException{
ResourceResolver resolver = resourceResolverHelper.getResourceResolver();
if (resolver == null) {
throw new FormsFoundationException(FormsFoundationException.UNEXPECTED_ERROR, new String[]{"Resource resolever is null"});
}
return resolver.adaptTo(TagManager.class);
}
/**
* This method returns the root path of given asset.
* @param assetPath
* @return String
* @throws FormsFoundationException
*/
public String getRootPath(String assetPath) throws FormsFoundationException {
String rootPath = "";
FormsAssetType assetType = getAssetType(assetPath);
if(assetType != null) {
rootPath = assetType.getRootPath();
}
return rootPath;
}
/**
* returns corresponding shadow node path under /content/dam/formsanddocuments.
* This method doesn't check path's existence
*
* @param assetPagePath
* @return corresponding shadow node path under /content/dam/formsanddocuments.
*/
public String getCorrespondingShadowNodePath(String assetPagePath) {
return assetPagePath.replace(FORM_PAGE_ROOT_PATH, FORM_ROOT_PATH);
}
/**
* Given a page path under /content/forms/af, return the top level asset cq page
* path e.g. a page representive of /content/forms/af/ic1/channels/web would
* return /content/forms/af/ic1 where both /content/forms/af/ic1 and
* /content/forms/af/ic1/channels/web are cq pages This method assumes that the
* top level asset is also a cq page and resides under /content/forms/af
*
* @param page
* a page path under /content/forms/af
* @return the top level asset cq page path
*/
public String getContainingAssetPagePath(Page page) {
Page parent = page;
PageManager pm = page.getPageManager();
String assetPath = null;
while (parent != null) {
assetPath = parent.getPath();
if (Text.isDescendantOrEqual(assetPath, FORM_PAGE_ROOT_PATH)) {
break;
}
int idx = assetPath.lastIndexOf("/");
String parentPath = null;
if (idx >= 0) {
parentPath = assetPath.substring(0, idx);
}
parent = pm.getContainingPage(parentPath);
}
return assetPath;
}
/**
* Tries to set the property change specified by {@code propName} and
* {@code propValue} on shadow node i.e. the node under
* /content/dam/formsanddocuments This method should be used to propagate
* changes to any property to the shadow node e.g. when lastModifiedTime changes
* under /content/forms/af/ic1/channels/web, then
* /content/dam/formsanddocuments/ic1 can be notified of the same change
*
* @param page
* a page in the hierarchy of a forms and documents asset
* representation under /content/forms/af
* @param propName e.g. jcr:lastModifiedTime
* @param propValue e.g. a Calendar instance
* @param resolver
* @param commit true if commit should be done, false otherwise
* @throws FormsFoundationException if {@code commit} is true and commit fails
*/
public void propagatePropertyToShadowNode(Page page, String propName, Object propValue, ResourceResolver resolver,
boolean commit) throws FormsFoundationException {
String assetPagePath = getContainingAssetPagePath(page);
String assetContentPath = getCorrespondingShadowNodePath(assetPagePath) + "/" + JcrConstants.JCR_CONTENT;
Resource assetContentResource = resolver.getResource(assetContentPath);
ModifiableValueMap mvm = assetContentResource.adaptTo(ModifiableValueMap.class);
mvm.put(propName, propValue);
if (commit) {
try {
resolver.commit();
} catch (Exception e) {
logger.error("Error while committing with property change: " + propName + " = " + propValue + " at " + assetContentPath);
throw new FormsFoundationException(e);
}
}
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy