001: /*
002: * Copyright (C) 2004, 2005 Joe Walnes.
003: * Copyright (C) 2006, 2007 XStream Committers.
004: * All rights reserved.
005: *
006: * The software in this package is published under the terms of the BSD
007: * style license a copy of which has been included with this distribution in
008: * the LICENSE.txt file.
009: *
010: * Created on 04. April 2004 by Joe Walnes
011: */
012: package com.thoughtworks.xstream.converters.extended;
013:
014: import com.thoughtworks.xstream.converters.ConversionException;
015: import com.thoughtworks.xstream.converters.Converter;
016: import com.thoughtworks.xstream.converters.MarshallingContext;
017: import com.thoughtworks.xstream.converters.SingleValueConverter;
018: import com.thoughtworks.xstream.converters.UnmarshallingContext;
019: import com.thoughtworks.xstream.io.HierarchicalStreamReader;
020: import com.thoughtworks.xstream.io.HierarchicalStreamWriter;
021:
022: import java.lang.reflect.Constructor;
023: import java.lang.reflect.Method;
024: import java.util.ArrayList;
025: import java.util.List;
026:
027: /**
028: * Converts a java.lang.reflect.Method to XML.
029: *
030: * @author Aslak Hellesøy
031: * @author Jörg Schaible
032: */
033: public class JavaMethodConverter implements Converter {
034:
035: private final SingleValueConverter javaClassConverter;
036:
037: /**
038: * @deprecated As of 1.2 - use other constructor and explicitly supply a ClassLoader.
039: */
040: public JavaMethodConverter() {
041: this (JavaMethodConverter.class.getClassLoader());
042: }
043:
044: public JavaMethodConverter(ClassLoader classLoader) {
045: this .javaClassConverter = new JavaClassConverter(classLoader);
046: }
047:
048: public boolean canConvert(Class type) {
049: return type.equals(Method.class)
050: || type.equals(Constructor.class);
051: }
052:
053: public void marshal(Object source, HierarchicalStreamWriter writer,
054: MarshallingContext context) {
055: if (source instanceof Method) {
056: Method method = (Method) source;
057: String declaringClassName = javaClassConverter
058: .toString(method.getDeclaringClass());
059: marshalMethod(writer, declaringClassName, method.getName(),
060: method.getParameterTypes());
061: } else {
062: Constructor method = (Constructor) source;
063: String declaringClassName = javaClassConverter
064: .toString(method.getDeclaringClass());
065: marshalMethod(writer, declaringClassName, null, method
066: .getParameterTypes());
067: }
068: }
069:
070: private void marshalMethod(HierarchicalStreamWriter writer,
071: String declaringClassName, String methodName,
072: Class[] parameterTypes) {
073:
074: writer.startNode("class");
075: writer.setValue(declaringClassName);
076: writer.endNode();
077:
078: if (methodName != null) {
079: // it's a method and not a ctor
080: writer.startNode("name");
081: writer.setValue(methodName);
082: writer.endNode();
083: }
084:
085: writer.startNode("parameter-types");
086: for (int i = 0; i < parameterTypes.length; i++) {
087: writer.startNode("class");
088: writer.setValue(javaClassConverter
089: .toString(parameterTypes[i]));
090: writer.endNode();
091: }
092: writer.endNode();
093: }
094:
095: public Object unmarshal(HierarchicalStreamReader reader,
096: UnmarshallingContext context) {
097: try {
098: boolean isMethodNotConstructor = context.getRequiredType()
099: .equals(Method.class);
100:
101: reader.moveDown();
102: String declaringClassName = reader.getValue();
103: Class declaringClass = (Class) javaClassConverter
104: .fromString(declaringClassName);
105: reader.moveUp();
106:
107: String methodName = null;
108: if (isMethodNotConstructor) {
109: reader.moveDown();
110: methodName = reader.getValue();
111: reader.moveUp();
112: }
113:
114: reader.moveDown();
115: List parameterTypeList = new ArrayList();
116: while (reader.hasMoreChildren()) {
117: reader.moveDown();
118: String parameterTypeName = reader.getValue();
119: parameterTypeList.add(javaClassConverter
120: .fromString(parameterTypeName));
121: reader.moveUp();
122: }
123: Class[] parameterTypes = (Class[]) parameterTypeList
124: .toArray(new Class[parameterTypeList.size()]);
125: reader.moveUp();
126:
127: if (isMethodNotConstructor) {
128: return declaringClass.getDeclaredMethod(methodName,
129: parameterTypes);
130: } else {
131: return declaringClass
132: .getDeclaredConstructor(parameterTypes);
133: }
134: } catch (NoSuchMethodException e) {
135: throw new ConversionException(e);
136: }
137: }
138: }
|