/* * GeoTools - The Open Source Java GIS Toolkit * http://geotools.org * * (C) 2014 - 2015, Open Source Geospatial Foundation (OSGeo) * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; * version 2.1 of the License. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. */ package org.geotools.util; import java.text.DecimalFormat; import java.text.NumberFormat; import java.util.Locale; import java.util.regex.Matcher; import java.util.regex.Pattern; import javax.measure.unit.Unit; import org.geotools.factory.Hints; import org.geotools.measure.Measure; /** * ConverterFactory which converts between the {@link Measure} and String. * * @author Andrea Aime - GeoSolutions * @since 12.0 */ public class MeasureConverterFactory implements ConverterFactory { static final Pattern MEASURE_PATTERN = Pattern .compile("\\s*([-\\+]?[0-9]*\\.?[0-9]*(?:[eE][-\\+]?[0-9]+)?)(.*)?"); public static final Converter CONVERTER = new Converter() { @Override public <T> T convert(Object source, Class<T> target) throws Exception { if (source == null) { return null; } else if (String.class.equals(target)) { Measure m = (Measure) source; DecimalFormat format = (DecimalFormat) NumberFormat .getNumberInstance(Locale.ENGLISH); if (m.doubleValue() < 1e-5) { format.applyPattern("0.###E0"); } else { format.applyPattern("#0.##"); } String v = format.format(m.doubleValue()); if (m.getUnit() != null) { return (T) (v + m.getUnit()); } else { return (T) v; } } if (!Measure.class.isAssignableFrom(target) || source == null) { return null; } String str = (String) source; if (str.trim().isEmpty()) { return null; } Matcher matcher = MEASURE_PATTERN.matcher(str); if (matcher.matches()) { double value = Double.parseDouble(matcher.group(1)); Unit unit = null; if (matcher.groupCount() == 2) { // this will throw an exception in case of failure String group = matcher.group(2).trim(); if (!group.isEmpty()) { unit = Unit.valueOf(group); } } return (T) new Measure(value, unit); } else { throw new IllegalArgumentException("Invalid measure " + str); } } }; public Converter createConverter(Class source, Class target, Hints hints) { if (CharSequence.class.isAssignableFrom(source) && Measure.class.isAssignableFrom(target)) { return CONVERTER; } else if (String.class.isAssignableFrom(target) && Measure.class.isAssignableFrom(source)) { return CONVERTER; } // not a case we can handle return null; } }