NodeComparator.java :  » Database-ORM » MMBase » org » mmbase » util » Java Open Source

Java Open Source » Database ORM » MMBase 
MMBase » org » mmbase » util » NodeComparator.java
/*

This software is OSI Certified Open Source Software.
OSI Certified is a certification mark of the Open Source Initiative.

The license (Mozilla version 1.0) can be read at the MMBase site.
See http://www.MMBase.org/license

*/

package org.mmbase.util;

import java.util.*;
import org.mmbase.module.core.*;

/**
 * This class implements the Comparator interface for comparing MMObjectNodes.
 * At forhand you specify in which fields a specified nodes should be compared,
 * these fields may not have a null value.
 *
 * @application Tools
 * @author Pierre van Rooden
 * @version $Id: NodeComparator.java,v 1.6 2004/10/12 11:17:44 pierre Exp $
 */
public class NodeComparator implements Comparator {

    public final static String UP = "UP";
    public final static String DOWN = "DOWN";

    /**
     * @todo Should be List, not Vector
     */
    private Vector fields;
    /**
     * @todo Should be List, not Vector
     */
    private Vector sortDirs;

    /**
     * Simple constructor that uses the default sort order (UP).
     * @param fields the fields on which the message nodes get compared.
     */
    public NodeComparator(Vector fields) {
        this.fields = fields;
        sortDirs = new Vector(fields.size());
    }

    /**
     * Constructor in which you spercify the sort order (UP or DOWN) per field.
     * @param fields the fields on which the message nodes get compared.
     * @param sortDirs the sort directions (UP or DOWN) for each field.
     */
    public NodeComparator(Vector fields, Vector sortDirs) {
        this.fields = fields;
        this.sortDirs = sortDirs;
        for (int i = sortDirs.size(); i < fields.size(); i++) {
            sortDirs.add(UP);
        }
    }

    /**
     * The two message nodes will be compared using the compare function of
     * the values of their fields.
     * Only Comparable values can be used (String, Numbers, Date), as well as
     * Boolean values.
     * In other cases it's assumed that the values cannot be ordered.
     * <br />
     * Note: this class assumes that values in fields are of similar types
     * (comparable to each other).
     *
     * @param o1 the first object to compare
     * @param o2 the second object to compare
     * @return 0 if both objects are equal, -1 if object 1 is 'less than'
     *    object 2, and +1 if object 1 is 'greater than' object 2.
     */
    public int compare(Object o1, Object o2) {
        Object f1, f2;
        int result=0;
        int fieldnr = 0;
        String field;
        while ((result == 0) && (fieldnr < fields.size())) {
            field =(String)fields.elementAt(fieldnr);
            f1 = ((MMObjectNode)o1).getValue(field);
            f2 = ((MMObjectNode)o2).getValue(field);
            if (f1 instanceof Comparable) {
                try {
                    result=((Comparable)f1).compareTo(f2);
                } catch (ClassCastException e) {
                    // types do not compare -
                    // possibly the in-memory value type differs from the
                    // database value type (this can occur if you use setValue
                    // with a deviating type).
                    // Solving this coukld bring this compare to a crawl, so we
                    // don't. Just edit stuff the right way.
                }
            } else if (!f1.equals(f2)) {
                if (f1 instanceof Boolean) {
                    result=((Boolean)f1).booleanValue() ? 1 : -1;
                }
            }
            fieldnr++;
        }
        if ((fieldnr>0) &&
            (fieldnr<=sortDirs.size()) &&
            ((String)sortDirs.elementAt(fieldnr-1)).equals(DOWN)) {
            result=-result;
        }
        return result;
    }

    /**
     * Returns whether another object is equal to this comparator (that is,
     * compare the same fields in the same order).
     * @param obj the object to compare
     * @return <code>true</code> if the objects are equal
     * @throws ClassCastException
     */
    public boolean equals(Object obj) {
        if (obj instanceof NodeComparator) {
            return (obj.hashCode()==hashCode());
        } else {
            throw new ClassCastException();
        }
    }

    /**
     * Returns the comparator's hash code.
     */
    public int hashCode() {
        return fields.hashCode()^sortDirs.hashCode();
    }
}
java2s.com  | Contact Us | Privacy Policy
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.