001/** 002 * ScalarParam -- A parameter that contains a single scalar value. 003 * 004 * Copyright (C) 2003-2017, by Joseph A. Huwaldt. All rights reserved. 005 * 006 * This library is free software; you can redistribute it and/or modify it under the terms 007 * of the GNU Lesser General Public License as published by the Free Software Foundation; 008 * either version 2 of the License, or (at your option) any later version. 009 * 010 * This library is distributed in the hope that it will be useful, but WITHOUT ANY 011 * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A 012 * PARTICULAR PURPOSE. See the GNU Library General Public License for more details. 013 * 014 * You should have received a copy of the GNU Lesser General Public License along with 015 * this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - 016 * Suite 330, Boston, MA 02111-1307, USA. Or visit: http://www.gnu.org/licenses/lgpl.html 017 */ 018package jahuwaldt.js.datareader; 019 020import jahuwaldt.js.param.Parameter; 021import java.text.MessageFormat; 022import java.util.Objects; 023import static java.util.Objects.requireNonNull; 024import javax.measure.converter.ConversionException; 025import javax.measure.quantity.Quantity; 026import javax.measure.unit.Unit; 027import javolution.context.ObjectFactory; 028import javolution.text.Text; 029 030/** 031 * A class that represents a scalar data value in a case. 032 * 033 * <p> Modified by: Joseph A. Huwaldt </p> 034 * 035 * @author Joseph A. Huwaldt, Date: March 5, 2003 036 * @version March 18, 2017 037 * @param <Q> Unit quantity type. 038 */ 039public final class ScalarParam<Q extends Quantity> extends UnitParameter<Q, ScalarParam> { 040 041 // The Parameter object backing this ScalarParam object. 042 private Parameter<Q> _param; 043 044 ////////////////////// 045 // Factory Creation // 046 ////////////////////// 047 /** 048 * Returns a new, preallocated or recycled <code>ScalarParam</code> instance (on the 049 * stack when executing in a <code>StackContext</code>) with the specified name, no 050 * units, and a value of 0. 051 * 052 * @param name The name to be assigned to this parameter (may not be 053 * <code>null</code>). 054 */ 055 private static ScalarParam newInstance(CharSequence name) { 056 ScalarParam o = FACTORY.object(); 057 try { 058 o.setName(name); 059 } catch (NullPointerException e) { 060 FACTORY.recycle(o); 061 throw e; 062 } 063 return o; 064 } 065 066 private static <Q extends Quantity> ScalarParam<Q> copyOf(ScalarParam<Q> original) { 067 ScalarParam<Q> measure = FACTORY.object(); 068 measure._param = original._param.copy(); 069 measure._unit = original._unit; 070 return measure; 071 } 072 073 private static final ObjectFactory<ScalarParam> FACTORY = new ObjectFactory<ScalarParam>() { 074 @Override 075 protected ScalarParam create() { 076 return new ScalarParam(); 077 } 078 079 @Override 080 protected void cleanup(ScalarParam obj) { 081 obj.reset(); 082 } 083 }; 084 085 /** 086 * Resets the internal state of this object to its default values. 087 */ 088 @Override 089 protected void reset() { 090 super.reset(); 091 _param = null; 092 } 093 094 /** 095 * Returns a copy of this parameter 096 * {@link javolution.context.AllocatorContext allocated} by the calling thread 097 * (possibly on the stack). 098 * 099 * @return an identical and independent copy of this parameter. 100 */ 101 @Override 102 public ScalarParam<Q> copy() { 103 return copyOf(this); 104 } 105 106 /** 107 * Recycles a parameter instance immediately (on the stack when executing in a 108 * StackContext). 109 * 110 * @param instance The instance to be recycled immediately. 111 */ 112 public static void recycle(ScalarParam instance) { 113 FACTORY.recycle(instance); 114 } 115 116 /** 117 * Do not allow the default constructor to be used. 118 */ 119 private ScalarParam() { 120 } 121 122 /** 123 * Returns a scalar with the specified name, value and units. 124 * 125 * @param <Q> The unit quantity type for this parameter. 126 * @param name The name of the parameter (may not be null). 127 * @param value The value to assign to this scalar in the specified units. 128 * @param unit The units for this scalar (may not be null). 129 * @return A new scalar with the specified value and units. 130 */ 131 public static <Q extends Quantity> ScalarParam<Q> valueOf(CharSequence name, double value, Unit<Q> unit) { 132 133 ScalarParam<Q> param = ScalarParam.newInstance(requireNonNull(name)); 134 param._unit = requireNonNull(unit); 135 param._param = Parameter.valueOf(value, unit); 136 137 return param; 138 } 139 140 /** 141 * Returns the parameter equivalent to this parameter but stated in the specified 142 * unit. 143 * 144 * @param unit The unit of the parameter to be returned (may not be null). 145 * @return A parameter equivalent to this parameter but stated in the specified unit. 146 * @throws ConversionException if the current model does not allows for conversion to 147 * the specified unit. 148 */ 149 @Override 150 public ScalarParam<Q> to(Unit<Q> unit) throws ConversionException { 151 if (Objects.equals(_unit, requireNonNull(unit))) 152 return this; 153 ScalarParam<Q> result = ScalarParam.newInstance(getName()); 154 result._unit = unit; 155 result._param = _param.to(unit); 156 return result; 157 } 158 159 /** 160 * Returns the parameter that has the same values as this parameter but with the units 161 * changed (<em>without</em> converting the values). 162 * 163 * @param unit The unit of the parameter to be returned (may not be null). 164 * @return a parameter equivalent to this parameter but stated in the specified unit. 165 * @throws ConversionException if the current model does not allows for conversion to 166 * the specified unit. 167 */ 168 @Override 169 public <R extends Quantity> ScalarParam<R> changeTo(Unit<R> unit) throws ConversionException { 170 requireNonNull(unit, MessageFormat.format(RESOURCES.getString("paramNullErr"),"unit")); 171 if (Objects.equals(_unit, unit)) 172 return (ScalarParam<R>)this; 173 ScalarParam<R> result = (ScalarParam<R>)FACTORY.object(); 174 result._unit = unit; 175 result._param = Parameter.valueOf(getValue(), unit); 176 return result; 177 } 178 179 /** 180 * Return the value of this parameter in reference SI units. 181 * 182 * @return The value of this parameter in reference SI units. 183 */ 184 public double getValueSI() { 185 Unit<Q> SIUnit = (Unit<Q>)getUnit().getStandardUnit(); 186 return _param.getValue(SIUnit); 187 } 188 189 /** 190 * Returns the value for this parameter stated in this parameter's 191 * {@link #getUnit unit}. 192 * 193 * @return the value of the parameter. 194 */ 195 public double getValue() { 196 return _param.getValue(); 197 } 198 199 /** 200 * Compares the specified object with this parameter for strict equality same value, 201 * same units, same name, same user data. 202 * 203 * @param obj the object to compare with. 204 * @return <code>true</code> if this parameter is identical to that parameter; 205 * <code>false</code> otherwise. 206 */ 207 @Override 208 public boolean equals(Object obj) { 209 if (this == obj) 210 return true; 211 if ((obj == null) || (obj.getClass() != this.getClass())) 212 return false; 213 214 ScalarParam that = (ScalarParam)obj; 215 if (!this._param.equals(that._param)) 216 return false; 217 218 return super.equals(obj); 219 } 220 221 /** 222 * Returns the hash code for this <code>UnitParameter</code>. 223 * 224 * @return the hash code value. 225 */ 226 @Override 227 public int hashCode() { 228 int hash = super.hashCode(); 229 230 hash = hash * 31 + _param.hashCode(); 231 232 return hash; 233 } 234 235 /** 236 * Create a Text representation of this parameter which consists of the parameter's 237 * name, value and unit. 238 * 239 * @return The Text representation of this parameter. 240 */ 241 @Override 242 public Text toText() { 243 return _param.toText(); 244 } 245 246 /** 247 * Create a String representation of this parameter which consists of the parameter's 248 * name + value + units. 249 * 250 * @return A String representation of this parameter. 251 */ 252 @Override 253 public String toString() { 254 return toText().toString(); 255 } 256}