| 43 | import matcher.type.Signature.ClassSignature; |
| 44 | |
| 45 | public final class ClassEnvironment implements ClassEnv { |
| 46 | public void init(ProjectConfig config, DoubleConsumer progressReceiver) { |
| 47 | final double cpInitCost = 0.05; |
| 48 | final double classReadCost = 0.2; |
| 49 | double progress = 0; |
| 50 | |
| 51 | inputsBeforeClassPath = config.hasInputsBeforeClassPath(); |
| 52 | nonObfuscatedClassPatternA = config.getNonObfuscatedClassPatternA().isEmpty() ? null : Pattern.compile(config.getNonObfuscatedClassPatternA()); |
| 53 | nonObfuscatedClassPatternB = config.getNonObfuscatedClassPatternB().isEmpty() ? null : Pattern.compile(config.getNonObfuscatedClassPatternB()); |
| 54 | nonObfuscatedMemberPatternA = config.getNonObfuscatedMemberPatternA().isEmpty() ? null : Pattern.compile(config.getNonObfuscatedMemberPatternA()); |
| 55 | nonObfuscatedMemberPatternB = config.getNonObfuscatedMemberPatternB().isEmpty() ? null : Pattern.compile(config.getNonObfuscatedMemberPatternB()); |
| 56 | |
| 57 | try { |
| 58 | for (int i = 0; i < 2; i++) { |
| 59 | if ((i == 0) != inputsBeforeClassPath) { |
| 60 | // class path indexing |
| 61 | initClassPath(config.getSharedClassPath(), inputsBeforeClassPath); |
| 62 | CompletableFuture.allOf( |
| 63 | CompletableFuture.runAsync(() -> extractorA.processClassPath(config.getClassPathA(), inputsBeforeClassPath)), |
| 64 | CompletableFuture.runAsync(() -> extractorB.processClassPath(config.getClassPathB(), inputsBeforeClassPath))).get(); |
| 65 | progress += cpInitCost; |
| 66 | } else { |
| 67 | // async class reading |
| 68 | CompletableFuture.allOf( |
| 69 | CompletableFuture.runAsync(() -> extractorA.processInputs(config.getPathsA(), nonObfuscatedClassPatternA)), |
| 70 | CompletableFuture.runAsync(() -> extractorB.processInputs(config.getPathsB(), nonObfuscatedClassPatternB))).get(); |
| 71 | progress += classReadCost; |
| 72 | } |
| 73 | |
| 74 | progressReceiver.accept(progress); |
| 75 | } |
| 76 | |
| 77 | // synchronous feature extraction |
| 78 | extractorA.process(nonObfuscatedMemberPatternA); |
| 79 | progressReceiver.accept(0.8); |
| 80 | |
| 81 | extractorB.process(nonObfuscatedMemberPatternB); |
| 82 | progressReceiver.accept(0.98); |
| 83 | } catch (InterruptedException | ExecutionException | IOException e) { |
| 84 | throw new RuntimeException(e); |
| 85 | } finally { |
| 86 | classPathIndex.clear(); |
| 87 | openFileSystems.forEach(Util::closeSilently); |
| 88 | openFileSystems.clear(); |
| 89 | } |
| 90 | |
| 91 | progressReceiver.accept(1); |
| 92 | } |
| 93 | |
| 94 | private void initClassPath(Collection<Path> sharedClassPath, boolean checkExisting) throws IOException { |
| 95 | for (Path archive : sharedClassPath) { |
| 96 | cpFiles.add(new InputFile(archive)); |
| 97 | |
| 98 | FileSystem fs = Util.iterateJar(archive, false, file -> { |
| 99 | String name = file.toAbsolutePath().toString(); |
| 100 | if (!name.startsWith("/") || !name.endsWith(".class") || name.startsWith("//")) throw new RuntimeException("invalid path: "+archive+" ("+name+")"); |
| 101 | name = name.substring(1, name.length() - ".class".length()); |
| 102 |
nothing calls this directly
no outgoing calls
no test coverage detected