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.

SignatureImpl.java 6.7KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243
  1. /* *******************************************************************
  2. * Copyright (c) 1999-2001 Xerox Corporation,
  3. * 2002 Palo Alto Research Center, Incorporated (PARC).
  4. * All rights reserved.
  5. * This program and the accompanying materials are made available
  6. * under the terms of the Eclipse Public License v 2.0
  7. * which accompanies this distribution and is available at
  8. * https://www.eclipse.org/org/documents/epl-2.0/EPL-2.0.txt
  9. *
  10. * Contributors:
  11. * Xerox/PARC initial implementation
  12. * ******************************************************************/
  13. package org.aspectj.runtime.reflect;
  14. import org.aspectj.lang.Signature;
  15. import java.util.StringTokenizer;
  16. abstract class SignatureImpl implements Signature {
  17. private static boolean useCache = true;
  18. int modifiers = -1;
  19. String name;
  20. String declaringTypeName;
  21. Class<?> declaringType;
  22. Cache stringCache;
  23. SignatureImpl(int modifiers, String name, Class<?> declaringType) {
  24. this.modifiers = modifiers;
  25. this.name = name;
  26. this.declaringType = declaringType;
  27. }
  28. protected abstract String createToString (StringMaker sm);
  29. /* Use a soft cache for the short, middle and long String representations */
  30. String toString (StringMaker sm) {
  31. String result = null;
  32. if (useCache) {
  33. if (stringCache == null) {
  34. try {
  35. stringCache = new CacheImpl();
  36. } catch (Throwable t) {
  37. useCache = false;
  38. }
  39. } else {
  40. result = stringCache.get(sm.cacheOffset);
  41. }
  42. }
  43. if (result == null) {
  44. result = createToString(sm);
  45. }
  46. if (useCache) {
  47. stringCache.set(sm.cacheOffset, result);
  48. }
  49. return result;
  50. }
  51. public final String toString() { return toString(StringMaker.middleStringMaker); }
  52. public final String toShortString() { return toString(StringMaker.shortStringMaker); }
  53. public final String toLongString() { return toString(StringMaker.longStringMaker); }
  54. public int getModifiers() {
  55. if (modifiers == -1) modifiers = extractInt(0);
  56. return modifiers;
  57. }
  58. public String getName() {
  59. if (name == null) name = extractString(1);
  60. return name;
  61. }
  62. public Class getDeclaringType() {
  63. if (declaringType == null) declaringType = extractType(2);
  64. return declaringType;
  65. }
  66. public String getDeclaringTypeName() {
  67. if (declaringTypeName == null) {
  68. declaringTypeName = getDeclaringType().getName();
  69. }
  70. return declaringTypeName;
  71. }
  72. String fullTypeName(Class<?> type) {
  73. if (type == null) return "ANONYMOUS";
  74. if (type.isArray()) return fullTypeName(type.getComponentType()) + "[]";
  75. return type.getName().replace('$', '.');
  76. }
  77. String stripPackageName(String name) {
  78. int dot = name.lastIndexOf('.');
  79. if (dot == -1) return name;
  80. return name.substring(dot+1);
  81. }
  82. String shortTypeName(Class<?> type) {
  83. if (type == null) return "ANONYMOUS";
  84. if (type.isArray()) return shortTypeName(type.getComponentType()) + "[]";
  85. return stripPackageName(type.getName()).replace('$', '.');
  86. }
  87. void addFullTypeNames(StringBuffer buf, Class[] types) {
  88. for (int i = 0; i < types.length; i++) {
  89. if (i > 0) buf.append(", ");
  90. buf.append(fullTypeName(types[i]));
  91. }
  92. }
  93. void addShortTypeNames(StringBuffer buf, Class[] types) {
  94. for (int i = 0; i < types.length; i++) {
  95. if (i > 0) buf.append(", ");
  96. buf.append(shortTypeName(types[i]));
  97. }
  98. }
  99. void addTypeArray(StringBuffer buf, Class[] types) {
  100. addFullTypeNames(buf, types);
  101. }
  102. // lazy version
  103. private String stringRep;
  104. ClassLoader lookupClassLoader = null;
  105. public void setLookupClassLoader(ClassLoader loader) {
  106. this.lookupClassLoader = loader;
  107. }
  108. private ClassLoader getLookupClassLoader() {
  109. if (lookupClassLoader == null) lookupClassLoader = this.getClass().getClassLoader();
  110. return lookupClassLoader;
  111. }
  112. public SignatureImpl(String stringRep) {
  113. this.stringRep = stringRep;
  114. }
  115. static final char SEP = '-';
  116. String extractString(int n) {
  117. //System.out.println(n + ": from " + stringRep);
  118. int startIndex = 0;
  119. int endIndex = stringRep.indexOf(SEP);
  120. while (n-- > 0) {
  121. startIndex = endIndex+1;
  122. endIndex = stringRep.indexOf(SEP, startIndex);
  123. }
  124. if (endIndex == -1) endIndex = stringRep.length();
  125. //System.out.println(" " + stringRep.substring(startIndex, endIndex));
  126. return stringRep.substring(startIndex, endIndex);
  127. }
  128. int extractInt(int n) {
  129. String s = extractString(n);
  130. return Integer.parseInt(s, 16);
  131. }
  132. Class<?> extractType(int n) {
  133. String s = extractString(n);
  134. return Factory.makeClass(s,getLookupClassLoader());
  135. }
  136. static String[] EMPTY_STRING_ARRAY = new String[0];
  137. static Class[] EMPTY_CLASS_ARRAY = new Class[0];
  138. static final String INNER_SEP = ":";
  139. String[] extractStrings(int n) {
  140. String s = extractString(n);
  141. StringTokenizer st = new StringTokenizer(s, INNER_SEP);
  142. final int N = st.countTokens();
  143. String[] ret = new String[N];
  144. for (int i = 0; i < N; i++) ret[i]= st.nextToken();
  145. return ret;
  146. }
  147. Class[] extractTypes(int n) {
  148. String s = extractString(n);
  149. StringTokenizer st = new StringTokenizer(s, INNER_SEP);
  150. final int N = st.countTokens();
  151. Class[] ret = new Class[N];
  152. for (int i = 0; i < N; i++) ret[i]= Factory.makeClass(st.nextToken(),getLookupClassLoader());
  153. return ret;
  154. }
  155. /*
  156. * Used for testing
  157. */
  158. static void setUseCache (boolean b) {
  159. useCache = b;
  160. }
  161. static boolean getUseCache () {
  162. return useCache;
  163. }
  164. private interface Cache {
  165. String get(int cacheOffset);
  166. void set(int cacheOffset, String result);
  167. }
  168. // separate implementation so we don't need SoftReference to hold the field...
  169. private static final class CacheImpl implements Cache {
  170. private java.lang.ref.SoftReference<String[]> toStringCacheRef;
  171. public CacheImpl() {
  172. makeCache();
  173. }
  174. public String get(int cacheOffset) {
  175. String[] cachedArray = array();
  176. if (cachedArray == null) {
  177. return null;
  178. }
  179. return cachedArray[cacheOffset];
  180. }
  181. public void set(int cacheOffset, String result) {
  182. String[] cachedArray = array();
  183. if (cachedArray == null) {
  184. cachedArray = makeCache();
  185. }
  186. cachedArray[cacheOffset] = result;
  187. }
  188. private String[] array() {
  189. return toStringCacheRef.get();
  190. }
  191. private String[] makeCache() {
  192. String[] array = new String[3];
  193. toStringCacheRef = new java.lang.ref.SoftReference<>(array);
  194. return array;
  195. }
  196. }
  197. }