001/*
002 * Units of Measurement Enum Implementation
003 * Copyright © 2005-2021, Werner Keil and others.
004 *
005 * All rights reserved.
006 *
007 * Redistribution and use in source and binary forms, with or without modification,
008 * are permitted provided that the following conditions are met:
009 *
010 * 1. Redistributions of source code must retain the above copyright notice,
011 *    this list of conditions and the following disclaimer.
012 *
013 * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions
014 *    and the following disclaimer in the documentation and/or other materials provided with the distribution.
015 *
016 * 3. Neither the name of JSR-385, Unit-API nor the names of their contributors may be used to endorse or promote products
017 *    derived from this software without specific prior written permission.
018 *
019 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
020 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
021 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
022 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
023 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
024 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
025 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
026 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
027 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
028 * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
029 */
030package tech.uom.impl.enums.format;
031
032import java.io.IOException;
033import java.math.BigDecimal;
034import java.text.ParsePosition;
035
036import javax.measure.Quantity;
037import javax.measure.Unit;
038import javax.measure.format.MeasurementParseException;
039
040import tech.uom.impl.enums.quantity.Quantities;
041import tech.uom.impl.enums.unit.DimensionlessUnit;
042
043/**
044 * A simple implementation of QuantityFormat
045 */
046@SuppressWarnings("rawtypes")
047public class SimpleQuantityFormat extends AbstractQuantityFormat {
048        /**
049         * 
050         */
051        private static final long serialVersionUID = 2447723879527543130L;
052        
053        /**
054         * Holds the default format instance.
055         */
056        private static final SimpleQuantityFormat DEFAULT = new SimpleQuantityFormat();
057
058        @Override
059        public Appendable format(Quantity quantity, Appendable dest) throws IOException {
060                Unit unit = quantity.getUnit();
061
062                dest.append(quantity.getValue().toString());
063                if (quantity.getUnit().equals(DimensionlessUnit.ONE))
064                        return dest;
065                dest.append(' ');
066                return SimpleUnitFormat.getInstance().format(unit, dest);
067        }
068
069        @SuppressWarnings("unchecked")
070        @Override
071        public Quantity<?> parse(CharSequence csq, ParsePosition cursor) throws MeasurementParseException {
072                int startDecimal = cursor.getIndex();
073                while ((startDecimal < csq.length()) && Character.isWhitespace(csq.charAt(startDecimal))) {
074                        startDecimal++;
075                }
076                int endDecimal = startDecimal + 1;
077                while ((endDecimal < csq.length()) && !Character.isWhitespace(csq.charAt(endDecimal))) {
078                        endDecimal++;
079                }
080                BigDecimal decimal = new BigDecimal(csq.subSequence(startDecimal, endDecimal).toString());
081                cursor.setIndex(endDecimal + 1);
082                Unit unit = SimpleUnitFormat.getInstance().parse(csq);
083                return Quantities.getQuantity(decimal, unit);
084        }
085
086        @SuppressWarnings("unchecked")
087        @Override
088        Quantity<?> parse(CharSequence csq, int index) throws MeasurementParseException {
089                int startDecimal = index; // cursor.getIndex();
090                while ((startDecimal < csq.length()) && Character.isWhitespace(csq.charAt(startDecimal))) {
091                        startDecimal++;
092                }
093                int endDecimal = startDecimal + 1;
094                while ((endDecimal < csq.length()) && !Character.isWhitespace(csq.charAt(endDecimal))) {
095                        endDecimal++;
096                }
097                Double decimal = new Double(csq.subSequence(startDecimal, endDecimal).toString());
098                Unit unit = SimpleUnitFormat.getInstance().parse(csq);
099                return Quantities.getQuantity(decimal, unit);
100        }
101
102        @Override
103        public Quantity<?> parse(CharSequence csq) throws MeasurementParseException {
104                return parse(csq, new ParsePosition(0));
105        }
106
107  /**
108   * Returns the quantity format for the default locale. The default format assumes the quantity is composed of a decimal number and a {@link Unit}
109   * separated by whitespace(s).
110   *
111   * @return <code>MeasureFormat.getInstance(NumberFormat.getInstance(), UnitFormat.getInstance())</code>
112   */
113  public static SimpleQuantityFormat getInstance() {
114    return DEFAULT;
115  }
116}