001: /*
002: * Copyright (C) 2005, 2006 Joe Walnes.
003: * Copyright (C) 2006, 2007, 2008 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 09. April 2005 by Joe Walnes
011: */
012: package com.thoughtworks.xstream.mapper;
013:
014: import com.thoughtworks.xstream.alias.ClassMapper;
015:
016: import java.util.HashMap;
017: import java.util.Iterator;
018: import java.util.Map;
019:
020: /**
021: * Mapper that allows a fully qualified class name to be replaced with a shorter alias.
022: *
023: * @author Joe Walnes
024: * @author Jörg Schaible
025: */
026: public class ClassAliasingMapper extends MapperWrapper {
027:
028: protected final Map typeToName = new HashMap();
029: protected final Map classToName = new HashMap();
030: protected transient Map nameToType = new HashMap();
031:
032: public ClassAliasingMapper(Mapper wrapped) {
033: super (wrapped);
034: }
035:
036: /**
037: * @deprecated since 1.2, use {@link #ClassAliasingMapper(Mapper)}
038: */
039: public ClassAliasingMapper(ClassMapper wrapped) {
040: this ((Mapper) wrapped);
041: }
042:
043: public void addClassAlias(String name, Class type) {
044: nameToType.put(name, type.getName());
045: classToName.put(type.getName(), name);
046: }
047:
048: /**
049: * @deprecated since 1.3, method was a leftover of an old implementation
050: */
051: public void addClassAttributeAlias(String name, Class type) {
052: addClassAlias(name, type);
053: }
054:
055: public void addTypeAlias(String name, Class type) {
056: nameToType.put(name, type.getName());
057: typeToName.put(type, name);
058: }
059:
060: public String serializedClass(Class type) {
061: String alias = (String) classToName.get(type.getName());
062: if (alias != null) {
063: return alias;
064: } else {
065: for (final Iterator iter = typeToName.keySet().iterator(); iter
066: .hasNext();) {
067: final Class compatibleType = (Class) iter.next();
068: if (compatibleType.isAssignableFrom(type)) {
069: return (String) typeToName.get(compatibleType);
070: }
071: }
072: return super .serializedClass(type);
073: }
074: }
075:
076: public Class realClass(String elementName) {
077: String mappedName = (String) nameToType.get(elementName);
078:
079: if (mappedName != null) {
080: Class type = primitiveClassNamed(mappedName);
081: if (type != null) {
082: return type;
083: }
084: elementName = mappedName;
085: }
086:
087: return super .realClass(elementName);
088: }
089:
090: public boolean itemTypeAsAttribute(Class clazz) {
091: return classToName.containsKey(clazz);
092: }
093:
094: public boolean aliasIsAttribute(String name) {
095: return nameToType.containsKey(name);
096: }
097:
098: private Object readResolve() {
099: nameToType = new HashMap();
100: for (final Iterator iter = classToName.keySet().iterator(); iter
101: .hasNext();) {
102: final Object type = iter.next();
103: nameToType.put(classToName.get(type), type);
104: }
105: for (final Iterator iter = typeToName.keySet().iterator(); iter
106: .hasNext();) {
107: final Class type = (Class) iter.next();
108: nameToType.put(typeToName.get(type), type.getName());
109: }
110: return this ;
111: }
112:
113: private Class primitiveClassNamed(String name) {
114: return name.equals("void") ? Void.TYPE
115: : name.equals("boolean") ? Boolean.TYPE : name
116: .equals("byte") ? Byte.TYPE : name
117: .equals("char") ? Character.TYPE : name
118: .equals("short") ? Short.TYPE : name
119: .equals("int") ? Integer.TYPE : name
120: .equals("long") ? Long.TYPE : name
121: .equals("float") ? Float.TYPE : name
122: .equals("double") ? Double.TYPE : null;
123: }
124: }
|