1 /** 2 * Copyright (c) 2008, SnakeYAML 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except 5 * in compliance with the License. You may obtain a copy of the License at 6 * 7 * http://www.apache.org/licenses/LICENSE-2.0 8 * 9 * Unless required by applicable law or agreed to in writing, software distributed under the License 10 * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express 11 * or implied. See the License for the specific language governing permissions and limitations under 12 * the License. 13 */ 14 package org.yaml.snakeyaml.issues.issue29; 15 16 import java.util.ArrayList; 17 import java.util.Arrays; 18 import java.util.Comparator; 19 import java.util.HashMap; 20 import java.util.List; 21 import java.util.Map; 22 import java.util.Set; 23 import java.util.TreeSet; 24 import junit.framework.TestCase; 25 import org.yaml.snakeyaml.DumperOptions; 26 import org.yaml.snakeyaml.Yaml; 27 import org.yaml.snakeyaml.introspector.BeanAccess; 28 import org.yaml.snakeyaml.introspector.Property; 29 import org.yaml.snakeyaml.nodes.NodeTuple; 30 import org.yaml.snakeyaml.nodes.ScalarNode; 31 import org.yaml.snakeyaml.nodes.SequenceNode; 32 import org.yaml.snakeyaml.nodes.Tag; 33 import org.yaml.snakeyaml.representer.Representer; 34 35 public class FlexibleScalarStylesInJavaBeanTest extends TestCase { 36 testDifferentStyles()37 public void testDifferentStyles() { 38 BigJavaBean bean1 = new BigJavaBean(1, "simple", "line 1\nline2\nzipcode", "short text1"); 39 List<Integer> numbers1 = new ArrayList<Integer>(Arrays.asList(1, 2, 3)); 40 bean1.setNumbers(numbers1); 41 Map<String, String> data1 = new HashMap<String, String>(); 42 data1.put("key1", "value1"); 43 data1.put("key2", "value2"); 44 bean1.setData(data1); 45 // 46 BigJavaBean bean2 = new BigJavaBean(1, "second", "line 111\nline 222\nzipcode 12345\n\n", 47 "info: semicolon is used"); 48 List<Integer> numbers2 = new ArrayList<Integer>(Arrays.asList(4, 5, 6, 777, 888, 999, 1000)); 49 bean2.setNumbers(numbers2); 50 Map<String, String> data2 = new HashMap<String, String>(); 51 data2.put("key21", "value12"); 52 data2.put("key22", "value with\ntwo lines"); 53 bean2.setData(data2); 54 // 55 List<BigJavaBean> list = new ArrayList<BigJavaBean>(); 56 list.add(bean1); 57 list.add(bean2); 58 Yaml yaml = new Yaml(new MyRepresenter()); 59 yaml.setBeanAccess(BeanAccess.FIELD); 60 String output = yaml.dump(list); 61 // System.out.println(output); 62 // parse back 63 @SuppressWarnings("unchecked") 64 List<BigJavaBean> parsed = yaml.load(output); 65 assertEquals(2, parsed.size()); 66 assertEquals(bean1, parsed.get(0)); 67 assertEquals(bean2, parsed.get(1)); 68 69 } 70 71 private class MyRepresenter extends Representer { 72 73 /* 74 * Change the default order. Important data goes first. 75 */ 76 @Override getProperties(Class<? extends Object> type)77 protected Set<Property> getProperties(Class<? extends Object> type) { 78 if (type.isAssignableFrom(BigJavaBean.class)) { 79 Set<Property> standard = super.getProperties(type); 80 Set<Property> sorted = new TreeSet<Property>(new PropertyComparator()); 81 sorted.addAll(standard); 82 return sorted; 83 } else { 84 return super.getProperties(type); 85 } 86 } 87 88 private class PropertyComparator implements Comparator<Property> { 89 compare(Property o1, Property o2)90 public int compare(Property o1, Property o2) { 91 // important go first 92 List<String> order = 93 new ArrayList<String>(Arrays.asList("id", "name", "description", "address")); 94 for (String name : order) { 95 int c = compareByName(o1, o2, name); 96 if (c != 0) { 97 return c; 98 } 99 } 100 // all the rest 101 return o1.compareTo(o2); 102 } 103 compareByName(Property o1, Property o2, String name)104 private int compareByName(Property o1, Property o2, String name) { 105 if (o1.getName().equals(name)) { 106 return -1; 107 } else if (o2.getName().equals(name)) { 108 return 1; 109 } 110 return 0;// compare further 111 } 112 } 113 114 @Override representJavaBeanProperty(Object javaBean, Property property, Object propertyValue, Tag customTag)115 protected NodeTuple representJavaBeanProperty(Object javaBean, Property property, 116 Object propertyValue, Tag customTag) { 117 if (javaBean instanceof BigJavaBean) { 118 BigJavaBean bean = (BigJavaBean) javaBean; 119 NodeTuple standard = 120 super.representJavaBeanProperty(javaBean, property, propertyValue, customTag); 121 if (property.getName().equals("numbers")) { 122 // when the list is small, make it block collection style 123 if (bean.getNumbers().size() < 5) { 124 SequenceNode n = (SequenceNode) standard.getValueNode(); 125 return new NodeTuple(standard.getKeyNode(), new SequenceNode(n.getTag(), true, 126 n.getValue(), n.getStartMark(), n.getEndMark(), DumperOptions.FlowStyle.BLOCK)); 127 } 128 } 129 if (property.getName().equals("description")) { 130 // if description contains ':' use folded scalar style and 131 // not single quoted scalar style 132 if (bean.getDescription().indexOf(':') > 0) { 133 ScalarNode n = (ScalarNode) standard.getValueNode(); 134 return new NodeTuple(standard.getKeyNode(), new ScalarNode(n.getTag(), n.getValue(), 135 n.getStartMark(), n.getEndMark(), DumperOptions.ScalarStyle.FOLDED)); 136 } 137 } 138 return standard; 139 } else { 140 return super.representJavaBeanProperty(javaBean, property, propertyValue, customTag); 141 } 142 } 143 } 144 } 145