001: // ============================================================================
002: // $Id: NullComparator.java,v 1.1 2005/12/14 13:31:04 davidahall Exp $
003: // Copyright (c) 2005 David A. Hall
004: // ============================================================================
005: // The contents of this file are subject to the Common Development and
006: // Distribution License (CDDL), Version 1.0 (the License); you may not use this
007: // file except in compliance with the License. You should have received a copy
008: // of the the License along with this file: if not, a copy of the License is
009: // available from Sun Microsystems, Inc.
010: //
011: // http://www.sun.com/cddl/cddl.html
012: //
013: // From time to time, the license steward (initially Sun Microsystems, Inc.) may
014: // publish revised and/or new versions of the License. You may not use,
015: // distribute, or otherwise make this file available under subsequent versions
016: // of the License.
017: //
018: // Alternatively, the contents of this file may be used under the terms of the
019: // GNU Lesser General Public License Version 2.1 or later (the "LGPL"), in which
020: // case the provisions of the LGPL are applicable instead of those above. If you
021: // wish to allow use of your version of this file only under the terms of the
022: // LGPL, and not to allow others to use your version of this file under the
023: // terms of the CDDL, indicate your decision by deleting the provisions above
024: // and replace them with the notice and other provisions required by the LGPL.
025: // If you do not delete the provisions above, a recipient may use your version
026: // of this file under the terms of either the CDDL or the LGPL.
027: //
028: // This library is distributed in the hope that it will be useful,
029: // but WITHOUT ANY WARRANTY; without even the implied warranty of
030: // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
031: // ============================================================================
032:
033: package net.sf.jga.util;
034:
035: import java.io.Serializable;
036: import java.util.Comparator;
037:
038: /**
039: * Comparator Decorator used to gracefully compare null and non-null values.
040: * In most cases, passing a null to a Comparator results in a NullPointerException,
041: * as (in the general case) null is not part of a class' strict ordering.
042: * However, in many applications, null objects must be included in an ordering.
043: * This wrapper can be used to shield an underlying Comparator from dealing
044: * with where in the ordering null values should fall.
045: * <p>
046: * A flag is provided that determines whether nulls are less than non-nulls,
047: * (the default case) or greater than non-nulls. When comparing two values,
048: * this comparator determines if either argument is null: if both are null,
049: * then 0 is returned (ie, all nulls are considered equal). If neither argument
050: * is null, then both arguments are passed to the wrapped comparator. If one
051: * argument is null, then a positive or negative integer is returned, depending
052: * on which argument was null and the setting of the flag.
053: */
054:
055: // UNTESTED
056: public class NullComparator<T> implements Comparator<T>, Serializable {
057:
058: // Flag determining if nulls appear before or after non-nulls in an ordering
059: private boolean _nullsAreLess = true;
060:
061: // Comparator used to compare pairs of non-null values
062: private Comparator<T> _comp;
063:
064: /**
065: * Builds a NullComparator that uses the given comparator to compare pairs
066: * of non-null values. Null values appear before non-null values in the
067: * resulting ordering.
068: */
069: public NullComparator(Comparator<T> comp) {
070: this (comp, true);
071: }
072:
073: /**
074: * Builds a NullComparator that uses the given comparator to compare pairs
075: * of non-null values, and uses the flag to determine if non-null values
076: * appear before non-null values in the resulting ordering.
077: */
078: public NullComparator(Comparator<T> comp, boolean flag) {
079: if (comp == null)
080: throw new IllegalArgumentException(
081: "A Comparator is required");
082:
083: _comp = comp;
084: _nullsAreLess = flag;
085: }
086:
087: /**
088: * Returns the comparator used to compare pairs of non-null values.
089: */
090: public Comparator<T> getComparator() {
091: return _comp;
092: }
093:
094: public int compare(T x, T y) {
095: if (x == null)
096: if (y == null)
097: return 0;
098: else
099: return _nullsAreLess ? -1 : 1;
100: else if (y == null)
101: return _nullsAreLess ? 1 : -1;
102: else
103: return _comp.compare(x, y);
104: }
105: }
|