001: /*
002: * Javassist, a Java-bytecode translator toolkit.
003: * Copyright (C) 1999-2006 Shigeru Chiba. All Rights Reserved.
004: *
005: * The contents of this file are subject to the Mozilla Public License Version
006: * 1.1 (the "License"); you may not use this file except in compliance with
007: * the License. Alternatively, the contents of this file may be used under
008: * the terms of the GNU Lesser General Public License Version 2.1 or later.
009: *
010: * Software distributed under the License is distributed on an "AS IS" basis,
011: * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
012: * for the specific language governing rights and limitations under the
013: * License.
014: */
015:
016: package javassist;
017:
018: import javassist.bytecode.Descriptor;
019:
020: /**
021: * A hash table associating class names with different names.
022: *
023: * <p>This hashtable is used for replacing class names in a class
024: * definition or a method body. Define a subclass of this class
025: * if a more complex mapping algorithm is needed. For example,
026: *
027: * <ul><pre>class MyClassMap extends ClassMap {
028: * public Object get(Object jvmClassName) {
029: * String name = toJavaName((String)jvmClassName);
030: * if (name.startsWith("java."))
031: * return toJvmName("java2." + name.substring(5));
032: * else
033: * return super.get(jvmClassName);
034: * }
035: * }</pre></ul>
036: *
037: * <p>This subclass maps <code>java.lang.String</code> to
038: * <code>java2.lang.String</code>. Note that <code>get()</code>
039: * receives and returns the internal representation of a class name.
040: * For example, the internal representation of <code>java.lang.String</code>
041: * is <code>java/lang/String</code>.
042: *
043: * @see #get(Object)
044: * @see CtClass#replaceClassName(ClassMap)
045: * @see CtNewMethod#copy(CtMethod,String,CtClass,ClassMap)
046: */
047: public class ClassMap extends java.util.HashMap {
048: private ClassMap parent;
049:
050: /**
051: * Constructs a hash table.
052: */
053: public ClassMap() {
054: parent = null;
055: }
056:
057: ClassMap(ClassMap map) {
058: parent = map;
059: }
060:
061: /**
062: * Maps a class name to another name in this hashtable.
063: * The names are obtained with calling <code>Class.getName()</code>.
064: * This method translates the given class names into the
065: * internal form used in the JVM before putting it in
066: * the hashtable.
067: *
068: * @param oldname the original class name
069: * @param newname the substituted class name.
070: */
071: public void put(CtClass oldname, CtClass newname) {
072: put(oldname.getName(), newname.getName());
073: }
074:
075: /**
076: * Maps a class name to another name in this hashtable.
077: * If the hashtable contains another mapping from the same
078: * class name, the old mapping is replaced.
079: * This method translates the given class names into the
080: * internal form used in the JVM before putting it in
081: * the hashtable.
082: *
083: * <p>If <code>oldname</code> is equivalent to
084: * <code>newname</code>, then this method does not
085: * perform anything; it does not record the mapping from
086: * <code>oldname</code> to <code>newname</code>. See
087: * <code>fix</code> method.
088: *
089: * @param oldname the original class name
090: * @param newname the substituted class name.
091: * @see #fix(String)
092: */
093: public void put(String oldname, String newname) {
094: if (oldname == newname)
095: return;
096:
097: String oldname2 = toJvmName(oldname);
098: String s = (String) get(oldname2);
099: if (s == null || !s.equals(oldname2))
100: super .put(oldname2, toJvmName(newname));
101: }
102:
103: protected final void put0(Object oldname, Object newname) {
104: super .put(oldname, newname);
105: }
106:
107: /**
108: * Returns the class name to wihch the given <code>jvmClassName</code>
109: * is mapped. A subclass of this class should override this method.
110: *
111: * <p>This method receives and returns the internal representation of
112: * class name used in the JVM.
113: *
114: * @see #toJvmName(String)
115: * @see #toJavaName(String)
116: */
117: public Object get(Object jvmClassName) {
118: Object found = super .get(jvmClassName);
119: if (found == null && parent != null)
120: return parent.get(jvmClassName);
121: else
122: return found;
123: }
124:
125: /**
126: * Prevents a mapping from the specified class name to another name.
127: */
128: public void fix(CtClass clazz) {
129: fix(clazz.getName());
130: }
131:
132: /**
133: * Prevents a mapping from the specified class name to another name.
134: */
135: public void fix(String name) {
136: String name2 = toJvmName(name);
137: super .put(name2, name2);
138: }
139:
140: /**
141: * Converts a class name into the internal representation used in
142: * the JVM.
143: */
144: public static String toJvmName(String classname) {
145: return Descriptor.toJvmName(classname);
146: }
147:
148: /**
149: * Converts a class name from the internal representation used in
150: * the JVM to the normal one used in Java.
151: */
152: public static String toJavaName(String classname) {
153: return Descriptor.toJavaName(classname);
154: }
155: }
|