001/* 002 * Units of Measurement Reference Implementation 003 * Copyright (c) 2005-2018, Jean-Marie Dautelle, Werner Keil, Otavio Santana. 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, Indriya 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.units.indriya.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.ParserException; 039 040import tech.units.indriya.AbstractQuantity; 041import tech.units.indriya.AbstractUnit; 042import tech.units.indriya.ComparableQuantity; 043import tech.units.indriya.quantity.NumberQuantity; 044import tech.units.indriya.quantity.Quantities; 045 046/** 047 * A simple implementation of QuantityFormat 048 */ 049@SuppressWarnings("rawtypes") 050public class SimpleQuantityFormat extends AbstractQuantityFormat { 051 /** 052 * Holds the default format instance. 053 */ 054 private static final SimpleQuantityFormat DEFAULT = new SimpleQuantityFormat(); 055 056 /** 057 * 058 */ 059 private static final long serialVersionUID = 2758248665095734058L; 060 061 @Override 062 public Appendable format(Quantity quantity, Appendable dest) throws IOException { 063 Unit unit = quantity.getUnit(); 064 065 dest.append(quantity.getValue().toString()); 066 if (quantity.getUnit().equals(AbstractUnit.ONE)) 067 return dest; 068 dest.append(' '); 069 return SimpleUnitFormat.getInstance().format(unit, dest); 070 } 071 072 @SuppressWarnings("unchecked") 073 @Override 074 public ComparableQuantity<?> parse(CharSequence csq, ParsePosition cursor) throws ParserException { 075 int startDecimal = cursor.getIndex(); 076 while ((startDecimal < csq.length()) && Character.isWhitespace(csq.charAt(startDecimal))) { 077 startDecimal++; 078 } 079 int endDecimal = startDecimal + 1; 080 while ((endDecimal < csq.length()) && !Character.isWhitespace(csq.charAt(endDecimal))) { 081 endDecimal++; 082 } 083 BigDecimal decimal = new BigDecimal(csq.subSequence(startDecimal, endDecimal).toString()); 084 cursor.setIndex(endDecimal + 1); 085 Unit unit = SimpleUnitFormat.getInstance().parse(csq, cursor); 086 return Quantities.getQuantity(decimal, unit); 087 } 088 089 @SuppressWarnings("unchecked") 090 @Override 091 AbstractQuantity<?> parse(CharSequence csq, int index) throws ParserException { 092 int startDecimal = index; // cursor.getIndex(); 093 while ((startDecimal < csq.length()) && Character.isWhitespace(csq.charAt(startDecimal))) { 094 startDecimal++; 095 } 096 int endDecimal = startDecimal + 1; 097 while ((endDecimal < csq.length()) && !Character.isWhitespace(csq.charAt(endDecimal))) { 098 endDecimal++; 099 } 100 Double decimal = new Double(csq.subSequence(startDecimal, endDecimal).toString()); 101 Unit unit = SimpleUnitFormat.getInstance().parse(csq, index); 102 return NumberQuantity.of(decimal, unit); 103 } 104 105 @Override 106 public ComparableQuantity<?> parse(CharSequence csq) throws ParserException { 107 return parse(csq, new ParsePosition(0)); 108 } 109 110 /** 111 * Returns the quantity format for the default locale. The default format assumes the quantity is composed of a decimal number and a {@link Unit} 112 * separated by whitespace(s). 113 * 114 * @return <code>MeasureFormat.getInstance(NumberFormat.getInstance(), UnitFormat.getInstance())</code> 115 */ 116 public static SimpleQuantityFormat getInstance() { 117 return DEFAULT; 118 } 119}