FrameworkImpl.java 8.85 KB
/*
 * Decompiled with CFR 0_118.
 * 
 * Could not load the following classes:
 *  com.day.cq.commons.inherit.HierarchyNodeInheritanceValueMap
 *  javax.jcr.AccessDeniedException
 *  javax.jcr.Node
 *  javax.jcr.NodeIterator
 *  javax.jcr.PathNotFoundException
 *  javax.jcr.Property
 *  javax.jcr.RepositoryException
 *  javax.jcr.ValueFormatException
 *  org.apache.sling.api.resource.Resource
 *  org.apache.sling.api.resource.ResourceResolver
 *  org.slf4j.Logger
 *  org.slf4j.LoggerFactory
 */
package com.day.cq.analytics.sitecatalyst.impl;

import com.day.cq.analytics.sitecatalyst.Framework;
import com.day.cq.analytics.sitecatalyst.FrameworkComponent;
import com.day.cq.commons.inherit.HierarchyNodeInheritanceValueMap;
import java.util.Collection;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;
import javax.jcr.AccessDeniedException;
import javax.jcr.Node;
import javax.jcr.NodeIterator;
import javax.jcr.PathNotFoundException;
import javax.jcr.Property;
import javax.jcr.RepositoryException;
import javax.jcr.ValueFormatException;
import org.apache.sling.api.resource.Resource;
import org.apache.sling.api.resource.ResourceResolver;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class FrameworkImpl
extends HierarchyNodeInheritanceValueMap
implements Framework {
    private static final String NN_MAPPINGS = "mappings";
    private static final String NN_PUBLIC = "public";
    private final Logger log;
    private Node node;
    private Resource resource;
    private Map<String, FrameworkComponent> allComponents;
    private Map<String, String> mappings;
    private Map<String, FrameworkComponent> componentMappings;

    public FrameworkImpl(Resource resource) {
        super(resource);
        this.log = LoggerFactory.getLogger(this.getClass());
        this.allComponents = new HashMap<String, FrameworkComponent>();
        this.mappings = new HashMap<String, String>();
        this.componentMappings = new HashMap<String, FrameworkComponent>();
        try {
            this.loadMappings(resource);
        }
        catch (RepositoryException e) {
            this.log.error("Failed loading mappings from resource at " + resource.getPath(), (Throwable)e);
        }
    }

    protected void loadMappings(Resource resource) throws RepositoryException, ValueFormatException, PathNotFoundException {
        this.log.debug("Loading mappings from resource {}", (Object)resource);
        this.resource = resource;
        Node parent = this.node = (Node)resource.adaptTo(Node.class);
        while (this.nodeMatchesResourceType(parent)) {
            this.log.debug("Collecting components from {}", (Object)parent);
            this.collectComponents(parent);
            if (this.stopPropagation(parent)) break;
            try {
                int n = parent.getName().equals("public") ? 3 : 2;
                int distanceFromParent = n;
                if (!this.stopInheritance(parent = this.getParent(parent, distanceFromParent).getNode("jcr:content"))) continue;
                break;
            }
            catch (AccessDeniedException e) {
                if (!this.log.isDebugEnabled()) break;
                this.log.debug("Access to parent of resource {} denied.", (Object)parent);
                break;
            }
            catch (RepositoryException e) {
                this.log.warn(e.toString(), (Throwable)e);
                break;
            }
        }
        for (FrameworkComponent component : this.allComponents.values()) {
            for (String scVar : component.inheritedKeySet()) {
                String cqVar = (String)component.getInherited(scVar, String.class);
                if (cqVar == null || "".equals(cqVar.trim())) continue;
                this.mappings.put(scVar, cqVar);
                this.componentMappings.put(scVar, component);
            }
        }
    }

    private Node getParent(Node current, int depth) throws RepositoryException {
        Node parent = current;
        while (depth-- > 0) {
            parent = parent.getParent();
        }
        return parent;
    }

    private boolean stopInheritance(Node parent) throws PathNotFoundException, RepositoryException, ValueFormatException {
        Node mappings = this.getNodeMaybeFoundOnPublicNode(parent, "mappings");
        return mappings != null && mappings.hasProperty("inheritance") && !mappings.getProperty("inheritance").getBoolean();
    }

    private Node getParentIfPublicNode(Node node) throws RepositoryException {
        if (node.getName().equals("public")) {
            try {
                return node.getParent();
            }
            catch (AccessDeniedException e) {
                return node;
            }
        }
        return node;
    }

    private Node getNodeMaybeFoundOnPublicNode(Node node, String nodeName) throws RepositoryException {
        Node publicNode;
        if (node.hasNode("public") && (publicNode = node.getNode("public")).hasNode(nodeName)) {
            return publicNode.getNode(nodeName);
        }
        if (node.hasNode(nodeName)) {
            return node.getNode(nodeName);
        }
        return null;
    }

    private boolean stopPropagation(Node parent) throws PathNotFoundException, RepositoryException, ValueFormatException {
        Node mappings = this.getNodeMaybeFoundOnPublicNode(parent, "mappings");
        return mappings != null && mappings.hasProperty("propagate") && !mappings.getProperty("propagate").getBoolean();
    }

    private boolean nodeMatchesResourceType(Node parent) throws RepositoryException, ValueFormatException, PathNotFoundException {
        if (parent == null) {
            return false;
        }
        if (parent.getName().equals("public")) {
            return true;
        }
        if ((parent = this.getParentIfPublicNode(parent)) == null) {
            return false;
        }
        Node current = this.getParentIfPublicNode(this.node);
        if (current == null) {
            return false;
        }
        return parent.hasProperty("sling:resourceType") && current.getProperty("sling:resourceType").getString().equals(parent.getProperty("sling:resourceType").getString());
    }

    private void collectComponents(Node framework) {
        try {
            framework = this.getPublicNodeIfExists(framework);
            for (Node componentNode : new ComponentNodes(framework)) {
                try {
                    FrameworkComponent component = (FrameworkComponent)this.resource.getResourceResolver().getResource(componentNode.getPath()).adaptTo(FrameworkComponent.class);
                    if (component == null || this.allComponents.containsKey(component.get((Object)"cq:componentPath"))) continue;
                    this.allComponents.put((String)component.get((Object)"cq:componentPath"), component);
                }
                catch (RepositoryException e) {
                    this.log.warn(e.toString(), (Throwable)e);
                }
            }
        }
        catch (RepositoryException e) {
            this.log.warn(e.toString(), (Throwable)e);
        }
    }

    private Node getPublicNodeIfExists(Node node) throws RepositoryException {
        if (node.hasNode("public")) {
            return node.getNode("public");
        }
        return node;
    }

    @Override
    public Map<String, FrameworkComponent> getAllComponents() {
        return this.allComponents;
    }

    @Override
    public boolean mapsSCVariable(String var) {
        return this.mappings.containsKey(var);
    }

    @Override
    public boolean mapsCQVariable(String var) {
        return this.mappings.containsValue(var);
    }

    @Override
    public String getMapping(String scVar) {
        return this.mappings.get(scVar);
    }

    @Override
    public FrameworkComponent getFrameworkComponent(String scVar) {
        return this.componentMappings.get(scVar);
    }

    @Override
    public Set<String> scVars() {
        return this.mappings.keySet();
    }

    @Override
    public Collection<String> cqVars() {
        return this.mappings.values();
    }

    class ComponentNodes
    implements Iterable<Node> {
        Node framework;

        public ComponentNodes(Node framework) {
            this.framework = framework;
        }

        @Override
        public Iterator<Node> iterator() {
            try {
                return this.framework.getNode("mappings").getNodes();
            }
            catch (RepositoryException e) {
                FrameworkImpl.this.log.debug(e.toString());
                return new Iterator<Node>(){

                    @Override
                    public boolean hasNext() {
                        return false;
                    }

                    @Override
                    public Node next() {
                        return null;
                    }

                    @Override
                    public void remove() {
                    }
                };
            }
        }

    }

}