blob: 76524fd3e9ba0fdac975c5056edda656dccc420f [file] [log] [blame]
/*
* Copyright (c) 2005, 2017, Werner Keil and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Werner Keil and others - initial API and implementation
*/
package org.eclipse.uomo.units.impl;
import org.eclipse.uomo.units.AbstractConverter;
import org.eclipse.uomo.units.AbstractUnit;
import javax.measure.Quantity;
import java.util.Map;
import javax.measure.Dimension;
import javax.measure.Unit;
import javax.measure.UnitConverter;
/**
* <p> This class represents metric units used in expressions to distinguish
* between quantities of a different nature but of the same dimensions.
* Alternate units are always unscaled metric units.</p>
*
* <p> Instances of this class are created through the
* {@link AbstractUnit#alternate(String)} method.</p>
*
* @param <Q> The type of the quantity measured by this unit.
*
* @author <a href="mailto:jean-marie@dautelle.com">Jean-Marie Dautelle</a>
* @version 1.2, $Date: 2017-12-21 $
*/
public final class AlternateUnit<Q extends Quantity<Q>> extends AbstractUnit<Q> {
/** The serialVersionUID */
private static final long serialVersionUID = -1234567854321234567L;
/**
* Holds the parent unit (a system unit).
*/
private final Unit<?> parent;
/**
* Holds the parent unit (a system unit).
*/
private final String symbol;
/**
* Creates an alternate unit for the specified unit identified by the
* specified name and symbol.
*
* @param symbol the symbol for this alternate unit.
* @param parent the system unit from which this alternate unit is
* derived.
* @throws UnsupportedOperationException if the parent is not
* an unscaled metric unit.
* @throws IllegalArgumentException if the specified symbol is
* associated to a different unit.
*/
@SuppressWarnings("rawtypes")
public AlternateUnit(Unit<?> parent, String symbol) {
this((AbstractUnit)parent, symbol);
}
/**
* Creates an alternate unit for the specified unit identified by the
* specified name and symbol.
*
* @param symbol the symbol for this alternate unit.
* @param parent the system unit from which this alternate unit is
* derived.
* @throws UnsupportedOperationException if the parent is not
* an unscaled metric unit.
* @throws IllegalArgumentException if the specified symbol is
* associated to a different unit.
*/
public AlternateUnit(AbstractUnit<?> parent, String symbol) {
if (parent == null || !parent.isUnscaledMetric())
throw new UnsupportedOperationException(parent + " is not an unscaled metric unit");
this.parent = parent;
this.symbol = symbol;
// Checks if the symbol is associated to a different unit.
synchronized (AbstractUnit.SYMBOL_TO_UNIT) {
AbstractUnit<?> unit = (AbstractUnit<?>) AbstractUnit.SYMBOL_TO_UNIT.get(symbol);
if (unit == null) {
AbstractUnit.SYMBOL_TO_UNIT.put(symbol, this);
return;
}
if (unit instanceof AlternateUnit<?>) {
AlternateUnit<?> existingUnit = (AlternateUnit<?>) unit;
if (symbol.equals(existingUnit.getSymbol()) && this.parent.equals(existingUnit.parent))
return; // OK, same unit.
}
throw new IllegalArgumentException("Symbol " + symbol + " is associated to a different unit");
}
}
@Override
public String getSymbol() {
return symbol;
}
@Override
public Unit<Q> getSystemUnit() {
return toMetric();
}
@Override
protected final AbstractUnit<Q> toMetric() {
return this;
}
@Override
public final UnitConverter getConverterToMetric() {
return AbstractConverter.IDENTITY;
}
@Override
public boolean equals(Object that) {
if (this == that)
return true;
if (!(that instanceof AlternateUnit<?>))
return false;
AlternateUnit<?> thatUnit = (AlternateUnit<?>) that;
return this.symbol.equals(thatUnit.symbol); // Symbols are unique.
}
@Override
public Dimension getDimension() {
return parent.getDimension();
}
@SuppressWarnings("rawtypes")
@Override
public UnitConverter getDimensionalTransform() {
return ((AbstractUnit)parent).getDimensionalTransform();
}
@Override
public Map<? extends Unit<?>, Integer> getBaseUnits() {
return parent.getBaseUnits();
}
@Override
public int hashCode() {
return symbol.hashCode();
}
}