
org.richfaces.cdk.ordering.PartialOrderToCompleteOrder Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of maven-richfaces-resources-plugin Show documentation
Show all versions of maven-richfaces-resources-plugin Show documentation
Maven plugin for packaging resources with web application
The newest version!
/*
* JBoss, Home of Professional Open Source.
* Copyright 2011, Red Hat, Inc., and individual contributors
* as indicated by the @author tags. See the copyright.txt file in the
* distribution for a full listing of individual contributors.
*
* This is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as
* published by the Free Software Foundation; either version 2.1 of
* the License, or (at your option) any later version.
*
* This software is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this software; if not, write to the Free
* Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
* 02110-1301 USA, or see the FSF site: http://www.fsf.org.
*/
package org.richfaces.cdk.ordering;
import java.util.Collection;
import java.util.HashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
import com.google.common.base.Predicate;
import com.google.common.base.Predicates;
import com.google.common.collect.Collections2;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.google.common.collect.Ordering;
import com.google.common.collect.Sets;
/**
*
* Stores partial orderings in order to be able derive complete ordering.
*
*
*
* When storing new partial ordering, checks that new partial ordering does not violates partial orderings stored before.
*
*
* @author Lukas Fryc
*/
public class PartialOrderToCompleteOrder {
// all items stored in partial orderings for quick access
private Set allItems = Sets.newLinkedHashSet();
// partial orderings used to check for ordering violation
private List partialOrderings = new LinkedList();
// map from items to their dependencies
private Map> dependencies = Maps.newLinkedHashMap();
/**
*
* Stores collection as partial ordering.
*
*
*
* Checks that this collection will not violate another partial orderings stored before.
*
*
* @param collection as partial order
*/
public void addPartialOrdering(Collection collection) {
if (collection == null || collection.isEmpty()) {
return;
}
checkCurrentPartialOrders(collection);
allItems.addAll(collection);
partialOrderings.add(new PartialOrdering(collection));
registerDependencies(Lists.newLinkedList(collection));
}
/**
* Provides all items which was stored in collections as partial orderings
*
* @return all items which was stored in collections as partial orderings
*/
public Set getAllItems() {
return allItems;
}
/**
*
* Provides current complete ordering derived from partial orderings.
*
*
* @return current complete ordering derived from partial orderings.
*/
public CompleteOrdering getCompleteOrdering() {
return new CompleteOrdering();
}
/**
* Get all items completely ordered.
*
* @return all items completely ordered.
*/
public Collection getCompletelyOrderedItems() {
return new CompleteOrdering().sortedCopy(allItems);
}
/**
* Class representing result of deriving complete ordering from stored partial orderings.
*/
public class CompleteOrdering extends Ordering {
private Set ordered = getCurrentOrder();
private Predicate IS_ORDERED = new Predicate() {
public boolean apply(T item) {
return ordered.contains(item);
}
};
public int compare(T left, T right) {
if (!ordered.contains(left) || !ordered.contains(right)) {
throw new IllegalStateException();
}
if (left.equals(right)) {
return 0;
}
for (T item : ordered) {
if (item.equals(left)) {
return -1;
} else if (item.equals(right)) {
return +1;
}
}
throw new IllegalStateException();
}
/**
*
* Returns new iterable sorted according to this complete ordering.
*
*
*
* All items which are unknown in this ordering are stored on the end of returned collection in the same order like in
* iterable.
*
*/
@SuppressWarnings("unchecked")
@Override
public List sortedCopy(Iterable iterable) {
List originList = (List) Lists.newLinkedList(iterable);
Collection onlyOrdered = Collections2.filter(originList, IS_ORDERED);
Collection onlyNotOrdered = Collections2.filter(originList, Predicates.not(IS_ORDERED));
List itemsInOrder = super.sortedCopy(onlyOrdered);
itemsInOrder.addAll(onlyNotOrdered);
return (List) itemsInOrder;
}
private Set getCurrentOrder() {
Set result = Sets.newLinkedHashSet();
DependencyResolver resolver = new DependencyResolver();
for (int i = 0; i < dependencies.size(); i++) {
List nodesWithoutDependencies = resolver.findNodesWithoutDependencies();
result.addAll(nodesWithoutDependencies);
resolver.removeNodes(nodesWithoutDependencies);
}
if (resolver.getSize() > 0) {
throw new IllegalStateException();
}
return result;
}
private class DependencyResolver {
private Map> deps = deepCopyOfDependencies();
private List findNodesWithoutDependencies() {
List list = Lists.newLinkedList();
for (Entry> entry : deps.entrySet()) {
if (entry.getValue().isEmpty()) {
list.add(entry.getKey());
}
}
return list;
}
private void removeNodes(List nodes) {
for (Set values : deps.values()) {
values.removeAll(nodes);
}
for (T node : nodes) {
deps.remove(node);
}
}
private Map> deepCopyOfDependencies() {
Map> result = Maps.newLinkedHashMap();
for (Entry> entry : dependencies.entrySet()) {
result.put(entry.getKey(), Sets.newHashSet(entry.getValue()));
}
return result;
}
public int getSize() {
return deps.size();
}
}
}
private void checkCurrentPartialOrders(Collection collection) {
for (PartialOrdering p : partialOrderings) {
List filtered = p.filter(collection);
if (!p.isStrictlyOrdered(filtered)) {
throw new IllegalPartialOrderingException("\ncollection: " + collection + "\n" + p);
}
}
}
private void registerDependencies(Collection collection) {
List reversedOrder = Lists.reverse(Lists.newLinkedList(collection));
Set newItemDependencies = Sets.newLinkedHashSet(collection);
for (T newItem : reversedOrder) {
newItemDependencies.remove(newItem);
registerDependenciesForItem(newItem, Sets.newLinkedHashSet(newItemDependencies));
}
}
private void registerDependenciesForItem(T item, Set newItemDependencies) {
if (!dependencies.containsKey(item)) {
dependencies.put(item, Sets.newHashSet());
}
Set itemDependences = dependencies.get(item);
itemDependences.addAll(newItemDependencies);
}
private class PartialOrdering extends Ordering {
private LinkedList order = Lists.newLinkedList();
private HashSet items = Sets.newHashSet();
public PartialOrdering(Collection collection) {
order = Lists.newLinkedList(collection);
items = Sets.newHashSet(collection);
}
public int compare(T left, T right) {
if (!items.contains(left)) {
throw new IllegalArgumentException("'" + left + "' is not part of this partial ordering");
}
if (!items.contains(right)) {
throw new IllegalArgumentException("'" + right + "' is not part of this partial ordering");
}
return order.indexOf(left) - order.indexOf(right);
}
public List filter(Collection collection) {
List list = new LinkedList(collection);
list.retainAll(items);
return list;
}
@Override
public String toString() {
return "PartialOrder" + order;
}
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy