1*ac2a7c1bSSadaf Ebrahimi /** 2*ac2a7c1bSSadaf Ebrahimi * Copyright (c) 2008, SnakeYAML 3*ac2a7c1bSSadaf Ebrahimi * 4*ac2a7c1bSSadaf Ebrahimi * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except 5*ac2a7c1bSSadaf Ebrahimi * in compliance with the License. You may obtain a copy of the License at 6*ac2a7c1bSSadaf Ebrahimi * 7*ac2a7c1bSSadaf Ebrahimi * http://www.apache.org/licenses/LICENSE-2.0 8*ac2a7c1bSSadaf Ebrahimi * 9*ac2a7c1bSSadaf Ebrahimi * Unless required by applicable law or agreed to in writing, software distributed under the License 10*ac2a7c1bSSadaf Ebrahimi * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express 11*ac2a7c1bSSadaf Ebrahimi * or implied. See the License for the specific language governing permissions and limitations under 12*ac2a7c1bSSadaf Ebrahimi * the License. 13*ac2a7c1bSSadaf Ebrahimi */ 14*ac2a7c1bSSadaf Ebrahimi package examples; 15*ac2a7c1bSSadaf Ebrahimi 16*ac2a7c1bSSadaf Ebrahimi import java.util.HashMap; 17*ac2a7c1bSSadaf Ebrahimi import java.util.Map; 18*ac2a7c1bSSadaf Ebrahimi import java.util.Objects; 19*ac2a7c1bSSadaf Ebrahimi import java.util.regex.Pattern; 20*ac2a7c1bSSadaf Ebrahimi import junit.framework.TestCase; 21*ac2a7c1bSSadaf Ebrahimi import org.yaml.snakeyaml.DumperOptions; 22*ac2a7c1bSSadaf Ebrahimi import org.yaml.snakeyaml.Yaml; 23*ac2a7c1bSSadaf Ebrahimi import org.yaml.snakeyaml.constructor.AbstractConstruct; 24*ac2a7c1bSSadaf Ebrahimi import org.yaml.snakeyaml.constructor.Constructor; 25*ac2a7c1bSSadaf Ebrahimi import org.yaml.snakeyaml.nodes.Node; 26*ac2a7c1bSSadaf Ebrahimi import org.yaml.snakeyaml.nodes.ScalarNode; 27*ac2a7c1bSSadaf Ebrahimi import org.yaml.snakeyaml.nodes.Tag; 28*ac2a7c1bSSadaf Ebrahimi import org.yaml.snakeyaml.representer.Represent; 29*ac2a7c1bSSadaf Ebrahimi import org.yaml.snakeyaml.representer.Representer; 30*ac2a7c1bSSadaf Ebrahimi 31*ac2a7c1bSSadaf Ebrahimi public class DiceExampleTest extends TestCase { 32*ac2a7c1bSSadaf Ebrahimi testRepresenter()33*ac2a7c1bSSadaf Ebrahimi public void testRepresenter() { 34*ac2a7c1bSSadaf Ebrahimi Dice dice = new Dice(3, 6); 35*ac2a7c1bSSadaf Ebrahimi DumperOptions options = new DumperOptions(); 36*ac2a7c1bSSadaf Ebrahimi options.setAllowReadOnlyProperties(true); 37*ac2a7c1bSSadaf Ebrahimi Yaml yaml = new Yaml(options); 38*ac2a7c1bSSadaf Ebrahimi String output = yaml.dump(dice); 39*ac2a7c1bSSadaf Ebrahimi assertEquals("!!examples.Dice {a: 3, b: 6}\n", output); 40*ac2a7c1bSSadaf Ebrahimi } 41*ac2a7c1bSSadaf Ebrahimi testDiceRepresenter()42*ac2a7c1bSSadaf Ebrahimi public void testDiceRepresenter() { 43*ac2a7c1bSSadaf Ebrahimi Dice dice = new Dice(3, 6); 44*ac2a7c1bSSadaf Ebrahimi Map<String, Dice> data = new HashMap<String, Dice>(); 45*ac2a7c1bSSadaf Ebrahimi data.put("gold", dice); 46*ac2a7c1bSSadaf Ebrahimi Yaml yaml = new Yaml(new DiceRepresenter(), new DumperOptions()); 47*ac2a7c1bSSadaf Ebrahimi String output = yaml.dump(data); 48*ac2a7c1bSSadaf Ebrahimi assertEquals("{gold: !dice '3d6'}\n", output); 49*ac2a7c1bSSadaf Ebrahimi } 50*ac2a7c1bSSadaf Ebrahimi 51*ac2a7c1bSSadaf Ebrahimi class DiceRepresenter extends Representer { 52*ac2a7c1bSSadaf Ebrahimi DiceRepresenter()53*ac2a7c1bSSadaf Ebrahimi public DiceRepresenter() { 54*ac2a7c1bSSadaf Ebrahimi this.representers.put(Dice.class, new RepresentDice()); 55*ac2a7c1bSSadaf Ebrahimi } 56*ac2a7c1bSSadaf Ebrahimi 57*ac2a7c1bSSadaf Ebrahimi private class RepresentDice implements Represent { 58*ac2a7c1bSSadaf Ebrahimi representData(Object data)59*ac2a7c1bSSadaf Ebrahimi public Node representData(Object data) { 60*ac2a7c1bSSadaf Ebrahimi Dice dice = (Dice) data; 61*ac2a7c1bSSadaf Ebrahimi String value = dice.getA() + "d" + dice.getB(); 62*ac2a7c1bSSadaf Ebrahimi return representScalar(new Tag("!dice"), value); 63*ac2a7c1bSSadaf Ebrahimi } 64*ac2a7c1bSSadaf Ebrahimi } 65*ac2a7c1bSSadaf Ebrahimi } 66*ac2a7c1bSSadaf Ebrahimi 67*ac2a7c1bSSadaf Ebrahimi class DiceConstructor extends Constructor { 68*ac2a7c1bSSadaf Ebrahimi DiceConstructor()69*ac2a7c1bSSadaf Ebrahimi public DiceConstructor() { 70*ac2a7c1bSSadaf Ebrahimi this.yamlConstructors.put(new Tag("!dice"), new ConstructDice()); 71*ac2a7c1bSSadaf Ebrahimi } 72*ac2a7c1bSSadaf Ebrahimi 73*ac2a7c1bSSadaf Ebrahimi private class ConstructDice extends AbstractConstruct { 74*ac2a7c1bSSadaf Ebrahimi construct(Node node)75*ac2a7c1bSSadaf Ebrahimi public Object construct(Node node) { 76*ac2a7c1bSSadaf Ebrahimi String val = constructScalar((ScalarNode) node); 77*ac2a7c1bSSadaf Ebrahimi int position = val.indexOf('d'); 78*ac2a7c1bSSadaf Ebrahimi Integer a = Integer.valueOf(val.substring(0, position)); 79*ac2a7c1bSSadaf Ebrahimi Integer b = Integer.valueOf(val.substring(position + 1)); 80*ac2a7c1bSSadaf Ebrahimi return new Dice(a, b); 81*ac2a7c1bSSadaf Ebrahimi } 82*ac2a7c1bSSadaf Ebrahimi } 83*ac2a7c1bSSadaf Ebrahimi } 84*ac2a7c1bSSadaf Ebrahimi 85*ac2a7c1bSSadaf Ebrahimi @SuppressWarnings("unchecked") testConstructor()86*ac2a7c1bSSadaf Ebrahimi public void testConstructor() { 87*ac2a7c1bSSadaf Ebrahimi Yaml yaml = new Yaml(new DiceConstructor()); 88*ac2a7c1bSSadaf Ebrahimi Object data = yaml.load("{initial hit points: !dice '8d4'}"); 89*ac2a7c1bSSadaf Ebrahimi Map<String, Dice> map = (Map<String, Dice>) data; 90*ac2a7c1bSSadaf Ebrahimi assertEquals(new Dice(8, 4), map.get("initial hit points")); 91*ac2a7c1bSSadaf Ebrahimi } 92*ac2a7c1bSSadaf Ebrahimi 93*ac2a7c1bSSadaf Ebrahimi // the tag must start with a digit 94*ac2a7c1bSSadaf Ebrahimi @SuppressWarnings("unchecked") testImplicitResolver()95*ac2a7c1bSSadaf Ebrahimi public void testImplicitResolver() { 96*ac2a7c1bSSadaf Ebrahimi Yaml yaml = new Yaml(new DiceConstructor(), new DiceRepresenter()); 97*ac2a7c1bSSadaf Ebrahimi // the tag must start with a digit 98*ac2a7c1bSSadaf Ebrahimi yaml.addImplicitResolver(new Tag("!dice"), Pattern.compile("\\d+d\\d+"), "123456789"); 99*ac2a7c1bSSadaf Ebrahimi // dump 100*ac2a7c1bSSadaf Ebrahimi Map<String, Dice> treasure = new HashMap<String, Dice>(); 101*ac2a7c1bSSadaf Ebrahimi treasure.put("treasure", new Dice(10, 20)); 102*ac2a7c1bSSadaf Ebrahimi String output = yaml.dump(treasure); 103*ac2a7c1bSSadaf Ebrahimi assertEquals("{treasure: 10d20}\n", output); 104*ac2a7c1bSSadaf Ebrahimi // load 105*ac2a7c1bSSadaf Ebrahimi Object data = yaml.load("{damage: 5d10}"); 106*ac2a7c1bSSadaf Ebrahimi Map<String, Dice> map = (Map<String, Dice>) data; 107*ac2a7c1bSSadaf Ebrahimi assertEquals(new Dice(5, 10), map.get("damage")); 108*ac2a7c1bSSadaf Ebrahimi } 109*ac2a7c1bSSadaf Ebrahimi 110*ac2a7c1bSSadaf Ebrahimi // the tag may start with anything 111*ac2a7c1bSSadaf Ebrahimi @SuppressWarnings("unchecked") testImplicitResolverWithNull()112*ac2a7c1bSSadaf Ebrahimi public void testImplicitResolverWithNull() { 113*ac2a7c1bSSadaf Ebrahimi Yaml yaml = new Yaml(new DiceConstructor(), new DiceRepresenter()); 114*ac2a7c1bSSadaf Ebrahimi // the tag may start with anything 115*ac2a7c1bSSadaf Ebrahimi yaml.addImplicitResolver(new Tag("!dice"), Pattern.compile("\\d+d\\d+"), null); 116*ac2a7c1bSSadaf Ebrahimi // dump 117*ac2a7c1bSSadaf Ebrahimi Map<String, Dice> treasure = new HashMap<String, Dice>(); 118*ac2a7c1bSSadaf Ebrahimi treasure.put("treasure", new Dice(10, 20)); 119*ac2a7c1bSSadaf Ebrahimi String output = yaml.dump(treasure); 120*ac2a7c1bSSadaf Ebrahimi assertEquals("{treasure: 10d20}\n", output); 121*ac2a7c1bSSadaf Ebrahimi // load 122*ac2a7c1bSSadaf Ebrahimi Object data = yaml.load("{damage: 5d10}"); 123*ac2a7c1bSSadaf Ebrahimi Map<String, Dice> map = (Map<String, Dice>) data; 124*ac2a7c1bSSadaf Ebrahimi assertEquals(new Dice(5, 10), map.get("damage")); 125*ac2a7c1bSSadaf Ebrahimi } 126*ac2a7c1bSSadaf Ebrahimi 127*ac2a7c1bSSadaf Ebrahimi static class DiceBean { 128*ac2a7c1bSSadaf Ebrahimi 129*ac2a7c1bSSadaf Ebrahimi public Dice treasure; 130*ac2a7c1bSSadaf Ebrahimi 131*ac2a7c1bSSadaf Ebrahimi @Override equals(Object o)132*ac2a7c1bSSadaf Ebrahimi public boolean equals(Object o) { 133*ac2a7c1bSSadaf Ebrahimi if (this == o) { 134*ac2a7c1bSSadaf Ebrahimi return true; 135*ac2a7c1bSSadaf Ebrahimi } 136*ac2a7c1bSSadaf Ebrahimi if (!(o instanceof DiceBean)) { 137*ac2a7c1bSSadaf Ebrahimi return false; 138*ac2a7c1bSSadaf Ebrahimi } 139*ac2a7c1bSSadaf Ebrahimi 140*ac2a7c1bSSadaf Ebrahimi DiceBean diceBean = (DiceBean) o; 141*ac2a7c1bSSadaf Ebrahimi return Objects.equals(treasure, diceBean.treasure); 142*ac2a7c1bSSadaf Ebrahimi } 143*ac2a7c1bSSadaf Ebrahimi 144*ac2a7c1bSSadaf Ebrahimi @Override hashCode()145*ac2a7c1bSSadaf Ebrahimi public int hashCode() { 146*ac2a7c1bSSadaf Ebrahimi return treasure != null ? treasure.hashCode() : 0; 147*ac2a7c1bSSadaf Ebrahimi } 148*ac2a7c1bSSadaf Ebrahimi } 149*ac2a7c1bSSadaf Ebrahimi testImplicitResolverJavaBean()150*ac2a7c1bSSadaf Ebrahimi public void testImplicitResolverJavaBean() { 151*ac2a7c1bSSadaf Ebrahimi Yaml yaml = new Yaml(new DiceConstructor(), new DiceRepresenter()); 152*ac2a7c1bSSadaf Ebrahimi // the tag must start with a digit 153*ac2a7c1bSSadaf Ebrahimi yaml.addImplicitResolver(new Tag("!dice"), Pattern.compile("\\d+d\\d+"), "123456789"); 154*ac2a7c1bSSadaf Ebrahimi // dump 155*ac2a7c1bSSadaf Ebrahimi DiceBean bean = new DiceBean(); 156*ac2a7c1bSSadaf Ebrahimi bean.treasure = new Dice(10, 20); 157*ac2a7c1bSSadaf Ebrahimi String output = yaml.dump(bean); 158*ac2a7c1bSSadaf Ebrahimi assertEquals("!!examples.DiceExampleTest$DiceBean {treasure: 10d20}\n", output); 159*ac2a7c1bSSadaf Ebrahimi // load 160*ac2a7c1bSSadaf Ebrahimi Object loaded = yaml.load(output); 161*ac2a7c1bSSadaf Ebrahimi assertEquals(loaded, bean); 162*ac2a7c1bSSadaf Ebrahimi } 163*ac2a7c1bSSadaf Ebrahimi } 164