View Javadoc
1 /* ==================================================================== 2 * Bigyo Software License, version 1.1 3 * 4 * Copyright (c) 2004, Zsombor Gegesy. All rights reserved. 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 9 * 1. Redistributions of source code must retain the above copyright 10 * notice, this list of conditions and the following disclaimer. 11 * 12 * 2. Redistributions in binary form must reproduce the above copyright 13 * notice, this list of conditions and the following disclaimer in 14 * the documentation and/or other materials provided with the 15 * distribution. 16 * 17 * 3. Neither the name of the Bigyo Group nor the name "Bigyo" nor 18 * the names of its contributors may be used to endorse or promote 19 * products derived from this software without specific prior 20 * written permission. 21 * 22 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 23 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 24 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 25 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 26 * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 27 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 28 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 29 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 30 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 31 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN 32 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 33 * POSSIBILITY OF SUCH DAMAGE. 34 * 35 * ==================================================================== 36 */ 37 38 package net.sf.bigyo.container; 39 40 import java.util.ArrayList; 41 import java.util.Iterator; 42 import java.util.List; 43 44 import com.thoughtworks.xstream.XStream; 45 import com.thoughtworks.xstream.alias.ClassMapper; 46 import com.thoughtworks.xstream.converters.Converter; 47 import com.thoughtworks.xstream.converters.ConverterLookup; 48 import com.thoughtworks.xstream.converters.ErrorWriter; 49 import com.thoughtworks.xstream.converters.MarshallingContext; 50 import com.thoughtworks.xstream.converters.UnmarshallingContext; 51 import com.thoughtworks.xstream.converters.reflection.ReflectionProvider; 52 import com.thoughtworks.xstream.core.JVM; 53 import com.thoughtworks.xstream.io.HierarchicalStreamReader; 54 import com.thoughtworks.xstream.io.HierarchicalStreamWriter; 55 56 /*** 57 * Creates a more 'compact' xml, instead of the verbose default. Usage: XStream 58 * xs = .... xs.registerConverter(new CompactReflectionConverter(xs)); 59 * 60 * Created on 2004.04.17. 61 * @author zombi@mailbox.hu 62 * 63 * 64 */ 65 public class CompactReflectionConverter implements Converter { 66 67 private ClassMapper classMapper; 68 private String classAttributeIdentifier; 69 ReflectionProvider reflectionProvider; 70 ConverterLookup lookup; 71 private String definedInAttributeIdentifier = "defined-in"; 72 private boolean accept = true; 73 74 public CompactReflectionConverter(ClassMapper classMapper, String classAttributeIdentifier, 75 ReflectionProvider reflectionProvider, ConverterLookup lookup) { 76 this.classMapper = classMapper; 77 this.classAttributeIdentifier = classAttributeIdentifier; 78 this.reflectionProvider = reflectionProvider; 79 this.lookup = lookup; 80 } 81 82 /*** 83 * @param xstream 84 */ 85 public CompactReflectionConverter(XStream xstream) { 86 this(xstream.getClassMapper(), "class-name", new JVM().bestReflectionProvider(), xstream.getConverterLookup()); 87 } 88 89 /* 90 * (non-Javadoc) 91 * 92 * @see com.thoughtworks.xstream.converters.reflection.ReflectionConverter#canConvert(java.lang.Class) 93 */ 94 public boolean canConvert(Class cls) { 95 if (accept) { 96 if (!cls.isPrimitive() && !cls.isArray() && !cls.isInterface()) { 97 return !cls.getName().startsWith("java."); 98 } 99 } 100 return false; 101 } 102 103 public void setAccept(boolean b) { 104 this.accept = b; 105 } 106 107 108 static class Record { 109 String fieldName; 110 Class fieldType; 111 Object newObj; 112 113 /*** 114 * @param fieldName 115 * @param fieldType 116 * @param newObj 117 */ 118 public Record(String fieldName, Class fieldType, Object newObj) { 119 super(); 120 this.fieldName = fieldName; 121 this.fieldType = fieldType; 122 this.newObj = newObj; 123 } 124 } 125 126 public void marshal(final Object source, final HierarchicalStreamWriter writer, final MarshallingContext context) { 127 final List complexFields = new ArrayList(); 128 reflectionProvider.visitSerializableFields(source, new ReflectionProvider.Visitor() { 129 130 public void visit(String fieldName, Class fieldType, Class definedIn, Object value) { 131 132 /* 133 * Object newObj = reflectionProvider.readField(source, 134 * fieldName); if (newObj != null) { Class actualType = 135 * newObj.getClass(); if 136 * (actualType.getName().startsWith("java.lang.")) { 137 * writer.addAttribute(fieldName, newObj.toString()); } else { 138 * complexFields.add(new Record(fieldName, fieldType, newObj)); 139 * } } 140 */ 141 142 if (value != null) { 143 Class actualType = value.getClass(); 144 if (actualType.getName().startsWith("java.lang.")) { 145 writer.addAttribute(fieldName, value.toString()); 146 } else { 147 complexFields.add(new Record(fieldName, fieldType, value)); 148 } 149 } 150 } 151 }); 152 for (Iterator iter = complexFields.iterator(); iter.hasNext();) { 153 Record r = (Record) iter.next(); 154 writer.startNode(classMapper.mapNameToXML(r.fieldName)); 155 Class defaultType = classMapper.lookupDefaultType(r.fieldType); 156 Class actualType = r.newObj.getClass(); 157 if (!actualType.equals(defaultType)) { 158 writer.addAttribute(classAttributeIdentifier, classMapper.lookupName(actualType)); 159 } 160 161 context.convertAnother(r.newObj); 162 163 writer.endNode(); 164 165 } 166 167 } 168 169 public Object unmarshal(final HierarchicalStreamReader reader, UnmarshallingContext context) { 170 // copy from ReflectionProvider 171 Object result = context.currentObject(); 172 173 if (result == null) { 174 result = reflectionProvider.newInstance(context.getRequiredType()); 175 } 176 // de-serialize simple fields 177 178 final Object finalResult = result; 179 reflectionProvider.visitSerializableFields(result, new ReflectionProvider.Visitor() { 180 181 /* 182 * (non-Javadoc) 183 * 184 * @see com.thoughtworks.xstream.converters.reflection.ReflectionProvider.Visitor#visit(java.lang.String, 185 * java.lang.Class, java.lang.Class, java.lang.Object) 186 */ 187 public void visit(String fieldName, Class fieldType, Class definedIn, Object value) { 188 if (fieldType.getName().startsWith("java.lang.") || fieldType.isPrimitive()) { 189 Converter converter = lookup.lookupConverterForType(fieldType); 190 final String fieldAttr = reader.getAttribute(fieldName); 191 if (fieldAttr != null) { 192 193 Object fieldValue = converter.unmarshal(new HierarchicalStreamReader() { 194 /* 195 * (non-Javadoc) 196 * 197 * @see com.thoughtworks.xstream.io.HierarchicalStreamReader#getValue() 198 */ 199 public String getValue() { 200 return fieldAttr; 201 } 202 203 public boolean hasMoreChildren() { 204 return false; 205 } 206 207 public void moveDown() { 208 209 } 210 211 public void moveUp() { 212 213 } 214 215 public String getNodeName() { 216 return null; 217 } 218 219 public String getAttribute(String arg0) { 220 return null; 221 } 222 223 public Object peekUnderlyingNode() { 224 return null; 225 } 226 227 public void appendErrors(ErrorWriter errorWriter) { 228 // TODO Auto-generated method stub 229 230 } 231 }, null); 232 reflectionProvider.writeField(finalResult, fieldName, fieldValue, definedIn); 233 //writeField(finalResult, fieldName, fieldValue); 234 } 235 } 236 } 237 }); 238 239 // copy from ReflectionProvider 240 241 while (reader.hasMoreChildren()) { 242 reader.moveDown(); 243 244 String fieldName = classMapper.mapNameFromXML(reader.getNodeName()); 245 246 String definedIn = reader.getAttribute(definedInAttributeIdentifier); 247 Class definedInCls = definedIn == null ? null : classMapper.lookupType(definedIn); 248 249 Class type; 250 String classAttribute = reader.getAttribute(classAttributeIdentifier); 251 if (classAttribute == null) { 252 type = classMapper.lookupDefaultType(reflectionProvider.getFieldType(result, fieldName, definedInCls)); 253 } else { 254 type = classMapper.lookupType(classAttribute); 255 } 256 257 Object fieldValue = context.convertAnother(result, type); 258 259 reflectionProvider.writeField(result, fieldName, fieldValue, definedInCls); 260 261 reader.moveUp(); 262 } 263 264 return result; 265 } 266 }

This page was automatically generated by Maven