*/
package eu.etaxonomy.cdm.vaadin.util.converter;
+import java.util.Arrays;
+import java.util.List;
import java.util.Locale;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
/**
+ *
* @author a.kohlbecker
* @since Apr 7, 2017
*
*/
public class JodaTimePartialConverter implements Converter<String, Partial> {
+ /**
+ * iso8601: YYY-MM-DD
+ * yyyymmddDot: dd.mm.yyyy
+ *
+ * @author a.kohlbecker
+ * @since Apr 10, 2017
+ *
+ */
+ public enum DateFormat {
+ ISO8601,
+ DAY_MONTH_YEAR_DOT
+ }
+
private static final long serialVersionUID = 976413549472527584L;
- static final String GLUE = "-";
+ DateFormat format;
+
+ Pattern partialPatternIso8601 = Pattern.compile("^(?<year>(?:[1,2][7,8,9,0,1])?[0-9]{2})(?:-(?<month>[0-1]?[0-9])(?:-(?<day>[0-3]?[0-9]))?)?$");
+
+ Pattern partialPatternDayMonthYearDot = Pattern.compile("^(?:(?:(?<day>[0-3]?[0-9])\\.)?(?<month>[0-1]?[0-9])\\.)?(?<year>(?:[1,2][7,8,9,0,1])?[0-9]{2})$");
+
+ List<Pattern> patterns = Arrays.asList(new Pattern[]{partialPatternIso8601, partialPatternDayMonthYearDot});
+
- Pattern partialPattern = Pattern.compile("^(?<year>(?:[1,2][7,8,9,0,1])?[0-9]{2})(?:-(?<month>[0-1]?[0-9])(?:-(?<day>[0-3]?[0-9]))?)?$");
/**
- *
+ * @param format The format of the string representation
*/
- public JodaTimePartialConverter() {
+ public JodaTimePartialConverter(DateFormat format) {
super();
+ this.format = format;
}
/**
Partial partial = null;
if(value != null){
partial = new Partial();
- Matcher m = partialPattern.matcher(value);
- if(m.matches()){
+ for(Pattern pattern : patterns){
+ Matcher m = pattern.matcher(value);
+ if(m.matches()){
+ partial = makePartial(m);
+ break;
+ }
+ }
+ }
+ return partial;
+ }
+
+ /**
+ * @param partial
+ * @param m
+ */
+ private Partial makePartial(Matcher m) {
+
+ Partial partial = new Partial();
+ try {
+ try {
+ String year = m.group("year");
+ partial = partial.with(DateTimeFieldType.year(), Integer.parseInt(year));
+ } catch (IllegalArgumentException e) {
+ // a valid year should be present here
+ throw new ConversionException(e);
+ }
+ try {
+ String month = m.group("month");
+ partial = partial.with(DateTimeFieldType.monthOfYear(), Integer.parseInt(month));
try {
- try {
- partial.with(DateTimeFieldType.year(), Integer.parseInt(m.group("year")));
- } catch (IllegalArgumentException e) {
- // a valid year should be present here
- throw new ConversionException(e);
- }
- try {
- partial.with(DateTimeFieldType.monthOfYear(), Integer.parseInt(m.group("month")));
- try {
- partial.with(DateTimeFieldType.dayOfMonth(), Integer.parseInt(m.group("day")));
- } catch (IllegalArgumentException e) {
- /* IGNORE days are not required */
- }
- } catch (IllegalArgumentException e) {
- /* IGNORE months are not required */
- }
- } catch (NumberFormatException ne) {
- // all numbers should be parsable, this is guaranteed by the partialPattern
- throw new ConversionException(ne);
+ String day = m.group("day");
+ partial = partial.with(DateTimeFieldType.dayOfMonth(), Integer.parseInt(day));
+ } catch (IllegalArgumentException e) {
+ /* IGNORE days are not required */
}
+ } catch (IllegalArgumentException e) {
+ /* IGNORE months are not required */
}
+ } catch (NumberFormatException ne) {
+ // all numbers should be parsable, this is guaranteed by the partialPattern
+ throw new ConversionException(ne);
}
return partial;
}
@Override
public String convertToPresentation(Partial value, Class<? extends String> targetType, Locale locale)
throws com.vaadin.data.util.converter.Converter.ConversionException {
- StringBuffer sb = new StringBuffer();
if(value != null){
+ switch(format) {
+ case ISO8601:
+ return formatIso8601(value);
+ case DAY_MONTH_YEAR_DOT:
+ return formatYyyymmddDot(value);
+ default:
+ return "JodaTimePartialConverter Error: unsupported format";
+ }
+ }
+ return "";
+ }
+
+ /**
+ * @param value
+ * @param sb
+ */
+ private String formatIso8601(Partial value) {
+ StringBuffer sb = new StringBuffer();
+ String glue = "-";
+ try {
+ sb.append(value.get(DateTimeFieldType.year()));
try {
- sb.append(value.get(DateTimeFieldType.year()));
+ String month = StringUtils.leftPad(Integer.toString((value.get(DateTimeFieldType.monthOfYear()))), 2, "0");
+ sb.append(glue).append(month);
try {
- String month = StringUtils.leftPad(Integer.toString((value.get(DateTimeFieldType.monthOfYear()))), 2, "0");
- sb.append(GLUE).append(month);
- try {
- String day = StringUtils.leftPad(Integer.toString((value.get(DateTimeFieldType.dayOfMonth()))), 2, "0");
- sb.append(GLUE).append(day);
- } catch (IllegalArgumentException e){
- /* IGNORE */
- }
+ String day = StringUtils.leftPad(Integer.toString((value.get(DateTimeFieldType.dayOfMonth()))), 2, "0");
+ sb.append(glue).append(day);
} catch (IllegalArgumentException e){
/* IGNORE */
}
} catch (IllegalArgumentException e){
/* IGNORE */
}
+ } catch (IllegalArgumentException e){
+ /* IGNORE */
}
return sb.toString();
}
+ /**
+ * @param value
+ * @param sb
+ */
+ private String formatYyyymmddDot(Partial value) {
+ StringBuffer sb = new StringBuffer();
+ String glue = ".";
+ try {
+ sb.append(StringUtils.reverse(Integer.toString(value.get(DateTimeFieldType.year()))));
+ try {
+ String month = StringUtils.leftPad(Integer.toString((value.get(DateTimeFieldType.monthOfYear()))), 2, "0");
+ sb.append(glue).append(StringUtils.reverse(month));
+ try {
+ String day = StringUtils.leftPad(Integer.toString((value.get(DateTimeFieldType.dayOfMonth()))), 2, "0");
+ sb.append(glue).append(StringUtils.reverse(day));
+ } catch (IllegalArgumentException e){
+ /* IGNORE */
+ }
+ } catch (IllegalArgumentException e){
+ /* IGNORE */
+ }
+ } catch (IllegalArgumentException e){
+ /* IGNORE */
+ }
+ return StringUtils.reverse(sb.toString());
+ }
+
/**
* {@inheritDoc}
*/
--- /dev/null
+/**
+* Copyright (C) 2017 EDIT
+* European Distributed Institute of Taxonomy
+* http://www.e-taxonomy.eu
+*
+* The contents of this file are subject to the Mozilla Public License Version 1.1
+* See LICENSE.TXT at the top of this package for the full license terms.
+*/
+package eu.etaxonomy.cdm.vaadin.util;
+
+import org.joda.time.DateTimeFieldType;
+import org.joda.time.Partial;
+import org.junit.Assert;
+import org.junit.Test;
+
+import eu.etaxonomy.cdm.vaadin.util.converter.JodaTimePartialConverter;
+
+/**
+ * @author a.kohlbecker
+ * @since Apr 10, 2017
+ *
+ */
+public class JodaTimePartialConverterTest extends Assert {
+
+ Partial y = new Partial(
+ new DateTimeFieldType[]{
+ DateTimeFieldType.year()
+ },
+ new int[]{
+ 2012
+ }
+ );
+ Partial ym = new Partial(
+ new DateTimeFieldType[]{
+ DateTimeFieldType.year(),
+ DateTimeFieldType.monthOfYear()
+ },
+ new int[]{
+ 2013,
+ 04
+ }
+ );
+ Partial ymd = new Partial(
+ new DateTimeFieldType[]{
+ DateTimeFieldType.year(),
+ DateTimeFieldType.monthOfYear(),
+ DateTimeFieldType.dayOfMonth()
+ },
+ new int[]{
+ 2014,
+ 04,
+ 12
+ }
+ );
+
+
+ @Test
+ public void toISO8601() {
+ JodaTimePartialConverter conv = new JodaTimePartialConverter(JodaTimePartialConverter.DateFormat.ISO8601);
+ assertEquals("2012", conv.convertToPresentation(y, String.class, null));
+ assertEquals("2013-04", conv.convertToPresentation(ym, String.class, null));
+ assertEquals("2014-04-12", conv.convertToPresentation(ymd, String.class, null));
+ }
+
+
+ @Test
+ public void toDAY_MONTH_YEAR_DOT() {
+ JodaTimePartialConverter conv = new JodaTimePartialConverter(JodaTimePartialConverter.DateFormat.DAY_MONTH_YEAR_DOT);
+ assertEquals("2012", conv.convertToPresentation(y, String.class, null));
+ assertEquals("04.2013", conv.convertToPresentation(ym, String.class, null));
+ assertEquals("12.04.2014", conv.convertToPresentation(ymd, String.class, null));
+ }
+
+ @Test
+ public void fromDAY_MONTH_YEAR_DOT() {
+ // using null as format since the conversion should work for all formats
+ JodaTimePartialConverter conv = new JodaTimePartialConverter(null);
+ assertEquals(y, conv.convertToModel("2012", Partial.class, null));
+ assertEquals(ym, conv.convertToModel("2013-04", Partial.class, null));
+ assertEquals(ym, conv.convertToModel("04.2013", Partial.class, null));
+ assertEquals(ymd, conv.convertToModel("2014-04-12", Partial.class, null));
+ assertEquals(ymd, conv.convertToModel("12.04.2014", Partial.class, null));
+ assertEquals(ymd, conv.convertToModel("12.4.2014", Partial.class, null));
+ }
+
+}