![JAR search and dependency download from the Maven repository](/logo.png)
com.day.cq.wcm.commons.WCMUtils Maven / Gradle / Ivy
Show all versions of aem-sdk-api Show documentation
/*
* Copyright 1997-2008 Day Management AG
* Barfuesserplatz 6, 4001 Basel, Switzerland
* All Rights Reserved.
*
* This software is the confidential and proprietary information of
* Day Management AG, ("Confidential Information"). You shall not
* disclose such Confidential Information and shall use it only in
* accordance with the terms of the license agreement you entered into
* with Day.
*/
package com.day.cq.wcm.commons;
import java.util.Locale;
import javax.annotation.Nullable;
import javax.jcr.Node;
import javax.servlet.ServletRequest;
import com.adobe.cq.launches.api.Launch;
import com.day.cq.commons.inherit.InheritanceValueMap;
import com.day.cq.tagging.Tag;
import com.day.cq.wcm.api.Page;
import com.day.cq.wcm.api.PageManager;
import com.day.cq.wcm.api.Template;
import com.day.cq.wcm.api.components.Component;
import com.day.cq.wcm.api.components.ComponentContext;
import com.day.cq.wcm.api.components.ComponentManager;
import com.day.cq.wcm.api.designer.Design;
import com.day.cq.wcm.api.designer.Designer;
import com.day.cq.wcm.api.designer.Style;
import com.day.cq.wcm.api.policies.ContentPolicy;
import com.day.cq.wcm.api.policies.ContentPolicyManager;
import com.day.cq.wcm.commons.policy.ContentPolicyStyle;
import org.apache.sling.api.SlingHttpServletRequest;
import org.apache.sling.api.resource.Resource;
import org.apache.sling.api.resource.ResourceResolver;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* The CMUtils
class provides utility methods for various
* aspects of the Core WCM system.
*/
public class WCMUtils {
/**
* default logger
*/
private static final Logger log = LoggerFactory.getLogger(WCMUtils.class);
/**
* debug parameter name
*/
public static final String DEBUG_PARAM = "debug";
// not to be instantiated
private WCMUtils() {
}
/**
* Returns the component according to the type of the resource or
* null
if no such component exists. This is a pure convenience
* method retrieving the component manager and invoking
* {@link ComponentManager#getComponentOfResource(Resource)}.
*
* @param resource to resolve
* @return the respective component or null
*/
public static Component getComponent(Resource resource) {
if (resource == null) {
log.debug("Resource to get component from must not be null");
return null;
}
ComponentManager compMgr = resource.getResourceResolver().adaptTo(ComponentManager.class);
if (compMgr == null) {
log.warn("Unable to retrieve component manager for {}", resource);
return null;
}
return compMgr.getComponentOfResource(resource);
}
/**
* Returns the content property of the given page. If the page does not
* contain this property, the page's parent's property is returned or
* null
if the page has no parent.
*
*
* Note that the standard "pageProperties" variable defined by the
* <cq:defineObjects/>
tag is now (since CQ 5.4) an
* {@link InheritanceValueMap} that provides
* {@link InheritanceValueMap#getInherited(String, Class)
* getInherited(String, Class)} and
* {@link InheritanceValueMap#getInherited(String, Object)
* getInherited(String, Object)} to search for those properties in parent
* pages if not found locally.
*
* @param page
* the page to retrieve the property from
* @param resolver
* for resolving parent pages
* @param name
* the property name
* @return the property value or null
*/
public static String getInheritedProperty(Page page,
ResourceResolver resolver,
String name) {
Page previousPage;
String value = null;
while (value == null && page != null) {
value = page.getProperties().get(name, String.class);
if (value == null) {
Resource res = resolver.getResource(page.getPath() + "/..");
if (res == null) {
page = null;
} else {
previousPage = page;
page = res.adaptTo(Page.class);
if (page == null) {
Launch launch = previousPage.adaptTo(Resource.class).adaptTo(Launch.class);
if (launch != null && launch.getSourceRootResource() != null) {
page = launch.getSourceRootResource().adaptTo(Page.class);
}
}
}
}
}
return value;
}
/**
* Returns the style associated with a policy for the given component context
*
* @param ctx
* @return the style provided by the policy
*/
@Nullable
private static Style getContentPolicyStyle(ComponentContext ctx) {
Resource resource = ctx.getResource();
if (resource == null) {
return null;
}
ResourceResolver resourceResolver = resource.getResourceResolver();
ContentPolicyManager policyManager = resourceResolver.adaptTo(ContentPolicyManager.class);
if(policyManager != null){
ContentPolicy currentPolicy = policyManager.getPolicy(ctx);
if (currentPolicy != null) {
//for compatibility with currentStyle only
return new ContentPolicyStyle(currentPolicy, ctx.getCell());
}
}
return null;
}
/**
* Returns the style for the given request. It's a convenience method
* that retrieves the respective page of the request resource, resolves its
* design, extracts the cell path and retrieves the style.
*
* A design and cell path can be specified '/-/' delimited as suffix.
* the design path only needs to include the part after the /etc/designs.
* eg: ...img.png/geometrixx/-/par/image
*
* @param request the request
* @return the style or null
*/
public static Style getStyle(SlingHttpServletRequest request) {
// try to figure out the 'current' page. which is either the one
// that is rendered, or the one that contains the requested resource
ComponentContext ctx = getComponentContext(request);
Resource resource = request.getResource();
ResourceResolver resourceResolver = request.getResourceResolver();
PageManager pageManager = resourceResolver.adaptTo(PageManager.class);
Page page = ctx == null ? null : ctx.getPage();
if (page == null) {
page = pageManager.getContainingPage(resource);
}
if (page == null) {
return null;
}
Template template = page.getTemplate();
// Page with structure template
if (ctx != null && template != null && template.hasStructureSupport()) {
return getContentPolicyStyle(ctx);
} else {
Designer designer = resourceResolver.adaptTo(Designer.class);
String designId = "";
String cellPath = "";
// grab paths from suffix, if present
String suffix = request.getRequestPathInfo().getSuffix();
if (suffix != null && suffix.length() > 0) {
if (!suffix.startsWith("/")) {
suffix = "/" + suffix;
}
int idx = suffix.indexOf("/-/");
if (idx >= 0) {
designId = suffix.substring(0, idx);
cellPath = suffix.substring(idx + 3);
} else {
designId = suffix;
}
}
// get design
Design design;
if (designId.length() > 0 && designer.hasDesign(designId)) {
design = designer.getDesign(designId);
} else {
cellPath = "";
design = designer.getDesign(page);
}
if (design == null) {
return null;
}
// get style
if (cellPath.length() > 0) {
return design.getStyle(cellPath);
} else if (ctx == null) {
return design.getStyle(resource);
} else {
return design.getStyle(ctx.getCell());
}
}
}
/**
* Returns the component context for the given request or null
* if not defined.
*
* @param request servlet request
* @return component context or null
*/
public static ComponentContext getComponentContext(ServletRequest request) {
return (ComponentContext) request.getAttribute(ComponentContext.CONTEXT_ATTR_NAME);
}
/**
* Returns a node for the given resource. If the node does not
* exist, returns null
*
* @param resource resource to adapt to node
* @return the node or null
*/
public static Node getNode(Resource resource) {
if(resource!=null) {
return resource.adaptTo(Node.class);
}
return null;
}
/**
* Returns a comma-separated list of keywords for the given page, based on
* the titles of the tags set on the page. Useful for the <meta
* keywords> element in HTML.
*
*
* Since CQ 5.4, this returns localized tag titles based on the page
* language or the default title if no localized title exists for that
* language. This is essentially the same as
* {@link #getKeywords(Page, boolean) getKeywords(page, false)}.
*
* @param page
* wcm page
* @return comma-separated list of keywords
*/
public static String getKeywords(Page page) {
return getKeywords(page, false);
}
/**
* Returns a comma-separated list of keywords for the given page, based on
* the titles of the tags set on the page. Useful for the <meta
* keywords> element in HTML.
*
*
* Returns localized tag titles based on the page language. A boolean flag
* allows to choose if only localized titles shall be returned or if it is
* ok to fallback to the default title in case no localized title exists for
* a given tag.
*
* @since 5.4
*
* @param page
* wcm page
* @param onlyLocalized
* if only keywords should be returned that have a localized
* variant for the given page locale
* @return comma-separated list of keywords
*/
public static String getKeywords(Page page, boolean onlyLocalized) {
StringBuffer keywords = new StringBuffer();
if (page != null) {
Locale locale = page.getLanguage(false);
Tag[] tags = page.getTags();
for (int i=0; i < tags.length; i++) {
if (onlyLocalized) {
String title = tags[i].getLocalizedTitle(locale);
if (title != null) {
if (keywords.length() > 0) keywords.append(", ");
keywords.append(title);
}
} else {
if (keywords.length() > 0) keywords.append(", ");
keywords.append(tags[i].getTitle(locale));
}
}
}
return keywords.toString();
}
}