001/* 002 * Units of Measurement Reference Implementation 003 * Copyright (c) 2005-2021, 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.spi; 031 032import java.util.Locale; 033import java.util.ResourceBundle.Control; 034import java.util.spi.LocaleServiceProvider; 035 036/** 037 * An abstract class for service providers that 038 * provide localized unit symbols and display names for the 039 * {@link javax.measure.Unit unit} class. 040 * Note that unit symbols are considered names when determining 041 * behaviors described in the 042 * {@link java.util.spi.LocaleServiceProvider LocaleServiceProvider} 043 * specification. 044 * 045 * @since 2.0.3 046 */ 047public abstract class UnitNameProvider extends LocaleServiceProvider { 048 049 /** 050 * Sole constructor. (For invocation by subclass constructors, typically 051 * implicit.) 052 */ 053 protected UnitNameProvider() { 054 } 055 056 /** 057 * Gets the symbol of the given unit for the specified locale. 058 * For example, for "m" (metre), the symbol is "m" if the specified 059 * locale is the US, while for other locales it may be "M". If no 060 * symbol can be determined, null should be returned. 061 * 062 * @param unitCode the unit code, which 063 * consists of three upper-case letters between 'A' (U+0041) and 064 * 'Z' (U+005A) 065 * @param locale the desired locale 066 * @return the symbol of the given unit for the specified locale, or null if 067 * the symbol is not available for the locale 068 * @exception NullPointerException if <code>unitCode</code> or 069 * <code>locale</code> is null 070 * @exception IllegalArgumentException if <code>unitCode</code> is not in 071 * the form of three upper-case letters, or <code>locale</code> isn't 072 * one of the locales returned from 073 * {@link java.util.spi.LocaleServiceProvider#getAvailableLocales() 074 * getAvailableLocales()}. 075 * @see javax.measure.Unit#getSymbol(java.util.Locale) 076 */ 077 public abstract String getSymbol(String unitCode, Locale locale); 078 079 /** 080 * Returns a name for the unit that is appropriate for display to the 081 * user. The default implementation returns null. 082 * 083 * @param unitCode the ISO 4217 unit, which 084 * consists of three upper-case letters between 'A' (U+0041) and 085 * 'Z' (U+005A) 086 * @param locale the desired locale 087 * @return the name for the unit that is appropriate for display to the 088 * user, or null if the name is not available for the locale 089 * @exception IllegalArgumentException if <code>unitCode</code> is not in 090 * the form of three upper-case letters, or <code>locale</code> isn't 091 * one of the locales returned from 092 * {@link java.util.spi.LocaleServiceProvider#getAvailableLocales() 093 * getAvailableLocales()}. 094 * @exception NullPointerException if <code>unitCode</code> or 095 * <code>locale</code> is <code>null</code> 096 */ 097 public String getDisplayName(String unitCode, Locale locale) { 098 if (unitCode == null || locale == null) { 099 throw new NullPointerException(); 100 } 101 102 // Check whether the unitCode is valid 103 char[] charray = unitCode.toCharArray(); 104 if (charray.length != 3) { 105 throw new IllegalArgumentException("The unitCode is not in the form of three upper-case letters."); 106 } 107 for (char c : charray) { 108 if (c < 'A' || c > 'Z') { 109 throw new IllegalArgumentException("The unit is not in the form of three upper-case letters."); 110 } 111 } 112 113 // Check whether the locale is valid 114 Control c = Control.getNoFallbackControl(Control.FORMAT_DEFAULT); 115 for (Locale l : getAvailableLocales()) { 116 if (c.getCandidateLocales("", l).contains(locale)) { 117 return null; 118 } 119 } 120 121 throw new IllegalArgumentException("The locale is not available"); 122 } 123} 124