You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

ClassMap.java 5.8KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178
  1. /*
  2. * Javassist, a Java-bytecode translator toolkit.
  3. * Copyright (C) 1999- Shigeru Chiba. All Rights Reserved.
  4. *
  5. * The contents of this file are subject to the Mozilla Public License Version
  6. * 1.1 (the "License"); you may not use this file except in compliance with
  7. * the License. Alternatively, the contents of this file may be used under
  8. * the terms of the GNU Lesser General Public License Version 2.1 or later,
  9. * or the Apache License Version 2.0.
  10. *
  11. * Software distributed under the License is distributed on an "AS IS" basis,
  12. * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
  13. * for the specific language governing rights and limitations under the
  14. * License.
  15. */
  16. package javassist;
  17. import java.util.HashMap;
  18. import javassist.bytecode.Descriptor;
  19. /**
  20. * A hash table associating class names with different names.
  21. *
  22. * <p>This hashtable is used for replacing class names in a class
  23. * definition or a method body. Define a subclass of this class
  24. * if a more complex mapping algorithm is needed. For example,
  25. *
  26. * <pre>class MyClassMap extends ClassMap {
  27. * public Object get(Object jvmClassName) {
  28. * String name = toJavaName((String)jvmClassName);
  29. * if (name.startsWith("java."))
  30. * return toJvmName("java2." + name.substring(5));
  31. * else
  32. * return super.get(jvmClassName);
  33. * }
  34. * }</pre>
  35. *
  36. * <p>This subclass maps <code>java.lang.String</code> to
  37. * <code>java2.lang.String</code>. Note that <code>get()</code>
  38. * receives and returns the internal representation of a class name.
  39. * For example, the internal representation of <code>java.lang.String</code>
  40. * is <code>java/lang/String</code>.
  41. *
  42. * <p>Note that this is a map from <code>String</code> to <code>String</code>.
  43. *
  44. * @see #get(Object)
  45. * @see CtClass#replaceClassName(ClassMap)
  46. * @see CtNewMethod#copy(CtMethod,String,CtClass,ClassMap)
  47. */
  48. public class ClassMap extends HashMap<String,String> {
  49. /** default serialVersionUID */
  50. private static final long serialVersionUID = 1L;
  51. private ClassMap parent;
  52. /**
  53. * Constructs a hash table.
  54. */
  55. public ClassMap() { parent = null; }
  56. ClassMap(ClassMap map) { parent = map; }
  57. /**
  58. * Maps a class name to another name in this hashtable.
  59. * The names are obtained with calling <code>Class.getName()</code>.
  60. * This method translates the given class names into the
  61. * internal form used in the JVM before putting it in
  62. * the hashtable.
  63. *
  64. * @param oldname the original class name
  65. * @param newname the substituted class name.
  66. */
  67. public void put(CtClass oldname, CtClass newname) {
  68. put(oldname.getName(), newname.getName());
  69. }
  70. /**
  71. * Maps a class name to another name in this hashtable.
  72. * If the hashtable contains another mapping from the same
  73. * class name, the old mapping is replaced.
  74. * This method translates the given class names into the
  75. * internal form used in the JVM before putting it in
  76. * the hashtable.
  77. *
  78. * <p>If <code>oldname</code> is identical to
  79. * <code>newname</code>, then this method does not
  80. * perform anything; it does not record the mapping from
  81. * <code>oldname</code> to <code>newname</code>. See
  82. * <code>fix</code> method.
  83. *
  84. * @param oldname the original class name.
  85. * @param newname the substituted class name.
  86. * @see #fix(String)
  87. */
  88. @Override
  89. public String put(String oldname, String newname) {
  90. if (oldname == newname)
  91. return oldname;
  92. String oldname2 = toJvmName(oldname);
  93. String s = get(oldname2);
  94. if (s == null || !s.equals(oldname2))
  95. return super.put(oldname2, toJvmName(newname));
  96. return s;
  97. }
  98. /**
  99. * Is equivalent to <code>put()</code> except that
  100. * the given mapping is not recorded into the hashtable
  101. * if another mapping from <code>oldname</code> is
  102. * already included.
  103. *
  104. * @param oldname the original class name.
  105. * @param newname the substituted class name.
  106. */
  107. public void putIfNone(String oldname, String newname) {
  108. if (oldname == newname)
  109. return;
  110. String oldname2 = toJvmName(oldname);
  111. String s = get(oldname2);
  112. if (s == null)
  113. super.put(oldname2, toJvmName(newname));
  114. }
  115. protected final String put0(String oldname, String newname) {
  116. return super.put(oldname, newname);
  117. }
  118. /**
  119. * Returns the class name to wihch the given <code>jvmClassName</code>
  120. * is mapped. A subclass of this class should override this method.
  121. *
  122. * <p>This method receives and returns the internal representation of
  123. * class name used in the JVM.
  124. *
  125. * @see #toJvmName(String)
  126. * @see #toJavaName(String)
  127. */
  128. @Override
  129. public String get(Object jvmClassName) {
  130. String found = super.get(jvmClassName);
  131. if (found == null && parent != null)
  132. return parent.get(jvmClassName);
  133. return found;
  134. }
  135. /**
  136. * Prevents a mapping from the specified class name to another name.
  137. */
  138. public void fix(CtClass clazz) {
  139. fix(clazz.getName());
  140. }
  141. /**
  142. * Prevents a mapping from the specified class name to another name.
  143. */
  144. public void fix(String name) {
  145. String name2 = toJvmName(name);
  146. super.put(name2, name2);
  147. }
  148. /**
  149. * Converts a class name into the internal representation used in
  150. * the JVM.
  151. */
  152. public static String toJvmName(String classname) {
  153. return Descriptor.toJvmName(classname);
  154. }
  155. /**
  156. * Converts a class name from the internal representation used in
  157. * the JVM to the normal one used in Java.
  158. */
  159. public static String toJavaName(String classname) {
  160. return Descriptor.toJavaName(classname);
  161. }
  162. }