|
25 | 25 | import java.io.IOException;
|
26 | 26 | import java.io.InputStream;
|
27 | 27 | import java.io.InputStreamReader;
|
| 28 | +import java.net.URL; |
28 | 29 | import java.util.HashMap;
|
29 | 30 | import java.util.HashSet;
|
30 | 31 | import java.util.Map;
|
|
45 | 46 | * directory is written. By default, the final <code>symbolMaps</code> directory is
|
46 | 47 | * <code>war/WEB-INF/deploy/<i>yourmodulename</i>/symbolMaps/</code>.
|
47 | 48 | */
|
48 |
| -public class StackTraceDeobfuscator { |
| 49 | +public abstract class StackTraceDeobfuscator { |
| 50 | + |
| 51 | + /** |
| 52 | + * Creates a deobfuscator that loads symbol and source map files under given resource path. Uses |
| 53 | + * StackTraceObfuscator's {@link ClassLoader}. |
| 54 | + */ |
| 55 | + public static StackTraceDeobfuscator fromResource(String symbolMapsPath) { |
| 56 | + final String basePath = symbolMapsPath.endsWith("/") ? symbolMapsPath : symbolMapsPath + "/"; |
| 57 | + final ClassLoader classLoader = StackTraceDeobfuscator.class.getClassLoader(); |
| 58 | + return new StackTraceDeobfuscator() { |
| 59 | + protected InputStream openInputStream(String fileName) throws IOException { |
| 60 | + String filePath = basePath + fileName; |
| 61 | + InputStream inputStream = classLoader.getResourceAsStream(filePath); |
| 62 | + if (inputStream == null) { |
| 63 | + throw new IOException("Missing resource: " + filePath); |
| 64 | + } |
| 65 | + return inputStream; |
| 66 | + } |
| 67 | + }; |
| 68 | + } |
| 69 | + |
| 70 | + /** |
| 71 | + * Creates a deobfuscator that loads symbol and source map files from the given directory. |
| 72 | + */ |
| 73 | + public static StackTraceDeobfuscator fromFileSystem(final String symbolMapsDirectory) { |
| 74 | + return new StackTraceDeobfuscator() { |
| 75 | + protected InputStream openInputStream(String fileName) throws IOException { |
| 76 | + return new FileInputStream(new File(symbolMapsDirectory, fileName)); |
| 77 | + } |
| 78 | + }; |
| 79 | + } |
| 80 | + |
| 81 | + /** |
| 82 | + * Creates a deobfuscator that loads symbol and source map files beneath the given URL. |
| 83 | + */ |
| 84 | + public static StackTraceDeobfuscator fromUrl(final URL urlPath) { |
| 85 | + return new StackTraceDeobfuscator() { |
| 86 | + protected InputStream openInputStream(String fileName) throws IOException { |
| 87 | + return new URL(urlPath, fileName).openStream(); |
| 88 | + } |
| 89 | + }; |
| 90 | + } |
49 | 91 |
|
50 | 92 | /**
|
51 | 93 | * A cache that maps obfuscated symbols to arbitrary non-null string values. The cache can assume
|
@@ -105,36 +147,16 @@ Map<String, String> getAll(String strongName, Set<String> symbols) {
|
105 | 147 | private static final int LINE_NUMBER_UNKNOWN = -1;
|
106 | 148 | private static final String SYMBOL_DATA_UNKNOWN = "";
|
107 | 149 |
|
108 |
| - private final boolean lazyLoad; |
109 |
| - private final File symbolMapsDirectory; |
110 | 150 | private final Map<String, SourceMapping> sourceMaps = new HashMap<String, SourceMapping>();
|
111 | 151 | private final SymbolCache symbolCache = new SymbolCache();
|
| 152 | + private boolean lazyLoad = false; |
112 | 153 |
|
113 | 154 | /**
|
114 |
| - * Creates a deobfuscator that loads symbol map files from the given directory. Symbol maps are |
115 |
| - * generated into the location specified by the GWT compiler <code>-deploy</code> command line |
116 |
| - * argument. |
117 |
| - * |
118 |
| - * @param symbolMapsDirectory the <code>symbolMaps</code> directory, with or without trailing |
119 |
| - * directory separator character |
| 155 | + * If set to {@code true}, only symbols requested to be deobfuscated are cached and the rest is |
| 156 | + * discarded. This provides a large memory savings at the expense of occasional extra disk reads. |
| 157 | + * Note that, this will only have effect on symbol maps that haven't been fully loaded yet. |
120 | 158 | */
|
121 |
| - public StackTraceDeobfuscator(String symbolMapsDirectory) { |
122 |
| - this(symbolMapsDirectory, false); |
123 |
| - } |
124 |
| - |
125 |
| - /** |
126 |
| - * Creates a deobfuscator that loads symbol map files from the given directory. Symbol maps are |
127 |
| - * generated into the location specified by the GWT compiler <code>-deploy</code> command line |
128 |
| - * argument. |
129 |
| - * |
130 |
| - * @param symbolMapsDirectory the <code>symbolMaps</code> directory, with or without trailing |
131 |
| - * directory separator character. Usually this directory will include files with .symbolmap |
132 |
| - or .json extensions. |
133 |
| - * @param lazyLoad if true, only symbols requested to be deobfuscated are cached. This provides a |
134 |
| - * large memory savings at the expense of occasional extra disk reads. |
135 |
| - */ |
136 |
| - public StackTraceDeobfuscator(String symbolMapsDirectory, boolean lazyLoad) { |
137 |
| - this.symbolMapsDirectory = new File(symbolMapsDirectory); |
| 159 | + public void setLazyLoad(boolean lazyLoad) { |
138 | 160 | this.lazyLoad = lazyLoad;
|
139 | 161 | }
|
140 | 162 |
|
@@ -293,26 +315,30 @@ public final StackTraceElement resymbolize(StackTraceElement ste, String strongN
|
293 | 315 |
|
294 | 316 | protected InputStream getSourceMapInputStream(String permutationStrongName, int fragmentNumber)
|
295 | 317 | throws IOException {
|
296 |
| - String filename = symbolMapsDirectory.getCanonicalPath() |
297 |
| - + File.separatorChar + permutationStrongName + "_sourceMap" + fragmentNumber + ".json"; |
298 |
| - return new FileInputStream(filename); |
| 318 | + return openInputStream(permutationStrongName + "_sourceMap" + fragmentNumber + ".json"); |
299 | 319 | }
|
300 | 320 |
|
301 | 321 | /**
|
302 | 322 | * Retrieves a new {@link InputStream} for the given permutation strong name. This implementation,
|
303 | 323 | * which subclasses may override, returns a {@link InputStream} for the <code>
|
304 |
| - * <i>permutation-strong-name</i>.symbolMap</code> file in the <code>symbolMaps</code> directory. |
| 324 | + * <i>permutation-strong-name</i>.symbolMap</code> file. |
305 | 325 | *
|
306 | 326 | * @param permutationStrongName the GWT permutation strong name
|
307 | 327 | * @return a new {@link InputStream}
|
308 | 328 | */
|
309 |
| - protected InputStream getSymbolMapInputStream(String permutationStrongName) |
310 |
| - throws IOException { |
311 |
| - String filename = symbolMapsDirectory.getCanonicalPath() |
312 |
| - + File.separatorChar + permutationStrongName + ".symbolMap"; |
313 |
| - return new FileInputStream(filename); |
| 329 | + protected InputStream getSymbolMapInputStream(String permutationStrongName) throws IOException { |
| 330 | + return openInputStream(permutationStrongName + ".symbolMap"); |
314 | 331 | }
|
315 | 332 |
|
| 333 | + /** |
| 334 | + * Opens a new {@link InputStream} for a symbol or source map file. |
| 335 | + * |
| 336 | + * @param fileName name of the symbol or source map file |
| 337 | + * @return an input stream for reading the file (doesn't need to be buffered). |
| 338 | + * @exception IOException if an I/O error occurs while creating the input stream. |
| 339 | + */ |
| 340 | + protected abstract InputStream openInputStream(String fileName) throws IOException; |
| 341 | + |
316 | 342 | private SourceMapping loadSourceMap(String permutationStrongName, int fragmentId) {
|
317 | 343 | SourceMapping toReturn = sourceMaps.get(permutationStrongName + fragmentId);
|
318 | 344 | if (toReturn == null) {
|
|
0 commit comments