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 org.yaml.snakeyaml.issues.issue94;
    18
    19  import static org.junit.Assert.assertEquals;
    20
    21  import org.junit.Test;
    22  import org.yaml.snakeyaml.Yaml;
    23  import org.yaml.snakeyaml.constructor.AbstractConstruct;
    24  import org.yaml.snakeyaml.constructor.Construct;
    25  import org.yaml.snakeyaml.constructor.Constructor;
    26  import org.yaml.snakeyaml.nodes.Node;
    27
    28  public class ChangeRuntimeClassTest {
    29
    30      @Test
    31      public void testWithGlobalTag() {
    32          String yamlText = "!!org.yaml.snakeyaml.issues.issue94.Entity\n" + "name: Matt\n"
    33                  + "nickName: Java\n";
    34
    35          // Now here that I would like to somehow intercept the constructor of
    36          // SnakeYaml and give it
    37          // an fresh instance of EntityLoadingProxy(); based on today's
    38          // temperature, so to speak...
    39          // that is un-preditable statically which proxy I will give it.
    40
    41          Yaml yaml = new Yaml(new MyConstructor());
    42
    43          Entity loadedEntity = null;
    44          loadedEntity = (Entity) yaml.load(yamlText);
    45
    46          assertEquals("Matt", loadedEntity.getName());
    47
    48          // The expectation below is from having intercepted setNickName() with
    49          // the artifical subclass and
    50          // performed the calculation.
    51          assertEquals("JJ-Java", loadedEntity.getNickName());
    52          assertEquals(EntityLoadingProxy.class, loadedEntity.getClass());
    53      }
    54
    55      @Test
    56      public void testNoTag() {
    57          String yamlText = "name: Matt\n" + "nickName: Java\n";
    58          Yaml yaml = new Yaml(new MyConstructor(Entity.class));
    59          Entity loadedEntity = null;
    60          loadedEntity = (Entity) yaml.load(yamlText);
    61          assertEquals("Matt", loadedEntity.getName());
    62          assertEquals("JJ-Java", loadedEntity.getNickName());
    63      }
    64
    65      /**
    66       * @see Constructor.ConstructYamlObject
    67       */
    68      private class MyConstructor extends Constructor {
    69          public MyConstructor() {
    70              super();
    71              this.yamlConstructors.put(null, new ConstructProxy());
    72          }
    73
    74          public MyConstructor(Class<?> clazz) {
    75              super(clazz);
    76              this.yamlConstructors.put(null, new ConstructProxy());
    77          }
    78
    79          private class ConstructProxy extends AbstractConstruct {
    80              private Construct getConstructor(Node node) {
    81                  Class<?> cl = getClassForNode(node);
    82                  if (cl.equals(Entity.class) && true) {
    83                      // today's temperature is high :)
    84                      cl = EntityLoadingProxy.class;
    85                  }
    86                  node.setType(cl);
    87                  // call the constructor as if the runtime class is defined
    88                  Construct constructor = yamlClassConstructors.get(node.getNodeId());
    89                  return constructor;
    90              }
    91
    92              public Object construct(Node node) {
    93                  return getConstructor(node).construct(node);
    94              }
    95          }
    96      }
    97  }