1 package com.thoughtworks.xstream.converters.extended; 2 3 import com.thoughtworks.xstream.converters.ConversionException; 4 import com.thoughtworks.xstream.converters.Converter; 5 import com.thoughtworks.xstream.converters.MarshallingContext; 6 import com.thoughtworks.xstream.converters.UnmarshallingContext; 7 import com.thoughtworks.xstream.io.HierarchicalStreamReader; 8 import com.thoughtworks.xstream.io.HierarchicalStreamWriter; 9 10 import java.lang.reflect.Constructor ; 11 import java.lang.reflect.Method ; 12 import java.util.ArrayList ; 13 import java.util.List ; 14 15 20 public class JavaMethodConverter implements Converter { 21 22 private final ClassLoader classLoader; 23 24 public JavaMethodConverter() { 25 this(JavaMethodConverter.class.getClassLoader()); 26 } 27 28 public JavaMethodConverter(ClassLoader classLoader) { 29 this.classLoader = classLoader; 30 } 31 32 public boolean canConvert(Class type) { 33 return type.equals(Method .class) || type.equals(Constructor .class); 34 } 35 36 public void marshal(Object source, HierarchicalStreamWriter writer, MarshallingContext context) { 37 if (source instanceof Method ) { 38 Method method = (Method ) source; 39 String declaringClassName = method.getDeclaringClass().getName(); 40 marshalMethod(writer, declaringClassName, method.getName(), method.getParameterTypes()); 41 } else { 42 Constructor method = (Constructor ) source; 43 String declaringClassName = method.getDeclaringClass().getName(); 44 marshalMethod(writer, declaringClassName, null, method.getParameterTypes()); 45 } 46 } 47 48 private void marshalMethod(HierarchicalStreamWriter writer, String declaringClassName, String methodName, Class [] parameterTypes) { 49 50 writer.startNode("class"); 51 writer.setValue(declaringClassName); 52 writer.endNode(); 53 54 if (methodName != null) { 55 writer.startNode("name"); 57 writer.setValue(methodName); 58 writer.endNode(); 59 } 60 61 writer.startNode("parameter-types"); 62 for (int i = 0; i < parameterTypes.length; i++) { 63 Class parameterType = parameterTypes[i]; 64 writer.startNode("class"); 65 writer.setValue(parameterType.getName()); 66 writer.endNode(); 67 } 68 writer.endNode(); 69 } 70 71 public Object unmarshal(HierarchicalStreamReader reader, UnmarshallingContext context) { 72 try { 73 boolean isMethodNotConstructor = context.getRequiredType().equals(Method .class); 74 75 reader.moveDown(); 76 String declaringClassName = reader.getValue(); 77 Class declaringClass = loadClass(declaringClassName); 78 reader.moveUp(); 79 80 String methodName = null; 81 if (isMethodNotConstructor) { 82 reader.moveDown(); 83 methodName = reader.getValue(); 84 reader.moveUp(); 85 } 86 87 reader.moveDown(); 88 List parameterTypeList = new ArrayList (); 89 while (reader.hasMoreChildren()) { 90 reader.moveDown(); 91 String parameterTypeName = reader.getValue(); 92 parameterTypeList.add(loadClass(parameterTypeName)); 93 reader.moveUp(); 94 } 95 Class [] parameterTypes = (Class []) parameterTypeList.toArray(new Class [parameterTypeList.size()]); 96 reader.moveUp(); 97 98 if (isMethodNotConstructor) { 99 return declaringClass.getMethod(methodName, parameterTypes); 100 } else { 101 return declaringClass.getConstructor(parameterTypes); 102 } 103 } catch (ClassNotFoundException e) { 104 throw new ConversionException(e); 105 } catch (NoSuchMethodException e) { 106 throw new ConversionException(e); 107 } 108 } 109 110 private Class loadClass(String className) throws ClassNotFoundException { 111 return classLoader.loadClass(className); 112 } 113 } 114 | Popular Tags |