| /** |
| * |
| * 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; |
| } |
| } |
| |
| } |