Index: C:/Documents and Settings/Maarten Winkels/workspace/xstream/src/java/com/thoughtworks/xstream/mapper/ClassAliasingMapper.java =================================================================== --- C:/Documents and Settings/Maarten Winkels/workspace/xstream/src/java/com/thoughtworks/xstream/mapper/ClassAliasingMapper.java (revision 639) +++ C:/Documents and Settings/Maarten Winkels/workspace/xstream/src/java/com/thoughtworks/xstream/mapper/ClassAliasingMapper.java (working copy) @@ -1,11 +1,17 @@ package com.thoughtworks.xstream.mapper; -import com.thoughtworks.xstream.alias.ClassMapper; - -import java.util.Map; +import java.util.ArrayList; import java.util.Collections; import java.util.HashMap; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import org.apache.commons.lang.ClassUtils; + +import com.thoughtworks.xstream.alias.CannotResolveClassException; +import com.thoughtworks.xstream.alias.ClassMapper; + /** * Mapper that allows a fully qualified class name to be replaced with a shorter alias. * @@ -15,22 +21,34 @@ protected final Map typeToNameMap = Collections.synchronizedMap(new HashMap()); protected final Map nameToTypeMap = Collections.synchronizedMap(new HashMap()); + protected final List defaultPackages = Collections.synchronizedList(new ArrayList()); public ClassAliasingMapper(ClassMapper wrapped) { super(wrapped); } public void addClassAlias(String name, Class type) { - nameToTypeMap.put(name, type.getName()); - typeToNameMap.put(type.getName(), name); + doStore(name, type.getName()); } + private void doStore(String alias, String className) { + nameToTypeMap.put(alias, className); + typeToNameMap.put(className, alias); + } + public String serializedClass(Class type) { String name = super.serializedClass(type); String alias = (String) typeToNameMap.get(type.getName()); if (alias != null) { return alias; } else { + Package p = type.getPackage(); + if (p != null && defaultPackages.contains(p.getName())) { + String result = ClassUtils.getShortClassName(type); + // Store for future fast access. + addClassAlias(result, type); + return result; + } return name; } } @@ -45,8 +63,28 @@ if (mappedName != null) { elementName = mappedName; } - - return super.realClass(elementName); + try { + return super.realClass(elementName); + } catch (CannotResolveClassException e) { + //Last resort, try default packages. + for (Iterator i = defaultPackages.iterator(); i.hasNext();) { + StringBuffer prefix = new StringBuffer((String) i.next()).append('.'); + try { + String className = prefix.append(elementName).toString(); + Class type = super.realClass(className); + // Store for future fast access. + doStore(elementName,className); + return type; + } catch (CannotResolveClassException f) { + // Not found in this package, try next. Silently ignore + } + } + //Cannot find, rethrow. + throw e; + } } + public void addPackage(Package p) { + defaultPackages.add(p.getName()); + } }