
com.adobe.aemds.guide.utils.GuideThemeUtils 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 may be covered by U.S. and Foreign Patents,
* patents in process, 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.aemds.guide.utils;
import com.adobe.aemds.guide.common.FDVersion;
import com.adobe.aemds.guide.model.TypekitConfiguration;
import com.adobe.aemds.guide.service.GuideException;
import com.adobe.aemds.guide.service.internal.TypekitConfigurationService;
import com.adobe.aemds.guide.themes.GuideThemeConstants;
import com.adobe.aemds.guide.themes.model.BreakpointInfo;
import com.adobe.aemds.guide.themes.model.Component;
import com.adobe.aemds.guide.themes.model.DefaultBreakpointInfo;
import com.adobe.aemds.guide.themes.model.Selector;
import com.adobe.aemds.guide.themes.model.Theme;
import com.adobe.aemds.guide.themes.model.ThemeMetadata;
import com.adobe.aemds.guide.utils.GuideUtils;
import com.day.cq.commons.jcr.JcrConstants;
import com.day.cq.wcm.webservicesupport.Configuration;
import com.day.cq.wcm.webservicesupport.ConfigurationManager;
import org.apache.commons.lang3.StringUtils;
import org.apache.jackrabbit.commons.JcrUtils;
import org.apache.sling.api.resource.ModifiableValueMap;
import org.apache.sling.api.resource.Resource;
import org.apache.sling.api.resource.ResourceResolver;
import org.apache.sling.api.resource.ValueMap;
import org.apache.sling.commons.json.JSONArray;
import org.apache.sling.commons.json.JSONException;
import org.apache.sling.commons.json.JSONObject;
import org.apache.sling.resourcemerger.api.ResourceMergerService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import javax.jcr.RepositoryException;
import org.apache.sling.api.resource.PersistenceException;
import javax.jcr.PathNotFoundException;
import javax.jcr.*;
import java.io.ByteArrayInputStream;
import java.util.*;
import com.day.cq.commons.jcr.JcrUtil;
import com.adobe.aemds.guide.themes.model.ThemeClientLib;
import com.day.cq.wcm.api.Page;
import com.day.cq.wcm.api.Template;
import com.day.cq.wcm.api.TemplatedResource;
/**
* @pad.exclude Exclude from Published API.
*/
public class GuideThemeUtils {
private static Logger logger = LoggerFactory.getLogger(GuideThemeUtils.class);
/**
* The API provides the form page path configured in the Theme
*
* @param resourceResolver ResourceResolver instance
* @param themeContentPath Path of the theme
* @return Form path using in theme editor
*/
public static String getConfiguredFormPagePath(ResourceResolver resourceResolver, String themeContentPath) {
if (resourceResolver == null) {
throw new GuideException("Invalid user session.");
}
Resource themeResource = resourceResolver.resolve(themeContentPath);
ThemeMetadata themeMetadata = themeResource.getChild(GuideThemeConstants.NODE_METADATA).adaptTo(ThemeMetadata.class);
return themeMetadata.getFormPagePath();
}
/**
* The API provides the form path configured in the Theme
*
* @param resourceResolver ResourceResolver instance
* @param themeContentPath Path of the theme
* @return Form path using in theme editor
*/
public static String getConfiguredFormPath(ResourceResolver resourceResolver, String themeContentPath) {
if (resourceResolver == null) {
throw new GuideException("Invalid user session.");
}
String formAssetPath = null;
try {
Session session = resourceResolver.adaptTo(Session.class);
if (themeContentPath != null && session.nodeExists(themeContentPath)) {
Node themeContentNode = session.getNode(themeContentPath);
if (themeContentNode.hasProperty(GuideThemeConstants.RELATIVE_PATH_CONFIGURED_FORM_REF)) {
formAssetPath = themeContentNode.getProperty(GuideThemeConstants.RELATIVE_PATH_CONFIGURED_FORM_REF).getString();
}
}
} catch (RepositoryException e) {
throw new GuideException(e);
}
return formAssetPath;
}
/**
* Get the theme client library for a given theme path
*
* @param resourceResolver ResourceResolver instance
* @param themeContentPath Path of the theme
* @return theme client library for a given theme path
*/
public static String getThemeClientlibCategory(ResourceResolver resourceResolver, String themeContentPath) {
if (resourceResolver == null) {
throw new GuideException("Invalid user session.");
}
String themeClientlibCategory = null;
try {
Session session = resourceResolver.adaptTo(Session.class);
if (themeContentPath != null && session.nodeExists(themeContentPath)) {
Node themeContentNode = session.getNode(themeContentPath);
if (themeContentNode.hasProperty(GuideThemeConstants.RELATIVE_PATH_PROPERTY_CLIENTLIB_CATEGORY)) {
themeClientlibCategory = themeContentNode.getProperty(GuideThemeConstants.RELATIVE_PATH_PROPERTY_CLIENTLIB_CATEGORY).getString();
}
}
} catch (RepositoryException e) {
throw new GuideException(e);
}
return themeClientlibCategory;
}
/**
* Get the base client lib category for the theme
*
* @param resourceResolver ResourceResolver instance
* @param themeContentPath Path of the theme
* @return base client lib category for the theme
*/
public static String getBaseClientlibCategory(ResourceResolver resourceResolver, String themeContentPath) {
if (resourceResolver == null) {
throw new GuideException("Invalid user session.");
}
String baseClientlibCategory = null;
try {
Session session = resourceResolver.adaptTo(Session.class);
if (themeContentPath != null && session.nodeExists(themeContentPath)) {
Node themeContentNode = session.getNode(themeContentPath);
if (themeContentNode.hasProperty(GuideThemeConstants.RELATIVE_PATH_PROPERTY_CLIENTLIB_REF)) {
String clientlibLoc = themeContentNode.getProperty(GuideThemeConstants.RELATIVE_PATH_PROPERTY_CLIENTLIB_REF).getString();
Node clientlibNode = session.getNode(clientlibLoc + "/" + themeContentNode.getParent().getName());
if (clientlibNode.hasProperty(GuideThemeConstants.RELATIVE_PATH_PROPERTY_DEPENDENCIES)) {
Value[] values = clientlibNode.getProperty(GuideThemeConstants.RELATIVE_PATH_PROPERTY_DEPENDENCIES).getValues();
baseClientlibCategory = values[0].getString();
}
}
}
} catch (RepositoryException e) {
throw new GuideException(e);
}
return baseClientlibCategory;
}
public static void saveThemeCSS(Theme theme,
ResourceResolver resolver,
ResourceMergerService resourceMergerService) throws GuideException {
try {
String cSSString = getThemeCSS(theme, resolver, resourceMergerService);
updateClientLibForTheme(resolver,
theme.getThemeNodeName(),
cSSString,
theme.getMetadata().getClientlibRef());
} catch (RepositoryException e) {
logger.error("Unable to save the Theme Css", e);
throw new GuideException(e);
}
}
public static String getThemeCSS(Theme theme, ResourceResolver resolver, ResourceMergerService resourceMergerService) {
String themeCss = "";
List themeFormBreakpointList = new ArrayList();
ThemeMetadata themeMetadata = theme.getMetadata();
List breakpoints = themeMetadata.getBreakpoints();
String themeFormPath = themeMetadata.getFormPagePath();
Resource breakpointNodeResource = GuideUtils.getFormBreakpointResource(resolver, themeFormPath);
if (breakpointNodeResource != null) {
Iterator childResources = breakpointNodeResource.getChildren().iterator();
while (childResources.hasNext()) {
Resource childResource = childResources.next();
BreakpointInfo breakpointInfo = childResource.adaptTo(BreakpointInfo.class);
themeFormBreakpointList.add(breakpointInfo);
}
}
if(!containsDefaultBreakpoint(breakpoints)) {
BreakpointInfo defaultBreakpoint = new DefaultBreakpointInfo();
breakpoints.add(defaultBreakpoint);
}
List sortedBreakpoints = sortBreakpoints(breakpoints);
// This list will be used to form to add breakpoint to theme. This scenario can occur when u have an additional
// breakpoint in the theme configured and you start styling that breakpoint.
List currentFormBreakpointList = sortBreakpoints(themeFormBreakpointList);
Iterator componentIterator = theme.getComponents().iterator();
while (componentIterator.hasNext()) {
Component component = componentIterator.next();
Map selectorMap = GuideStyleMigrationUtils.getSelectorMap(component.getComponentPath(), resolver, resourceMergerService, "cq:themeConfig");
themeCss += getComponentCssString(component, resolver, sortedBreakpoints, currentFormBreakpointList, selectorMap, themeMetadata);
}
themeCss += theme.getRawCss();
return themeCss;
}
private static boolean containsDefaultBreakpoint(List breakpoints) {
Iterator breakpointIterator = breakpoints.iterator();
while(breakpointIterator.hasNext()) {
BreakpointInfo breakpoint = breakpointIterator.next();
if(breakpoint.getId().equals("default")) {
return true;
}
}
return false;
}
public static String getComponentCssString(Component component,
ResourceResolver resolver,
List sortedBreakpoints,
List additionalBreakpointList,
Map selectorMap,
ThemeMetadata themeMetadata) {
//themeMetadata and additionalBreakpointList only makes sense in theme only for the logic to add any additional breakpoint.
// These two can be completely ignored while looking at inline css generation.
String themeCss = "";
Iterator selectorIterator = component.getSelectors().iterator();
while (selectorIterator.hasNext()) {
Selector selector = selectorIterator.next();
ValueMap selectorProperties = selector.getSelectorAllProperties();
Iterator breakpointIterator = sortedBreakpoints.iterator();
//As visible this is theme specific logic to look at any additional breakpoint in selector json
// which is not present in theme breakpoint list. For inline empy set is added just to have same code flow.
// This makes no sense for inline css generation as there we make breakpoints list from form itself.
Set selectorBreakpointIdSet = (additionalBreakpointList.isEmpty() ? new HashSet() : selector.getBreakpointsIdSet());
while (breakpointIterator.hasNext()) {
BreakpointInfo breakpoint = breakpointIterator.next();
themeCss += getSelectorCssString(breakpoint, selector, selectorProperties, resolver, selectorMap, component.getInlineClass());
String currentBreakpointId = breakpoint.getId();
if (selectorBreakpointIdSet.contains(currentBreakpointId)) {
selectorBreakpointIdSet.remove(currentBreakpointId);
}
}
// Theme sepecific Logic to add any additional breakpoint if found in selector json.
Iterator additionalBreakpointListIterator = additionalBreakpointList.iterator();
while(additionalBreakpointListIterator.hasNext() && !selectorBreakpointIdSet.isEmpty()) {
BreakpointInfo breakpoint = additionalBreakpointListIterator.next();
String breakpointId = breakpoint.getId();
if (selectorBreakpointIdSet.contains(breakpointId)) {
addBreakpointToTheme(breakpoint, themeMetadata);
sortedBreakpoints.add(breakpoint);
GuideThemeUtils.sortBreakpoints(sortedBreakpoints);
themeCss += getSelectorCssString(breakpoint, selector, selectorProperties, resolver, selectorMap, component.getInlineClass());
}
}
}
return themeCss;
}
private static void addBreakpointToTheme(BreakpointInfo breakpoint, ThemeMetadata themeMetadata) {
try {
Resource breakpointResource = themeMetadata.getResource().getChild("breakpoints");
Node themeBreakpointNode = breakpointResource.adaptTo(Node.class);
Node newBreakpointNode = themeBreakpointNode.addNode(breakpoint.getId(), GuideConstants.NT_UNSTRUCTURED);
newBreakpointNode.setProperty("title", breakpoint.getName());
newBreakpointNode.setProperty("width", breakpoint.getMax());
} catch (Exception e) {
logger.error("Unable to add breakpoint to theme", e);
}
}
private static String getSelectorCssString(BreakpointInfo breakpoint,
Selector selector,
ValueMap selectorProperties,
ResourceResolver resolver,
Map selectorMap,
String inlineClass) {
String selectorCss = "";
String breakpointId = breakpoint.getId();
List stylePropertyNames = selector.getStylePropertyNames(breakpointId);
if (stylePropertyNames.size() > 0) {
if (!breakpointId.equals("default")) {
selectorCss += "@media (max-width : " + breakpoint.getMax() + "px){\n";
}
Iterator propertiesIterator = stylePropertyNames.iterator();
while (propertiesIterator.hasNext()) {
String propertyName = propertiesIterator.next();
if (selectorProperties.get(propertyName) != null) {
String stateName = propertyName.substring(propertyName.indexOf("#") + 1);
HashSet maskedPropertiesSet = selector.getMaskedPropertiesSet(breakpointId, stateName);
String[] cssProperties = selector.getCssPropertiesList(breakpointId, stateName).toArray(new String[0]);
String selectorPath = selectorMap.get(selector.getId());
if (selectorPath != null) {
if (!stateName.equals("default")) {
selectorPath = selectorMap.get(selector.getId()) + "/states/" + stateName;
}
if (resolver.getResource(selectorPath) != null && resolver.getResource(selectorPath).getValueMap().containsKey("cssSelector")) {
ValueMap valueMap = resolver.getResource(selectorPath).getValueMap();
String cssSelector, cssOverride = "", beforeSelector = "", afterSelector = "", addonCss = "";
String inlinePrefix = "";
cssSelector = generateSelectorString(inlineClass, valueMap.get("cssSelector").toString(), true);
selectorCss += cssSelector + "{\n";
for (String cssProperty : cssProperties) {
String key = cssProperty.substring(0, cssProperty.indexOf(':'));
String value = cssProperty.substring(cssProperty.indexOf(':') + 1);
if (key.equals(GuideThemeConstants.CSS_OVERRIDE_PROPERTY_NAME)) {
cssOverride = getCssPropertyValue(GuideThemeConstants.CSS_OVERRIDE_PROPERTY_NAME, value, maskedPropertiesSet);
} else if (key.equals(GuideThemeConstants.AFTER_PSEUDO_ELEMENT_PROPERTY_NAME)) {
afterSelector = getPseudoCSSString(cssSelector, "::after", getCssPropertyValue(GuideThemeConstants.AFTER_PSEUDO_ELEMENT_PROPERTY_NAME, value, maskedPropertiesSet));
} else if (key.equals(GuideThemeConstants.BEFORE_PSEUDO_ELEMENT_PROPERTY_NAME)) {
beforeSelector = getPseudoCSSString(cssSelector, "::before", getCssPropertyValue(GuideThemeConstants.BEFORE_PSEUDO_ELEMENT_PROPERTY_NAME, value, maskedPropertiesSet));
} else if (key.equals(GuideThemeConstants.ADDON_CSS_ELEMENT_PROPERTY_NAME)) {
addonCss = getAddonCSSString(inlineClass, value);
} else {
String propertyValueCssString = key + ":" + value + ";\n";
selectorCss += getCssPropertyValue(key, propertyValueCssString, maskedPropertiesSet);
}
}
selectorCss += cssOverride + "\n";
selectorCss += "}\n";
selectorCss += beforeSelector;
selectorCss += afterSelector;
selectorCss += addonCss;
} else {
logger.error("CSS selector string not found for resource: " + selectorPath);
}
} else {
logger.error("CSS selector information not found for selector Id: " + selector.getId());
}
}
}
if (!breakpointId.equals("default")) {
selectorCss += "}\n";
}
}
return selectorCss;
}
public static void saveInlineCSS(Resource resource, String formPath, ResourceMergerService resourceMergerService) {
ResourceResolver resolver = resource.getResourceResolver();
String resourceType = resource.getResourceType();
List breakpointInfoList = new ArrayList();
Resource breakpointNodeResource = GuideUtils.getFormBreakpointResource(resolver, formPath);
if (breakpointNodeResource != null) {
Iterator childResources = breakpointNodeResource.getChildren().iterator();
while (childResources.hasNext()) {
Resource childResource = childResources.next();
BreakpointInfo breakpointInfo = childResource.adaptTo(BreakpointInfo.class);
breakpointInfoList.add(breakpointInfo);
}
}
BreakpointInfo defaultBreakpoint = new DefaultBreakpointInfo();
breakpointInfoList.add(defaultBreakpoint);
List sortedBreakpoints = GuideThemeUtils.sortBreakpoints(breakpointInfoList);
Resource styleResource = resource.getChild("style");
String overridePath = resolver.getResource(resourceType).getPath();
Map selectorMap = GuideStyleMigrationUtils.getSelectorMap(overridePath, resolver, resourceMergerService, "cq:styleConfig");
if (styleResource != null) {
com.adobe.aemds.guide.themes.model.Component component = styleResource.adaptTo(com.adobe.aemds.guide.themes.model.Component.class);
String cssString = GuideThemeUtils.getComponentCssString(component, resolver, sortedBreakpoints, new ArrayList(), selectorMap, null);
ModifiableValueMap properties = resource.adaptTo(ModifiableValueMap.class);
properties.put("cssStyle", cssString);
}
}
private static String getAddonCSSString(String inlineClass, String value) {
String cssString = "";
try {
JSONObject addOnCSSObject = new JSONObject(value);
JSONObject selectors = addOnCSSObject.getJSONObject("selectors");
Iterator selectorKeys = selectors.keys();
while (selectorKeys.hasNext()) {
String key = selectorKeys.next();
JSONObject selector = selectors.getJSONObject(key);
String cssSelectorString = generateSelectorString(inlineClass, selector.getString("cssSelector"), false);
cssString += cssSelectorString + " {\n";
JSONObject properties = selector.getJSONObject("properties");
Iterator propertyKeys = properties.keys();
while (propertyKeys.hasNext()) {
String propertyKey = propertyKeys.next();
String propValue = properties.getString(propertyKey);
cssString += propertyKey + ":" + propValue + ";\n";
}
cssString += "}\n";
}
} catch (JSONException e) {
logger.error("Unable to parse addonCss object", e);
}
return cssString;
}
//if target is set return it, else return the resource itself
private static Resource getTargetResource(Resource resource) {
ValueMap values = resource.getValueMap();
String target = values.get("target", String.class);
if (target != null) {
ResourceResolver resolver = resource.getResourceResolver();
return resolver.getResource(target);
}
return resource;
}
private static String getPseudoCSSString(String selectorString, String pseudoElementString, String value) {
StringBuilder selectorValueBuilder = new StringBuilder();
String cssString = "";
StringTokenizer st = new StringTokenizer(selectorString, ",");
while (st.hasMoreElements()) {
selectorValueBuilder.append(st.nextElement())
.append(pseudoElementString);
if (st.hasMoreElements()) {
selectorValueBuilder.append(",");
}
}
cssString += selectorValueBuilder.toString();
cssString += "{\n";
cssString += value + "\n";
cssString += "}\n";
return cssString;
}
/**
* Internal method to update the client library CSS when the theme is updated
*
* @param resolver resource resolver
* @param clientLibName client library name
* @param cssString CSS definition for the theme
* @param clientLibPath client library path
* @throws RepositoryException
*/
private static void updateClientLibForTheme(ResourceResolver resolver,
String clientLibName,
String cssString,
String clientLibPath) throws RepositoryException {
Resource cssTxtResource;
Session session = resolver.adaptTo(Session.class);
String clientLibCompletePath = clientLibPath + "/" + clientLibName;
Resource clientLibResource = resolver.getResource(clientLibCompletePath);
if (clientLibResource != null) {
// Upload the css file
Resource contentResource = clientLibResource.getChild("css/theme.css/jcr:content");
//Binary binary = session.getValueFactory().createBinary(new ByteArrayInputStream(cssString.getBytes()));
ModifiableValueMap map = contentResource.adaptTo(ModifiableValueMap.class);
map.put(GuideThemeConstants.PROPERTY_JCR_DATA, cssString);
// Update the lastModified date so that the updated clientLib is picked.
cssTxtResource = clientLibResource.getChild("css.txt/jcr:content");
ModifiableValueMap txtMap = cssTxtResource.adaptTo(ModifiableValueMap.class);
Calendar currentTime = Calendar.getInstance();
txtMap.put(JcrConstants.JCR_LASTMODIFIED,currentTime);
} else {
logger.error("Unable to find clientLib at location {}", clientLibCompletePath);
}
}
public static List sortBreakpoints(List breakpoints) {
Collections.sort(breakpoints, new Comparator() {
@Override
public int compare(BreakpointInfo breakpoint2, BreakpointInfo breakpoint1) {
if (breakpoint2.getMax() == -1) {
return -1;
}
if (breakpoint1.getMax() == -1) {
return 1;
}
return breakpoint1.getMax().compareTo(breakpoint2.getMax());
}
});
return breakpoints;
}
/**
* Check if Property present in masked List or not.
* @param cssString CssString to be commented.
* @return value final resolved value
*/
public static String makeCssComment(String cssString) {
return "/*" + cssString + "*/";
}
/**
* The API copies the asset Resource in inline style from fromResource to toResource.
*
* @param fromResource the Resource whose style resource is being copied.
* @param toResource the Resource where style resource is copied.
* @param resourceResolver resourceResolver instance.
*/
public static void copyAssets(Resource fromResource, Resource toResource, ResourceResolver resourceResolver) {
try {
String fromResourceAssetPath = fromResource.getPath() + "/" + GuideThemeConstants.STYLE_ASSETS_NODE;
Resource fromResourceAsset = resourceResolver.getResource(fromResourceAssetPath);
Session session = resourceResolver.adaptTo(Session.class);
if (fromResourceAsset != null) {
String toResourceAssetPath = toResource.getPath() + "/" + GuideThemeConstants.STYLE_ASSETS_NODE;
Resource toResourceAsset = resourceResolver.getResource(toResourceAssetPath);
if (toResourceAsset == null) {
String toResourcePath = toResource.getPath();
Node fromResourceAssetNode = session.getNode(fromResourceAssetPath),
toResourceNode = session.getNode(toResourcePath);
JcrUtil.copy(fromResourceAssetNode, toResourceNode, null);
} else {
Iterator children = fromResourceAsset.listChildren();
Node toResourceAssetNode = session.getNode(toResourceAssetPath);
while (children.hasNext()) {
Resource imageResource = children.next();
String imageResourceName = imageResource.getName(),
imageResourcePath = imageResource.getPath(),
oldImageResourcePath = toResourceAssetPath + "/" + imageResourceName;
if (session.itemExists(oldImageResourcePath)) {
session.removeItem(oldImageResourcePath);
}
Node imageNode = session.getNode(imageResourcePath);
JcrUtil.copy(imageNode, toResourceAssetNode, null);
}
}
session.save();
}
} catch (PathNotFoundException e) {
logger.error("Error in copying StyleAsset", e);
} catch (RepositoryException e) {
logger.error("Error in copying StyleAsset", e);
}
}
/**
* The API copies the style Resource in inline style from fromResource to toResource.
*
* @param fromResource the Resource whose style resource is being copied.
* @param toResource the Resource where style resource is copied.
* @param resourceResolver resourceResolver instance.
* @param cssClass cssClass of the copied Resource.
*/
public static void copyStyles(Resource fromResource, Resource toResource, ResourceResolver resourceResolver, String cssClass) {
try {
String fromResourcePath = fromResource.getPath(),
fromResourceStylePath = fromResourcePath + "/" + GuideThemeConstants.STYLE_NODE,
toResourcePath = toResource.getPath(),
toResourceStylePath = toResourcePath + "/" + GuideThemeConstants.STYLE_NODE;
Session session = resourceResolver.adaptTo(Session.class);
Resource fromResourceStyle = resourceResolver.getResource(fromResourceStylePath);
Resource toResourceStyle = resourceResolver.getResource(toResourceStylePath);
ModifiableValueMap toResourcePropertyMap = toResource.adaptTo(ModifiableValueMap.class);
ModifiableValueMap fromResourcePropertyMap = fromResource.adaptTo(ModifiableValueMap.class);
if (fromResourceStyle == null) {
if (toResourcePropertyMap != null) {
if (toResourcePropertyMap.containsKey(GuideThemeConstants.CSS_STYLE_PROPERTY)) {
toResourcePropertyMap.remove(GuideThemeConstants.CSS_STYLE_PROPERTY);
}
if (toResourcePropertyMap.containsKey(GuideThemeConstants.CSS_CLASS_PROPERTY)) {
toResourcePropertyMap.remove(GuideThemeConstants.CSS_CLASS_PROPERTY);
}
}
if (toResourceStyle != null) {
resourceResolver.delete(toResourceStyle);
}
} else {
if (!toResourcePropertyMap.containsKey(GuideThemeConstants.CSS_CLASS_PROPERTY)) {
toResourcePropertyMap.put(GuideThemeConstants.CSS_CLASS_PROPERTY, cssClass);
}
toResourcePropertyMap.put(GuideThemeConstants.CSS_STYLE_PROPERTY, fromResourcePropertyMap.get(GuideThemeConstants.CSS_STYLE_PROPERTY));
Node fromResourceStyleNode = session.getNode(fromResourceStylePath),
toResourceNode = session.getNode(toResourcePath);
JcrUtil.copy(fromResourceStyleNode, toResourceNode, null);
}
session.save();
resourceResolver.commit();
} catch (PersistenceException e) {
logger.error("Error in copying StyleNode", e);
} catch (PathNotFoundException e) {
logger.error("Error in copying StyleNode", e);
} catch (RepositoryException e) {
logger.error("Error in copying StyleNode", e);
}
}
/**
* Check if Property present in masked List or not.
* @param property property that needs to be checked masked or not.
* @param value css value.
* @param maskedPropertiesSet Set of properties that are masked.
* @return value final resolved value.
*/
private static String getCssPropertyValue(String property, String value, HashSet maskedPropertiesSet) {
if(maskedPropertiesSet.contains(property)) {
if(property.equals(GuideThemeConstants.AFTER_PSEUDO_ELEMENT_PROPERTY_NAME) || property.equals(GuideThemeConstants.AFTER_PSEUDO_ELEMENT_PROPERTY_NAME) || property.equals(GuideThemeConstants.BEFORE_PSEUDO_ELEMENT_PROPERTY_NAME)) {
value = "";
} else {
value = makeCssComment(value);
}
}
return value;
}
/**
* get clientLib category of the given resource.
* @param themeResource Theme jcr content resource
* @return clientLibCategory clientLib category of the given theme resource.
*/
public static String getClientLibCategory (Resource themeResource) {
String category = null;
if (themeResource != null) {
ThemeClientLib clientLib = getThemeClientLib(themeResource);
if(clientLib != null) {
category = clientLib.getCategory();
}
}
return category;
}
/**
* get clientLib path of the given resource.
* @param themeResource Theme jcr content resource
* @return clientLibPath clientLib path of the given theme resource.
*
*/
public static String getClientLibPath (Resource themeResource) {
String path = null;
if (themeResource != null) {
ThemeClientLib clientLib = getThemeClientLib(themeResource);
if(clientLib != null) {
path = clientLib.getPath();
}
}
return path;
}
private static ThemeClientLib getThemeClientLib(Resource themeResource) {
ThemeClientLib clientLib = null;
if (themeResource != null) {
String themeNodeName = themeResource.getParent().getName();
ResourceResolver resolver = themeResource.getResourceResolver();
ValueMap themeMetaData = themeResource.getChild(GuideThemeConstants.NODE_METADATA).adaptTo(ValueMap.class);
String path = themeMetaData.get(GuideThemeConstants.PROPERTY_CLIENTLIB_REF, String.class) + "/" + themeNodeName;
Resource clientLibResource = resolver.getResource(path);
if (clientLibResource != null) {
clientLib = clientLibResource.adaptTo(ThemeClientLib.class);
} else {
logger.info("Theme client library missing at {}. Falling back to the default client library", path);
}
}
return clientLib;
}
/**
* Gets the path of web font config associated with a theme.
*
* @param resourceResolver
* @param themeContentPath Path of jcr:content node of theme resource.
* @return The path of web font config
*/
public static String getWebFontConfig(ResourceResolver resourceResolver, String themeContentPath){
Resource themeResource = resourceResolver.getResource(themeContentPath);
if (GuideThemeUtils.isResourceTheme(themeResource)) {
ValueMap themeMetaData = themeResource.getChild(GuideThemeConstants.NODE_METADATA).adaptTo(ValueMap.class);
return themeMetaData.get(GuideThemeConstants.PROPERTY_WEB_FONT_CONFIG, String.class);
}
return null;
}
/**
* Gets the common clientLib to be included with Theme.
*
* @param themeContentResource Theme jcr:content resource.
* @return Name of the common clientLib to be included
*/
public static String getCommonClientLibName(Resource themeContentResource){
Resource themeMetadataResource = themeContentResource.getChild(GuideThemeConstants.NODE_METADATA);
ValueMap metadata = themeMetadataResource.adaptTo(ValueMap.class);
// if theme created from version of that of default spec (ie) 1.0, then use the legacy client library
String targetSpec = metadata.get(GuideConstants.FD_TARGET_VERSION, String.class);
if(targetSpec == null) {
targetSpec = GuideThemeConstants.THEME_LEGACY_TARGET_SPEC_VERSION;
}
if(FDVersion.compare(GuideThemeConstants.THEME_LEGACY_TARGET_SPEC_VERSION, targetSpec) == 0) {
return "guide.theme2.common.legacy620";
}
return "guide.theme2.common";
}
/**
* Gets the clientLib details to be included for an Adaptive Form
*
* @param formResource Form resource
* @param themeOverride Path of Theme to be overridden
* @param pageFallbackClientlib fallback clientLib
* @return ThemeClientLibData object containing the client category names
*/
public static ThemeClientLibData getClientLibNames(Resource formResource, String themeOverride, String pageFallbackClientlib) {
Resource themeContentResource = null;
String themeClientLibName = null,
commonClientLibName = null;
if (StringUtils.isNotBlank(themeOverride)) {
ResourceResolver resourceResolver = formResource.getResourceResolver();
themeContentResource = resourceResolver.getResource(themeOverride);
if(GuideThemeUtils.isResourceTheme(themeContentResource)) {
commonClientLibName = GuideThemeUtils.getCommonClientLibName(themeContentResource);
themeClientLibName = GuideThemeUtils.getClientLibCategory(themeContentResource);
}
}
if(themeClientLibName == null) {
themeContentResource = GuideUtils.getThemeResource(formResource);
if (themeContentResource != null) {
commonClientLibName = GuideThemeUtils.getCommonClientLibName(themeContentResource);
themeClientLibName = GuideThemeUtils.getClientLibCategory(themeContentResource);
}
}
if(themeClientLibName == null) {
if (StringUtils.isNotBlank(pageFallbackClientlib)) {
//As default is same for all the version and we keep on updating it its common should always be latest version of common.
themeClientLibName = pageFallbackClientlib;
commonClientLibName = "guide.theme2.common";
//TODO: Ideally we should not have a fallbackClientlib, and rather fallback theme.
//This should be documented for 6.3 (not documentation seen yet for 6.2 for this fallbackLibrary.jsp)
//Keeping the commonClientLib to legacy. For 0 regression need an API to find theme for given client
}
}
ThemeClientLibData clientLibData = new ThemeClientLibData();
clientLibData.setCommonClientLib(commonClientLibName);
if(themeClientLibName != null) {
clientLibData.setThemeClientLib(themeClientLibName);
}
//If form's theme as well as fallback clientlib both are null it means is old form
// and will not have common or theme.
return clientLibData;
}
/**
* Check whether the resource type is theme
*
* @param themeContentResource Theme jcr:content resource.
* @return whether resource type is theme or not
*/
public static boolean isResourceTheme(Resource themeContentResource){
boolean isResourceTheme = false;
if (themeContentResource != null) {
isResourceTheme = themeContentResource.isResourceType(GuideThemeConstants.THEME_SLING_RESOURCE_TYPE_VALUE);
}
return isResourceTheme;
}
/**
* Check whether the resource type is theme
*
* @param className Inline Style component prefiex Class.
* @param cssSelector css selector for the particular selector.
* @param makeDescendantSelector If we want prefix class to be along side the css selector or above it.
* @return whether resource type is theme or not
*/
public static String generateSelectorString(String className, String cssSelector, Boolean makeDescendantSelector) {
if (StringUtils.isEmpty(className)) {
return cssSelector;
}
String selectorString = "";
String[] selectorArray = cssSelector.split(",");
for (int i = 0; i < selectorArray.length; i++) {
if (i != 0) {
selectorString += ",";
}
if (makeDescendantSelector) {
selectorString += "." + className + " " + selectorArray[i];
} else {
selectorString += "." + className + selectorArray[i];
}
}
return selectorString;
}
public static void addTypekitConfigurations(JSONArray response, Resource theme,
TypekitConfigurationService typekitConfigurationService) throws JSONException {
Collection collection = typekitConfigurationService.getConfigurationCollection(theme);
Iterator iterator = collection.iterator();
while (iterator.hasNext()) {
TypekitConfiguration configuration = iterator.next();
JSONObject responseObject = new JSONObject();
responseObject.put("text", StringUtils.isNotEmpty(configuration.title()) ?
configuration.title() : configuration.name());
responseObject.put("value", configuration.name());
response.put(responseObject);
}
}
public static void addTypekitConfigurations(JSONArray response, Resource theme,
ResourceResolver resourceResolver,
TypekitConfigurationService typekitConfigurationService) throws JSONException {
addTypekitConfigurations(response, resourceResolver);
addTypekitConfigurations(response, theme, typekitConfigurationService);
}
@Deprecated
public static void addTypekitConfigurations(JSONArray response, ResourceResolver resourceResolver) throws JSONException {
ConfigurationManager configManager = resourceResolver.adaptTo(ConfigurationManager.class);
Iterator it = configManager.getConfigurations(GuideConstants.TYPEKIT_CLOUD_SERVICE_ROOT_PATH);
while (it.hasNext()) {
Configuration configuration = it.next();
JSONObject responseObject = new JSONObject();
responseObject.put("text", configuration.getTitle());
responseObject.put("value", configuration.getPath());
response.put(responseObject);
}
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy