• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

unitsofmeasurement / indriya / 2285

18 Feb 2025 10:54PM UTC coverage: 71.202% (+0.07%) from 71.134%
2285

push

circleci

keilw
435: AbstractUnit.asType() will accept any si-units as valid class input

Task-Url: https://github.com/unitsofmeasurement/indriya/issues/435

12 of 12 new or added lines in 1 file covered. (100.0%)

1 existing line in 1 file now uncovered.

3731 of 5240 relevant lines covered (71.2%)

0.71 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

94.74
/src/main/java/tech/units/indriya/unit/UnitDimension.java
1
/*
2
 * Units of Measurement Reference Implementation
3
 * Copyright (c) 2005-2025, Jean-Marie Dautelle, Werner Keil, Otavio Santana.
4
 *
5
 * All rights reserved.
6
 *
7
 * Redistribution and use in source and binary forms, with or without modification,
8
 * are permitted provided that the following conditions are met:
9
 *
10
 * 1. Redistributions of source code must retain the above copyright notice,
11
 *    this list of conditions and the following disclaimer.
12
 *
13
 * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions
14
 *    and the following disclaimer in the documentation and/or other materials provided with the distribution.
15
 *
16
 * 3. Neither the name of JSR-385, Indriya nor the names of their contributors may be used to endorse or promote products
17
 *    derived from this software without specific prior written permission.
18
 *
19
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
20
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
21
 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22
 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
23
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
24
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
25
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
26
 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
28
 * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29
 */
30
package tech.units.indriya.unit;
31

32
import javax.measure.Dimension;
33
import javax.measure.Quantity;
34
import javax.measure.Unit;
35
import javax.measure.spi.ServiceProvider;
36
import javax.measure.spi.SystemOfUnits;
37

38
import tech.units.indriya.AbstractUnit;
39
import java.io.Serializable;
40
import java.util.Collection;
41
import java.util.HashMap;
42
import java.util.List;
43
import java.util.Map;
44
import java.util.Objects;
45
import java.util.logging.Level;
46
import java.util.logging.Logger;
47

48
/**
49
 * <p>
50
 * This class represents a dimension of a unit of measurement.
51
 * </p>
52
 *
53
 * <p>
54
 * The dimension associated to any given quantity are given by the published
55
 * {@link Dimension} instances. For convenience, a static method
56
 * <code>UnitDimension.of(Class)</code> aggregating the results of all
57
 * 
58
 * {@link Dimension} instances is provided.<br>
59
 * <br>
60
 * <code>
61
 *        Dimension speedDimension
62
 *            = UnitDimension.of(Speed.class);
63
 *     </code>
64
 * </p>
65
 *
66
 * @author <a href="mailto:jean-marie@dautelle.com">Jean-Marie Dautelle</a>
67
 * @author <a href="mailto:werner@units.tech">Werner Keil</a>
68
 * @author  Martin Desruisseaux (Geomatys)
69
 * @author  Andi Huber
70
 * @version 2.2, Feb 18, 2025
71
 * @since 2.0
72
 */
73
public class UnitDimension implements Dimension, Serializable {
74
    /**        */
75
        private static final long serialVersionUID = 7806787530512644696L;
76

77
        private static final Logger LOGGER = Logger.getLogger(UnitDimension.class.getName());
1✔
78

79
        /**
80
         * Holds dimensionless.
81
         * 
82
         * @since 1.0
83
         */
84
        public static final Dimension NONE = new UnitDimension(AbstractUnit.ONE);
1✔
85

86
        /**
87
         * Holds length dimension (L).
88
         * 
89
         * @since 1.0
90
         */
91
        public static final Dimension LENGTH = new UnitDimension('L');
1✔
92

93
        /**
94
         * Holds mass dimension (M).
95
         * 
96
         * @since 1.0
97
         */
98
        public static final Dimension MASS = new UnitDimension('M');
1✔
99

100
        /**
101
         * Holds time dimension (T).
102
         * 
103
         * @since 1.0
104
         */
105
        public static final Dimension TIME = new UnitDimension('T');
1✔
106

107
        /**
108
         * Holds electric current dimension (I).
109
         * 
110
         * @since 1.0
111
         */
112
        public static final Dimension ELECTRIC_CURRENT = new UnitDimension('I');
1✔
113

114
        /**
115
         * Holds temperature dimension (Θ).
116
         * 
117
         * @since 1.0
118
         */
119
        public static final Dimension TEMPERATURE = new UnitDimension('\u0398');
1✔
120

121
        /**
122
         * Holds amount of substance dimension (N).
123
         * 
124
         * @since 1.0
125
         */
126
        public static final Dimension AMOUNT_OF_SUBSTANCE = new UnitDimension('N');
1✔
127

128
        /**
129
         * Holds luminous intensity dimension (J).
130
         */
131
        public static final Dimension LUMINOUS_INTENSITY = new UnitDimension('J');
1✔
132

133
        /**
134
         * Holds the pseudo unit associated to this dimension.
135
         */
136
        private final Unit<?> pseudoUnit;
137

138
        /**
139
         * Returns the dimension for the specified quantity type by aggregating the
140
         * results from the default {@link javax.measure.spi.SystemOfUnits SystemOfUnits} or <code>null</code> if the specified
141
         * quantity is unknown.
142
         *
143
         * @param quantityType the quantity type.
144
         * @return the dimension for the quantity type or <code>null</code>.
145
         * @since 1.1
146
         */
147
        public static <Q extends Quantity<Q>> Dimension of(Class<Q> quantityType) {
148
                // TODO: For a Java 9+ version use .takeWhile, see https://www.tutorialspoint.com/break-or-return-from-java-8-stream-foreach
149
                Unit<Q> systemUnit = null;
1✔
150
                List<ServiceProvider> providers = ServiceProvider.available();
1✔
151
                for (ServiceProvider provider: providers) {
1✔
152
                        Collection<SystemOfUnits> unitSystems = provider.getSystemOfUnitsService().getAvailableSystemsOfUnits();
1✔
153
                        for (SystemOfUnits systemOfUnits : unitSystems) {
1✔
154
                                systemUnit = systemOfUnits.getUnit(quantityType);
1✔
155
                                if (systemUnit != null) {
1✔
156
                                        break;
1✔
157
                                }
158
                        }
1✔
159
                }
1✔
160
                if (systemUnit == null && LOGGER.isLoggable(Level.FINE)) {
1✔
UNCOV
161
                        LOGGER.log(Level.FINE, "Quantity type: " + quantityType + " unknown");
×
162
                }
163
                return (systemUnit != null) ? systemUnit.getDimension() : null;
1✔
164
        }
165

166
        /**
167
         * Returns the dimension for the specified symbol.
168
         *
169
         * @param sambol the quantity symbol.
170
         * @return the dimension for the given symbol.
171
         * @since 1.0.1
172
         */
173
        public static Dimension parse(char symbol) {
174
                return new UnitDimension(symbol);
1✔
175
        }
176

177
        /**
178
         * Returns the unit dimension having the specified symbol.
179
         *
180
         * @param symbol the associated symbol.
181
         */
182
        @SuppressWarnings("rawtypes")
183
        private UnitDimension(char symbol) {
1✔
184
                pseudoUnit = new BaseUnit("[" + symbol + ']', NONE);
1✔
185
        }
1✔
186

187
        /**
188
         * Constructor from pseudo-unit (not visible).
189
         *
190
         * @param pseudoUnit the pseudo-unit.
191
         */
192
        private UnitDimension(Unit<?> pseudoUnit) {
1✔
193
                this.pseudoUnit = pseudoUnit;
1✔
194
        }
1✔
195
        
196
        /**
197
         * Default Constructor (not visible).
198
         *
199
         */
200
        protected UnitDimension() {
201
                this(AbstractUnit.ONE);
×
202
        }
×
203
        
204

205
        /**
206
         * Returns the product of this dimension with the one specified. 
207
         * If the specified dimension is not a <code>UnitDimension</code>, then
208
         * <code>that.multiply(this)</code> is returned.
209
         *
210
         * @param that the dimension multiplicand.
211
         * @return <code>this * that</code>
212
         * @since 1.0
213
         */
214
        public Dimension multiply(Dimension that) {
215
                return that instanceof UnitDimension
1✔
216
                        ? this.multiply((UnitDimension) that)
1✔
217
                : that.multiply(this);
1✔
218
        }
219

220
        /**
221
         * Returns the product of this dimension with the one specified.
222
         *
223
         * @param that the dimension multiplicand.
224
         * @return <code>this * that</code>
225
         * @since 1.0
226
         */
227
        private UnitDimension multiply(UnitDimension that) {
228
                return new UnitDimension(this.pseudoUnit.multiply(that.pseudoUnit));
1✔
229
        }
230

231
        /**
232
         * Returns the quotient of this dimension with the one specified.
233
         * If the specified dimension is not a <code>UnitDimension</code>, then
234
     * <code>that.divide(this).pow(-1)</code> is returned.
235
         *
236
         * @param that the dimension divisor.
237
         * @return <code>this / that</code>
238
         * @since 1.0
239
         */
240
        public Dimension divide(Dimension that) {
241
                return that instanceof UnitDimension
1✔
242
                        ? this.divide((UnitDimension) that)
1✔
243
                : that.divide(this).pow(-1);
1✔
244
        }
245

246
        /**
247
         * Returns the quotient of this dimension with the one specified.
248
         *
249
         * @param that the dimension divisor.
250
         * @return <code>this / that</code>
251
         * @since 1.0
252
         */
253
        private UnitDimension divide(UnitDimension that) {
254
                return new UnitDimension(ProductUnit.ofQuotient(pseudoUnit, that.pseudoUnit));
1✔
255
        }
256

257
        /**
258
         * Returns this dimension raised to an exponent.
259
         *
260
         * @param n the exponent.
261
         * @return the result of raising this dimension to the exponent.
262
         * @since 1.0
263
         */
264
        public UnitDimension pow(int n) {
265
                return new UnitDimension(this.pseudoUnit.pow(n));
1✔
266
        }
267

268
        /**
269
         * Returns the given root of this dimension.
270
         *
271
         * @param n the root's order.
272
         * @return the result of taking the given root of this dimension.
273
         * @throws ArithmeticException if <code>n == 0</code>.
274
         * @since 1.0
275
         */
276
        public UnitDimension root(int n) {
277
                return new UnitDimension(this.pseudoUnit.root(n));
1✔
278
        }
279

280
        /**
281
         * Returns the fundamental (base) dimensions and their exponent whose product is
282
         * this dimension or <code>null</code> if this dimension is a fundamental
283
         * dimension.
284
         *
285
         * @return the mapping between the base dimensions and their exponent.
286
         * @since 1.0
287
         */
288
        @SuppressWarnings("rawtypes")
289
        public Map<? extends Dimension, Integer> getBaseDimensions() {
290
                Map<? extends Unit, Integer> pseudoUnits = pseudoUnit.getBaseUnits();
1✔
291
                if (pseudoUnits == null) {
1✔
292
                        return null;
1✔
293
                }
294
                final Map<UnitDimension, Integer> baseDimensions = new HashMap<>();
1✔
295
                for (Map.Entry<? extends Unit, Integer> entry : pseudoUnits.entrySet()) {
1✔
296
                        baseDimensions.put(new UnitDimension(entry.getKey()), entry.getValue());
1✔
297
                }
1✔
298
                return baseDimensions;
1✔
299
        }
300

301
        @Override
302
        public String toString() {
303
                return pseudoUnit.toString();
1✔
304
        }
305

306
        @Override
307
        public boolean equals(Object obj) {
308
                if (this == obj) {
1✔
309
                        return true;
1✔
310
                }
311
                if (obj instanceof UnitDimension) {
1✔
312
                        UnitDimension other = (UnitDimension) obj;
1✔
313
                        return Objects.equals(pseudoUnit, other.pseudoUnit);
1✔
314
                }
315
                return false;
1✔
316
        }
317

318
        @Override
319
        public int hashCode() {
320
                return Objects.hashCode(pseudoUnit);
1✔
321
        }
322
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc