blob: b4a9ddf1770332b373acc3dcab4c8b5e4dd03696 [file] [log] [blame]
/**
*
* Copyright (c) 2011, 2016 - Loetz GmbH&Co.KG (69115 Heidelberg, Germany)
*
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License 2.0
* which accompanies this distribution, and is available at
* https://www.eclipse.org/legal/epl-2.0/
*
* SPDX-License-Identifier: EPL-2.0
*
* Contributors:
* Florian Pirchner - Initial implementation
*
*/
package org.eclipse.osbp.ecview.extension.presentation.vaadin.converter;
import java.text.DecimalFormat;
import java.text.DecimalFormatSymbols;
import java.text.NumberFormat;
import java.text.ParseException;
import java.util.Locale;
import java.util.Map.Entry;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import org.eclipse.emf.common.util.BasicEMap;
import org.eclipse.emf.common.util.EMap;
import org.eclipse.osbp.ecview.core.common.services.IServiceRegistry;
import org.eclipse.osbp.ecview.extension.model.converter.YCustomDecimalConverter;
import org.eclipse.osbp.ecview.extension.vaadin.components.utils.FunctionWrapper;
import org.eclipse.osbp.runtime.web.vaadin.components.converter.DecimalConverter;
import org.eclipse.osbp.ui.api.functionlibrary.IFunctionLibraryService;
import org.eclipse.osbp.utils.functionnormalizer.api.FunctionTypingAPI;
import org.eclipse.osbp.xtext.functionlibrary.common.uomo.DimensionlessUnit;
import org.eclipse.uomo.units.impl.BaseAmount;
import org.eclipse.uomo.units.impl.format.LocalUnitFormatImpl;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.unitsofmeasurement.quantity.Dimensionless;
/**
* The Class CustomDecimalConverter.
*/
@SuppressWarnings("serial")
public class CustomDecimalConverter extends DecimalConverter {
/** The Constant LOGGER. */
private static final Logger LOGGER = LoggerFactory
.getLogger(CustomDecimalConverter.class);
/** The registry. */
private IServiceRegistry registry;
/** The y converter. */
private transient YCustomDecimalConverter yConverter;
/** The converted decimal format. */
private DecimalFormat convertedDecimalFormat;
/** The default decimal format. */
private final DecimalFormat defaultDecimalFormat = new DecimalFormat();
/**
* Instantiates a new custom decimal converter.
*
* @param registry
* the registry
* @param yConverter
* the y converter
*/
public CustomDecimalConverter(IServiceRegistry registry,
YCustomDecimalConverter yConverter) {
this.registry = registry;
this.yConverter = yConverter;
}
/**
* Instantiates a new custom decimal converter.
*/
public CustomDecimalConverter() {
}
/* (non-Javadoc)
* @see com.vaadin.data.util.converter.AbstractStringToNumberConverter#convertToPresentation(java.lang.Object, java.lang.Class, java.util.Locale)
*/
@Override
public String convertToPresentation(Double value,
Class<? extends String> targetType, Locale locale)
throws ConversionException { // NOSONAR
if (value == null) {
return null;
}
FunctionTypingAPI functionTypingAPI = new FunctionTypingAPI();
for (Entry<String, String> entry : getProperties()) {
if (functionTypingAPI.getFunctionConverterTypeName()
.equalsIgnoreCase(entry.getKey())) {
return handleToPresentationFormat(entry.getValue()+".valueToPresentationConverter", value,
locale, yConverter.getBaseUnit());
}
}
return getToPresentationFormat(locale).format(value);
}
/* (non-Javadoc)
* @see com.vaadin.data.util.converter.StringToDoubleConverter#convertToModel(java.lang.String, java.lang.Class, java.util.Locale)
*/
@Override
public Double convertToModel(String value,
Class<? extends Double> targetType, Locale locale)
throws ConversionException { // NOSONAR
Number n = null;
String suffix = "";
if (value != null){
try {
FunctionTypingAPI functionTypingAPI = new FunctionTypingAPI();
if (locale != null){
DecimalFormatSymbols newSymbols = new DecimalFormatSymbols(locale);
defaultDecimalFormat.setDecimalFormatSymbols(newSymbols);
}
MeasurementValue measure = splitValue(value);
if(measure != null) {
n = defaultDecimalFormat.parse(measure.getValue());
suffix = measure.getUnit();
} else {
n = 0;
}
for (Entry<String, String> entry : getProperties()) {
if (functionTypingAPI.getFunctionConverterTypeName()
.equalsIgnoreCase(entry.getKey())) {
n = handleToModelFormat(entry.getValue()+".valueToModelConverter", n.doubleValue(),
locale, yConverter.getBaseUnit(), suffix);
}
}
} catch (ParseException e) {
return null;
}
}
return n == null ? null : n.doubleValue();
}
/**
* Gets the properties.
*
* @return the properties
*/
public EMap<String, String> getProperties() {
if (yConverter != null) {
return yConverter.getProperties();
}
return new BasicEMap<>();
}
/**
* Gets the to presentation format.
*
* @param locale
* the locale
* @return the to presentation format
*/
// @Override
protected NumberFormat getToPresentationFormat(Locale locale) {
if (convertedDecimalFormat != null) {
return convertedDecimalFormat;
} else {
return super.getFormat(locale);
}
}
/**
* Handle to presentation format.
*
* @param functionFqn
* the function fqn
* @param value
* the value
* @param locale
* the locale
* @param baseUnit
* the base unit
* @return the string
*/
// Helper Methods
private String handleToPresentationFormat(String functionFqn, Double value,
Locale locale, String baseUnit) {
FunctionWrapper wrapper = new FunctionWrapper(functionFqn);
try {
if (locale != null) {
IFunctionLibraryService service = registry
.getService(IFunctionLibraryService.class.getName());
if (service == null) {
LOGGER.error("No IFunctionLibraryService available");
return getAmountOutput(new BaseAmount<Dimensionless>(value, DimensionlessUnit.NOSYMBOL), locale);
}
BaseAmount<?> callResult = (BaseAmount<?>) service
.invoke(wrapper.getClassName(),
wrapper.getMethodName(), value, locale,
baseUnit);
if (callResult!=null){
return getAmountOutput(callResult, locale);
} else {
LOGGER.error("The called converter function call {} is not defined. Please define the required function in your Functionlibrary DSL instance!", functionFqn);
}
}
} catch (ClassCastException ex) {
LOGGER.error("Return type of the function call {} is not a {}", functionFqn, BaseAmount.class.getSimpleName());
}
return getAmountOutput(new BaseAmount<Dimensionless>(value, DimensionlessUnit.NOSYMBOL), locale);
}
/**
* Gets the amount output.
*
* @param amount
* the amount
* @param locale
* the locale
* @return the amount output
*/
private String getAmountOutput(BaseAmount<?> amount, Locale locale) {
LocalUnitFormatImpl localUnitFormat = LocalUnitFormatImpl.getInstance();
if (locale!=null){
localUnitFormat = LocalUnitFormatImpl.getInstance(locale);
}
// as you can't use icu for compatibilty reasons, this functions are used - instead of getUnit()
String convertedUnit = localUnitFormat.format(amount.unit());
// as you can't use icu for compatibilty reasons, this functions are used - instead of getNumber()
String convertedNumber = getToPresentationFormat(locale).format(amount.value());
StringBuilder strBuf = new StringBuilder(convertedNumber).append(" ").append(convertedUnit);
return strBuf.toString();
}
/**
* Handle to model format.
*
* @param functionFqn
* the function fqn
* @param value
* the value
* @param locale
* the locale
* @param baseSuffix
* the base suffix
* @param suffix
* the suffix
* @return the double
*/
private Double handleToModelFormat(String functionFqn, Double value,
Locale locale, String baseSuffix, String suffix) {
FunctionWrapper wrapper = new FunctionWrapper(functionFqn);
try {
if (locale != null) {
IFunctionLibraryService service = registry
.getService(IFunctionLibraryService.class.getName());
if (service == null) {
LOGGER.error("No IFunctionLibraryService available");
return value;
}
return (Double) service.invoke(wrapper.getClassName(), wrapper.getMethodName(), value,locale, baseSuffix, suffix);
}
} catch (ClassCastException ex) {
LOGGER.error("Return type of the function call '" + functionFqn
+ "' is not a " + Double.class.getSimpleName() + "!");
}
return value;
}
/**
* Split value.
*
* @param value
* the value
* @return the measurement value
*/
private MeasurementValue splitValue(String value){
Pattern p = Pattern.compile("\\d+([.,]\\d+)?");
char groupSeparator = defaultDecimalFormat.getDecimalFormatSymbols().getGroupingSeparator();
String newValue = value.replace(String.valueOf(groupSeparator), "");
Matcher m = p.matcher(newValue);
if (m.find()) {
String unit = newValue.replace(newValue.substring(m.start(), m.end()),"").trim();
return new MeasurementValue(m.group(), unit);
}
return null;
}
/**
* Sets the converted decimal format.
*
* @param decimalFormat
* the new converted decimal format
*/
public void setConvertedDecimalFormat(DecimalFormat decimalFormat) {
this.convertedDecimalFormat = decimalFormat;
}
/**
* The Class MeasurementValue.
*/
// Helper Inner Class
class MeasurementValue {
/** The value. */
String value;
/** The unit. */
String unit;
/**
* Instantiates a new measurement value.
*
* @param value
* the value
* @param unit
* the unit
*/
public MeasurementValue(String value, String unit) {
super();
this.value = value;
this.unit = unit;
}
/**
* Gets the value.
*
* @return the value
*/
public String getValue() {
return value;
}
/**
* Sets the value.
*
* @param value
* the new value
*/
public void setValue(String value) {
this.value = value;
}
/**
* Gets the unit.
*
* @return the unit
*/
public String getUnit() {
return unit;
}
/**
* Sets the unit.
*
* @param unit
* the new unit
*/
public void setUnit(String unit) {
this.unit = unit;
}
}
}