blob: 98af2f86507bd919226f548fc5e8ec2235bf04a9 [file] [log] [blame]
/*
* 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;
}
} catch (SiteException e) {
throw new RuntimeException(e);
}
}
return result;
}
}
}