PNumber.java :  » Media » praxis » net » neilcsmith » praxis » core » types » Java Open Source

Java Open Source » Media » praxis 
praxis » net » neilcsmith » praxis » core » types » PNumber.java
/*
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
 * 
 * Copyright 2010 Neil C Smith.
 * 
 * This code is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License version 3 only, as
 * published by the Free Software Foundation.
 * 
 * This code 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 General Public License
 * version 3 for more details.
 * 
 * You should have received a copy of the GNU General Public License version 3
 * along with this work; if not, see http://www.gnu.org/licenses/
 * 
 * 
 * Please visit http://neilcsmith.net if you need additional information or
 * have any questions.
 */
package net.neilcsmith.praxis.core.types;

import net.neilcsmith.praxis.core.Argument;
import net.neilcsmith.praxis.core.ArgumentFormatException;
import net.neilcsmith.praxis.core.info.ArgumentInfo;

/**
 *
 * @author Neil C Smith
 */
public final class PNumber extends Argument implements Comparable<PNumber> {

    public final static int MAX_VALUE = Integer.MAX_VALUE;
    public final static int MIN_VALUE = Integer.MIN_VALUE;
    private double value;
    private boolean isInteger;
    private String string;

    private PNumber(double value, String str) {
        this.value = value;
        this.isInteger = false;
        this.string = str;
    }

    private PNumber(int value, String str) {
        this.value = value;
        this.isInteger = true;
        this.string = str;
    }

    public double value() {
        return value;
    }

    public int toIntValue() {
        if (isInteger) {
            return (int) value;
        } else {
            return (int) Math.round(value);
        }

    }

    @Override
    public String toString() {
        if (string != null) {
            return string;
        } else if (isInteger) {
            return Integer.toString(toIntValue());
        } else {
            return Double.toString(value);
        }
    }

    @Override
    public int hashCode() {
        long bits = Double.doubleToLongBits(value);
        return (int) (bits ^ (bits >>> 32));
    }

    @Override
    public boolean equals(Object obj) {
        if (obj instanceof PNumber) {
            return Double.doubleToLongBits(((PNumber) obj).value) == Double.doubleToLongBits(value);
        }
        return false;
    }

    @Override
    public boolean isEquivalent(Argument arg) {
        // @TODO should we allow small margin of error???
        try {
            return equals(PNumber.coerce(arg));
        } catch (ArgumentFormatException ex) {
            return false;
        }
    }

    public int compareTo(PNumber o) {
        return Double.compare(value, o.value);
    }

    public boolean isInteger() {
        return isInteger;
    }

    public static PNumber valueOf(double val) {
        return valueOf(val, null);
    }
    
    private static PNumber valueOf(double val, String str) {
        if (val > MAX_VALUE) {
            val = MAX_VALUE;
        } else if (val < MIN_VALUE) {
            val = MIN_VALUE;
        } else if (Double.isInfinite(val) || Double.isNaN(val)) {
            val = 0;
        }
        return new PNumber(val, str);
    }

    public static PNumber valueOf(int val) {
        return new PNumber(val, null);
    }

    public static PNumber valueOf(String str) throws ArgumentFormatException {
        try {
            if (str.indexOf('.') > -1) {
                return valueOf(Double.parseDouble(str), str);
            } else {
                return new PNumber(Integer.parseInt(str), str);
            }
        } catch (Exception ex) {
            throw new ArgumentFormatException(ex);
        }
    }

    public static PNumber coerce(
            Argument arg) throws ArgumentFormatException {
        if (arg instanceof PNumber) {
            return (PNumber) arg;
        } else {
            return valueOf(arg.toString());
        }

    }

    public static ArgumentInfo info() {
        return ArgumentInfo.create(PNumber.class, null);
    }

    public static ArgumentInfo info(
            double min, double max) {
        return info(valueOf(min), valueOf(max));
    }

    public static ArgumentInfo info(
            int min, int max) {
        return info(valueOf(min), valueOf(max));
    }

    public static ArgumentInfo info(
            PNumber min, PNumber max) {
        PMap map = PMap.valueOf(PString.valueOf("minimum"), min,
                PString.valueOf("maximum"), max);
        return ArgumentInfo.create(PNumber.class, map);
    }

}
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.