ref #6169 JodaTimePartialConverter support for multiple formats
authorAndreas Kohlbecker <a.kohlbecker@bgbm.org>
Mon, 10 Apr 2017 14:08:36 +0000 (16:08 +0200)
committerAndreas Kohlbecker <a.kohlbecker@bgbm.org>
Mon, 10 Apr 2017 14:08:36 +0000 (16:08 +0200)
src/main/java/eu/etaxonomy/cdm/vaadin/component/PartialDateField.java
src/main/java/eu/etaxonomy/cdm/vaadin/component/TimePeriodField.java
src/main/java/eu/etaxonomy/cdm/vaadin/util/converter/JodaTimePartialConverter.java
src/test/java/eu/etaxonomy/cdm/vaadin/util/JodaTimePartialConverterTest.java [new file with mode: 0644]
src/test/java/eu/etaxonomy/cdm/vaadin/util/converter/TypeDesignationConverterTest.java [moved from src/test/java/eu/etaxonomy/cdm/vaadin/util/TypeDesignationConverterTest.java with 95% similarity]

index 70530f021ab7bf1545a24c491d0a19897ede6425..2f5bcc5198d473f3c7444081735d527906d7ec45 100644 (file)
@@ -25,12 +25,14 @@ import eu.etaxonomy.cdm.vaadin.util.converter.JodaTimePartialConverter;
  */
 public class PartialDateField extends TextField {
 
+    JodaTimePartialConverter.DateFormat format = JodaTimePartialConverter.DateFormat.DAY_MONTH_YEAR_DOT;
+
     /**
      *
      */
     public PartialDateField() {
         super();
-        setConverter(new JodaTimePartialConverter());
+        setConverter(new JodaTimePartialConverter(format));
     }
 
     /**
@@ -38,7 +40,7 @@ public class PartialDateField extends TextField {
      */
     public PartialDateField(Property dataSource) {
         super(dataSource);
-        setConverter(new JodaTimePartialConverter());
+        setConverter(new JodaTimePartialConverter(format));
     }
 
     /**
@@ -47,7 +49,7 @@ public class PartialDateField extends TextField {
      */
     public PartialDateField(String caption, Property dataSource) {
         super(caption, dataSource);
-        setConverter(new JodaTimePartialConverter());
+        setConverter(new JodaTimePartialConverter(format));
     }
 
     /**
@@ -56,7 +58,7 @@ public class PartialDateField extends TextField {
      */
     public PartialDateField(String caption, String value) {
         super(caption, value);
-        setConverter(new JodaTimePartialConverter());
+        setConverter(new JodaTimePartialConverter(format));
     }
 
     /**
@@ -64,7 +66,7 @@ public class PartialDateField extends TextField {
      */
     public PartialDateField(String caption) {
         super(caption);
-        setConverter(new JodaTimePartialConverter());
+        setConverter(new JodaTimePartialConverter(format));
     }
 
 
index b4a8c6c87151d58328ab259d49c7db2c0adb06bc..f32ee8cd162e1bdf66c5688a5202cb845d93700b 100644 (file)
@@ -73,7 +73,9 @@ public class TimePeriodField extends CustomField<TimePeriod> {
         parseField.addTextChangeListener(e -> parseInput(e));
 
         PartialDateField startDate = new PartialDateField("Start");
+        startDate.setInputPrompt("dd.mm.yyy");
         PartialDateField endDate = new PartialDateField("End");
+        endDate.setInputPrompt("dd.mm.yyy");
         freeText = new TextField("FreeText");
         freeText.setWidth(100, Unit.PERCENTAGE);
 
index 71e5450f166560dbd2aa24ab855488089d5b9338..500db1fbf3f651253fe837b910b171eb775c06f0 100644 (file)
@@ -8,6 +8,8 @@
 */
 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;
@@ -20,23 +22,44 @@ import com.vaadin.data.util.converter.Converter;
 
 
 /**
+ *
  * @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;
     }
 
     /**
@@ -48,30 +71,47 @@ public class JodaTimePartialConverter implements Converter<String, Partial> {
         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;
     }
@@ -82,29 +122,73 @@ public class JodaTimePartialConverter implements Converter<String, 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}
      */
diff --git a/src/test/java/eu/etaxonomy/cdm/vaadin/util/JodaTimePartialConverterTest.java b/src/test/java/eu/etaxonomy/cdm/vaadin/util/JodaTimePartialConverterTest.java
new file mode 100644 (file)
index 0000000..77225ca
--- /dev/null
@@ -0,0 +1,86 @@
+/**
+* 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));
+    }
+
+}
similarity index 95%
rename from src/test/java/eu/etaxonomy/cdm/vaadin/util/TypeDesignationConverterTest.java
rename to src/test/java/eu/etaxonomy/cdm/vaadin/util/converter/TypeDesignationConverterTest.java
index d96f336e1a50be4427cec3bcfd06bd3bbf723383..50a8f58b9df6f4ef3756e2d1d5bf614ddbc86356 100644 (file)
@@ -6,7 +6,7 @@
 * 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;
+package eu.etaxonomy.cdm.vaadin.util.converter;
 
 import static org.junit.Assert.assertNotNull;
 
@@ -28,6 +28,7 @@ import eu.etaxonomy.cdm.model.occurrence.SpecimenOrObservationType;
 import eu.etaxonomy.cdm.model.reference.Reference;
 import eu.etaxonomy.cdm.model.reference.ReferenceFactory;
 import eu.etaxonomy.cdm.vaadin.CdmVaadinBaseTest;
+import eu.etaxonomy.cdm.vaadin.util.TypeDesignationConverter;
 
 /**
  * @author a.kohlbecker