001/*
002 * Units of Measurement API
003 * Copyright (c) 2014-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 nor the names of its 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 javax.measure.spi;
031
032import java.util.Collection;
033import java.util.Collections;
034import java.util.EnumSet;
035import java.util.Set;
036import javax.measure.Prefix;
037
038/**
039 * This interface represents the service to obtain a {@link SystemOfUnits system
040 * of units}.
041 *
042 * <p>
043 * Common systems of units are "SI" (System International) or Metric system,
044 * "Imperial" (British), or "US" (US Customary).
045 * </p>
046 *
047 * @author <a href="mailto:[email protected]">Jean-Marie Dautelle</a>
048 * @author <a href="mailto:[email protected]">Werner Keil</a>
049 * @author <a href="mailto:[email protected]">Martin
050 *         Desruisseaux</a>
051 * @version 1.6, June 21, 2018
052 * @since 1.0
053 *
054 * @see <a href=
055 *      "http://en.wikipedia.org/wiki/International_System_of_Units">Wikipedia:
056 *      International System of Units</a>
057 */
058public interface SystemOfUnitsService {
059
060        /**
061         * Returns the default {@link SystemOfUnits system of units}. Depending on the
062         * implementation this may be the <a href=
063         * "http://en.wikipedia.org/wiki/International_System_of_Units">International
064         * System of Units</a> or another default system.
065         *
066         * @return the default system of units.
067         */
068        SystemOfUnits getSystemOfUnits();
069
070        /**
071         * Returns the system of units having the specified name or <code>null</code> if
072         * none is found.
073         *
074         * @param name the system of unit name.
075         * @return the given system of units.
076         */
077        SystemOfUnits getSystemOfUnits(String name);
078
079        /**
080         * Gets a list with available systems for this {@link SystemOfUnitsService}.
081         *
082         * @return list of available systems of units, never null.
083         */
084        Collection<SystemOfUnits> getAvailableSystemsOfUnits();
085
086        /**
087         * Returns a {@link Set} containing the values of a particular {@link Prefix}
088         * type.<br>
089         * This method may be used to iterate over the prefixes as follows:
090         *
091         * <pre>
092         * <code>
093         *    for(Prefix p : service.getPrefixes(PrefixType.class))
094         *        System.out.println(p);
095         * </code>
096         * </pre>
097         *
098         * @param prefixType the {@link Prefix} type
099         * @return a set containing the constant values of this Prefix type, in the
100         *         order they're declared
101         * @throws ClassCastException if the class is not compatible with the desired
102         *                            Prefix implementation or does not implement Prefix at all.
103         * @since 2.0
104         */
105        @SuppressWarnings("unchecked")
106        default Set<Prefix> getPrefixes(@SuppressWarnings("rawtypes") Class prefixType) {
107                if (Prefix.class.isAssignableFrom(prefixType)) {
108                        return Collections.<Prefix>unmodifiableSet(EnumSet.allOf(prefixType.asSubclass(Enum.class)));
109                } else {
110                        throw new ClassCastException(String.format("%s does not implement Prefix", prefixType));
111                        // TODO or should we throw a different exception here, MeasurementException or IllegalArgumentException?
112                }
113        }
114}