All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.anrisoftware.globalpom.format.measurement.ValueFormat Maven / Gradle / Ivy

/*
 * Copyright 2016 Erwin Müller 
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.anrisoftware.globalpom.format.measurement;

import static com.anrisoftware.globalpom.measurement.RoundToSignificantFigures.roundToDecimal;
import static com.anrisoftware.globalpom.measurement.RoundToSignificantFigures.roundToSignificant;
import static org.apache.commons.lang3.Validate.isTrue;

import java.text.DecimalFormatSymbols;
import java.text.FieldPosition;
import java.text.Format;
import java.text.ParseException;
import java.text.ParsePosition;
import java.util.Locale;

import javax.inject.Inject;

import com.anrisoftware.globalpom.measurement.Value;
import com.anrisoftware.globalpom.measurement.ValueFactory;
import com.google.inject.assistedinject.Assisted;
import com.google.inject.assistedinject.AssistedInject;

/**
 * Formats and parses a {@link Value} value.
 *
 * @author Erwin Mueller, [email protected]
 * @since 2.4
 */
@SuppressWarnings("serial")
public class ValueFormat extends Format {

    private final ValueFactory valueFactory;

    private final DecimalFormatSymbols symbols;

    private final Locale locale;

    @Inject
    private ValueFormatLogger log;

    private ValueFormatWorker formatWorker;

    private ValueParserWorkerFactory parserWorkerFactory;

    private boolean scientificNotation;

    private Integer sig;

    private Integer dec;

    /**
     * @see ValueFormatFactory#create(ValueFactory)
     */
    @AssistedInject
    ValueFormat(@Assisted ValueFactory valueFactory) {
        this(valueFactory, Locale.getDefault());
    }

    /**
     * @see ValueFormatFactory#create(Locale, ValueFactory)
     */
    @AssistedInject
    ValueFormat(@Assisted ValueFactory valueFactory, @Assisted Locale locale) {
        this.sig = null;
        this.dec = null;
        this.scientificNotation = false;
        this.valueFactory = valueFactory;
        this.symbols = DecimalFormatSymbols.getInstance(locale);
        this.locale = locale;
        this.formatWorker = createValueFormatWorker();
        this.parserWorkerFactory = createValueParserWorkerFactory();
    }

    /**
     * Set to use the scientific notation for formatting the value.
     *
     * @param scientificNotation
     *            set to {@code true} to use the scientific notation.
     */
    public void setUseScientificNotation(boolean scientificNotation) {
        this.scientificNotation = scientificNotation;
        this.formatWorker = createValueFormatWorker();
    }

    /**
     * Sets the significant figures for formatting the value.
     *
     * @param sig
     *            the {@link Integer} significant figures.
     */
    public void setSignificant(int sig) {
        isTrue(sig > 0, "%d>0", sig);
        this.sig = sig;
        this.formatWorker = createValueFormatWorker();
        this.parserWorkerFactory = createValueParserWorkerFactory();
    }

    /**
     * Sets the least significant decimal for formatting the value.
     *
     * @param dec
     *            the {@link Integer} least significant decimal.
     */
    public void setDecimal(int dec) {
        isTrue(dec > 0, "%d>0", dec);
        this.dec = dec;
        this.formatWorker = createValueFormatWorker();
        this.parserWorkerFactory = createValueParserWorkerFactory();
    }

    /**
     * Formats the specified value.
     * 

* The format follows the pattern: * *

     * value[(uncertainty)]
     * 
* *

*

Examples

*

*

    *
  • exact value: {@code 0.0123} *
  • uncertain value: {@code 5.0(0.2)} *
* * @param obj * the {@link Value}. */ @Override public StringBuffer format(Object obj, StringBuffer buff, FieldPosition pos) { if (obj instanceof Value) { Value value = (Value) obj; formatWorker.valueToString(value, buff); } return buff; } /** * Formats the value according to the significant figure and least * significant decimal. * * @param value * the {@link Double} value. * * @param order * the {@link Integer} order. * * @param sig * the {@link Integer} significant figure. * * @param dec * the {@link Integer} least significant decimal, * * @return the formatted {@link String}. */ public String formatNumber(double value, int order, int sig, int dec) { ValueFormatWorker w = new NormalValueFormatWorker(symbols, sig, dec); return w.formatNumber(value, order, sig, dec); } /** * Formats the value according to the significant figure and least * significant decimal in a scientific format. * * @param value * the {@link Double} value. * * @param order * the {@link Integer} order. * * @param sig * the {@link Integer} significant figure. * * @param dec * the {@link Integer} least significant decimal, * * @return the formatted {@link String}. */ public String formatScientificValue(double value, int order, int sig, int dec) { ValueFormatWorker w = new ScientificValueFormatWorker(symbols, sig, dec); return w.formatNumber(value, order, sig, dec); } @Override public Object parseObject(String source, ParsePosition pos) { return parse(source, pos); } /** * Parses the specified string to value. *

* The format follows the pattern: * *

     * value[(uncertain)]
     * 
* *

*

Examples

*

*

    *
  • exact value: {@code 0.0123} *
  • uncertain value: {@code 5.0(0.2)} *
  • uncertain value: {@code 5.0(2)} *
  • uncertain value: {@code 5.0(2)e-12} *
  • uncertain value: {@code 5.0(2)E-12} *
* * @return the parsed {@link Value}. * * @throws ParseException * if the string cannot be parsed to a value. */ public Value parse(String source) throws ParseException { ParsePosition pos = new ParsePosition(0); Value result = parse(source, pos); if (pos.getIndex() == 0) { throw log.errorParseValue(source, pos); } return result; } /** * @see #parse(String) * * @param pos * the index {@link ParsePosition} position from where to start * parsing. */ public Value parse(String source, ParsePosition pos) { source = source.substring(pos.getIndex()); try { Value address = parserWorkerFactory.getValueParserWorker(source, pos).stringToValue(source, null, pos); pos.setErrorIndex(-1); pos.setIndex(source.length()); return address; } catch (ParseException e) { pos.setIndex(0); pos.setErrorIndex(0); return null; } catch (NumberFormatException e) { pos.setIndex(0); pos.setErrorIndex(0); return null; } } /** * Parses the value with the specified uncertainty. * * @param source * the {@link String} source. * * @param unc * the {@link Double} uncertainty or {@link Double#NaN}. * * @param pos * the index {@link ParsePosition} position from where to start * parsing. * * @return the {@link Value}. */ public Value parse(String source, double unc, ParsePosition pos) { try { Value value = parserWorkerFactory.getValueParserWorker(source, pos) .stringToValue(source, unc, pos); pos.setErrorIndex(-1); pos.setIndex(source.length()); return value; } catch (ParseException e) { pos.setIndex(0); pos.setErrorIndex(0); return null; } catch (NumberFormatException e) { pos.setIndex(0); pos.setErrorIndex(0); return null; } } /** * Parses the value with the specified uncertainty. * * @param source * the {@link String} source. * * @param unc * the {@link Double} uncertainty. * * @return the {@link Value}. * * @throws ParseException * if the string cannot be parsed to a value. */ public Value parse(String source, double unc) throws ParseException { ParsePosition pos = new ParsePosition(0); Value result = parse(source, pos); if (pos.getIndex() == 0) { throw log.errorParseValue(source, pos); } return result; } static double roundValue(double value, int sig, int dec) { value = roundToSignificant(value, sig); value = roundToDecimal(value, dec); return value; } private ValueFormatWorker createValueFormatWorker() { if (scientificNotation) { return new ScientificValueFormatWorker(symbols, sig, dec); } else { return new NormalValueFormatWorker(symbols, sig, dec); } } private ValueParserWorkerFactory createValueParserWorkerFactory() { return new ValueParserWorkerFactory(symbols, locale, sig, dec, valueFactory); } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy