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