001/* 002 * Units of Measurement Reference Implementation 003 * Copyright (c) 2005-2017, Jean-Marie Dautelle, Werner Keil, V2COM. 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-363 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 tec.units.ri.quantity; 031 032import static tec.units.ri.unit.Units.*; 033 034import java.util.HashMap; 035import java.util.Map; 036 037import javax.measure.Quantity; 038import javax.measure.Unit; 039import javax.measure.quantity.*; 040import javax.measure.spi.QuantityFactory; 041 042import tec.units.ri.AbstractQuantity; 043import tec.units.ri.AbstractUnit; 044 045/** 046 * The default factory implementation. This factory provides a default implementation for every {@link AbstractQuantity} sub-type. 047 * 048 * For example:<br> 049 * <code> 050 * Quantity<Mass> m = DefaultQuantityFactory.getInstance(Mass.class).create(23.0, KILOGRAM); // 23.0 kg<br> 051 * Quantity<Time> m = DefaultQuantityFactory.getInstance(Time.class).create(124, MILLI(SECOND)); // 124 ms 052 * </code> 053 * 054 * @param <Q> 055 * The type of the quantity. 056 * 057 * @author <a href="mailto:martin.desruisseaux@geomatys.com">Martin Desruisseaux</a> 058 * @author <a href="mailto:units@catmedia.us">Werner Keil</a> 059 * @author <a href="mailto:jean-marie@dautelle.com">Jean-Marie Dautelle</a> 060 * @version 1.0, $Date: 2016-10-04 $ 061 * @since 1.0 062 */ 063public final class DefaultQuantityFactory<Q extends Quantity<Q>> extends AbstractQuantityFactory<Q> { 064 /** 065 * The type of the quantities created by this factory. 066 */ 067 @SuppressWarnings("unused") 068 private final Class<Q> type; 069 070 /** 071 * The metric unit for quantities created by this factory. 072 */ 073 private final Unit<Q> metricUnit; 074 075 /** 076 * Creates a new factory for quantities of the given type. 077 * 078 * @param type 079 * The type of the quantities created by this factory. 080 */ 081 @SuppressWarnings("unchecked") 082 DefaultQuantityFactory(final Class<Q> type) { 083 this.type = type; 084 metricUnit = CLASS_TO_METRIC_UNIT.get(type); 085 } 086 087 @SuppressWarnings("rawtypes") 088 static final Map<Class, Unit> CLASS_TO_METRIC_UNIT = new HashMap<Class, Unit>(); 089 static { 090 CLASS_TO_METRIC_UNIT.put(Dimensionless.class, AbstractUnit.ONE); 091 CLASS_TO_METRIC_UNIT.put(ElectricCurrent.class, AMPERE); 092 CLASS_TO_METRIC_UNIT.put(LuminousIntensity.class, CANDELA); 093 CLASS_TO_METRIC_UNIT.put(Temperature.class, KELVIN); 094 CLASS_TO_METRIC_UNIT.put(Mass.class, KILOGRAM); 095 CLASS_TO_METRIC_UNIT.put(Length.class, METRE); 096 CLASS_TO_METRIC_UNIT.put(AmountOfSubstance.class, MOLE); 097 CLASS_TO_METRIC_UNIT.put(Time.class, SECOND); 098 CLASS_TO_METRIC_UNIT.put(Angle.class, RADIAN); 099 CLASS_TO_METRIC_UNIT.put(SolidAngle.class, STERADIAN); 100 CLASS_TO_METRIC_UNIT.put(Frequency.class, HERTZ); 101 CLASS_TO_METRIC_UNIT.put(Force.class, NEWTON); 102 CLASS_TO_METRIC_UNIT.put(Pressure.class, PASCAL); 103 CLASS_TO_METRIC_UNIT.put(Energy.class, JOULE); 104 CLASS_TO_METRIC_UNIT.put(Power.class, WATT); 105 CLASS_TO_METRIC_UNIT.put(ElectricCharge.class, COULOMB); 106 CLASS_TO_METRIC_UNIT.put(ElectricPotential.class, VOLT); 107 CLASS_TO_METRIC_UNIT.put(ElectricCapacitance.class, FARAD); 108 CLASS_TO_METRIC_UNIT.put(ElectricResistance.class, OHM); 109 CLASS_TO_METRIC_UNIT.put(ElectricConductance.class, SIEMENS); 110 CLASS_TO_METRIC_UNIT.put(MagneticFlux.class, WEBER); 111 CLASS_TO_METRIC_UNIT.put(MagneticFluxDensity.class, TESLA); 112 CLASS_TO_METRIC_UNIT.put(ElectricInductance.class, HENRY); 113 CLASS_TO_METRIC_UNIT.put(LuminousFlux.class, LUMEN); 114 CLASS_TO_METRIC_UNIT.put(Illuminance.class, LUX); 115 CLASS_TO_METRIC_UNIT.put(Radioactivity.class, BECQUEREL); 116 CLASS_TO_METRIC_UNIT.put(RadiationDoseAbsorbed.class, GRAY); 117 CLASS_TO_METRIC_UNIT.put(RadiationDoseEffective.class, SIEVERT); 118 CLASS_TO_METRIC_UNIT.put(CatalyticActivity.class, KATAL); 119 CLASS_TO_METRIC_UNIT.put(Speed.class, METRE_PER_SECOND); 120 CLASS_TO_METRIC_UNIT.put(Acceleration.class, METRE_PER_SQUARE_SECOND); 121 CLASS_TO_METRIC_UNIT.put(Area.class, SQUARE_METRE); 122 CLASS_TO_METRIC_UNIT.put(Volume.class, CUBIC_METRE); 123 } 124 125 public Quantity<Q> create(Number value, Unit<Q> unit) { 126 return Quantities.getQuantity(value, unit); 127 } 128 129 public Unit<Q> getSystemUnit() { 130 return metricUnit; 131 } 132 133 /** 134 * Returns the default instance for the specified quantity type. 135 * 136 * @param <Q> 137 * The type of the quantity 138 * @param type 139 * the quantity type 140 * @return the quantity factory for the specified type 141 */ 142 @SuppressWarnings("unchecked") 143 public static <Q extends Quantity<Q>> QuantityFactory<Q> getInstance(final Class<Q> type) { 144 logger.log(LOG_LEVEL, "Type: " + type + ": " + type.isInterface()); 145 QuantityFactory<Q> factory; 146 if (!type.isInterface()) { 147 factory = new DefaultQuantityFactory<Q>(type); 148 // TODO use instances? 149 } else { 150 factory = INSTANCES.get(type); 151 if (factory != null) 152 return factory; 153 if (!Quantity.class.isAssignableFrom(type)) 154 // This exception is not documented because it should never 155 // happen if the 156 // user don't try to trick the Java generic types system with 157 // unsafe cast. 158 throw new ClassCastException(); 159 factory = new DefaultQuantityFactory<Q>(type); 160 setInstance(type, factory); 161 } 162 return factory; 163 } 164}