info.magnolia.rendering.template.configured.ConfiguredInheritance.java Source code

Java tutorial

Introduction

Here is the source code for info.magnolia.rendering.template.configured.ConfiguredInheritance.java

Source

/**
 * This file Copyright (c) 2011-2012 Magnolia International
 * Ltd.  (http://www.magnolia-cms.com). All rights reserved.
 *
 *
 * This file is dual-licensed under both the Magnolia
 * Network Agreement and the GNU General Public License.
 * You may elect to use one or the other of these licenses.
 *
 * This file is distributed in the hope that it will be
 * useful, but AS-IS and WITHOUT ANY WARRANTY; without even the
 * implied warranty of MERCHANTABILITY or FITNESS FOR A
 * PARTICULAR PURPOSE, TITLE, or NONINFRINGEMENT.
 * Redistribution, except as permitted by whichever of the GPL
 * or MNA you select, is prohibited.
 *
 * 1. For the GPL license (GPL), you can redistribute and/or
 * modify this file under the terms of the GNU General
 * Public License, Version 3, as published by the Free Software
 * Foundation.  You should have received a copy of the GNU
 * General Public License, Version 3 along with this program;
 * if not, write to the Free Software Foundation, Inc., 51
 * Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 *
 * 2. For the Magnolia Network Agreement (MNA), this file
 * and the accompanying materials are made available under the
 * terms of the MNA which accompanies this distribution, and
 * is available at http://www.magnolia-cms.com/mna.html
 *
 * Any modifications to this file must keep this entire header
 * intact.
 *
 */
package info.magnolia.rendering.template.configured;

import info.magnolia.jcr.RuntimeRepositoryException;
import info.magnolia.jcr.predicate.AbstractPredicate;
import info.magnolia.jcr.util.NodeTypes;
import info.magnolia.jcr.util.NodeUtil;
import info.magnolia.objectfactory.Components;
import info.magnolia.rendering.template.InheritanceConfiguration;

import java.util.Comparator;

import javax.jcr.Node;
import javax.jcr.NodeIterator;
import javax.jcr.RepositoryException;

import org.apache.commons.lang.StringUtils;

/**
 * Defines behavior for inheritance. Allows for enabling
 *
 * @version $Id$
 */
public class ConfiguredInheritance implements InheritanceConfiguration {

    public static final String COMPONENTS_ALL = "all";
    public static final String COMPONENTS_NONE = "none";
    public static final String COMPONENTS_FILTERED = "filtered";

    public static final String PROPERTIES_ALL = "all";
    public static final String PROPERTIES_NONE = "none";

    private Boolean enabled = false;
    private String components = COMPONENTS_FILTERED;
    private String properties = PROPERTIES_ALL;
    private Class<? extends AbstractPredicate<Node>> predicateClass;
    private Class<? extends Comparator<Node>> nodeComparatorClass;

    @Override
    public Boolean isEnabled() {
        return enabled;
    }

    public void setEnabled(Boolean enabled) {
        this.enabled = enabled;
    }

    public void setComponents(String components) {
        this.components = components;
    }

    public void setProperties(String properties) {
        this.properties = properties;
    }

    @Override
    public Boolean isInheritsProperties() {
        return isEnabled() != null && isEnabled()
                && StringUtils.equalsIgnoreCase(StringUtils.trim(properties), PROPERTIES_ALL);
    }

    @Override
    public Boolean isInheritsComponents() {
        return isEnabled() != null && isEnabled()
                && (StringUtils.equalsIgnoreCase(StringUtils.trim(components), COMPONENTS_ALL)
                        || StringUtils.equalsIgnoreCase(StringUtils.trim(components), COMPONENTS_FILTERED));
    }

    @Override
    public AbstractPredicate<Node> getComponentPredicate() {
        if (isEnabled() == null || !isEnabled()) {
            return new InheritNothingInheritancePredicate();
        }
        if (predicateClass != null) {
            return Components.newInstance(predicateClass);
        }
        if (StringUtils.equalsIgnoreCase(StringUtils.trim(components), COMPONENTS_ALL)) {
            return new AllComponentsAndResourcesInheritancePredicate();
        }
        if (StringUtils.equalsIgnoreCase(StringUtils.trim(components), COMPONENTS_FILTERED)) {
            return new FilteredComponentInheritancePredicate();
        }
        return new InheritNothingInheritancePredicate();
    }

    public void setPredicateClass(Class<? extends AbstractPredicate<Node>> predicateClass) {
        this.predicateClass = predicateClass;
    }

    @Override
    public Comparator<Node> getComponentComparator() {
        if (nodeComparatorClass != null) {
            return Components.newInstance(nodeComparatorClass);
        }
        return new NodeDepthComparator();
    }

    public void setNodeComparatorClass(Class<? extends Comparator<Node>> nodeComparatorClass) {
        this.nodeComparatorClass = nodeComparatorClass;
    }

    /**
     * Predicate for component inheritance that includes only nodes with a a property named 'inheritable' that needs to
     * be present and set to 'true'.
     */
    public static class FilteredComponentInheritancePredicate extends AbstractPredicate<Node> {

        public static final String INHERITED_PROPERTY_NAME = "inheritable";

        @Override
        public boolean evaluateTyped(Node node) {
            try {
                return NodeUtil.isNodeType(node, NodeTypes.Component.NAME)
                        && (node.hasProperty(INHERITED_PROPERTY_NAME)
                                && Boolean.parseBoolean(node.getProperty(INHERITED_PROPERTY_NAME).getString()));
            } catch (RepositoryException e) {
                throw new RuntimeRepositoryException(e);
            }
        }
    }

    /**
     * Predicate for component inheritance that includes all components.
     */
    public static class AllComponentsAndResourcesInheritancePredicate extends AbstractPredicate<Node> {

        @Override
        public boolean evaluateTyped(Node node) {
            try {
                return NodeUtil.isNodeType(node, NodeTypes.Component.NAME)
                        || NodeUtil.isNodeType(node, NodeTypes.Resource.NAME);
            } catch (RepositoryException e) {
                throw new RuntimeRepositoryException(e);
            }
        }
    }

    /**
     * Predicate for component inheritance that includes no components.
     */
    public static class InheritNothingInheritancePredicate extends AbstractPredicate<Node> {

        @Override
        public boolean evaluateTyped(Node node) {
            return false;
        }
    }

    /**
     * Comparator for ordering nodes by depth placing nodes deeper in the hierarchy after those further up and ordering
     * nodes on the same level by the order they appear as siblings.
     */
    public static class NodeDepthComparator implements Comparator<Node> {

        @Override
        public int compare(Node lhs, Node rhs) {
            try {
                if (lhs.getDepth() != rhs.getDepth())
                    return lhs.getDepth() - rhs.getDepth();
                return getSiblingIndex(lhs) - getSiblingIndex(rhs);
            } catch (RepositoryException e) {
                throw new RuntimeRepositoryException(e);
            }
        }

        private int getSiblingIndex(Node node) throws RepositoryException {
            if (node.getDepth() == 0) {
                return 0;
            }
            int index = 0;
            NodeIterator nodes = node.getParent().getNodes();
            while (nodes.hasNext()) {
                if (NodeUtil.isSame(node, nodes.nextNode())) {
                    return index;
                }
                index++;
            }
            return -1;
        }
    }
}