diff options
author | Artur Signell <artur@vaadin.com> | 2016-08-26 09:55:30 +0300 |
---|---|---|
committer | Artur Signell <artur@vaadin.com> | 2016-08-26 17:25:47 +0000 |
commit | 73e30628a518a51f9fceedcfa4a03ef5eeefbcf6 (patch) | |
tree | d6c2c69c66fcfec4a15e1e39a0a5ec9e33e4589d /compatibility-server | |
parent | d13ca5506a2f7eb3dce75b98238bdb280ec7fa20 (diff) | |
download | vaadin-framework-73e30628a518a51f9fceedcfa4a03ef5eeefbcf6.tar.gz vaadin-framework-73e30628a518a51f9fceedcfa4a03ef5eeefbcf6.zip |
Move old converters and DefaultConverterFactory to compatibility package
Change-Id: I42b933d1cb46cccb4a00211ee6eab699723b8804
Diffstat (limited to 'compatibility-server')
18 files changed, 2107 insertions, 0 deletions
diff --git a/compatibility-server/src/main/java/com/vaadin/v7/data/util/converter/AbstractStringToNumberConverter.java b/compatibility-server/src/main/java/com/vaadin/v7/data/util/converter/AbstractStringToNumberConverter.java new file mode 100644 index 0000000000..bd9392ee01 --- /dev/null +++ b/compatibility-server/src/main/java/com/vaadin/v7/data/util/converter/AbstractStringToNumberConverter.java @@ -0,0 +1,123 @@ +/* + * Copyright 2000-2016 Vaadin Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + */ + +package com.vaadin.v7.data.util.converter; + +import java.text.NumberFormat; +import java.text.ParsePosition; +import java.util.Locale; + +/** + * A converter that converts from the number type T to {@link String} and back. + * Uses the given locale and {@link NumberFormat} for formatting and parsing. + * Automatically trims the input string, removing any leading and trailing white + * space. + * <p> + * Override and overwrite {@link #getFormat(Locale)} to use a different format. + * </p> + * + * @author Vaadin Ltd + * @since 7.1 + */ +public abstract class AbstractStringToNumberConverter<T> + implements Converter<String, T> { + + /** + * Returns the format used by {@link #convertToPresentation(Object, Locale)} + * and {@link #convertToModel(Object, Locale)}. + * + * @param locale + * The locale to use + * @return A NumberFormat instance + * @since 7.1 + */ + protected NumberFormat getFormat(Locale locale) { + if (locale == null) { + locale = Locale.getDefault(); + } + + return NumberFormat.getNumberInstance(locale); + } + + /** + * Convert the value to a Number using the given locale and + * {@link #getFormat(Locale)}. + * + * @param value + * The value to convert + * @param locale + * The locale to use for conversion + * @return The converted value + * @throws ConversionException + * If there was a problem converting the value + * @since 7.1 + */ + protected Number convertToNumber(String value, + Class<? extends Number> targetType, Locale locale) + throws ConversionException { + if (value == null) { + return null; + } + + // Remove leading and trailing white space + value = value.trim(); + + // Parse and detect errors. If the full string was not used, it is + // an error. + ParsePosition parsePosition = new ParsePosition(0); + Number parsedValue = getFormat(locale).parse(value, parsePosition); + if (parsePosition.getIndex() != value.length()) { + throw new ConversionException("Could not convert '" + value + + "' to " + getModelType().getName()); + } + + if (parsedValue == null) { + // Convert "" to null + return null; + } + + return parsedValue; + } + + /* + * (non-Javadoc) + * + * @see + * com.vaadin.data.util.converter.Converter#convertToPresentation(java.lang + * .Object, java.util.Locale) + */ + @Override + public String convertToPresentation(T value, + Class<? extends String> targetType, Locale locale) + throws ConversionException { + if (value == null) { + return null; + } + + return getFormat(locale).format(value); + } + + /* + * (non-Javadoc) + * + * @see com.vaadin.data.util.converter.Converter#getPresentationType() + */ + @Override + public Class<String> getPresentationType() { + return String.class; + } + +} diff --git a/compatibility-server/src/main/java/com/vaadin/v7/data/util/converter/ConverterUtil.java b/compatibility-server/src/main/java/com/vaadin/v7/data/util/converter/ConverterUtil.java new file mode 100644 index 0000000000..b0679e9caf --- /dev/null +++ b/compatibility-server/src/main/java/com/vaadin/v7/data/util/converter/ConverterUtil.java @@ -0,0 +1,260 @@ +/* + * Copyright 2000-2016 Vaadin Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + */ +package com.vaadin.v7.data.util.converter; + +import java.io.Serializable; +import java.util.Locale; + +import com.vaadin.server.VaadinSession; + +public class ConverterUtil implements Serializable { + + /** + * Finds a converter that can convert from the given presentation type to + * the given model type and back. Uses the given application to find a + * {@link ConverterFactory} or, if application is null, uses the + * {@link VaadinSession#getCurrent()}. + * + * @param <PRESENTATIONTYPE> + * the presentation type + * @param <MODELTYPE> + * the model type + * @param presentationType + * the presentation type + * @param modelType + * the model type + * @param session + * the session to use to find a ConverterFactory or null to use + * the current session + * @return a Converter capable of converting between the given types or null + * if no converter was found + */ + public static <PRESENTATIONTYPE, MODELTYPE> Converter<PRESENTATIONTYPE, MODELTYPE> getConverter( + Class<PRESENTATIONTYPE> presentationType, + Class<MODELTYPE> modelType, VaadinSession session) { + Converter<PRESENTATIONTYPE, MODELTYPE> converter = null; + if (session == null) { + session = VaadinSession.getCurrent(); + } + + if (session != null) { + ConverterFactory factory = session.getConverterFactory(); + converter = factory.createConverter(presentationType, modelType); + } + return converter; + + } + + /** + * Convert the given value from the data source type to the UI type. + * + * @param modelValue + * the model value to convert + * @param presentationType + * the type of the presentation value + * @param converter + * the converter to use + * @param locale + * the locale to use for conversion + * @param <PRESENTATIONTYPE> + * the presentation type + * @param <MODELTYPE> + * the model type + * + * @return the converted value, compatible with the presentation type, or + * the original value if its type is compatible and no converter is + * set. + * @throws Converter.ConversionException + * if there was a problem converting the value + */ + @SuppressWarnings("unchecked") + public static <PRESENTATIONTYPE, MODELTYPE> PRESENTATIONTYPE convertFromModel( + MODELTYPE modelValue, + Class<? extends PRESENTATIONTYPE> presentationType, + Converter<PRESENTATIONTYPE, MODELTYPE> converter, + Locale locale) throws Converter.ConversionException { + if (converter != null) { + /* + * If there is a converter, always use it. It must convert or throw + * an exception. + */ + PRESENTATIONTYPE presentation = converter.convertToPresentation( + modelValue, presentationType, locale); + if (presentation != null + && !presentationType.isInstance(presentation)) { + throw new Converter.ConversionException( + "Converter returned an object of type " + + presentation.getClass().getName() + + " when expecting " + + presentationType.getName()); + } + + return presentation; + } + if (modelValue == null) { + // Null should always be passed through the converter but if there + // is no converter we can safely return null + return null; + } + + if (presentationType.isAssignableFrom(modelValue.getClass())) { + return (PRESENTATIONTYPE) modelValue; + } else { + throw new Converter.ConversionException( + "Unable to convert value of type " + + modelValue.getClass().getName() + + " to presentation type " + presentationType + + ". No converter is set and the types are not compatible."); + } + } + + /** + * Convert the given value from the presentation (UI) type to model (data + * source) type. + * + * @param presentationValue + * the presentation value to convert + * @param modelType + * the type of the model + * @param converter + * the converter to use + * @param locale + * the locale to use for conversion + * @param <PRESENTATIONTYPE> + * the presentation type + * @param <MODELTYPE> + * the model type + * + * @return the converted value, compatible with the model type, or the + * original value if its type is compatible and no converter is set. + * @throws Converter.ConversionException + * if there was a problem converting the value + */ + public static <MODELTYPE, PRESENTATIONTYPE> MODELTYPE convertToModel( + PRESENTATIONTYPE presentationValue, Class<MODELTYPE> modelType, + Converter<PRESENTATIONTYPE, MODELTYPE> converter, + Locale locale) throws Converter.ConversionException { + if (converter != null) { + /* + * If there is a converter, always use it. It must convert or throw + * an exception. + */ + MODELTYPE model = converter.convertToModel(presentationValue, + modelType, locale); + if (model != null && !modelType.isInstance(model)) { + throw new Converter.ConversionException( + "Converter returned an object of type " + + model.getClass().getName() + + " when expecting " + modelType.getName()); + } + + return model; + } + + if (presentationValue == null) { + // Null should always be passed through the converter but if there + // is no converter we can safely return null + return null; + } + + if (modelType == null) { + // No model type, return original value + return (MODELTYPE) presentationValue; + } else if (modelType.isAssignableFrom(presentationValue.getClass())) { + // presentation type directly compatible with model type + return modelType.cast(presentationValue); + } else { + throw new Converter.ConversionException( + "Unable to convert value of type " + + presentationValue.getClass().getName() + + " to model type " + modelType + + ". No converter is set and the types are not compatible."); + } + + } + + /** + * Checks if the given converter can handle conversion between the given + * presentation and model type. Does strict type checking and only returns + * true if the converter claims it can handle exactly the given types. + * + * @see #canConverterPossiblyHandle(Converter, Class, Class) + * + * @param converter + * The converter to check. If this is null the result is always + * false. + * @param presentationType + * The presentation type + * @param modelType + * The model type + * @return true if the converter supports conversion between the given + * presentation and model type, false otherwise + */ + public static boolean canConverterHandle(Converter<?, ?> converter, + Class<?> presentationType, Class<?> modelType) { + if (converter == null) { + return false; + } + + if (modelType != converter.getModelType()) { + return false; + } + if (presentationType != converter.getPresentationType()) { + return false; + } + + return true; + } + + /** + * Checks if it possible that the given converter can handle conversion + * between the given presentation and model type somehow. + * + * @param converter + * The converter to check. If this is null the result is always + * false. + * @param presentationType + * The presentation type + * @param modelType + * The model type + * @return true if the converter possibly support conversion between the + * given presentation and model type, false otherwise + */ + public static boolean canConverterPossiblyHandle( + Converter<?, ?> converter, Class<?> presentationType, + Class<?> modelType) { + if (converter == null) { + return false; + } + Class<?> converterModelType = converter.getModelType(); + + if (!modelType.isAssignableFrom(converterModelType) + && !converterModelType.isAssignableFrom(modelType)) { + // model types are not compatible in any way + return false; + } + + Class<?> converterPresentationType = converter.getPresentationType(); + if (!presentationType.isAssignableFrom(converterPresentationType) + && !converterPresentationType + .isAssignableFrom(presentationType)) { + // presentation types are not compatible in any way + return false; + } + + return true; + } +} diff --git a/compatibility-server/src/main/java/com/vaadin/v7/data/util/converter/DateToLongConverter.java b/compatibility-server/src/main/java/com/vaadin/v7/data/util/converter/DateToLongConverter.java new file mode 100644 index 0000000000..467b848988 --- /dev/null +++ b/compatibility-server/src/main/java/com/vaadin/v7/data/util/converter/DateToLongConverter.java @@ -0,0 +1,89 @@ +/* + * Copyright 2000-2016 Vaadin Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + */ + +package com.vaadin.v7.data.util.converter; + +import java.util.Date; +import java.util.Locale; + +/** + * A converter that converts from {@link Long} to {@link Date} and back. + * + * @author Vaadin Ltd + * @since 7.0 + */ +public class DateToLongConverter implements Converter<Date, Long> { + + /* + * (non-Javadoc) + * + * @see + * com.vaadin.data.util.converter.Converter#convertToModel(java.lang.Object, + * java.lang.Class, java.util.Locale) + */ + @Override + public Long convertToModel(Date value, Class<? extends Long> targetType, + Locale locale) { + if (value == null) { + return null; + } + + return value.getTime(); + } + + /* + * (non-Javadoc) + * + * @see + * com.vaadin.data.util.converter.Converter#convertToPresentation(java.lang + * .Object, java.lang.Class, java.util.Locale) + */ + @Override + public Date convertToPresentation(Long value, + Class<? extends Date> targetType, Locale locale) { + if (targetType != getPresentationType()) { + throw new ConversionException( + "Converter only supports " + getPresentationType().getName() + + " (targetType was " + targetType.getName() + ")"); + } + if (value == null) { + return null; + } + + return new Date(value); + } + + /* + * (non-Javadoc) + * + * @see com.vaadin.data.util.converter.Converter#getModelType() + */ + @Override + public Class<Long> getModelType() { + return Long.class; + } + + /* + * (non-Javadoc) + * + * @see com.vaadin.data.util.converter.Converter#getPresentationType() + */ + @Override + public Class<Date> getPresentationType() { + return Date.class; + } + +} diff --git a/compatibility-server/src/main/java/com/vaadin/v7/data/util/converter/DateToSqlDateConverter.java b/compatibility-server/src/main/java/com/vaadin/v7/data/util/converter/DateToSqlDateConverter.java new file mode 100644 index 0000000000..c789e7d1e8 --- /dev/null +++ b/compatibility-server/src/main/java/com/vaadin/v7/data/util/converter/DateToSqlDateConverter.java @@ -0,0 +1,82 @@ +/* + * Copyright 2000-2016 Vaadin Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + */ + +/** + * + */ +package com.vaadin.v7.data.util.converter; + +import java.util.Date; +import java.util.Locale; + +/** + * Converter for handling conversion between {@link java.util.Date} and + * {@link java.sql.Date}. This is used when a PopupDateField or InlineDateField + * is connected to a java.sql.Date property, typically through a JPAContainer or + * SQLContainer. Note that information (time information) is lost when + * converting from {@link java.util.Date} to {@link java.sql.Date}. + * + * @since 7.1 + * @author Vaadin Ltd + */ +public class DateToSqlDateConverter + implements Converter<Date, java.sql.Date> { + + @Override + public java.sql.Date convertToModel(Date value, + Class<? extends java.sql.Date> targetType, Locale locale) + throws ConversionException { + if (targetType != getModelType()) { + throw new ConversionException( + "Converter only supports " + getModelType().getName() + + " (targetType was " + targetType.getName() + ")"); + } + + if (value == null) { + return null; + } + + return new java.sql.Date(value.getTime()); + } + + @Override + public Date convertToPresentation(java.sql.Date value, + Class<? extends Date> targetType, Locale locale) + throws ConversionException { + if (targetType != getPresentationType()) { + throw new ConversionException( + "Converter only supports " + getPresentationType().getName() + + " (targetType was " + targetType.getName() + ")"); + } + + if (value == null) { + return null; + } + + return new Date(value.getTime()); + } + + @Override + public Class<java.sql.Date> getModelType() { + return java.sql.Date.class; + } + + @Override + public Class<Date> getPresentationType() { + return Date.class; + } + +} diff --git a/compatibility-server/src/main/java/com/vaadin/v7/data/util/converter/DefaultConverterFactory.java b/compatibility-server/src/main/java/com/vaadin/v7/data/util/converter/DefaultConverterFactory.java new file mode 100644 index 0000000000..681cbfc6b2 --- /dev/null +++ b/compatibility-server/src/main/java/com/vaadin/v7/data/util/converter/DefaultConverterFactory.java @@ -0,0 +1,133 @@ +/* + * Copyright 2000-2016 Vaadin Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + */ + +package com.vaadin.v7.data.util.converter; + +import java.math.BigDecimal; +import java.math.BigInteger; +import java.util.Date; +import java.util.logging.Logger; + +import com.vaadin.server.VaadinSession; + +/** + * Default implementation of {@link ConverterFactory}. Provides converters + * for standard types like {@link String}, {@link Double} and {@link Date}. + * </p> + * <p> + * Custom converters can be provided by extending this class and using + * {@link VaadinSession#setConverterFactory(ConverterFactory)}. + * </p> + * + * @author Vaadin Ltd + * @since 7.0 + */ +public class DefaultConverterFactory implements ConverterFactory { + + private final static Logger log = Logger + .getLogger(DefaultConverterFactory.class.getName()); + + @Override + public <PRESENTATION, MODEL> Converter<PRESENTATION, MODEL> createConverter( + Class<PRESENTATION> presentationType, Class<MODEL> modelType) { + Converter<PRESENTATION, MODEL> converter = findConverter( + presentationType, modelType); + if (converter != null) { + log.finest(getClass().getName() + " created a " + + converter.getClass()); + return converter; + } + + // Try to find a reverse converter + Converter<MODEL, PRESENTATION> reverseConverter = findConverter( + modelType, presentationType); + if (reverseConverter != null) { + log.finest(getClass().getName() + " created a reverse " + + reverseConverter.getClass()); + return new ReverseConverter<PRESENTATION, MODEL>( + reverseConverter); + } + + log.finest(getClass().getName() + " could not find a converter for " + + presentationType.getName() + " to " + modelType.getName() + + " conversion"); + return null; + + } + + protected <PRESENTATION, MODEL> Converter<PRESENTATION, MODEL> findConverter( + Class<PRESENTATION> presentationType, Class<MODEL> modelType) { + if (presentationType == String.class) { + // TextField converters and more + Converter<PRESENTATION, MODEL> converter = (Converter<PRESENTATION, MODEL>) createStringConverter( + modelType); + if (converter != null) { + return converter; + } + } else if (presentationType == Date.class) { + // DateField converters and more + Converter<PRESENTATION, MODEL> converter = (Converter<PRESENTATION, MODEL>) createDateConverter( + modelType); + if (converter != null) { + return converter; + } + } + + return null; + + } + + protected Converter<Date, ?> createDateConverter( + Class<?> sourceType) { + if (Long.class.isAssignableFrom(sourceType)) { + return new DateToLongConverter(); + } else if (java.sql.Date.class.isAssignableFrom(sourceType)) { + return new DateToSqlDateConverter(); + } else { + return null; + } + } + + protected Converter<String, ?> createStringConverter( + Class<?> sourceType) { + if (Double.class.isAssignableFrom(sourceType)) { + return new StringToDoubleConverter(); + } else if (Float.class.isAssignableFrom(sourceType)) { + return new StringToFloatConverter(); + } else if (Integer.class.isAssignableFrom(sourceType)) { + return new StringToIntegerConverter(); + } else if (Long.class.isAssignableFrom(sourceType)) { + return new StringToLongConverter(); + } else if (BigDecimal.class.isAssignableFrom(sourceType)) { + return new StringToBigDecimalConverter(); + } else if (Boolean.class.isAssignableFrom(sourceType)) { + return new StringToBooleanConverter(); + } else if (Date.class.isAssignableFrom(sourceType)) { + return new StringToDateConverter(); + } else if (Enum.class.isAssignableFrom(sourceType)) { + return new StringToEnumConverter(); + } else if (BigInteger.class.isAssignableFrom(sourceType)) { + return new StringToBigIntegerConverter(); + } else if (Short.class.isAssignableFrom(sourceType)) { + return new StringToShortConverter(); + } else if (Byte.class.isAssignableFrom(sourceType)) { + return new StringToByteConverter(); + } else { + return null; + } + } + +} diff --git a/compatibility-server/src/main/java/com/vaadin/v7/data/util/converter/ReverseConverter.java b/compatibility-server/src/main/java/com/vaadin/v7/data/util/converter/ReverseConverter.java new file mode 100644 index 0000000000..cbbf62ad6c --- /dev/null +++ b/compatibility-server/src/main/java/com/vaadin/v7/data/util/converter/ReverseConverter.java @@ -0,0 +1,97 @@ +/* + * Copyright 2000-2016 Vaadin Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + */ + +package com.vaadin.v7.data.util.converter; + +import java.util.Locale; + +/** + * A converter that wraps another {@link Converter} and reverses source + * and target types. + * + * @param <MODEL> + * The source type + * @param <PRESENTATION> + * The target type + * + * @author Vaadin Ltd + * @since 7.0 + */ +public class ReverseConverter<PRESENTATION, MODEL> + implements Converter<PRESENTATION, MODEL> { + + private Converter<MODEL, PRESENTATION> realConverter; + + /** + * Creates a converter from source to target based on a converter that + * converts from target to source. + * + * @param converter + * The converter to use in a reverse fashion + */ + public ReverseConverter( + Converter<MODEL, PRESENTATION> converter) { + this.realConverter = converter; + } + + /* + * (non-Javadoc) + * + * @see com.vaadin.data.util.converter.Converter#convertToModel(java + * .lang.Object, java.util.Locale) + */ + @Override + public MODEL convertToModel(PRESENTATION value, + Class<? extends MODEL> targetType, Locale locale) + throws com.vaadin.v7.data.util.converter.Converter.ConversionException { + return realConverter.convertToPresentation(value, targetType, locale); + } + + /* + * (non-Javadoc) + * + * @see + * com.vaadin.data.util.converter.Converter#convertToPresentation(java.lang + * .Object, java.util.Locale) + */ + @Override + public PRESENTATION convertToPresentation(MODEL value, + Class<? extends PRESENTATION> targetType, Locale locale) + throws com.vaadin.v7.data.util.converter.Converter.ConversionException { + return realConverter.convertToModel(value, targetType, locale); + } + + /* + * (non-Javadoc) + * + * @see com.vaadin.data.util.converter.Converter#getSourceType() + */ + @Override + public Class<MODEL> getModelType() { + return realConverter.getPresentationType(); + } + + /* + * (non-Javadoc) + * + * @see com.vaadin.data.util.converter.Converter#getTargetType() + */ + @Override + public Class<PRESENTATION> getPresentationType() { + return realConverter.getModelType(); + } + +} diff --git a/compatibility-server/src/main/java/com/vaadin/v7/data/util/converter/StringToBigDecimalConverter.java b/compatibility-server/src/main/java/com/vaadin/v7/data/util/converter/StringToBigDecimalConverter.java new file mode 100644 index 0000000000..ff8649b7d8 --- /dev/null +++ b/compatibility-server/src/main/java/com/vaadin/v7/data/util/converter/StringToBigDecimalConverter.java @@ -0,0 +1,60 @@ +/* + * Copyright 2000-2016 Vaadin Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + */ +package com.vaadin.v7.data.util.converter; + +import java.math.BigDecimal; +import java.text.DecimalFormat; +import java.text.NumberFormat; +import java.util.Locale; + +/** + * A converter that converts from {@link String} to {@link BigDecimal} and back. + * Uses the given locale and a {@link NumberFormat} instance for formatting and + * parsing. + * <p> + * Leading and trailing white spaces are ignored when converting from a String. + * </p> + * <p> + * Override and overwrite {@link #getFormat(Locale)} to use a different format. + * </p> + * + * @author Vaadin Ltd + * @since 7.2 + */ +public class StringToBigDecimalConverter + extends AbstractStringToNumberConverter<BigDecimal> { + @Override + protected NumberFormat getFormat(Locale locale) { + NumberFormat numberFormat = super.getFormat(locale); + if (numberFormat instanceof DecimalFormat) { + ((DecimalFormat) numberFormat).setParseBigDecimal(true); + } + + return numberFormat; + } + + @Override + public BigDecimal convertToModel(String value, + Class<? extends BigDecimal> targetType, Locale locale) + throws com.vaadin.v7.data.util.converter.Converter.ConversionException { + return (BigDecimal) convertToNumber(value, BigDecimal.class, locale); + } + + @Override + public Class<BigDecimal> getModelType() { + return BigDecimal.class; + } +} diff --git a/compatibility-server/src/main/java/com/vaadin/v7/data/util/converter/StringToBigIntegerConverter.java b/compatibility-server/src/main/java/com/vaadin/v7/data/util/converter/StringToBigIntegerConverter.java new file mode 100644 index 0000000000..d645fd35ad --- /dev/null +++ b/compatibility-server/src/main/java/com/vaadin/v7/data/util/converter/StringToBigIntegerConverter.java @@ -0,0 +1,67 @@ +/* + * Copyright 2000-2016 Vaadin Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + */ +package com.vaadin.v7.data.util.converter; + +import java.math.BigDecimal; +import java.math.BigInteger; +import java.text.DecimalFormat; +import java.text.NumberFormat; +import java.util.Locale; + +/** + * A converter that converts from {@link String} to {@link BigInteger} and back. + * Uses the given locale and a {@link NumberFormat} instance for formatting and + * parsing. + * <p> + * Leading and trailing white spaces are ignored when converting from a String. + * </p> + * <p> + * Override and overwrite {@link #getFormat(Locale)} to use a different format. + * </p> + * + * @author Vaadin Ltd + * @since 7.4 + */ +public class StringToBigIntegerConverter + extends AbstractStringToNumberConverter<BigInteger> { + + @Override + protected NumberFormat getFormat(Locale locale) { + NumberFormat numberFormat = super.getFormat(locale); + if (numberFormat instanceof DecimalFormat) { + ((DecimalFormat) numberFormat).setParseBigDecimal(true); + } + + return numberFormat; + } + + @Override + public BigInteger convertToModel(String value, + Class<? extends BigInteger> targetType, Locale locale) + throws com.vaadin.v7.data.util.converter.Converter.ConversionException { + + BigDecimal bigDecimalValue = (BigDecimal) convertToNumber(value, + BigDecimal.class, locale); + + return (bigDecimalValue != null) ? bigDecimalValue.toBigInteger() + : null; + } + + @Override + public Class<BigInteger> getModelType() { + return BigInteger.class; + } +} diff --git a/compatibility-server/src/main/java/com/vaadin/v7/data/util/converter/StringToBooleanConverter.java b/compatibility-server/src/main/java/com/vaadin/v7/data/util/converter/StringToBooleanConverter.java new file mode 100644 index 0000000000..c8ebea6e5b --- /dev/null +++ b/compatibility-server/src/main/java/com/vaadin/v7/data/util/converter/StringToBooleanConverter.java @@ -0,0 +1,182 @@ +/* + * Copyright 2000-2016 Vaadin Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + */ + +package com.vaadin.v7.data.util.converter; + +import java.util.Locale; + +/** + * A converter that converts from {@link String} to {@link Boolean} and back. + * The String representation is given by {@link Boolean#toString()} or provided + * in constructor {@link #StringToBooleanConverter(String, String)}. + * <p> + * Leading and trailing white spaces are ignored when converting from a String. + * </p> + * <p> + * For language-dependent representation, subclasses should overwrite + * {@link #getFalseString(Locale)} and {@link #getTrueString(Locale)} + * </p> + * + * @author Vaadin Ltd + * @since 7.0 + */ +public class StringToBooleanConverter + implements Converter<String, Boolean> { + + private final String trueString; + + private final String falseString; + + /** + * Creates converter with default string representations - "true" and + * "false" + * + */ + public StringToBooleanConverter() { + this(Boolean.TRUE.toString(), Boolean.FALSE.toString()); + } + + /** + * Creates converter with custom string representation. + * + * @since 7.5.4 + * @param falseString + * string representation for <code>false</code> + * @param trueString + * string representation for <code>true</code> + */ + public StringToBooleanConverter(String trueString, + String falseString) { + this.trueString = trueString; + this.falseString = falseString; + } + + /* + * (non-Javadoc) + * + * @see + * com.vaadin.data.util.converter.Converter#convertToModel(java.lang.Object, + * java.lang.Class, java.util.Locale) + */ + @Override + public Boolean convertToModel(String value, + Class<? extends Boolean> targetType, Locale locale) + throws ConversionException { + if (value == null || value.isEmpty()) { + return null; + } + + // Remove leading and trailing white space + value = value.trim(); + + if (getTrueString().equals(value)) { + return true; + } else if (getFalseString().equals(value)) { + return false; + } else { + throw new ConversionException("Cannot convert " + value + " to " + + getModelType().getName()); + } + } + + /** + * Gets the string representation for true. Default is "true", if not set in + * constructor. + * + * @return the string representation for true + */ + protected String getTrueString() { + return trueString; + } + + /** + * Gets the string representation for false. Default is "false", if not set + * in constructor. + * + * @return the string representation for false + */ + protected String getFalseString() { + return falseString; + } + + /* + * (non-Javadoc) + * + * @see + * com.vaadin.data.util.converter.Converter#convertToPresentation(java.lang + * .Object, java.lang.Class, java.util.Locale) + */ + @Override + public String convertToPresentation(Boolean value, + Class<? extends String> targetType, Locale locale) + throws ConversionException { + if (value == null) { + return null; + } + if (value) { + return getTrueString(locale); + } else { + return getFalseString(locale); + } + } + + /** + * Gets the locale-depended string representation for false. Default is + * locale-independent value provided by {@link #getFalseString()} + * + * @since 7.5.4 + * @param locale + * to be used + * @return the string representation for false + */ + protected String getFalseString(Locale locale) { + return getFalseString(); + } + + /** + * Gets the locale-depended string representation for true. Default is + * locale-independent value provided by {@link #getTrueString()} + * + * @since 7.5.4 + * @param locale + * to be used + * @return the string representation for true + */ + protected String getTrueString(Locale locale) { + return getTrueString(); + } + + /* + * (non-Javadoc) + * + * @see com.vaadin.data.util.converter.Converter#getModelType() + */ + @Override + public Class<Boolean> getModelType() { + return Boolean.class; + } + + /* + * (non-Javadoc) + * + * @see com.vaadin.data.util.converter.Converter#getPresentationType() + */ + @Override + public Class<String> getPresentationType() { + return String.class; + } + +} diff --git a/compatibility-server/src/main/java/com/vaadin/v7/data/util/converter/StringToByteConverter.java b/compatibility-server/src/main/java/com/vaadin/v7/data/util/converter/StringToByteConverter.java new file mode 100644 index 0000000000..e915a95550 --- /dev/null +++ b/compatibility-server/src/main/java/com/vaadin/v7/data/util/converter/StringToByteConverter.java @@ -0,0 +1,89 @@ +/* + * Copyright 2000-2016 Vaadin Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + */ + +package com.vaadin.v7.data.util.converter; + +import java.text.NumberFormat; +import java.util.Locale; + +/** + * A converter that converts from {@link String} to {@link Byte} and back. Uses + * the given locale and a {@link NumberFormat} instance for formatting and + * parsing. + * <p> + * Override and overwrite {@link #getFormat(Locale)} to use a different format. + * </p> + * + * @author Vaadin Ltd + * @since 7.4 + */ +public class StringToByteConverter + extends AbstractStringToNumberConverter<Byte> { + + /** + * Returns the format used by + * {@link #convertToPresentation(Byte, Class, Locale)} and + * {@link #convertToModel(String, Class, Locale)} + * + * @param locale + * The locale to use + * @return A NumberFormat instance + */ + @Override + protected NumberFormat getFormat(Locale locale) { + if (locale == null) { + locale = Locale.getDefault(); + } + return NumberFormat.getIntegerInstance(locale); + } + + /* + * (non-Javadoc) + * + * @see + * com.vaadin.data.util.converter.Converter#convertToModel(java.lang.Object, + * java.lang.Class, java.util.Locale) + */ + @Override + public Byte convertToModel(String value, Class<? extends Byte> targetType, + Locale locale) throws ConversionException { + Number n = convertToNumber(value, targetType, locale); + + if (n == null) { + return null; + } + + byte byteValue = n.byteValue(); + if (byteValue == n.longValue()) { + return byteValue; + } + + throw new ConversionException("Could not convert '" + value + "' to " + + Byte.class.getName() + ": value out of range"); + + } + + /* + * (non-Javadoc) + * + * @see com.vaadin.data.util.converter.Converter#getModelType() + */ + @Override + public Class<Byte> getModelType() { + return Byte.class; + } + +} diff --git a/compatibility-server/src/main/java/com/vaadin/v7/data/util/converter/StringToCollectionConverter.java b/compatibility-server/src/main/java/com/vaadin/v7/data/util/converter/StringToCollectionConverter.java new file mode 100644 index 0000000000..708cc13fe8 --- /dev/null +++ b/compatibility-server/src/main/java/com/vaadin/v7/data/util/converter/StringToCollectionConverter.java @@ -0,0 +1,244 @@ +/* + * Copyright 2000-2016 Vaadin Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + */ +package com.vaadin.v7.data.util.converter; + +import java.io.Serializable; +import java.lang.reflect.Modifier; +import java.util.ArrayList; +import java.util.Collection; +import java.util.HashSet; +import java.util.Iterator; +import java.util.Locale; + +/** + * A converter that converts from {@link String} to {@link Collection} of tokens + * and back. + * <p> + * Allows to break a string into tokens using delimiter. Each token can be + * converted to its own model using provided converter. + * <p> + * Default constructor uses <code>", "</code> as delimiter string and + * {@link String} for token types. Other constructors allow to configure + * delimiter and token types. + * + * @since 7.5.0 + * + * @author Vaadin Ltd + */ +public class StringToCollectionConverter + implements Converter<String, Collection> { + + private final String delimiter; + private final Converter<String, ?> tokenConverter; + private final Class<?> tokenType; + private final CollectionFactory factory; + + /** + * Creates converter with <code>", "</code> as delimiter and {@link String} + * as token model type in collection. + */ + public StringToCollectionConverter() { + this(", ", null, String.class); + } + + /** + * Creates converter with given {@code delimiter} and {@link String} as + * token model type in collection. + * + * @param delimiter + * custom delimiter + */ + public StringToCollectionConverter(String delimiter) { + this(delimiter, null, String.class); + } + + /** + * Creates converter with given {@code tokenConverter} for convert tokens + * and expected {@code tokenType}. + * <p> + * If {@code tokenConverter} is null then no conversation is done and + * {@link String} is used as token type in resulting model collection. + * + * @param tokenConverter + * converter for token + * @param tokenType + * expected token model type + */ + public StringToCollectionConverter( + Converter<String, ?> tokenConverter, Class<?> tokenType) { + this(", ", tokenConverter, tokenType); + } + + /** + * Creates converter with given {@code tokenConverter} for convert tokens + * and expected {@code tokenType}. + * <p> + * If {@code tokenConverter} is null then no conversation is done and + * {@link String} is used as token type in resulting model collection. + * + * @param tokenConverter + * converter for token + * @param tokenType + * expected token model type + * @param delimiter + * delimiter in presentation string + */ + public StringToCollectionConverter(String delimiter, + Converter<String, ?> tokenConverter, Class<?> tokenClass) { + this(delimiter, tokenConverter, tokenClass, + new DefaultCollectionFactory()); + } + + /** + * Creates converter with given {@code tokenConverter} for convert tokens + * and expected {@code tokenType}. + * <p> + * If {@code tokenConverter} is null then no conversation is done and + * {@link String} is used as token type in resulting model collection. + * + * @param tokenConverter + * converter for token + * @param tokenType + * expected token model type + * @param delimiter + * delimiter in presentation string + * @param factory + * factory to create resulting collection + */ + public StringToCollectionConverter(String delimiter, + Converter<String, ?> tokenConverter, Class<?> tokenClass, + CollectionFactory factory) { + if (delimiter == null || delimiter.isEmpty()) { + throw new IllegalArgumentException( + "Delimiter should be non-empty string"); + } + this.delimiter = delimiter; + this.tokenConverter = tokenConverter; + tokenType = tokenClass; + this.factory = factory; + } + + @Override + public Class<Collection> getModelType() { + return Collection.class; + } + + @Override + public Class<String> getPresentationType() { + return String.class; + } + + @Override + public Collection convertToModel(String value, + Class<? extends Collection> targetType, Locale locale) + throws Converter.ConversionException { + if (value == null) { + return null; + } + + int index = value.indexOf(delimiter); + int previous = 0; + Collection result = factory.createCollection(targetType); + Converter converter = tokenConverter; + while (index != -1) { + collectToken(value.substring(previous, index), result, converter, + locale); + previous = index + delimiter.length(); + index = value.indexOf(delimiter, previous); + } + collectToken(value.substring(previous), result, converter, locale); + return result; + } + + @Override + public String convertToPresentation(Collection value, + Class<? extends String> targetType, Locale locale) + throws Converter.ConversionException { + if (value == null) { + return null; + } + StringBuilder builder = new StringBuilder(); + Converter converter = tokenConverter; + for (Iterator<?> iterator = value.iterator(); iterator.hasNext();) { + if (converter == null) { + builder.append(iterator.next()); + } else { + builder.append(converter.convertToPresentation(iterator.next(), + targetType, locale)); + } + builder.append(delimiter); + } + if (builder.length() > 0) { + return builder.substring(0, builder.length() - delimiter.length()); + } else { + return builder.toString(); + } + } + + private void collectToken(String token, Collection collection, + Converter converter, Locale locale) { + if (converter == null) { + collection.add(token); + } else { + collection.add(converter.convertToModel(token, tokenType, locale)); + } + } + + /** + * Default collection factory implementation. + * + * @author Vaadin Ltd + */ + public static class DefaultCollectionFactory implements CollectionFactory { + + @Override + public Collection<?> createCollection( + Class<? extends Collection> type) { + if (type.isAssignableFrom(ArrayList.class)) { + return new ArrayList(); + } else if (type.isAssignableFrom(HashSet.class)) { + return new HashSet(); + } else if (!type.isInterface() + && !Modifier.isAbstract(type.getModifiers())) { + try { + return type.newInstance(); + } catch (InstantiationException ignore) { + } catch (IllegalAccessException ignore) { + } + } + return new ArrayList(); + } + + } + + /** + * Collection factory. Defines a strategy to create collection by collection + * class. + * + * @author Vaadin Ltd + */ + public interface CollectionFactory extends Serializable { + + /** + * Create collection by its {@code type}. + * + * @param type + * collection type + * @return instantiated collection with given {@code type} + */ + Collection<?> createCollection(Class<? extends Collection> type); + } +} diff --git a/compatibility-server/src/main/java/com/vaadin/v7/data/util/converter/StringToDateConverter.java b/compatibility-server/src/main/java/com/vaadin/v7/data/util/converter/StringToDateConverter.java new file mode 100644 index 0000000000..7d7f5b96aa --- /dev/null +++ b/compatibility-server/src/main/java/com/vaadin/v7/data/util/converter/StringToDateConverter.java @@ -0,0 +1,132 @@ +/* + * Copyright 2000-2016 Vaadin Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + */ + +package com.vaadin.v7.data.util.converter; + +import java.text.DateFormat; +import java.text.ParsePosition; +import java.util.Date; +import java.util.Locale; + +/** + * A converter that converts from {@link Date} to {@link String} and back. Uses + * the given locale and {@link DateFormat} for formatting and parsing. + * <p> + * Leading and trailing white spaces are ignored when converting from a String. + * </p> + * <p> + * Override and overwrite {@link #getFormat(Locale)} to use a different format. + * </p> + * + * @author Vaadin Ltd + * @since 7.0 + */ +public class StringToDateConverter + implements Converter<String, Date> { + + /** + * Returns the format used by + * {@link #convertToPresentation(Date, Class,Locale)} and + * {@link #convertToModel(String, Class, Locale)}. + * + * @param locale + * The locale to use + * @return A DateFormat instance + */ + protected DateFormat getFormat(Locale locale) { + if (locale == null) { + locale = Locale.getDefault(); + } + + DateFormat f = DateFormat.getDateTimeInstance(DateFormat.MEDIUM, + DateFormat.MEDIUM, locale); + f.setLenient(false); + return f; + } + + /* + * (non-Javadoc) + * + * @see + * com.vaadin.data.util.converter.Converter#convertToModel(java.lang.Object, + * java.lang.Class, java.util.Locale) + */ + @Override + public Date convertToModel(String value, Class<? extends Date> targetType, + Locale locale) + throws com.vaadin.v7.data.util.converter.Converter.ConversionException { + if (targetType != getModelType()) { + throw new ConversionException( + "Converter only supports " + getModelType().getName() + + " (targetType was " + targetType.getName() + ")"); + } + + if (value == null) { + return null; + } + + // Remove leading and trailing white space + value = value.trim(); + + ParsePosition parsePosition = new ParsePosition(0); + Date parsedValue = getFormat(locale).parse(value, parsePosition); + if (parsePosition.getIndex() != value.length()) { + throw new ConversionException("Could not convert '" + value + + "' to " + getModelType().getName()); + } + + return parsedValue; + } + + /* + * (non-Javadoc) + * + * @see + * com.vaadin.data.util.converter.Converter#convertToPresentation(java.lang + * .Object, java.lang.Class, java.util.Locale) + */ + @Override + public String convertToPresentation(Date value, + Class<? extends String> targetType, Locale locale) + throws com.vaadin.v7.data.util.converter.Converter.ConversionException { + if (value == null) { + return null; + } + + return getFormat(locale).format(value); + } + + /* + * (non-Javadoc) + * + * @see com.vaadin.data.util.converter.Converter#getModelType() + */ + @Override + public Class<Date> getModelType() { + return Date.class; + } + + /* + * (non-Javadoc) + * + * @see com.vaadin.data.util.converter.Converter#getPresentationType() + */ + @Override + public Class<String> getPresentationType() { + return String.class; + } + +} diff --git a/compatibility-server/src/main/java/com/vaadin/v7/data/util/converter/StringToDoubleConverter.java b/compatibility-server/src/main/java/com/vaadin/v7/data/util/converter/StringToDoubleConverter.java new file mode 100644 index 0000000000..1da06aa834 --- /dev/null +++ b/compatibility-server/src/main/java/com/vaadin/v7/data/util/converter/StringToDoubleConverter.java @@ -0,0 +1,64 @@ +/* + * Copyright 2000-2016 Vaadin Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + */ + +package com.vaadin.v7.data.util.converter; + +import java.text.NumberFormat; +import java.util.Locale; + +/** + * A converter that converts from {@link String} to {@link Double} and back. + * Uses the given locale and a {@link NumberFormat} instance for formatting and + * parsing. + * <p> + * Leading and trailing white spaces are ignored when converting from a String. + * </p> + * <p> + * Override and overwrite {@link #getFormat(Locale)} to use a different format. + * </p> + * + * @author Vaadin Ltd + * @since 7.0 + */ +public class StringToDoubleConverter + extends AbstractStringToNumberConverter<Double> { + + /* + * (non-Javadoc) + * + * @see + * com.vaadin.data.util.converter.Converter#convertToModel(java.lang.Object, + * java.util.Locale) + */ + @Override + public Double convertToModel(String value, + Class<? extends Double> targetType, Locale locale) + throws ConversionException { + Number n = convertToNumber(value, targetType, locale); + return n == null ? null : n.doubleValue(); + } + + /* + * (non-Javadoc) + * + * @see com.vaadin.data.util.converter.Converter#getModelType() + */ + @Override + public Class<Double> getModelType() { + return Double.class; + } + +} diff --git a/compatibility-server/src/main/java/com/vaadin/v7/data/util/converter/StringToEnumConverter.java b/compatibility-server/src/main/java/com/vaadin/v7/data/util/converter/StringToEnumConverter.java new file mode 100644 index 0000000000..d753b1e73f --- /dev/null +++ b/compatibility-server/src/main/java/com/vaadin/v7/data/util/converter/StringToEnumConverter.java @@ -0,0 +1,161 @@ +/* + * Copyright 2000-2016 Vaadin Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + */ +package com.vaadin.v7.data.util.converter; + +import java.util.EnumSet; +import java.util.Locale; + +/** + * A converter that converts from {@link String} to an {@link Enum} and back. + * <p> + * Designed to provide nice human readable strings for {@link Enum} classes + * conforming to one of these patterns: + * <ul> + * <li>The constants are named SOME_UPPERCASE_WORDS and there's no toString + * implementation.</li> + * <li>toString() always returns the same human readable string that is not the + * same as its name() value. Each constant in the enum type returns a distinct + * toString() value.</li> + * </ul> + * Will not necessarily work correctly for other cases. + * </p> + * + * @author Vaadin Ltd + * @since 7.4 + */ +public class StringToEnumConverter + implements Converter<String, Enum> { + + @Override + public Enum convertToModel(String value, Class<? extends Enum> targetType, + Locale locale) throws ConversionException { + if (value == null || value.trim().equals("")) { + return null; + } + + return stringToEnum(value, targetType, locale); + } + + /** + * Converts the given string to the given enum type using the given locale + * <p> + * Compatible with {@link #enumToString(Enum, Locale)} + * + * @param value + * The string value to convert + * @param enumType + * The type of enum to create + * @param locale + * The locale to use for conversion. If null, the JVM default + * locale will be used + * @return The enum which matches the given string + * @throws ConversionException + * if the conversion fails + */ + public static <T extends Enum<T>> T stringToEnum(String value, + Class<T> enumType, Locale locale) throws ConversionException { + if (locale == null) { + locale = Locale.getDefault(); + } + + if (!enumType.isEnum()) { + throw new ConversionException( + enumType.getName() + " is not an enum type"); + } + + // First test for the human-readable value since that's the more likely + // input + String upperCaseValue = value.toUpperCase(locale); + T match = null; + for (T e : EnumSet.allOf(enumType)) { + String upperCase = enumToString(e, locale).toUpperCase(locale); + if (upperCase.equals(upperCaseValue)) { + if (match != null) { + throw new ConversionException("Both " + match.name() + + " and " + e.name() + + " are matching the input string " + value); + } + match = e; + } + } + + if (match != null) { + return match; + } + + // Then fall back to using a strict match based on name() + try { + return Enum.valueOf(enumType, upperCaseValue); + } catch (Exception ee) { + throw new ConversionException(ee); + } + } + + /** + * Converts the given enum to a human readable string using the given locale + * <p> + * Compatible with {@link #stringToEnum(String, Class, Locale)} + * + * @param value + * The enum value to convert + * @param locale + * The locale to use for conversion. If null, the JVM default + * locale will be used + * @return A human readable string based on the enum + * @throws ConversionException + * if the conversion fails + */ + public static String enumToString(Enum<?> value, Locale locale) { + if (locale == null) { + locale = Locale.getDefault(); + } + + String enumString = value.toString(); + if (enumString.equals(value.name())) { + // FOO -> Foo + // FOO_BAR -> Foo bar + // _FOO -> _foo + String result = enumString.substring(0, 1).toUpperCase(locale); + result += enumString.substring(1).toLowerCase(locale).replace('_', + ' '); + return result; + } else { + return enumString; + } + } + + @Override + public String convertToPresentation(Enum value, + Class<? extends String> targetType, Locale locale) + throws ConversionException { + if (value == null) { + return null; + } + + return enumToString(value, locale); + } + + @Override + public Class<Enum> getModelType() { + return Enum.class; + } + + @Override + public Class<String> getPresentationType() { + return String.class; + } + +} diff --git a/compatibility-server/src/main/java/com/vaadin/v7/data/util/converter/StringToFloatConverter.java b/compatibility-server/src/main/java/com/vaadin/v7/data/util/converter/StringToFloatConverter.java new file mode 100644 index 0000000000..e37cf89784 --- /dev/null +++ b/compatibility-server/src/main/java/com/vaadin/v7/data/util/converter/StringToFloatConverter.java @@ -0,0 +1,63 @@ +/* + * Copyright 2000-2016 Vaadin Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + */ + +package com.vaadin.v7.data.util.converter; + +import java.text.NumberFormat; +import java.util.Locale; + +/** + * A converter that converts from {@link String} to {@link Float} and back. Uses + * the given locale and a {@link NumberFormat} instance for formatting and + * parsing. + * <p> + * Leading and trailing white spaces are ignored when converting from a String. + * </p> + * <p> + * Override and overwrite {@link #getFormat(Locale)} to use a different format. + * </p> + * + * @author Vaadin Ltd + * @since 7.0 + */ +public class StringToFloatConverter + extends AbstractStringToNumberConverter<Float> { + + /* + * (non-Javadoc) + * + * @see + * com.vaadin.data.util.converter.Converter#convertToModel(java.lang.Object, + * java.util.Locale) + */ + @Override + public Float convertToModel(String value, Class<? extends Float> targetType, + Locale locale) throws ConversionException { + Number n = convertToNumber(value, targetType, locale); + return n == null ? null : n.floatValue(); + } + + /* + * (non-Javadoc) + * + * @see com.vaadin.data.util.converter.Converter#getModelType() + */ + @Override + public Class<Float> getModelType() { + return Float.class; + } + +} diff --git a/compatibility-server/src/main/java/com/vaadin/v7/data/util/converter/StringToIntegerConverter.java b/compatibility-server/src/main/java/com/vaadin/v7/data/util/converter/StringToIntegerConverter.java new file mode 100644 index 0000000000..82dcf7e6b8 --- /dev/null +++ b/compatibility-server/src/main/java/com/vaadin/v7/data/util/converter/StringToIntegerConverter.java @@ -0,0 +1,94 @@ +/* + * Copyright 2000-2016 Vaadin Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + */ + +package com.vaadin.v7.data.util.converter; + +import java.text.NumberFormat; +import java.util.Locale; + +/** + * A converter that converts from {@link String} to {@link Integer} and back. + * Uses the given locale and a {@link NumberFormat} instance for formatting and + * parsing. + * <p> + * Override and overwrite {@link #getFormat(Locale)} to use a different format. + * </p> + * + * @author Vaadin Ltd + * @since 7.0 + */ +public class StringToIntegerConverter + extends AbstractStringToNumberConverter<Integer> { + + /** + * Returns the format used by + * {@link #convertToPresentation(Integer, Class, Locale)} and + * {@link #convertToModel(String, Class, Locale)} + * + * @param locale + * The locale to use + * @return A NumberFormat instance + */ + @Override + protected NumberFormat getFormat(Locale locale) { + if (locale == null) { + locale = Locale.getDefault(); + } + return NumberFormat.getIntegerInstance(locale); + } + + /* + * (non-Javadoc) + * + * @see + * com.vaadin.data.util.converter.Converter#convertToModel(java.lang.Object, + * java.lang.Class, java.util.Locale) + */ + @Override + public Integer convertToModel(String value, + Class<? extends Integer> targetType, Locale locale) + throws ConversionException { + Number n = convertToNumber(value, targetType, locale); + + if (n == null) { + return null; + } + + int intValue = n.intValue(); + if (intValue == n.longValue()) { + // If the value of n is outside the range of long, the return value + // of longValue() is either Long.MIN_VALUE or Long.MAX_VALUE. The + // above comparison promotes int to long and thus does not need to + // consider wrap-around. + return intValue; + } + + throw new ConversionException("Could not convert '" + value + "' to " + + Integer.class.getName() + ": value out of range"); + + } + + /* + * (non-Javadoc) + * + * @see com.vaadin.data.util.converter.Converter#getModelType() + */ + @Override + public Class<Integer> getModelType() { + return Integer.class; + } + +} diff --git a/compatibility-server/src/main/java/com/vaadin/v7/data/util/converter/StringToLongConverter.java b/compatibility-server/src/main/java/com/vaadin/v7/data/util/converter/StringToLongConverter.java new file mode 100644 index 0000000000..29c129c3fd --- /dev/null +++ b/compatibility-server/src/main/java/com/vaadin/v7/data/util/converter/StringToLongConverter.java @@ -0,0 +1,78 @@ +/* + * Copyright 2000-2016 Vaadin Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + */ + +package com.vaadin.v7.data.util.converter; + +import java.text.NumberFormat; +import java.util.Locale; + +/** + * A converter that converts from {@link String} to {@link Long} and back. Uses + * the given locale and a {@link NumberFormat} instance for formatting and + * parsing. + * <p> + * Override and overwrite {@link #getFormat(Locale)} to use a different format. + * </p> + * + * @author Vaadin Ltd + * @since 7.2 + */ +public class StringToLongConverter + extends AbstractStringToNumberConverter<Long> { + + /** + * Returns the format used by + * {@link #convertToPresentation(Long, Class, Locale)} and + * {@link #convertToModel(String, Class, Locale)} + * + * @param locale + * The locale to use + * @return A NumberFormat instance + */ + @Override + protected NumberFormat getFormat(Locale locale) { + if (locale == null) { + locale = Locale.getDefault(); + } + return NumberFormat.getIntegerInstance(locale); + } + + /* + * (non-Javadoc) + * + * @see + * com.vaadin.data.util.converter.Converter#convertToModel(java.lang.Object, + * java.lang.Class, java.util.Locale) + */ + @Override + public Long convertToModel(String value, Class<? extends Long> targetType, + Locale locale) throws ConversionException { + Number n = convertToNumber(value, targetType, locale); + return n == null ? null : n.longValue(); + + } + + /* + * (non-Javadoc) + * + * @see com.vaadin.data.util.converter.Converter#getModelType() + */ + @Override + public Class<Long> getModelType() { + return Long.class; + } + +} diff --git a/compatibility-server/src/main/java/com/vaadin/v7/data/util/converter/StringToShortConverter.java b/compatibility-server/src/main/java/com/vaadin/v7/data/util/converter/StringToShortConverter.java new file mode 100644 index 0000000000..71408eb53e --- /dev/null +++ b/compatibility-server/src/main/java/com/vaadin/v7/data/util/converter/StringToShortConverter.java @@ -0,0 +1,89 @@ +/* + * Copyright 2000-2016 Vaadin Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + */ + +package com.vaadin.v7.data.util.converter; + +import java.text.NumberFormat; +import java.util.Locale; + +/** + * A converter that converts from {@link String} to {@link Short} and back. Uses + * the given locale and a {@link NumberFormat} instance for formatting and + * parsing. + * <p> + * Override and overwrite {@link #getFormat(Locale)} to use a different format. + * </p> + * + * @author Vaadin Ltd + * @since 7.4 + */ +public class StringToShortConverter + extends AbstractStringToNumberConverter<Short> { + + /** + * Returns the format used by + * {@link #convertToPresentation(Short, Class, Locale)} and + * {@link #convertToModel(String, Class, Locale)} + * + * @param locale + * The locale to use + * @return A NumberFormat instance + */ + @Override + protected NumberFormat getFormat(Locale locale) { + if (locale == null) { + locale = Locale.getDefault(); + } + return NumberFormat.getIntegerInstance(locale); + } + + /* + * (non-Javadoc) + * + * @see + * com.vaadin.data.util.converter.Converter#convertToModel(java.lang.Object, + * java.lang.Class, java.util.Locale) + */ + @Override + public Short convertToModel(String value, Class<? extends Short> targetType, + Locale locale) throws ConversionException { + Number n = convertToNumber(value, targetType, locale); + + if (n == null) { + return null; + } + + short shortValue = n.shortValue(); + if (shortValue == n.longValue()) { + return shortValue; + } + + throw new ConversionException("Could not convert '" + value + "' to " + + Short.class.getName() + ": value out of range"); + + } + + /* + * (non-Javadoc) + * + * @see com.vaadin.data.util.converter.Converter#getModelType() + */ + @Override + public Class<Short> getModelType() { + return Short.class; + } + +} |