1 package com.thoughtworks.xstream.converters.extended; 2 3 import com.thoughtworks.xstream.alias.ClassMapper; 4 import com.thoughtworks.xstream.converters.ConversionException; 5 import com.thoughtworks.xstream.converters.Converter; 6 import com.thoughtworks.xstream.converters.MarshallingContext; 7 import com.thoughtworks.xstream.converters.UnmarshallingContext; 8 import com.thoughtworks.xstream.io.HierarchicalStreamReader; 9 import com.thoughtworks.xstream.io.HierarchicalStreamWriter; 10 11 import java.lang.reflect.InvocationHandler ; 12 import java.lang.reflect.Proxy ; 13 import java.util.ArrayList ; 14 import java.util.List ; 15 16 22 public class DynamicProxyConverter implements Converter { 23 24 private ClassLoader classLoader; 25 private ClassMapper classMapper; 26 27 public DynamicProxyConverter(ClassMapper classMapper) { 28 this(classMapper, DynamicProxyConverter.class.getClassLoader()); 29 } 30 31 public DynamicProxyConverter(ClassMapper classMapper, ClassLoader classLoader) { 32 this.classLoader = classLoader; 33 this.classMapper = classMapper; 34 } 35 36 public boolean canConvert(Class type) { 37 return type.equals(ClassMapper.DynamicProxy.class) || Proxy.isProxyClass(type); 38 } 39 40 public void marshal(Object source, HierarchicalStreamWriter writer, MarshallingContext context) { 41 InvocationHandler invocationHandler = Proxy.getInvocationHandler(source); 42 addInterfacesToXml(source, writer); 43 writer.startNode("handler"); 44 writer.addAttribute("class", classMapper.lookupName(invocationHandler.getClass())); 45 context.convertAnother(invocationHandler); 46 writer.endNode(); 47 } 48 49 private void addInterfacesToXml(Object source, HierarchicalStreamWriter writer) { 50 Class [] interfaces = source.getClass().getInterfaces(); 51 for (int i = 0; i < interfaces.length; i++) { 52 Class currentInterface = interfaces[i]; 53 writer.startNode("interface"); 54 writer.setValue(classMapper.lookupName(currentInterface)); 55 writer.endNode(); 56 } 57 } 58 59 public Object unmarshal(HierarchicalStreamReader reader, UnmarshallingContext context) { 60 List interfaces = new ArrayList (); 61 InvocationHandler handler = null; 62 while (reader.hasMoreChildren()) { 63 reader.moveDown(); 64 String elementName = reader.getNodeName(); 65 if (elementName.equals("interface")) { 66 interfaces.add(classMapper.lookupType(reader.getValue())); 67 } else if (elementName.equals("handler")) { 68 Class handlerType = classMapper.lookupType(reader.getAttribute("class")); 69 handler = (InvocationHandler ) context.convertAnother(null, handlerType); 70 } 71 reader.moveUp(); 72 } 73 if (handler == null) { 74 throw new ConversionException("No InvocationHandler specified for dynamic proxy"); 75 } 76 Class [] interfacesAsArray = new Class [interfaces.size()]; 77 interfaces.toArray(interfacesAsArray); 78 return Proxy.newProxyInstance(classLoader, interfacesAsArray, handler); 79 } 80 } 81 | Popular Tags |