/* * WPCleaner: A tool to help on Wikipedia maintenance tasks. * Copyright (C) 2013 Nicolas Vervelle * * See README.txt file for licensing information. */ package org.wikipediacleaner.api.data; import java.io.Externalizable; import java.io.ObjectInput; import java.io.ObjectOutput; import java.util.Comparator; import java.util.Iterator; import java.util.List; /** * A generic composite comparator class. * * A list of several simple comparators are used one after * an other until a meaningful result is obtained. * @param <T> */ public class CompositeComparator<T> implements NamedComparator<T>, Cloneable, Externalizable { private List<NamedComparator<T>> comparators; private List<Boolean> orders; private final String name; /** * Composite comparator constructor. */ public CompositeComparator() { this(null, null, null); } /** * Composite comparator constructor. * * @param name Comparator name. */ public CompositeComparator(String name) { this(name, null, null); } /** * @param name Comparator name. * @param comparators List of comparators. */ public CompositeComparator( String name, List<NamedComparator<T>> comparators) { this(name, comparators, null); } /** * @param name Comparator name. * @param comparators List of comparators. * @param orders List of orders. */ public CompositeComparator( String name, List<NamedComparator<T>> comparators, List<Boolean> orders) { this.name = name; setComparators(comparators); setOrders(orders); } /* (non-Javadoc) * @see org.wikipediacleaner.api.data.NamedComparator#getName() */ @Override public String getName() { return name; } /* (non-Javadoc) * @see java.lang.Object#toString() */ @Override public String toString() { return name; } /** * @param comparators List of comparators. */ public void setComparators(List<NamedComparator<T>> comparators) { this.comparators = comparators; } /** * @return Number of comparators. */ public int getComparatorsCount() { return (comparators != null) ? comparators.size() : 0; } /** * @param index Comparator index. * @return Comparator. */ public NamedComparator<T> getComparator(int index) { return comparators.get(index); } /** * @param orders List of orders. */ public void setOrders(List<Boolean> orders) { this.orders = orders; } /** * @param index Comparator index. * @return Comparator order (TRUE = Ascending). */ public Boolean getOrder(int index) { if ((orders != null) && (index >= 0) && (index < orders.size())) { return orders.get(index); } return Boolean.TRUE; } /** * @param itemName Comparator name. * @param up Flag indicating if the comparator should be moved up or down. */ public void moveComparator(String itemName, boolean up) { for (int i = 0; i < comparators.size(); i++) { NamedComparator<T> comparator = comparators.get(i); if (comparator.getName().equals(itemName)) { if (up) { if (i > 0) { comparators.remove(i); comparators.add(i - 1, comparator); if ((orders != null) && (orders.size() >= i)) { if (orders.size() == i) { orders.add(i - 1, Boolean.TRUE); } else { Boolean old = orders.remove(i); orders.add(i - 1, old); } } } } else { if (i < comparators.size() - 1) { comparators.remove(i); comparators.add(i + 1, comparator); if ((orders != null) && (orders.size() > i)) { if (orders.size() == i + 1) { orders.add(i, Boolean.TRUE); } else { Boolean old = orders.remove(i); orders.add(i + 1, old); } } } } return; } } } /** * Reorder comparators. * * @param names Elementary comparator names. * @param newOrders New orders. */ public void orderComparators(List<String> names, List<Boolean> newOrders) { if (comparators != null) { for (int index = names.size(); index > 0; index--) { String comparatorName = names.get(index); for (int i = 0; i < comparators.size(); i++) { NamedComparator<T> comparator = comparators.get(i); if (comparatorName.equals(comparator.getName())) { comparators.remove(i); comparators.add(0, comparator); if (orders.size() > i) { orders.remove(i); } orders.add(0, newOrders.get(index)); } } } } } /* (non-Javadoc) * @see java.util.Comparator#compare(java.lang.Object, java.lang.Object) */ @Override public int compare(T o1, T o2) { if (comparators != null) { Iterator<NamedComparator<T>> itComparator = comparators.iterator(); Iterator<Boolean> itBoolean = (orders != null) ? orders.iterator() : null; while (itComparator.hasNext()) { Comparator<T> c = itComparator.next(); Boolean order = ((itBoolean != null) && (itBoolean.hasNext())) ? itBoolean.next() : Boolean.TRUE; int result = c.compare(o1, o2); //System.out.println("Comparing [" + o1 + "] and [" + o2 + "] by " + c + ": " + result); if (result != 0) { return (Boolean.FALSE.equals(order) ? -1 : 1) * result; } } } return 0; } /* (non-Javadoc) * @see java.io.Externalizable#readExternal(java.io.ObjectInput) */ @Override public void readExternal(@SuppressWarnings("unused") ObjectInput input) { // } /* (non-Javadoc) * @see java.io.Externalizable#writeExternal(java.io.ObjectOutput) */ @Override public void writeExternal(@SuppressWarnings("unused") ObjectOutput output) { // } /* (non-Javadoc) * @see java.lang.Object#clone() */ @SuppressWarnings("unchecked") @Override public CompositeComparator<T> clone() { try { return (CompositeComparator<T>) super.clone(); } catch (CloneNotSupportedException e) { // } return null; } }