WidgetConfigDocument.java 12.5 KB
/*
 * Decompiled with CFR 0_118.
 * 
 * Could not load the following classes:
 *  com.day.cq.dam.api.Asset
 *  com.day.cq.dam.api.Rendition
 *  org.apache.commons.lang.StringUtils
 *  org.apache.sling.api.adapter.SlingAdaptable
 *  org.apache.sling.api.resource.Resource
 *  org.apache.sling.api.resource.ResourceResolver
 *  org.apache.sling.api.resource.ValueMap
 *  org.slf4j.Logger
 *  org.slf4j.LoggerFactory
 */
package com.adobe.cq.mobile.platform.impl;

import com.adobe.cq.mobile.platform.impl.MobileAppException;
import com.adobe.cq.mobile.platform.impl.utils.MobileUtil;
import com.day.cq.dam.api.Asset;
import com.day.cq.dam.api.Rendition;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import org.apache.commons.lang.StringUtils;
import org.apache.sling.api.adapter.SlingAdaptable;
import org.apache.sling.api.resource.Resource;
import org.apache.sling.api.resource.ResourceResolver;
import org.apache.sling.api.resource.ValueMap;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NamedNodeMap;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;

public class WidgetConfigDocument
extends SlingAdaptable {
    private static final Logger log = LoggerFactory.getLogger(WidgetConfigDocument.class);
    public static final String XMLNS_GAP = "http://phonegap.com/ns/1.0";
    public static final String XMLNS_CQ = "http://www.day.com/jcr/cq/1.0";
    private final Document doc;
    private static Map<String, String> multiMap = new LinkedHashMap<String, String>();

    public WidgetConfigDocument(Document doc) {
        if (doc == null) {
            throw new IllegalArgumentException("Cannot instantiate widget document. Document cannot be null.");
        }
        this.doc = doc;
    }

    public static WidgetConfigDocument loadConfigDocument(InputStream stream) throws MobileAppException {
        if (stream != null) {
            try {
                DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
                dbf.setNamespaceAware(true);
                dbf.setIgnoringComments(true);
                dbf.setExpandEntityReferences(true);
                DocumentBuilder db = dbf.newDocumentBuilder();
                WidgetConfigDocument configDoc = new WidgetConfigDocument(db.parse(stream));
                return configDoc;
            }
            catch (Exception e) {
                throw new MobileAppException("Unable to load the widget configuration document", e);
            }
        }
        return null;
    }

    public static WidgetConfigDocument loadConfigDocument(String path, Resource parent) throws MobileAppException {
        if (parent == null) {
            throw new IllegalArgumentException("Cannot load widget document. Widget resource cannot be null.");
        }
        Resource configResource = parent.getResourceResolver().getResource(path);
        if (configResource != null) {
            try {
                Asset configAsset = (Asset)configResource.adaptTo(Asset.class);
                if (configAsset != null) {
                    configResource = configAsset.getOriginal();
                }
                InputStream configIS = (InputStream)configResource.adaptTo(InputStream.class);
                WidgetConfigDocument configDoc = WidgetConfigDocument.loadConfigDocument(configIS);
                Resource widgetRes = parent.getChild("widget");
                configDoc.mergeWidgetConfig(widgetRes);
                return configDoc;
            }
            catch (MobileAppException e) {
                log.error("Unable to parse the widget configuration resource. {}", (Object)configResource.getPath(), (Object)e);
                throw new MobileAppException("Unable to load the widget configuration resource at: " + configResource.getPath(), e);
            }
        }
        return null;
    }

    public String getId() {
        return this.doc.getDocumentElement().getAttribute("id");
    }

    public String getVersion() {
        return this.doc.getDocumentElement().getAttribute("version");
    }

    public String getName() {
        return this.getElementContent("name").trim();
    }

    public String getDescription() {
        return this.getElementContent("description").trim();
    }

    public String getContentSource() {
        Element eContent = this.getFirstElement("content");
        if (eContent != null) {
            String contentSrc = eContent.getAttribute("src");
            if (StringUtils.isNotBlank((String)contentSrc)) {
                if (contentSrc.startsWith("/")) {
                    contentSrc = contentSrc.substring(1);
                }
                if (!contentSrc.endsWith(".html")) {
                    contentSrc = contentSrc + ".html";
                }
            }
            return contentSrc;
        }
        return "";
    }

    public String getAccessOrigin() {
        Element eAccess = this.getFirstElement("access");
        if (eAccess != null) {
            return eAccess.getAttribute("origin");
        }
        return "";
    }

    public Map<String, String> getAuthor() {
        Element eAuthor = this.getFirstElement("author");
        if (eAuthor != null) {
            HashMap<String, String> authorMap = new HashMap<String, String>();
            authorMap.put("href", eAuthor.getAttribute("href"));
            authorMap.put("email", eAuthor.getAttribute("email"));
            authorMap.put("value", eAuthor.getTextContent().trim());
            return authorMap;
        }
        return null;
    }

    public Element getDefaultIconElement() {
        NodeList nList = this.doc.getElementsByTagName("icon");
        for (int i = 0; i < nList.getLength(); ++i) {
            Element eElement = (Element)nList.item(i);
            NamedNodeMap attrs = eElement.getAttributes();
            Node iconSrc = attrs.getNamedItem("src");
            Node fileReference = attrs.getNamedItem("fileReference");
            if (iconSrc == null && fileReference == null) continue;
            if (attrs.getLength() == 1) {
                return eElement;
            }
            if (attrs.getLength() <= 1 || fileReference == null || iconSrc == null) continue;
            return eElement;
        }
        return null;
    }

    public String getDefaultIconPath() {
        Element eElement = this.getDefaultIconElement();
        if (eElement != null) {
            if (eElement.hasAttribute("fileReference")) {
                return eElement.getAttribute("fileReference");
            }
            return eElement.getAttribute("src");
        }
        return "";
    }

    public List<String> getIconPaths() {
        NodeList nList = this.doc.getElementsByTagName("icon");
        ArrayList<String> pathList = new ArrayList<String>();
        for (int i = 0; i < nList.getLength(); ++i) {
            Node iconNode = nList.item(i);
            if (iconNode.getNodeType() != 1) continue;
            Element eElement = (Element)iconNode;
            pathList.add(eElement.getAttribute("src"));
        }
        return pathList;
    }

    public String getPreferenceValue(String name) {
        Element prefElement = this.getPreference(name);
        if (prefElement != null) {
            return prefElement.getAttribute("value");
        }
        return "";
    }

    public Element getPreference(String name) {
        NodeList nList = this.doc.getElementsByTagName("preference");
        for (int i = 0; i < nList.getLength(); ++i) {
            Element eElement;
            Node prefNode = nList.item(i);
            if (prefNode.getNodeType() != 1 || !(eElement = (Element)prefNode).getAttribute("name").equals(name)) continue;
            return eElement;
        }
        return null;
    }

    public List<String> getPlatforms() {
        NodeList nList = this.doc.getElementsByTagNameNS("http://phonegap.com/ns/1.0", "platform");
        ArrayList<String> platformList = new ArrayList<String>();
        for (int i = 0; i < nList.getLength(); ++i) {
            Node platformNode = nList.item(i);
            if (platformNode.getNodeType() != 1) continue;
            Element eElement = (Element)platformNode;
            platformList.add(eElement.getAttribute("name"));
        }
        return platformList;
    }

    public List<Map<String, String>> getPlugins() {
        NodeList nList = this.doc.getElementsByTagNameNS("http://phonegap.com/ns/1.0", "plugin");
        ArrayList<Map<String, String>> pluginList = new ArrayList<Map<String, String>>();
        for (int i = 0; i < nList.getLength(); ++i) {
            Node pluginNode = nList.item(i);
            if (pluginNode.getNodeType() != 1) continue;
            Element eElement = (Element)pluginNode;
            HashMap<String, String> map = new HashMap<String, String>();
            map.put("name", eElement.getAttribute("name"));
            map.put("version", eElement.getAttribute("version"));
            pluginList.add(map);
        }
        return pluginList;
    }

    public <AdapterType> AdapterType adaptTo(Class<AdapterType> type) {
        if (type == Document.class) {
            return (AdapterType)this.doc;
        }
        return null;
    }

    private Element getFirstElement(String name) {
        NodeList nList = this.doc.getElementsByTagName(name);
        if (nList.getLength() > 0) {
            return (Element)nList.item(0);
        }
        return null;
    }

    private String getElementContent(String name) {
        Element el = this.getFirstElement(name);
        if (el != null) {
            return el.getTextContent();
        }
        return "";
    }

    private void mergeWidgetConfig(Resource widgetRes) throws MobileAppException {
        if (widgetRes != null) {
            this.applyResourceProperties(this.doc.getDocumentElement(), widgetRes);
            this.sanitize();
        }
    }

    private void sanitize() {
        Element eContent = this.getFirstElement("content");
        if (eContent != null) {
            eContent.setAttribute("src", this.getContentSource());
        }
    }

    private void applyResourceProperties(Element element, Resource res) {
        ValueMap props = res.getValueMap();
        if (element != null && props != null) {
            for (Map.Entry entry : props.entrySet()) {
                if (((String)entry.getKey()).indexOf(":") >= 0 || !(entry.getValue() instanceof String)) continue;
                String value = MobileUtil.normalizePath((String)entry.getValue(), res);
                if (((String)entry.getKey()).equals("text")) {
                    element.setTextContent(value);
                    continue;
                }
                element.setAttribute((String)entry.getKey(), value);
            }
        }
        Iterable childResources = res.getChildren();
        for (Resource child : childResources) {
            if (multiMap.containsKey(child.getName())) {
                Iterable allChildren = child.getChildren();
                for (Resource pref : allChildren) {
                    this.applyResourceProperties(this.getChildElement(element, multiMap.get(child.getName()), pref.getName()), pref);
                }
                continue;
            }
            this.applyResourceProperties(this.getChildElement(element, child.getName()), child);
        }
    }

    private Element getChildElement(Element parent, String nodeName) {
        return this.getChildElement(parent, nodeName, null);
    }

    private Element getChildElement(Element parent, String nodeName, String name) {
        if (nodeName == null || nodeName.length() == 0) {
            return null;
        }
        Element element = null;
        for (Node child = parent.getFirstChild(); child != null; child = child.getNextSibling()) {
            if (!(child instanceof Element) || !nodeName.equals(child.getNodeName())) continue;
            String nameAttrValue = ((Element)child).getAttribute("name");
            if (name != null && name.length() > 0 && !name.equals(nameAttrValue)) continue;
            element = (Element)child;
            break;
        }
        if (element == null) {
            element = parent.getOwnerDocument().createElement(nodeName);
            if (name != null && name.length() > 0) {
                element.setAttribute("name", name);
            }
            parent.appendChild(element);
        }
        return element;
    }

    static {
        multiMap.put("preferences", "preference");
        multiMap.put("plugins", "plugin");
        multiMap.put("variables", "variable");
    }
}