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.text.FieldPosition; 034import java.text.Format; 035import java.text.ParsePosition; 036 037import javax.measure.Quantity; 038import javax.measure.format.MeasurementParseException; 039import javax.measure.format.QuantityFormat; 040 041import tech.uom.lib.common.function.Parser; 042 043/** 044 * <p> 045 * This class provides the interface for formatting and parsing {@link Quantity quantities}. 046 * </p> 047 * 048 * @author <a href="mailto:jean-marie@dautelle.com">Jean-Marie Dautelle</a> 049 * @author <a href="mailto:werner@uom.technology">Werner Keil</a> 050 * @version 1.1, $Date: 2019-03-11 $ 051 * @since 2.0 052 * 053 */ 054@SuppressWarnings("rawtypes") 055public abstract class AbstractQuantityFormat extends Format implements QuantityFormat, Parser<CharSequence, Quantity> { 056 // TODO for later, see https://github.com/unitsofmeasurement/indriya/issues/17 057 // * <p> 058 // * Instances of this class should be able to format quantities stated in {@link MixedUnit}. 059 // * </p> 060 061 /** 062 * 063 */ 064 private static final long serialVersionUID = -4628006924354248662L; 065 066 /** 067 * Formats the specified quantity into an <code>Appendable</code>. 068 * 069 * @param quantity 070 * the quantity to format. 071 * @param dest 072 * the appendable destination. 073 * @return the specified <code>Appendable</code>. 074 * @throws IOException 075 * if an I/O exception occurs. 076 */ 077 public abstract Appendable format(Quantity<?> quantity, Appendable dest) throws IOException; 078 079 /** 080 * Parses a portion of the specified <code>CharSequence</code> from the specified position to produce an object. If parsing succeeds, then the index 081 * of the <code>cursor</code> argument is updated to the index after the last character used. 082 * 083 * @param csq 084 * the <code>CharSequence</code> to parse. 085 * @param cursor 086 * the cursor holding the current parsing index. 087 * @return the object parsed from the specified character sub-sequence. 088 * @throws IllegalArgumentException 089 * if any problem occurs while parsing the specified character sequence (e.g. illegal syntax). 090 */ 091 public abstract Quantity<?> parse(CharSequence csq, ParsePosition cursor) throws IllegalArgumentException, MeasurementParseException; 092 093 /** 094 * Parses a portion of the specified <code>CharSequence</code> from the specified position to produce an object. If parsing succeeds, then the index 095 * of the <code>cursor</code> argument is updated to the index after the last character used. 096 * 097 * @param csq 098 * the <code>CharSequence</code> to parse. 099 * @param cursor 100 * the cursor holding the current parsing index. 101 * @return the object parsed from the specified character sub-sequence. 102 * @throws IllegalArgumentException 103 * if any problem occurs while parsing the specified character sequence (e.g. illegal syntax). 104 */ 105 @Override 106 public abstract Quantity<?> parse(CharSequence csq) throws MeasurementParseException; 107 108 /** 109 * Parses a portion of the specified <code>CharSequence</code> from the specified position to produce an object. If parsing succeeds, then the index 110 * of the <code>cursor</code> argument is updated to the index after the last character used. 111 * 112 * @param csq 113 * the <code>CharSequence</code> to parse. 114 * @param index 115 * the current parsing index. 116 * @return the object parsed from the specified character sub-sequence. 117 * @throws IllegalArgumentException 118 * if any problem occurs while parsing the specified character sequence (e.g. illegal syntax). 119 */ 120 abstract Quantity<?> parse(CharSequence csq, int index) throws IllegalArgumentException, MeasurementParseException; 121 122 @Override 123 public final StringBuffer format(Object obj, final StringBuffer toAppendTo, FieldPosition pos) { 124 if (!(obj instanceof Quantity<?>)) 125 throw new IllegalArgumentException("obj: Not an instance of Quantity"); 126 if ((toAppendTo == null) || (pos == null)) 127 throw new NullPointerException(); 128 return (StringBuffer) format((Quantity<?>) obj, toAppendTo); 129 } 130 131 @Override 132 public final Quantity<?> parseObject(String source, ParsePosition pos) { 133 try { 134 return parse(source, pos); 135 } catch (IllegalArgumentException | MeasurementParseException e) { 136 return null; 137 } 138 } 139 140 /** 141 * Convenience method equivalent to {@link #format(Quantity, Appendable)} except it does not raise an IOException. 142 * 143 * @param quantity 144 * the quantity to format. 145 * @param dest 146 * the appendable destination. 147 * @return the specified <code>StringBuilder</code>. 148 */ 149 protected final StringBuffer format(Quantity<?> quantity, StringBuffer dest) { 150 try { 151 return (StringBuffer) this.format(quantity, (Appendable) dest); 152 } catch (IOException ex) { 153 throw new RuntimeException(ex); // Should not happen. 154 } 155 } 156 157 public final String format(Quantity<?> quantity) { 158 return (this.format(quantity, new StringBuffer())).toString(); 159 } 160}