1
11 package com.thoughtworks.xstream.mapper;
12
13 import java.io.IOException;
14 import java.io.ObjectInputStream;
15 import java.io.ObjectOutputStream;
16 import java.io.Serializable;
17 import java.util.Comparator;
18 import java.util.HashMap;
19 import java.util.Iterator;
20 import java.util.Map;
21 import java.util.TreeMap;
22
23
24
29 public class PackageAliasingMapper extends MapperWrapper implements Serializable {
30
31 private static final Comparator REVERSE = new Comparator() {
32
33 public int compare(final Object o1, final Object o2) {
34 return ((String)o2).compareTo((String)o1);
35 }
36 };
37
38 private Map packageToName = new TreeMap(REVERSE);
39 protected transient Map nameToPackage = new HashMap();
40
41 public PackageAliasingMapper(final Mapper wrapped) {
42 super(wrapped);
43 }
44
45 public void addPackageAlias(String name, String pkg) {
46 if (name.length() > 0 && name.charAt(name.length() - 1) != '.') {
47 name += '.';
48 }
49 if (pkg.length() > 0 && pkg.charAt(pkg.length() - 1) != '.') {
50 pkg += '.';
51 }
52 nameToPackage.put(name, pkg);
53 packageToName.put(pkg, name);
54 }
55
56 public String serializedClass(final Class type) {
57 final String className = type.getName();
58 int length = className.length();
59 int dot = -1;
60 do {
61 dot = className.lastIndexOf('.', length);
62 final String pkg = dot < 0 ? "" : className.substring(0, dot + 1);
63 final String alias = (String)packageToName.get(pkg);
64 if (alias != null) {
65 return alias + (dot < 0 ? className : className.substring(dot + 1));
66 }
67 length = dot - 1;
68 } while (dot >= 0);
69 return super.serializedClass(type);
70 }
71
72 public Class realClass(String elementName) {
73 int length = elementName.length();
74 int dot = -1;
75 do {
76 dot = elementName.lastIndexOf('.', length);
77 final String name = dot < 0 ? "" : elementName.substring(0, dot) + '.';
78 final String packageName = (String)nameToPackage.get(name);
79
80 if (packageName != null) {
81 elementName = packageName
82 + (dot < 0 ? elementName : elementName.substring(dot + 1));
83 break;
84 }
85 length = dot - 1;
86 } while (dot >= 0);
87
88 return super.realClass(elementName);
89 }
90
91 private void writeObject(final ObjectOutputStream out) throws IOException {
92 out.writeObject(new HashMap(packageToName));
93 }
94
95 private void readObject(final ObjectInputStream in)
96 throws IOException, ClassNotFoundException {
97 packageToName = new TreeMap(REVERSE);
98 packageToName.putAll((Map)in.readObject());
99 nameToPackage = new HashMap();
100 for (final Iterator iter = packageToName.keySet().iterator(); iter.hasNext();) {
101 final Object type = iter.next();
102 nameToPackage.put(packageToName.get(type), type);
103 }
104 }
105 }
106