1 /* Copyright 2002-2025 CS GROUP
2 * Licensed to CS GROUP (CS) under one or more
3 * contributor license agreements. See the NOTICE file distributed with
4 * this work for additional information regarding copyright ownership.
5 * CS licenses this file to You under the Apache License, Version 2.0
6 * (the "License"); you may not use this file except in compliance with
7 * the License. You may obtain a copy of the License at
8 *
9 * http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 */
17 package org.orekit.utils.units;
18
19 import java.util.Arrays;
20 import java.util.HashMap;
21 import java.util.List;
22 import java.util.Map;
23
24 import org.orekit.errors.OrekitException;
25 import org.orekit.errors.OrekitMessages;
26
27 /** {@link Unit} with a {@link Prefix}.
28 * @author Luc Maisonobe
29 * @since 11.0
30 */
31 class PrefixedUnit extends Unit {
32
33 /** Serializable UID. */
34 private static final long serialVersionUID = 20210407L;
35
36 /** Allowed units with SI prefixes, with various aliases for angles, year, sfu, and tecu. */
37 private static final Map<String, PrefixedUnit> ALLOWED;
38
39 static {
40 final List<Unit> base = Arrays.asList(Unit.SECOND,
41 Unit.MINUTE,
42 Unit.HOUR,
43 Unit.DAY,
44 Unit.DAY.alias("day"),
45 Unit.YEAR,
46 Unit.YEAR.alias("yr"),
47 Unit.HERTZ,
48 Unit.METRE,
49 Unit.GRAM, // only case were we must use a derived unit
50 Unit.AMPERE,
51 Unit.RADIAN,
52 Unit.DEGREE,
53 Unit.DEGREE.alias("◦"),
54 Unit.DEGREE.alias("deg"),
55 Unit.ARC_MINUTE,
56 Unit.ARC_MINUTE.alias("'"),
57 Unit.ARC_SECOND,
58 Unit.ARC_SECOND.alias("''"),
59 Unit.ARC_SECOND.alias("\""),
60 Unit.ARC_SECOND.alias("as"), // must be after second to override atto-seconds
61 Unit.REVOLUTION,
62 Unit.NEWTON,
63 Unit.PASCAL, // must be after year to override peta-years
64 Unit.BAR,
65 Unit.JOULE,
66 Unit.WATT,
67 Unit.COULOMB,
68 Unit.VOLT,
69 Unit.OHM,
70 Unit.TESLA,
71 Unit.SOLAR_FLUX_UNIT,
72 Unit.SOLAR_FLUX_UNIT.alias("SFU"),
73 Unit.SOLAR_FLUX_UNIT.alias("sfu"),
74 Unit.TOTAL_ELECTRON_CONTENT_UNIT,
75 Unit.TOTAL_ELECTRON_CONTENT_UNIT.alias("tecu"),
76 Unit.EARTH_RADII,
77 Unit.CYCLE);
78 ALLOWED = new HashMap<>(base.size() * Prefix.values().length);
79 for (final Unit unit : base) {
80 ALLOWED.put(unit.getName(), new PrefixedUnit(null, unit));
81 for (final Prefix prefix : Prefix.values()) {
82 final PrefixedUnit pu = new PrefixedUnit(prefix, unit);
83 ALLOWED.put(pu.getName(), pu);
84 }
85 }
86
87 // units that don't accept any prefix
88 for (final Unit noPrefix : Arrays.asList(Unit.PERCENT, Unit.ONE, Unit.ONE.alias("#"))) {
89 ALLOWED.put(noPrefix.getName(), new PrefixedUnit(null, noPrefix));
90 }
91
92 }
93
94 /** Simple constructor.
95 * @param prefix SI prefix (may be null)
96 * @param unit base unit
97 */
98 PrefixedUnit(final Prefix prefix, final Unit unit) {
99 super((prefix == null) ? unit.getName() : (prefix.getSymbol() + unit.getName()),
100 (prefix == null) ? unit.getScale() : (prefix.getFactor() * unit.getScale()),
101 unit.getMass(), unit.getLength(), unit.getTime(), unit.getCurrent(), unit.getAngle());
102 }
103
104 /** Get one of the allowed prefixed unit.
105 * @param name name of the prefixed unit
106 * @return prefixed unit with that name
107 */
108 public static PrefixedUnit valueOf(final String name) {
109 final PrefixedUnit prefixedUnit = ALLOWED.get(name);
110 if (prefixedUnit == null) {
111 throw new OrekitException(OrekitMessages.UNKNOWN_UNIT, name);
112 }
113 return prefixedUnit;
114 }
115
116 }