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.resolver;
17 
18 import java.awt.Point;
19 import java.util.ArrayList;
20 import java.util.LinkedHashMap;
21 import java.util.List;
22 import java.util.Map;
23 import java.util.regex.Pattern;
24 
25 import junit.framework.TestCase;
26 
27 import org.yaml.snakeyaml.DumperOptions;
28 import org.yaml.snakeyaml.Yaml;
29 import org.yaml.snakeyaml.constructor.AbstractConstruct;
30 import org.yaml.snakeyaml.constructor.Constructor;
31 import org.yaml.snakeyaml.nodes.Node;
32 import org.yaml.snakeyaml.nodes.ScalarNode;
33 import org.yaml.snakeyaml.nodes.Tag;
34 import org.yaml.snakeyaml.representer.Represent;
35 import org.yaml.snakeyaml.representer.Representer;
36 
37 public class ResolverTest extends TestCase {
38 
39     @SuppressWarnings("unchecked")
testAddImplicitResolver()40     public void testAddImplicitResolver() {
41         Yaml yaml = new Yaml(new MyConstructor(), new MyRepresenter());
42         Pattern regexp = Pattern.compile("\\d\\d-\\d\\d-\\d\\d\\d");
43         yaml.addImplicitResolver(new Tag(Tag.PREFIX + "Phone"), regexp, "0123456789");
44         Phone phone1 = new Phone("12-34-567");
45         Phone phone2 = new Phone("11-22-333");
46         Phone phone3 = new Phone("44-55-777");
47         List<Phone> etalonList = new ArrayList<Phone>();
48         etalonList.add(phone1);
49         etalonList.add(phone2);
50         etalonList.add(phone3);
51         String output = yaml.dump(etalonList);
52         assertEquals("[12-34-567, 11-22-333, 44-55-777]\n", output);
53         List<Phone> parsedList = (List<Phone>) yaml.load(output);
54         assertEquals(3, parsedList.size());
55         assertEquals(phone1, parsedList.get(0));
56         assertEquals(phone2, parsedList.get(1));
57         assertEquals(phone3, parsedList.get(2));
58         assertEquals(etalonList, parsedList);
59     }
60 
testAddImplicitResolver2()61     public void testAddImplicitResolver2() {
62         Yaml yaml = new Yaml(new PointRepresenter());
63         Pattern regexp = Pattern.compile("\\d\\d-\\d\\d-\\d\\d\\d");
64         yaml.addImplicitResolver(new Tag(Tag.PREFIX + "Phone"), regexp, "\0");
65         Pattern regexp2 = Pattern.compile("x\\d_y\\d");
66         // try any scalar, and not only those which start with 'x'
67         yaml.addImplicitResolver(new Tag(Tag.PREFIX + "Point"), regexp2, null);
68         Map<String, Object> map = new LinkedHashMap<String, Object>();
69         map.put("a", new Phone("12-34-567"));
70         map.put("b", new Point(1, 5));
71         String output = yaml.dump(map);
72         assertEquals("{a: 12-34-567, b: x1_y5}\n", output);
73     }
74 
75     class Phone {
76         private String number;
77 
Phone(String n)78         public Phone(String n) {
79             this.number = n;
80         }
81 
getNumber()82         public String getNumber() {
83             return number;
84         }
85 
86         @Override
equals(Object obj)87         public boolean equals(Object obj) {
88             if (!(obj instanceof Phone)) {
89                 return false;
90             }
91             return toString().equals(obj.toString());
92         }
93 
94         @Override
toString()95         public String toString() {
96             return "Phone: " + number;
97         }
98     }
99 
100     class MyRepresenter extends Representer {
MyRepresenter()101         public MyRepresenter() {
102             this.representers.put(Phone.class, new RepresentPhone());
103         }
104 
105         private class RepresentPhone implements Represent {
representData(Object data)106             public Node representData(Object data) {
107                 Phone phone = (Phone) data;
108                 String value = phone.getNumber();
109                 return representScalar(new Tag(Tag.PREFIX + "Phone"), value);
110             }
111         }
112     }
113 
114     class MyConstructor extends Constructor {
MyConstructor()115         public MyConstructor() {
116             this.yamlConstructors.put(new Tag(Tag.PREFIX + "Phone"), new ConstructPhone());
117         }
118 
119         private class ConstructPhone extends AbstractConstruct {
construct(Node node)120             public Object construct(Node node) {
121                 String val = (String) constructScalar((ScalarNode) node);
122                 return new Phone(val);
123             }
124         }
125     }
126 
127     class PointRepresenter extends Representer {
PointRepresenter()128         public PointRepresenter() {
129             this.representers.put(Point.class, new RepresentPoint());
130             this.representers.put(Phone.class, new RepresentPhone());
131         }
132 
133         private class RepresentPoint implements Represent {
representData(Object data)134             public Node representData(Object data) {
135                 Point phone = (Point) data;
136                 String value = "x" + (int) phone.getX() + "_y" + (int) phone.getY();
137                 return representScalar(new Tag(Tag.PREFIX + "Point"), value);
138             }
139         }
140 
141         private class RepresentPhone implements Represent {
representData(Object data)142             public Node representData(Object data) {
143                 Phone phone = (Phone) data;
144                 String value = phone.getNumber();
145                 return representScalar(new Tag(Tag.PREFIX + "Phone"), value);
146             }
147         }
148     }
149 
150 }
151