001/* 002 * Units of Measurement Enum Implementation 003 * Copyright © 2005-2021, Werner Keil and others. 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, Unit-API 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.uom.impl.enums.function; 031 032import java.util.ArrayList; 033import java.util.List; 034 035import javax.measure.UnitConverter; 036 037/** 038 * <p> The base class for our {@link UnitConverter} physics implementations.</p> 039 * 040 * @author <a href="mailto:units@catmedia.us">Werner Keil</a> 041 * @version 0.7.1, $Date: 2014-09-07 $ 042 */ 043public abstract class AbstractConverter implements UnitConverter { 044 045 /** 046 * 047 */ 048 //private static final long serialVersionUID = 5790242858468427131L; 049 050 /** 051 * The ratio of the circumference of a circle to its diameter. 052 **/ 053 protected static final double PI = 3.1415926535897932384626433832795; 054 055 /** 056 * Holds identity converter. 057 */ 058 public static final AbstractConverter IDENTITY = new Identity(); 059 060 /** 061 * Default constructor. 062 */ 063 protected AbstractConverter() { 064 } 065 066 /** 067 * Concatenates this physics converter with another physics converter. 068 * The resulting converter is equivalent to first converting by the 069 * specified converter (right converter), and then converting by 070 * this converter (left converter). 071 * 072 * @param that the other converter. 073 * @return the concatenation of this converter with that converter. 074 */ 075 public AbstractConverter concatenate(AbstractConverter that) { 076 return (that == IDENTITY) ? this : new Pair(this, that); 077 } 078 079 public boolean isIdentity() { 080 return false; 081 } 082 083 @Override 084 public abstract boolean equals(Object cvtr); 085 086 @Override 087 public abstract int hashCode(); 088 089 public abstract AbstractConverter inverse(); 090 091 public UnitConverter concatenate(UnitConverter converter) { 092 return (converter == IDENTITY) ? this : new Pair(this, converter); 093 } 094 095 public List<? extends UnitConverter> getConversionSteps() { 096 List<AbstractConverter> converters = new ArrayList<AbstractConverter>(); 097 converters.add(this); 098 return converters; 099 } 100 101 public Number convert(Number value) { 102 return convert(Double.valueOf(value.doubleValue())); 103 } 104 105 public abstract double convert(double value); 106 107 /** 108 * This class represents the identity converter (singleton). 109 */ 110 private static final class Identity extends AbstractConverter { 111 112 @Override 113 public boolean isIdentity() { 114 return true; 115 } 116 117 @Override 118 public Identity inverse() { 119 return this; 120 } 121 122 @Override 123 public double convert(double value) { 124 return value; 125 } 126 127 128 @Override 129 public UnitConverter concatenate(UnitConverter converter) { 130 return converter; 131 } 132 133 @Override 134 public boolean equals(Object cvtr) { 135 return (cvtr instanceof Identity) ? true : false; 136 } 137 138 @Override 139 public int hashCode() { 140 return 0; 141 } 142 143 public boolean isLinear() { 144 return true; 145 } 146 } 147 148 /** 149 * This class represents converters made up of two or more separate 150 * converters (in matrix notation <code>[pair] = [left] x [right]</code>). 151 */ 152 private static final class Pair extends AbstractConverter { 153 154 /** 155 * Holds the first converter. 156 */ 157 private UnitConverter left; 158 159 /** 160 * Holds the second converter. 161 */ 162 private UnitConverter right; 163 164 /** 165 * Creates a converter pair from the combined 166 * transformation of the specified converters. 167 * 168 * @param left the left converter. 169 * @param right the right converter. 170 */ 171 public Pair(UnitConverter left, UnitConverter right) { 172 this.left = left; 173 this.right = right; 174 } 175 176 public boolean isLinear() { 177 return left.isLinear() && right.isLinear(); 178 } 179 180 @Override 181 public boolean isIdentity() { 182 return false; 183 } 184 185 @Override 186 public List<UnitConverter> getConversionSteps() { 187 final List<UnitConverter> steps = new ArrayList<UnitConverter>(); 188 List<? extends UnitConverter> leftCompound = left.getConversionSteps(); 189 List<? extends UnitConverter> rightCompound = right.getConversionSteps(); 190 steps.addAll(leftCompound); 191 steps.addAll(rightCompound); 192 return steps; 193 } 194 195 @Override 196 public Pair inverse() { 197 return new Pair(right.inverse(), left.inverse()); 198 } 199 200 @Override 201 public double convert(double value) { 202 return left.convert(right.convert(value)); 203 } 204 205 @Override 206 public boolean equals(Object cvtr) { 207 if (this == cvtr) return true; 208 if (!(cvtr instanceof Pair)) return false; 209 Pair that = (Pair) cvtr; 210 return (this.left.equals(that.left)) && (this.right.equals(that.right)); 211 } 212 213 @Override 214 public int hashCode() { 215 return left.hashCode() + right.hashCode(); 216 } 217 218 } 219 220}