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.issue29; 17 18 import java.beans.IntrospectionException; 19 import java.util.ArrayList; 20 import java.util.Arrays; 21 import java.util.Comparator; 22 import java.util.HashMap; 23 import java.util.List; 24 import java.util.Map; 25 import java.util.Set; 26 import java.util.TreeSet; 27 28 import junit.framework.TestCase; 29 30 import org.yaml.snakeyaml.Yaml; 31 import org.yaml.snakeyaml.introspector.BeanAccess; 32 import org.yaml.snakeyaml.introspector.Property; 33 import org.yaml.snakeyaml.nodes.NodeTuple; 34 import org.yaml.snakeyaml.nodes.ScalarNode; 35 import org.yaml.snakeyaml.nodes.SequenceNode; 36 import org.yaml.snakeyaml.nodes.Tag; 37 import org.yaml.snakeyaml.representer.Representer; 38 39 public class FlexibleScalarStylesInJavaBeanTest extends TestCase { testDifferentStyles()40 public void testDifferentStyles() { 41 BigJavaBean bean1 = new BigJavaBean(1, "simple", "line 1\nline2\nzipcode", "short text1"); 42 List<Integer> numbers1 = new ArrayList<Integer>(Arrays.asList(1, 2, 3)); 43 bean1.setNumbers(numbers1); 44 Map<String, String> data1 = new HashMap<String, String>(); 45 data1.put("key1", "value1"); 46 data1.put("key2", "value2"); 47 bean1.setData(data1); 48 // 49 BigJavaBean bean2 = new BigJavaBean(1, "second", "line 111\nline 222\nzipcode 12345\n\n", 50 "info: semicolon is used"); 51 List<Integer> numbers2 = new ArrayList<Integer>(Arrays.asList(4, 5, 6, 777, 888, 999, 1000)); 52 bean2.setNumbers(numbers2); 53 Map<String, String> data2 = new HashMap<String, String>(); 54 data2.put("key21", "value12"); 55 data2.put("key22", "value with\ntwo lines"); 56 bean2.setData(data2); 57 // 58 List<BigJavaBean> list = new ArrayList<BigJavaBean>(); 59 list.add(bean1); 60 list.add(bean2); 61 Yaml yaml = new Yaml(new MyRepresenter()); 62 yaml.setBeanAccess(BeanAccess.FIELD); 63 String output = yaml.dump(list); 64 // System.out.println(output); 65 // parse back 66 @SuppressWarnings("unchecked") 67 List<BigJavaBean> parsed = (List<BigJavaBean>) yaml.load(output); 68 assertEquals(2, parsed.size()); 69 assertEquals(bean1, parsed.get(0)); 70 assertEquals(bean2, parsed.get(1)); 71 72 } 73 74 private class MyRepresenter extends Representer { 75 /* 76 * Change the default order. Important data goes first. 77 */ 78 @Override getProperties(Class<? extends Object> type)79 protected Set<Property> getProperties(Class<? extends Object> type) 80 throws IntrospectionException { 81 if (type.isAssignableFrom(BigJavaBean.class)) { 82 Set<Property> standard = super.getProperties(type); 83 Set<Property> sorted = new TreeSet<Property>(new PropertyComparator()); 84 sorted.addAll(standard); 85 return sorted; 86 } else { 87 return super.getProperties(type); 88 } 89 } 90 91 private class PropertyComparator implements Comparator<Property> { compare(Property o1, Property o2)92 public int compare(Property o1, Property o2) { 93 // important go first 94 List<String> order = new ArrayList<String>(Arrays.asList("id", "name", 95 "description", "address")); 96 for (String name : order) { 97 int c = compareByName(o1, o2, name); 98 if (c != 0) { 99 return c; 100 } 101 } 102 // all the rest 103 return o1.compareTo(o2); 104 } 105 compareByName(Property o1, Property o2, String name)106 private int compareByName(Property o1, Property o2, String name) { 107 if (o1.getName().equals(name)) { 108 return -1; 109 } else if (o2.getName().equals(name)) { 110 return 1; 111 } 112 return 0;// compare further 113 } 114 } 115 116 @Override representJavaBeanProperty(Object javaBean, Property property, Object propertyValue, Tag customTag)117 protected NodeTuple representJavaBeanProperty(Object javaBean, Property property, 118 Object propertyValue, Tag customTag) { 119 if (javaBean instanceof BigJavaBean) { 120 BigJavaBean bean = (BigJavaBean) javaBean; 121 NodeTuple standard = super.representJavaBeanProperty(javaBean, property, 122 propertyValue, customTag); 123 if (property.getName().equals("numbers")) { 124 // when the list is small, make it block collection style 125 if (bean.getNumbers().size() < 5) { 126 SequenceNode n = (SequenceNode) standard.getValueNode(); 127 return new NodeTuple(standard.getKeyNode(), new SequenceNode(n.getTag(), 128 true, n.getValue(), n.getStartMark(), n.getEndMark(), false)); 129 } 130 } 131 if (property.getName().equals("description")) { 132 // if description contains ':' use folded scalar style and 133 // not single quoted scalar style 134 if (bean.getDescription().indexOf(':') > 0) { 135 ScalarNode n = (ScalarNode) standard.getValueNode(); 136 return new NodeTuple(standard.getKeyNode(), new ScalarNode(n.getTag(), 137 n.getValue(), n.getStartMark(), n.getEndMark(), '>')); 138 } 139 } 140 return standard; 141 } else { 142 return super 143 .representJavaBeanProperty(javaBean, property, propertyValue, customTag); 144 } 145 } 146 } 147 } 148