<commit_before>/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 *  contributor license agreements.  See the NOTICE file distributed with
 *  this work for additional information regarding copyright ownership.
 *  The ASF licenses this file to You under the Apache License, Version 2.0
 *  (the "License"); you may not use this file except in compliance with
 *  the License.  You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS,
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the License for the specific language governing permissions and
 *  limitations under the License.
 *
 */

package org.apache.lenya.cms.site;

import java.util.Arrays;
import java.util.Comparator;

import org.apache.avalon.framework.logger.AbstractLogEnabled;
import org.apache.avalon.framework.service.ServiceException;
import org.apache.avalon.framework.service.ServiceManager;
import org.apache.avalon.framework.service.Serviceable;
import org.apache.lenya.cms.publication.DocumentFactory;

/**
 * Abstract base class for site managers.
 * 
 * @version $Id$
 */
public abstract class AbstractSiteManager extends AbstractLogEnabled implements SiteManager, Serviceable {

    protected ServiceManager manager;

    /**
     * @see org.apache.avalon.framework.service.Serviceable#service(org.apache.avalon.framework.service.ServiceManager)
     */
    public void service(ServiceManager manager) throws ServiceException {
        this.manager = manager;
    }
    
    /**
     * Ctor.
     * @param manager The service manager.
     */
    public AbstractSiteManager() {
    }

    /**
     * @see org.apache.lenya.cms.site.SiteManager#sortAscending(org.apache.lenya.cms.publication.util.DocumentSet)
     */
    public SiteNode[] sortAscending(SiteNode[] nodes) throws SiteException {
        if (nodes.length > 0) {

            DocumentFactory map = nodes[0].getStructure().getPublication().getFactory();
            if (!check(map, new NodeSet(this.manager, nodes))) {
                throw new SiteException("The dependence relation is not a strict partial order!");
            }

            SiteNode[] sortedNodes = (SiteNode[]) Arrays.asList(nodes).toArray(new SiteNode[nodes.length]);
            Arrays.sort(sortedNodes, new NodeComparator(map));
            return sortedNodes;
        }
        else {
            return  nodes;
        }
    }

    /**
     * Checks if the dependence relation is a strict partial order.
     * 
     * @param map The identity map to operate on.
     * @param set The document set to check.
     * @return A boolean value.
     * @throws SiteException when something went wrong.
     */
    protected boolean check(DocumentFactory map, NodeSet set) throws SiteException {
        boolean isStrictPartialOrder = isIrreflexive(map, set) && isAntisymmetric(map, set)
                && isTransitive(map, set);
        return isStrictPartialOrder;
    }

    /**
     * Checks if the dependence relation is antisymmetric.
     * 
     * @param map The identity map to operate on.
     * @param set The document set to check.
     * @return A boolean value.
     * @throws SiteException when something went wrong.
     */
    protected boolean isAntisymmetric(DocumentFactory map, NodeSet set) throws SiteException {
        SiteNode[] resources = set.getNodes();
        boolean isAntisymmetric = true;
        for (int i = 0; i < resources.length; i++) {
            for (int j = i + 1; j < resources.length; j++) {
                if (requires(map, resources[i], resources[j])
                        && requires(map, resources[j], resources[i])
                        && !(resources[i] == resources[j])) {
                    isAntisymmetric = false;
                }
            }
        }
        return isAntisymmetric;
    }

    /**
     * Checks if the dependence relation is transitive.
     * 
     * @param map The identity map to operate on.
     * @param set The document set to check.
     * @return A boolean value.
     * @throws SiteException when something went wrong.
     */
    protected boolean isTransitive(DocumentFactory map, NodeSet set) throws SiteException {
        SiteNode[] resources = set.getNodes();
        boolean isTransitive = true;
        for (int i = 0; i < resources.length; i++) {
            for (int j = i + 1; j < resources.length; j++) {
                for (int k = j + 1; k < resources.length; k++) {
                    if (requires(map, resources[i], resources[j])
                            && requires(map, resources[j], resources[k])
                            && !requires(map, resources[i], resources[k])) {
                        isTransitive = false;
                    }
                }
            }
        }
        return isTransitive;
    }

    /**
     * Checks if the dependence relation is irreflexive.
     * 
     * @param map The identity map to operate on.
     * @param set The document set.
     * @return A boolean value
     * @throws SiteException
     */
    protected boolean isIrreflexive(DocumentFactory map, NodeSet set) throws SiteException {
        SiteNode[] resources = set.getNodes();
        boolean isIrreflexive = true;
        for (int i = 0; i < resources.length; i++) {
            if (requires(map, resources[i], resources[i])) {
                isIrreflexive = false;
            }
        }
        return isIrreflexive;
    }

    /**
     * Compares nodes according to the dependence relation.
     */
    public class NodeComparator implements Comparator {

        /**
         * Ctor.
         * 
         * @param map The identity map to operate on.
         */
        public NodeComparator(DocumentFactory map) {
            this.map = map;
        }

        private DocumentFactory map;

        /**
         * @see java.util.Comparator#compare(java.lang.Object, java.lang.Object)
         */
        public int compare(Object arg0, Object arg1) {
            int result = 0;
            if (arg0 instanceof SiteNode && arg1 instanceof SiteNode) {
                SiteNode doc1 = (SiteNode) arg0;
                SiteNode doc2 = (SiteNode) arg1;

                try {
                    if (AbstractSiteManager.this.requires(map, doc1, doc2)) {
                        result = 1;
                    }
                    if (AbstractSiteManager.this.requires(map, doc2, doc1)) {
                        result = -1;
                    }<commit_msg>Pointless to have both checks run. Wrapped second in else. Related to bug 44577.<commit_after>/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 *  contributor license agreements.  See the NOTICE file distributed with
 *  this work for additional information regarding copyright ownership.
 *  The ASF licenses this file to You under the Apache License, Version 2.0
 *  (the "License"); you may not use this file except in compliance with
 *  the License.  You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS,
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the License for the specific language governing permissions and
 *  limitations under the License.
 *
 */

package org.apache.lenya.cms.site;

import java.util.Arrays;
import java.util.Comparator;

import org.apache.avalon.framework.logger.AbstractLogEnabled;
import org.apache.avalon.framework.service.ServiceException;
import org.apache.avalon.framework.service.ServiceManager;
import org.apache.avalon.framework.service.Serviceable;
import org.apache.lenya.cms.publication.DocumentFactory;

/**
 * Abstract base class for site managers.
 * 
 * @version $Id$
 */
public abstract class AbstractSiteManager extends AbstractLogEnabled implements SiteManager, Serviceable {

    protected ServiceManager manager;

    /**
     * @see org.apache.avalon.framework.service.Serviceable#service(org.apache.avalon.framework.service.ServiceManager)
     */
    public void service(ServiceManager manager) throws ServiceException {
        this.manager = manager;
    }
    
    /**
     * Ctor.
     * @param manager The service manager.
     */
    public AbstractSiteManager() {
    }

    /**
     * @see org.apache.lenya.cms.site.SiteManager#sortAscending(org.apache.lenya.cms.publication.util.DocumentSet)
     */
    public SiteNode[] sortAscending(SiteNode[] nodes) throws SiteException {
        if (nodes.length > 0) {

            DocumentFactory map = nodes[0].getStructure().getPublication().getFactory();
            if (!check(map, new NodeSet(this.manager, nodes))) {
                throw new SiteException("The dependence relation is not a strict partial order!");
            }

            SiteNode[] sortedNodes = (SiteNode[]) Arrays.asList(nodes).toArray(new SiteNode[nodes.length]);
            Arrays.sort(sortedNodes, new NodeComparator(map));
            return sortedNodes;
        }
        else {
            return  nodes;
        }
    }

    /**
     * Checks if the dependence relation is a strict partial order.
     * 
     * @param map The identity map to operate on.
     * @param set The document set to check.
     * @return A boolean value.
     * @throws SiteException when something went wrong.
     */
    protected boolean check(DocumentFactory map, NodeSet set) throws SiteException {
        boolean isStrictPartialOrder = isIrreflexive(map, set) && isAntisymmetric(map, set)
                && isTransitive(map, set);
        return isStrictPartialOrder;
    }

    /**
     * Checks if the dependence relation is antisymmetric.
     * 
     * @param map The identity map to operate on.
     * @param set The document set to check.
     * @return A boolean value.
     * @throws SiteException when something went wrong.
     */
    protected boolean isAntisymmetric(DocumentFactory map, NodeSet set) throws SiteException {
        SiteNode[] resources = set.getNodes();
        boolean isAntisymmetric = true;
        for (int i = 0; i < resources.length; i++) {
            for (int j = i + 1; j < resources.length; j++) {
                if (requires(map, resources[i], resources[j])
                        && requires(map, resources[j], resources[i])
                        && !(resources[i] == resources[j])) {
                    isAntisymmetric = false;
                }
            }
        }
        return isAntisymmetric;
    }

    /**
     * Checks if the dependence relation is transitive.
     * 
     * @param map The identity map to operate on.
     * @param set The document set to check.
     * @return A boolean value.
     * @throws SiteException when something went wrong.
     */
    protected boolean isTransitive(DocumentFactory map, NodeSet set) throws SiteException {
        SiteNode[] resources = set.getNodes();
        boolean isTransitive = true;
        for (int i = 0; i < resources.length; i++) {
            for (int j = i + 1; j < resources.length; j++) {
                for (int k = j + 1; k < resources.length; k++) {
                    if (requires(map, resources[i], resources[j])
                            && requires(map, resources[j], resources[k])
                            && !requires(map, resources[i], resources[k])) {
                        isTransitive = false;
                    }
                }
            }
        }
        return isTransitive;
    }

    /**
     * Checks if the dependence relation is irreflexive.
     * 
     * @param map The identity map to operate on.
     * @param set The document set.
     * @return A boolean value
     * @throws SiteException
     */
    protected boolean isIrreflexive(DocumentFactory map, NodeSet set) throws SiteException {
        SiteNode[] resources = set.getNodes();
        boolean isIrreflexive = true;
        for (int i = 0; i < resources.length; i++) {
            if (requires(map, resources[i], resources[i])) {
                isIrreflexive = false;
            }
        }
        return isIrreflexive;
    }

    /**
     * Compares nodes according to the dependence relation.
     */
    public class NodeComparator implements Comparator {

        /**
         * Ctor.
         * 
         * @param map The identity map to operate on.
         */
        public NodeComparator(DocumentFactory map) {
            this.map = map;
        }

        private DocumentFactory map;

        /**
         * @see java.util.Comparator#compare(java.lang.Object, java.lang.Object)
         */
        public int compare(Object arg0, Object arg1) {
            int result = 0;
            if (arg0 instanceof SiteNode && arg1 instanceof SiteNode) {
                SiteNode doc1 = (SiteNode) arg0;
                SiteNode doc2 = (SiteNode) arg1;

                try {
                    if (AbstractSiteManager.this.requires(map, doc1, doc2)) {
                        result = 1;
                    }
                    else if (AbstractSiteManager.this.requires(map, doc2, doc1)) {
                        result = -1;
                    }
{'fraction_non_alphanumeric': 0.09415730337078651, 'fraction_numerical': 0.004419475655430711, 'mean_word_length': 2.0919407132931913, 'pattern_counts': {'":': 0, '<': 15, '<?xml version=': 0, '>': 5, 'https://': 0, 'lorem ipsum': 0, 'www.': 2, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '5525170', 'n_tokens_mistral': 3564, 'n_tokens_neox': 3436, 'n_words': 1102}