Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance. Project price only 1 $
You can buy this project and download/modify it how often you want.
package net.sf.gluebooster.java.booster.basic.container;
import java.util.Collection;
import java.util.Comparator;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import org.apache.commons.collections4.Transformer;
import org.apache.commons.lang3.tuple.Pair;
import net.sf.gluebooster.java.booster.basic.math.graph.BoostedNodeGraph;
import net.sf.gluebooster.java.booster.essentials.meta.BoostedComparator;
/**
* Utility methods for comparators.
*
* @author CBauer
* @defaultParamText o1 the first object
* @defaultParamText o2 the second object
*
*/
@SuppressWarnings("rawtypes")
public class ComparatorBoostUtils implements
BoostedComparator {
/**
* The compare-algorithm should be a comparision of elements
*/
private static final int COMPARE_BY_ELEMENT_VALUES = 1;
/**
* The compare-algorithm should be a comparision of PAIRS
*/
private static final int COMPARE_PAIRS = 2;
/**
* The comparator knows the immediate predecessors of an element
*/
private static final int COMPARE_BY_GRAPH_ORDERING = 3;
private static final int COMPARE_WITH_STRING_DEFAULT = 4;
/**
* The type/algorithm of the comparision
*/
private int type;
/**
* Maps classes to integers (that are used for comparison).
*/
private Map elementValues;
/**
* Transforms classes into pairs
*/
private Transformer pairTransformer;
/**
* One comparator.
*/
private Comparator comparator1;
/**
* Another comparator.
*/
private Comparator comparator2;
/**
* Should a left element be compared with a right element.
*/
private Boolean compareLeftWithRight;
/**
* The graph containing an order. There is an edge from a to b if a <= b. If a == b then there must be to edges, one from a to b and on from b to a
*
*/
private BoostedNodeGraph ordering;
/**
* A mapping of the elements/velue to the corresponding node in the ordering graph.
*/
private Map nodeMapping;
private ComparatorBoostUtils(int type) {
this.type = type;
}
/**
* Compares objects by using a graph map with the immediate predecessor of the elements
*
* @param immediatePredecessors
* mapping lower object to higher object
* @return the created comparator
*/
public static > BoostedComparator createComparatorByImmediatePredecessors(
Map immediatePredecessors) throws Exception {
ComparatorBoostUtils result = new ComparatorBoostUtils(
COMPARE_BY_GRAPH_ORDERING);
result.ordering = new BoostedNodeGraph();
result.nodeMapping = new HashMap();
for (Entry entry : immediatePredecessors.entrySet()) {
result.addNodeToOrderingIfNonExistent(entry.getKey());
result.addNodesToOrderingIfNonExistent(entry.getValue());
BoostedNode source = result.nodeMapping.get(entry.getKey());
for (T target : entry.getValue()) {
result.ordering.addEdge(result.nodeMapping.get(target), source);
}
}
// result.ordering.simpleDisplay();
return result;
}
/**
* Creates a new node for a given value in the ordering graph when necessary
*
* @param value
* the value that is to be put into the ordering graph
* @return true, if added (= if the value did not exist in the ordering graph before)
*/
private boolean addNodeToOrderingIfNonExistent(ComparedClass value) {
if (nodeMapping.containsKey(value)) {
return false;
} else {
BoostedNode node = ordering.addNodeWithValue(value);
nodeMapping.put(value, node);
return true;
}
}
/**
* Creates new nodes for given values in the ordering graph when necessary
*
* @param values
* the values that are to be put into the ordering graph
* @return true, if at least one value has been added added (= if the value did not exist in the ordering graph before)
*/
private boolean addNodesToOrderingIfNonExistent(
Collection values) {
boolean result = false;
for (ComparedClass value : values) {
result |= addNodeToOrderingIfNonExistent(value);
}
return result;
}
/**
* Creates a comparator by comparing the positions in a given list
*
* @param ordering
* the list with the ordering
* @return the created comparator
*/
public static BoostedComparator createComparatorByListPosition(
List ordering) {
ComparatorBoostUtils result = new ComparatorBoostUtils(
COMPARE_BY_ELEMENT_VALUES);
result.elementValues = new HashMap();
for (int i = ordering.size() - 1; i >= 0; i--) {
result.elementValues.put(ordering.get(i), i);
}
return result;
}
/**
* Creates a comparator by comparing the positions in a given list
*
* @param ordering
* the list with the ordering
* @return the created comparator
*/
public static BoostedComparator createComparatorWithStringAsDefault() {
ComparatorBoostUtils result = new ComparatorBoostUtils(COMPARE_WITH_STRING_DEFAULT);
return result;
}
/**
* Creates a comparator that transforms objects into pairs which are compared. The left and right values are compared separately. There is only a compare
* result when both parts have the same result. Then the result is returned.
*
* @param pairTransformer
* creates a pair from a value
* @param leftComparator
* compares the left side of the pair
* @param rightComparator
* compares the right side of the pair.
* @return the created comparator
*/
public static BoostedComparator createPairComparator(
Transformer pairTransformer, Comparator leftComparator,
Comparator rightComparator) {
ComparatorBoostUtils result = new ComparatorBoostUtils(
COMPARE_PAIRS);
result.pairTransformer = pairTransformer;
result.comparator1 = leftComparator;
result.comparator2 = rightComparator;
result.compareLeftWithRight = Boolean.FALSE;
return result;
}
/**
* Creates a comparator that transforms objects into pairs which are compared. The left and right values are compared separately. Optionally separately
* crosswise (left with right) comparisons may be done. There is only a compare result when all parts have the same result. Then the result is returned.
*
* @param pairTransformer
* creates a pair from a value
* @param comparator
* compares the sides of the pair
* @param compareLeftWithRight
* should additionally a crosswise comparison be considered
* @return the created comparator
*/
public static BoostedComparator createPairComparator(
Transformer pairTransformer, Comparator comparator,
boolean compareLeftWithRight) {
ComparatorBoostUtils result = new ComparatorBoostUtils(
COMPARE_PAIRS);
result.pairTransformer = pairTransformer;
result.comparator1 = comparator;
result.comparator2 = comparator;
result.compareLeftWithRight = compareLeftWithRight;
return result;
}
/**
* Compares two objects by using a comparator
*
* @param comparator
* does the comparison. May be a BoostedComparator
* @return null if the boostedcomparator throws an exception
*/
public static Integer compare(E o1, E o2, Comparator comparator) {
if (comparator instanceof BoostedComparator) {
try {
return comparator.compare(o1, o2);
} catch (IllegalStateException ex) {
// this execption expresses that no comparison can be done.
return null;
}
} else {
return comparator.compare(o1, o2);
}
}
@Override
public int compare(ComparedClass o1, ComparedClass o2) {
switch (type) {
case COMPARE_BY_ELEMENT_VALUES:
return compareByElementValues(o1, o2);
case COMPARE_PAIRS:
return comparePairs(o1, o2);
case COMPARE_BY_GRAPH_ORDERING:
return compareByGraphOrdering(o1, o2);
case COMPARE_WITH_STRING_DEFAULT:
if (o1 instanceof Comparable) {
return ((Comparable) o1).compareTo(o2);
} else {
return ("" + o1).compareTo("" + o2);
}
default:
throw new UnsupportedOperationException("compare type " + type
+ " not yet supported");
}
}
/**
* Returns an exception that states the the two objects can not be compared
*
* @param info
* info why the comparison is not possible
* @return the created exception
*/
private IllegalStateException createCouldNotCompare(ComparedClass o1,
ComparedClass o2, String info) {
if (info == null) {
info = "";
}
return new IllegalStateException("could not compare " + o1 + " and "
+ o2 + " " + info);
}
/**
* Compares two object by anaylzing their position in a graph.
*
* @return o1 is less than o2 if o1 is a predecessor of o2.
*/
private int compareByGraphOrdering(ComparedClass o1,ComparedClass o2) {
BoostedNode node1 = nodeMapping.get(o1);
BoostedNode node2 = nodeMapping.get(o2);
boolean o1BeforeO2 = ordering.isWalk(node1, node2);
boolean o2BeforeO1 = ordering.isWalk(node2, node1);
if (o1BeforeO2 && o2BeforeO1) {
return 0;
} else if (o1BeforeO2) {
return -1;
} else if (o2BeforeO1) {
return 1;
} else {
throw createCouldNotCompare(o1, o2, null);
}
}
/**
* Compares by comparing the integers of the corrseponding element values.
*
* @return the comparison result
*/
private int compareByElementValues(ComparedClass o1, ComparedClass o2) {
Integer i1 = elementValues.get(o1);
Integer i2 = elementValues.get(o2);
if (i1 == null || i2 == null) {
throw createCouldNotCompare(o1, o2,
"because not all element values are present");
} else {
return i1.compareTo(i2);
}
}
/**
* Compares by transforming the objects into pairs which are compared.
*
* The left and right values are compared separately. Optionally separately crosswise (left with right) comparisons may be done. There is only a compare
* result when all parts have the same result. Then the result is returned.
*
* @return the result of the comparison
*/
private int comparePairs(ComparedClass o1, ComparedClass o2) {
Pair pair1 = pairTransformer.transform(o1);
Pair pair2 = pairTransformer.transform(o2);
if (pair1.equals(pair2))
return 0;
Integer leftCompare = compare(pair1.getLeft(), pair2.getLeft(),
comparator1);
Integer rightCompare = compare(pair1.getRight(), pair2.getRight(),
comparator2);
Integer leftRightCompare = null;
Integer rightLeftCompare = null;
if (Boolean.TRUE.equals(compareLeftWithRight)) {
leftRightCompare = compare(pair1.getLeft(), pair2.getRight(),
comparator1);
rightLeftCompare = compare(pair1.getRight(), pair2.getLeft(),
comparator1);
}
// if the sign of all comparisons is equal or 0 or null return the sign
// as result
// if all is null nothing is known
// if different signs occur nothing is known
Integer result = null;
result = computeSign(result, leftCompare);
result = computeSign(result, rightCompare);
result = computeSign(result, leftRightCompare);
result = computeSign(result, rightLeftCompare);
if (result == null || result.intValue() == 0) {
throw createCouldNotCompare(o1, o2, " pairs are " + pair1 + " "
+ pair2);
} else {
return result.intValue();
}
}
/**
* Checks whether two signs are equal
*
* @param oldCompare
* the first sign (the original sign)
* @param compareValue
* the second sign (the current sign)
* @return the compareValue if no changes happened or the oldCompare is null; old compare if the compareValue is 0 or not known
* @throws IllegalStateException
* if the signs are different
*/
private static Integer computeSign(Integer oldCompare, Integer compareValue)
throws IllegalStateException {
if (oldCompare == null)
return compareValue;
if (compareValue == null || compareValue.intValue() == 0)
return oldCompare;
if (Math.signum(oldCompare) * Math.signum(compareValue) >= 0) { // equal
// or 0
return compareValue; // because it is not 0
} else {
throw new IllegalStateException("comparison not possible");
}
}
}