org.ut.biolab.medsavant.shared.model.Range.java Source code

Java tutorial

Introduction

Here is the source code for org.ut.biolab.medsavant.shared.model.Range.java

Source

/**
 * See the NOTICE file distributed with this work for additional
 * information regarding copyright ownership.
 *
 * 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.ut.biolab.medsavant.shared.model;

import java.io.Serializable;
import java.text.NumberFormat;
import java.text.ParseException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.TreeSet;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

/**
 *
 * @author mfiume
 */
public class Range implements Comparable<Range>, Serializable {

    private static final Log LOG = LogFactory.getLog(Range.class);
    private static final String RANGE_STRING = " - ";

    private double min;
    private double max;

    public Range(double min, double max) {
        this.min = min;
        this.max = max;
    }

    public Range(double[] rangeArray) {
        this.min = rangeArray[0];
        this.max = rangeArray[1];
    }

    public double getMin() {
        return min;
    }

    public double getMax() {
        return max;
    }

    public void setMin(double min) {
        this.min = min;
    }

    public void setMax(double max) {
        this.max = max;
    }

    /**
     * Get the list you get by merging the Range objects in the collection
     *
     * @param range
     * @return the merged list.
     */
    public static List<Range> merge(Collection<Range> range) {
        List<Range> mergedList = new ArrayList<Range>();

        // Arrange first in order by starting positions.
        TreeSet<Range> allRangesInOrder = new TreeSet<Range>();
        allRangesInOrder.addAll(range);

        // Merge now.
        Range curMerged = null;

        for (Range r : allRangesInOrder) {
            if (curMerged != null && curMerged.canBeMergedWith(r)) {
                // merge them here
                curMerged.max = Math.max(curMerged.max, r.max);
                curMerged.min = Math.min(curMerged.min, r.min);
            } else {
                if (curMerged != null) {
                    mergedList.add(curMerged);
                }
                curMerged = new Range(r.min, r.max);
            }
        }
        // Merge in the last one.
        if (curMerged != null) {
            mergedList.add(curMerged);
        }
        return mergedList;
    }

    /**
     * Compare two Range objects by starting point.  When starting points are
     * the same, differentiate by ending point.
     * @param range
     * @return
     * @author Nirvana
     */
    @Override
    public int compareTo(Range range) {
        if (min < range.min) {
            return -1;
        } else if (min > range.min) {
            return 1;
        } else {
            // If both have the same min, differentiate by max.
            if (max < range.max) {
                return -1;
            } else if (max > range.max) {
                return 1;
            } else {
                return 0;
            }
        }
    }

    /**
     * This range object equals another object iff the other is a range object,
     * and has the same min and max as this object.  This complies with the
     * comparator method (compareTo).
     */
    @Override
    public boolean equals(Object that) {
        if (that instanceof Range) {
            Range r = (Range) that;
            return r.min == min && r.max == max;
        }
        return false;
    }

    @Override
    public int hashCode() {
        int hash = 5;
        hash = 17 * hash + (int) (Double.doubleToLongBits(this.min) ^ (Double.doubleToLongBits(this.min) >>> 32));
        hash = 17 * hash + (int) (Double.doubleToLongBits(this.max) ^ (Double.doubleToLongBits(this.max) >>> 32));
        return hash;
    }

    /**
     * Returns true iff this range and the range given intersect (i.e. can be merged).
     */
    public boolean canBeMergedWith(Range r) {
        return min <= r.max && max >= r.min;
    }

    @Override
    public String toString() {
        return NumberFormat.getInstance().format(min) + RANGE_STRING + NumberFormat.getInstance().format(max);
    }

    public static Range rangeFromString(String range) {
        String[] values = range.split(RANGE_STRING);
        double minValue = 0;
        double maxValue = 0;
        try {
            minValue = NumberFormat.getInstance().parse(values[0]).doubleValue();
            maxValue = NumberFormat.getInstance().parse(values[1]).doubleValue();
        } catch (ParseException ex) {
            LOG.error("Unable to parse " + range + " as a range.", ex);
        }
        return new Range(minValue, maxValue);
    }

    /**
     * Forces proper ordering and limits.
     */
    public void bound(int min, int max, boolean defaultMin) {
        if (this.min > this.max) {
            if (defaultMin) {
                this.max = this.min;
            } else {
                this.min = this.max;
            }
        }
        if (this.min < min || this.min > max) {
            this.min = Math.min(max, Math.max(min, this.min));
        }
        if (this.max > max || this.max < min) {
            this.max = Math.max(min, Math.min(max, this.max));
        }
    }
}