PageStyleConfigProvider.java 17.3 KB
/*
 * Decompiled with CFR 0_118.
 * 
 * Could not load the following classes:
 *  com.adobe.forms.common.service.StaleAssetIndicatorService
 *  com.day.cq.wcm.api.Page
 *  com.day.cq.wcm.api.Template
 *  com.day.cq.wcm.api.TemplateManager
 *  com.day.cq.wcm.api.components.Component
 *  com.day.cq.wcm.api.components.ComponentContext
 *  com.day.cq.wcm.api.components.ComponentManager
 *  com.day.cq.wcm.commons.WCMUtils
 *  javax.servlet.Servlet
 *  javax.servlet.ServletException
 *  javax.servlet.ServletRequest
 *  org.apache.commons.lang3.StringUtils
 *  org.apache.felix.scr.annotations.Component
 *  org.apache.felix.scr.annotations.Properties
 *  org.apache.felix.scr.annotations.Property
 *  org.apache.felix.scr.annotations.Reference
 *  org.apache.felix.scr.annotations.Service
 *  org.apache.sling.api.SlingHttpServletRequest
 *  org.apache.sling.api.SlingHttpServletResponse
 *  org.apache.sling.api.request.RequestPathInfo
 *  org.apache.sling.api.resource.NonExistingResource
 *  org.apache.sling.api.resource.Resource
 *  org.apache.sling.api.resource.ResourceResolver
 *  org.apache.sling.api.resource.ValueMap
 *  org.apache.sling.api.servlets.SlingAllMethodsServlet
 *  org.apache.sling.commons.json.JSONException
 *  org.apache.sling.commons.json.JSONObject
 *  org.apache.sling.commons.json.io.JSONWriter
 *  org.slf4j.Logger
 *  org.slf4j.LoggerFactory
 */
package com.adobe.aemds.guide.servlet;

import com.adobe.aemds.guide.cache.Cache;
import com.adobe.aemds.guide.cache.CacheManager;
import com.adobe.aemds.guide.internal.CSSUtils;
import com.adobe.aemds.guide.themes.CSSObject;
import com.adobe.aemds.guide.themes.CSSProperty;
import com.adobe.aemds.guide.themes.Selector;
import com.adobe.aemds.guide.utils.GuideUtils;
import com.adobe.forms.common.service.StaleAssetIndicatorService;
import com.day.cq.wcm.api.Page;
import com.day.cq.wcm.api.Template;
import com.day.cq.wcm.api.TemplateManager;
import com.day.cq.wcm.api.components.ComponentContext;
import com.day.cq.wcm.api.components.ComponentManager;
import com.day.cq.wcm.commons.WCMUtils;
import java.io.IOException;
import java.io.PrintWriter;
import java.io.Writer;
import java.util.ArrayDeque;
import java.util.Calendar;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
import javax.servlet.Servlet;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import org.apache.commons.lang3.StringUtils;
import org.apache.felix.scr.annotations.Component;
import org.apache.felix.scr.annotations.Properties;
import org.apache.felix.scr.annotations.Property;
import org.apache.felix.scr.annotations.Reference;
import org.apache.felix.scr.annotations.Service;
import org.apache.sling.api.SlingHttpServletRequest;
import org.apache.sling.api.SlingHttpServletResponse;
import org.apache.sling.api.request.RequestPathInfo;
import org.apache.sling.api.resource.NonExistingResource;
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.api.servlets.SlingAllMethodsServlet;
import org.apache.sling.commons.json.JSONException;
import org.apache.sling.commons.json.JSONObject;
import org.apache.sling.commons.json.io.JSONWriter;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/*
 * This class specifies class file version 49.0 but uses Java 6 signatures.  Assumed Java 6.
 */
@Component(metatype=0)
@Service(value={Servlet.class})
@Properties(value={@Property(name="sling.servlet.resourceTypes", value={"foundation/components/page", "wcm/foundation/components/page"}), @Property(name="sling.servlet.methods", value={"GET"}), @Property(name="service.description", value={"Adaptive Form Bulk Editor"}), @Property(name="sling.servlet.selectors", value={"inline", "theme"}), @Property(name="sling.servlet.extensions", value={"styleconfig", "css"})})
public class PageStyleConfigProvider
extends SlingAllMethodsServlet {
    private Logger logger = LoggerFactory.getLogger(PageStyleConfigProvider.class);
    @Reference
    private CacheManager cacheManager;
    @Reference
    private StaleAssetIndicatorService staleAssetIndicatorService;

    protected void doGet(SlingHttpServletRequest request, SlingHttpServletResponse response) throws ServletException, IOException {
        RequestPathInfo pathInfo = request.getRequestPathInfo();
        String extension = pathInfo.getExtension();
        String selector = pathInfo.getSelectorString();
        String pagePath = this.getPagePath(request);
        if (pagePath == null) {
            return;
        }
        if ("styleconfig".equals(extension)) {
            if ("inline".equals(selector)) {
                this.writeStyleConfig(request, response, pagePath, false);
            } else if ("theme".equals(selector)) {
                this.writeStyleConfig(request, response, pagePath, true);
            }
        } else if ("css".equals(extension) && "inline".equals(selector)) {
            response.setContentType("text/css");
            response.getWriter().write(this.getCSSStyle(request, pagePath, false));
        }
    }

    private String getPagePath(SlingHttpServletRequest request) {
        String pagePath = request.getParameter("pagePath");
        if (pagePath == null) {
            pagePath = request.getResource().getPath();
        }
        return pagePath;
    }

    private Map<String, Integer> getBreakPointsInfo(SlingHttpServletRequest request, String pagePath) {
        Resource res = request.getResourceResolver().getResource(pagePath + "/cq:responsive");
        HashMap<String, Integer> breakpointMap = new HashMap<String, Integer>();
        try {
            if (res != null && (res = request.getResourceResolver().getResource(pagePath + "/cq:responsive/breakpoints")) != null) {
                for (Resource bp : res.getChildren()) {
                    String name = bp.getName();
                    ValueMap props = (ValueMap)bp.adaptTo(ValueMap.class);
                    Object width = props.get((Object)"width");
                    breakpointMap.put(name, Integer.valueOf(width.toString()));
                }
            }
        }
        catch (Exception e) {
            this.logger.error("unable to generate breakpoints information. Using a default one only", (Throwable)e);
            breakpointMap.clear();
        }
        if (!breakpointMap.containsKey("default")) {
            breakpointMap.put("default", Integer.MAX_VALUE);
        }
        return breakpointMap;
    }

    private String getCSSStyle(SlingHttpServletRequest request, String pagePath, boolean isTheme) throws IOException {
        Cache styleCache = this.cacheManager.getOrCreateCache("cache.pagestyles");
        String damPath = StringUtils.replace((String)pagePath, (String)"/content/forms/af/", (String)"/content/dam/formsanddocuments/", (int)1);
        Calendar LMT = Calendar.getInstance();
        String cssStyle = "";
        String contextPath = request.getContextPath() != null ? request.getContextPath() : "";
        String cacheKey = pagePath;
        if (!damPath.equals(pagePath)) {
            damPath = StringUtils.substringBefore((String)damPath, (String)"/jcr:content");
            Resource damNode = request.getResourceResolver().getResource(damPath);
            LMT = GuideUtils.getCurrentLMT(damNode, this.staleAssetIndicatorService);
            if (!styleCache.isCacheEntryStale(cacheKey, LMT)) {
                this.logger.debug("Cache Hit for Inline Styles");
                cssStyle = (String)styleCache.get(cacheKey);
                return cssStyle;
            }
        }
        this.logger.debug("Cache Miss for Inline Styles");
        InlineStyleSelectorProvider selectorProvider = new InlineStyleSelectorProvider();
        CSSObject cssObject = new CSSObject(selectorProvider);
        Map<String, Integer> breakpointMap = this.getBreakPointsInfo(request, pagePath);
        boolean useImportantForStyle = false;
        cssObject.setBreakpointInfo(breakpointMap);
        ArrayDeque<Object> resources = new ArrayDeque<Object>(100);
        Resource pageResource = request.getResourceResolver().getResource(pagePath);
        if (pageResource != null) {
            resources.addLast((Object)pageResource);
        }
        CSSUtils cssUtils = new CSSUtils();
        while (resources.size() > 0) {
            Resource res = (Resource)resources.removeFirst();
            if (res.getResourceType() != null) {
                ValueMap props = (ValueMap)res.adaptTo(ValueMap.class);
                if (this.isFragmentResource(res)) {
                    String fragmentPath = (String)props.get((Object)"fragRef");
                    String fragmentPagePath = StringUtils.replace((String)fragmentPath, (String)"/content/dam/formsanddocuments/", (String)"/content/forms/af/", (int)1);
                    cssStyle = cssStyle + this.getCSSStyle(request, fragmentPagePath, isTheme);
                } else {
                    String styleProps = (String)props.get((Object)"styleProperties");
                    String nodeClass = (String)props.get((Object)"guideNodeClass");
                    String componentCssStyle = (String)props.get((Object)"cssStyle");
                    if (!StringUtils.isEmpty((CharSequence)componentCssStyle)) {
                        componentCssStyle = cssUtils.processUrls(componentCssStyle, contextPath, res.getPath());
                        cssStyle = cssStyle + componentCssStyle;
                    }
                }
            }
            Iterator children = res.listChildren();
            while (children.hasNext()) {
                resources.addLast(children.next());
            }
        }
        styleCache.put(cacheKey, cssStyle, LMT);
        return cssStyle;
    }

    private boolean isFragmentResource(Resource res) {
        ValueMap props = (ValueMap)res.adaptTo(ValueMap.class);
        return "guidePanel".equals(props.get("guideNodeClass", (Object)"")) && !"".equals(props.get("fragRef", (Object)""));
    }

    private void writeStyleConfig(SlingHttpServletRequest request, SlingHttpServletResponse response, String pagePath, boolean isTheme) throws IOException {
        HashMap<String, String> result = new HashMap<String, String>();
        ResourceResolver resolver = request.getResourceResolver();
        ComponentContext context = WCMUtils.getComponentContext((ServletRequest)request);
        Resource pageResource = resolver.getResource(pagePath);
        ArrayDeque<Object> resources = new ArrayDeque<Object>(100);
        if (context != null) {
            Template template = context.getPage().getTemplate();
            if (template.hasStructureSupport() && isTheme) {
                TemplateManager manager = (TemplateManager)resolver.adaptTo(TemplateManager.class);
                List structuredResources = manager.getStructureResources(context);
                for (Resource r : structuredResources) {
                    resources.addLast((Object)r);
                }
            } else if (pageResource != null) {
                resources.addLast((Object)pageResource);
            }
        } else if (pageResource != null) {
            resources.addLast((Object)pageResource);
        }
        JSONWriter writer = new JSONWriter((Writer)response.getWriter());
        try {
            writer.object();
            while (resources.size() > 0) {
                com.day.cq.wcm.api.components.Component component;
                Resource res = (Resource)resources.removeFirst();
                if (res.getResourceType() != null && (component = this.getComponentOfResource(request, res)) != null && !result.containsKey(component.getResourceType())) {
                    String resType = component.getResourceType();
                    result.put(resType, "");
                    Resource styleConfigRes = this.getStyleConfig(resolver, component, isTheme);
                    if (!(styleConfigRes instanceof NonExistingResource)) {
                        writer.key(resType);
                        writer.object();
                        this.dumpStyleConfig(styleConfigRes, writer);
                        writer.endObject();
                    }
                }
                Iterator children = res.listChildren();
                while (children.hasNext()) {
                    resources.addLast(children.next());
                }
            }
            writer.endObject();
        }
        catch (JSONException e) {
            this.logger.error("unable to get style config for the page " + e.getMessage(), (Throwable)e);
        }
    }

    private com.day.cq.wcm.api.components.Component getComponentOfResource(SlingHttpServletRequest request, Resource res) {
        ComponentManager compMgr = (ComponentManager)request.getResourceResolver().adaptTo(ComponentManager.class);
        ValueMap properties = (ValueMap)res.adaptTo(ValueMap.class);
        String resType = (String)properties.get("sling:resourceType", (Object)"");
        if (resType.equals("")) {
            return null;
        }
        com.day.cq.wcm.api.components.Component component = compMgr.getComponentOfResource(res);
        return component;
    }

    private Resource getStyleConfig(ResourceResolver resolver, com.day.cq.wcm.api.components.Component comp, boolean isTheme) {
        Resource styleResource = null;
        String compPath = comp.getPath();
        String styleConfigPath = "mnt/override/" + compPath;
        styleConfigPath = isTheme ? styleConfigPath + "/_cq_themeConfig" : styleConfigPath + "/_cq_styleConfig";
        styleResource = resolver.resolve(styleConfigPath);
        ValueMap values = styleResource.getValueMap();
        String target = (String)values.get("target", String.class);
        if (target != null) {
            styleConfigPath = target;
            if (isTheme) {
                styleConfigPath = styleConfigPath.replace("cq:styleConfig", "_cq_styleConfig").replace("cq:themeConfig", "_cq_themeConfig");
            }
            styleResource = resolver.resolve(styleConfigPath);
        }
        return styleResource;
    }

    private void dumpStyleConfig(Resource styleConfig, JSONWriter writer) throws JSONException {
        writer.key(styleConfig.getName());
        writer.object();
        ValueMap valueMap = styleConfig.getValueMap();
        String target = (String)valueMap.get("target", String.class);
        if (target != null) {
            String themeConfigPath = target;
            themeConfigPath = themeConfigPath.replace("cq:styleConfig", "_cq_styleConfig").replace("cq:themeConfig", "_cq_themeConfig");
            ResourceResolver resolver = styleConfig.getResourceResolver();
            styleConfig = resolver.resolve(themeConfigPath);
            valueMap = styleConfig.getValueMap();
        }
        Set properties = valueMap.keySet();
        for (String prop : properties) {
            writer.key(prop).value(valueMap.get((Object)prop));
        }
        for (Resource child : styleConfig.getChildren()) {
            this.dumpStyleConfig(child, writer);
        }
        writer.endObject();
    }

    protected void bindCacheManager(CacheManager cacheManager) {
        this.cacheManager = cacheManager;
    }

    protected void unbindCacheManager(CacheManager cacheManager) {
        if (this.cacheManager == cacheManager) {
            this.cacheManager = null;
        }
    }

    protected void bindStaleAssetIndicatorService(StaleAssetIndicatorService staleAssetIndicatorService) {
        this.staleAssetIndicatorService = staleAssetIndicatorService;
    }

    protected void unbindStaleAssetIndicatorService(StaleAssetIndicatorService staleAssetIndicatorService) {
        if (this.staleAssetIndicatorService == staleAssetIndicatorService) {
            this.staleAssetIndicatorService = null;
        }
    }

    /*
     * This class specifies class file version 49.0 but uses Java 6 signatures.  Assumed Java 6.
     */
    private static class InlineStyleSelectorProvider
    extends CSSObject.SelectorProvider {
        private static final String CSS_CLASS_PROP = "cq:cssClass";
        private Resource resource;

        private InlineStyleSelectorProvider() {
        }

        public void setEditableResource(Resource res) {
            this.resource = res;
        }

        private String applyCssClass(String className, String selector) {
            String[] selectors = selector.split(",");
            Object[] newSelectorString = new String[selectors.length];
            int i = 0;
            for (String cssSelector : selectors) {
                newSelectorString[i++] = "." + className + " " + cssSelector;
            }
            return StringUtils.join((Object[])newSelectorString, (String)",");
        }

        @Override
        public Selector getCSSRule(Resource selectorStyleConfig, List<CSSProperty> properties, Resource stateStyleConfig, JSONObject htmlAttrs) {
            Selector selector = null;
            if (this.isIdSelector(selectorStyleConfig)) {
                return null;
            }
            String cssSelectorString = this.getSelectorString(stateStyleConfig);
            if (cssSelectorString != null) {
                ValueMap props = this.resource.getValueMap();
                String cssClass = (String)props.get("cq:cssClass", (Object)"");
                if (cssClass.length() > 0) {
                    cssSelectorString = this.applyCssClass(cssClass, cssSelectorString);
                }
                selector = new Selector(cssSelectorString, cssClass, properties);
            }
            return selector;
        }
    }

}