View Javadoc

    1   /**
    2    * Copyright (c) 2008-2011, http://www.snakeyaml.org
    3    *
    4    * Licensed under the Apache License, Version 2.0 (the "License");
    5    * you may not use this file except in compliance with the License.
    6    * You may obtain a copy of the License at
    7    *
    8    *     http://www.apache.org/licenses/LICENSE-2.0
    9    *
    10   * Unless required by applicable law or agreed to in writing, software
    11   * distributed under the License is distributed on an "AS IS" BASIS,
    12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    13   * See the License for the specific language governing permissions and
    14   * limitations under the License.
    15   */
    16
    17  package examples.jodatime;
    18
    19  import java.util.Date;
    20  import java.util.List;
    21
    22  import junit.framework.TestCase;
    23
    24  import org.joda.time.DateMidnight;
    25  import org.joda.time.DateTime;
    26  import org.joda.time.DateTimeZone;
    27  import org.yaml.snakeyaml.DumperOptions;
    28  import org.yaml.snakeyaml.DumperOptions.FlowStyle;
    29  import org.yaml.snakeyaml.Yaml;
    30  import org.yaml.snakeyaml.constructor.Construct;
    31  import org.yaml.snakeyaml.constructor.Constructor;
    32  import org.yaml.snakeyaml.events.Event;
    33  import org.yaml.snakeyaml.events.ScalarEvent;
    34  import org.yaml.snakeyaml.nodes.Node;
    35  import org.yaml.snakeyaml.nodes.NodeId;
    36  import org.yaml.snakeyaml.nodes.Tag;
    37
    38  public class JodaTimeExampleTest extends TestCase {
    39      private static final long timestamp = 1000000000000L;
    40
    41      public void testDump() {
    42          DateTime time = new DateTime(timestamp, DateTimeZone.UTC);
    43          Yaml yaml = new Yaml(new JodaTimeRepresenter());
    44          String joda = yaml.dump(time);
    45          String date = new Yaml().dump(new Date(timestamp));
    46          assertEquals(date, joda);
    47          assertEquals("2001-09-09T01:46:40Z\n", joda);
    48      }
    49
    50      public void testLoad() {
    51          Yaml yaml = new Yaml(new JodaTimeContructor());
    52          DateTime time = (DateTime) yaml.load("2001-09-09T01:46:40Z");
    53          assertEquals(new DateTime(timestamp, DateTimeZone.UTC), time);
    54      }
    55
    56      /**
    57       * @see http://code.google.com/p/snakeyaml/issues/detail?id=128
    58       */
    59      public void testLoadBeanWithBlockFlow() {
    60          MyBean bean = new MyBean();
    61          bean.setId("id123");
    62          DateTime etalon = new DateTime(timestamp, DateTimeZone.UTC);
    63          bean.setDate(etalon);
    64          DumperOptions options = new DumperOptions();
    65          options.setDefaultFlowStyle(FlowStyle.BLOCK);
    66          Yaml dumper = new Yaml(new JodaTimeRepresenter(), options);
    67          // compare Nodes with flow style AUTO and flow style BLOCK
    68          Node node1 = dumper.represent(bean);
    69          DumperOptions options2 = new DumperOptions();
    70          options2.setDefaultFlowStyle(FlowStyle.AUTO);
    71          Yaml dumper2 = new Yaml(new JodaTimeRepresenter(), options2);
    72          Node node2 = dumper2.represent(bean);
    73          assertEquals(node2.toString(), node1.toString());
    74          // compare Events with flow style AUTO and flow style BLOCK
    75          List<Event> events1 = dumper.serialize(node1);
    76          List<Event> events2 = dumper2.serialize(node2);
    77          assertEquals(events2.size(), events1.size());
    78          int i = 0;
    79          for (Event etalonEvent : events2) {
    80              assertEquals(etalonEvent, events1.get(i++));
    81              if (etalonEvent instanceof ScalarEvent) {
    82                  ScalarEvent scalar = (ScalarEvent) etalonEvent;
    83                  if (scalar.getValue().equals("2001-09-09T01:46:40Z")) {
    84                      assertTrue(scalar.getImplicit().canOmitTagInPlainScalar());
    85                      assertFalse(scalar.getImplicit().canOmitTagInNonPlainScalar());
    86                  }
    87              }
    88          }
    89          // Nodes and Events are the same. Only emitter may influence the output.
    90          String doc1 = dumper.dump(bean);
    91          // System.out.println(doc1);
    92          /*
    93           * 'date' must be used only with the explicit '!!timestamp' tag.
    94           * Implicit tag will not work because 'date' is the JavaBean property
    95           * and in this case the empty constructor of the class will be used.
    96           * Since this constructor does not exist for JodaTime an exception will
    97           * be thrown.
    98           */
    99          assertEquals("!!examples.jodatime.MyBean\ndate: 2001-09-09T01:46:40Z\nid: id123\n", doc1);
    100         /*
    101          * provided JodaTimeContructor will be ignored because 'date' is a
    102          * JavaBean property and its class gets more priority then the implicit
    103          * '!!timestamp' tag.
    104          */
    105         Yaml loader = new Yaml(new JodaTimeContructor());
    106         try {
    107             loader.load(doc1);
    108         } catch (Exception e) {
    109             assertTrue(
    110                     "The error must indicate that JodaTime cannot be created from the scalar value.",
    111                     e.getMessage()
    112                             .contains(
    113                                     "No String constructor found. Exception=org.joda.time.DateTime.<init>(java.lang.String)"));
    114         }
    115         // we have to provide a special way to create JodaTime instances from
    116         // scalars
    117         Yaml loader2 = new Yaml(new JodaPropertyConstructor());
    118         MyBean parsed = (MyBean) loader2.load(doc1);
    119         assertEquals(etalon, parsed.getDate());
    120     }
    121
    122     /**
    123      * !!timestamp must be used, without it the implicit tag will be ignored
    124      * because 'date' is the JavaBean property.
    125      *
    126      * Since the timestamp contains ':' character it cannot use plain scalar
    127      * style in the FLOW mapping style. Emitter suggests single quoted scalar
    128      * style and that is why the explicit '!!timestamp' is present in the YAML
    129      * document.
    130      *
    131      * @see http://code.google.com/p/snakeyaml/issues/detail?id=128
    132      *
    133      */
    134     public void testLoadBeanWithAutoFlow() {
    135         MyBean bean = new MyBean();
    136         bean.setId("id123");
    137         DateTime etalon = new DateTime(timestamp, DateTimeZone.UTC);
    138         bean.setDate(etalon);
    139         DumperOptions options = new DumperOptions();
    140         options.setDefaultFlowStyle(FlowStyle.AUTO);
    141         Yaml dumper = new Yaml(new JodaTimeRepresenter(), options);
    142         String doc = dumper.dump(bean);
    143         //System.out.println(doc);
    144         assertEquals(
    145                 "!!examples.jodatime.MyBean {date: !!timestamp '2001-09-09T01:46:40Z', id: id123}\n",
    146                 doc);
    147         Yaml loader = new Yaml(new JodaTimeContructor());
    148         MyBean parsed = (MyBean) loader.load(doc);
    149         assertEquals(etalon, parsed.getDate());
    150     }
    151
    152     /**
    153      * test issue 109
    154      */
    155     public void test109() {
    156         Date someDate = new DateMidnight(9, 2, 21, DateTimeZone.forID("Europe/Amsterdam")).toDate();
    157         Yaml yaml = new Yaml();
    158         String timestamp = yaml.dump(someDate);
    159         assertEquals("0009-02-22T23:40:28Z\n", timestamp);
    160         // System.out.println(timestamp);
    161         Object o = yaml.load(timestamp);
    162         assertEquals(someDate, o);
    163     }
    164
    165     class JodaPropertyConstructor extends Constructor {
    166         public JodaPropertyConstructor() {
    167             yamlClassConstructors.put(NodeId.scalar, new TimeStampConstruct());
    168         }
    169
    170         class TimeStampConstruct extends Constructor.ConstructScalar {
    171             @Override
    172             public Object construct(Node nnode) {
    173                 if (nnode.getTag().equals("tag:yaml.org,2002:timestamp")) {
    174                     Construct dateConstructor = yamlConstructors.get(Tag.TIMESTAMP);
    175                     Date date = (Date) dateConstructor.construct(nnode);
    176                     return new DateTime(date, DateTimeZone.UTC);
    177                 } else {
    178                     return super.construct(nnode);
    179                 }
    180             }
    181
    182         }
    183     }
    184 }