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.

DefaultCacheKeyResolver.java 3.4KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118
  1. /*******************************************************************************
  2. * Copyright (c) 2012 Contributors.
  3. * All rights reserved.
  4. * This program and the accompanying materials are made available
  5. * under the terms of the Eclipse Public License v 2.0
  6. * which accompanies this distribution and is available at
  7. * https://www.eclipse.org/org/documents/epl-2.0/EPL-2.0.txt
  8. *
  9. * Contributors:
  10. * John Kew (vmware) initial implementation
  11. *******************************************************************************/
  12. package org.aspectj.weaver.tools.cache;
  13. import java.net.URL;
  14. import java.net.URLClassLoader;
  15. import java.util.Collections;
  16. import java.util.LinkedList;
  17. import java.util.List;
  18. import java.util.zip.CRC32;
  19. /**
  20. * Naive default class and classloader hashing implementation useful
  21. * for some multi-classloader environments.
  22. * <p>
  23. * This implementation creates classloader scopes of the form:<br>
  24. * "ExampleClassLoaderName.[crc hash]"
  25. * </p>
  26. * <p>
  27. * And weaved class keys of the form:<br>
  28. * "com.foo.BarClassName.[bytes len][crc].weaved"
  29. * </p>
  30. * <p>
  31. * And generated class keys of the form:<br>
  32. * "com.foo.BarClassName$AjClosure.generated
  33. * </p>
  34. */
  35. public class DefaultCacheKeyResolver implements CacheKeyResolver {
  36. public static final String GENERATED_SUFFIX = ".generated";
  37. public static final String WEAVED_SUFFIX = ".weaved";
  38. /**
  39. * Create a scope from a set of urls and aspect urls. Creates scope
  40. * of the form "ExampleClassLoaderName.[md5sum]" or
  41. * "ExampleClassLoaderName.[crc]"
  42. *
  43. * @param cl the classloader which uses the cache, can be null
  44. * @param aspects the aspects
  45. * @return a unique string for URLClassloaders, otherwise a non-unique classname
  46. */
  47. public String createClassLoaderScope(ClassLoader cl, List<String> aspects) {
  48. String name = cl != null ? cl.getClass().getSimpleName() : "unknown";
  49. List<String> hashableStrings = new LinkedList<>();
  50. StringBuilder hashable = new StringBuilder(256);
  51. // Add the list of loader urls to the hash list
  52. if (cl instanceof URLClassLoader) {
  53. URL[] urls = ((URLClassLoader) cl).getURLs();
  54. for (URL url : urls) {
  55. hashableStrings.add(url.toString());
  56. }
  57. }
  58. hashableStrings.addAll(aspects);
  59. Collections.sort(hashableStrings);
  60. for (String url : hashableStrings) {
  61. hashable.append(url);
  62. }
  63. String hash = null;
  64. byte[] bytes = hashable.toString().getBytes();
  65. hash = crc(bytes);
  66. return name + '.' + hash;
  67. }
  68. private String crc(byte[] input) {
  69. CRC32 crc32 = new CRC32();
  70. crc32.update(input);
  71. return String.valueOf(crc32.getValue());
  72. }
  73. public String getGeneratedRegex() {
  74. return ".*" + GENERATED_SUFFIX;
  75. }
  76. public String getWeavedRegex() {
  77. return ".*" + WEAVED_SUFFIX;
  78. }
  79. /**
  80. * Converts a cache key back to a className
  81. *
  82. * @param key to convert
  83. * @return className, e.g. "com.foo.Bar"
  84. */
  85. public String keyToClass(String key) {
  86. if (key.endsWith(GENERATED_SUFFIX)) {
  87. return key.replaceAll(GENERATED_SUFFIX + "$", "");
  88. }
  89. if (key.endsWith(WEAVED_SUFFIX)) {
  90. return key.replaceAll("\\.[^.]+" + WEAVED_SUFFIX, "");
  91. }
  92. return key;
  93. }
  94. public CachedClassReference weavedKey(String className, byte[] original_bytes) {
  95. String hash = crc(original_bytes);
  96. return new CachedClassReference(className + "." + hash + WEAVED_SUFFIX, className);
  97. }
  98. public CachedClassReference generatedKey(String className) {
  99. return new CachedClassReference(className + GENERATED_SUFFIX, className);
  100. }
  101. }