• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2025 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 package com.android.dependencymapper;
17 
18 import com.android.dependencymapper.DependencyProto;
19 
20 import com.google.gson.Gson;
21 import com.google.gson.GsonBuilder;
22 
23 import java.io.FileWriter;
24 import java.io.IOException;
25 import java.io.OutputStream;
26 import java.nio.file.Files;
27 import java.nio.file.Path;
28 import java.util.Enumeration;
29 import java.util.HashMap;
30 import java.util.HashSet;
31 import java.util.Map;
32 import java.util.Set;
33 import java.util.jar.JarEntry;
34 import java.util.jar.JarFile;
35 
36 public class Utils {
37 
trimAndConvertToPackageBasedPath(String fileBasedPath)38     public static String trimAndConvertToPackageBasedPath(String fileBasedPath) {
39         // Remove ".class" from the fileBasedPath, then replace "/" with "."
40         return fileBasedPath.replaceAll("\\..*", "").replaceAll("/", ".");
41     }
42 
buildPackagePrependedClassSource(String qualifiedClassPath, String classSource)43     public static String buildPackagePrependedClassSource(String qualifiedClassPath,
44             String classSource) {
45         // Find the location of the start of classname in the qualifiedClassPath
46         int classNameSt = qualifiedClassPath.lastIndexOf(".") + 1;
47         // Replace the classname in qualifiedClassPath with classSource
48         return qualifiedClassPath.substring(0, classNameSt) + classSource;
49     }
50 
writeContentsToJson(DependencyProto.FileDependencyList contents, Path jsonOut)51     public static void writeContentsToJson(DependencyProto.FileDependencyList contents, Path jsonOut) {
52         Gson gson = new GsonBuilder().setPrettyPrinting().create();
53         Map<String, Set<String>> jsonMap = new HashMap<>();
54         for (DependencyProto.FileDependency fileDependency : contents.getFileDependencyList()) {
55             jsonMap.putIfAbsent(fileDependency.getFilePath(),
56                     Set.copyOf(fileDependency.getFileDependenciesList()));
57         }
58         String json = gson.toJson(jsonMap);
59         try (FileWriter file = new FileWriter(jsonOut.toFile())) {
60             file.write(json);
61         } catch (IOException e) {
62             System.err.println("Error writing json output to: " + jsonOut);
63             throw new RuntimeException(e);
64         }
65     }
66 
writeContentsToProto(DependencyProto.FileDependencyList usages, Path protoOut)67     public static void writeContentsToProto(DependencyProto.FileDependencyList usages, Path protoOut) {
68         try {
69             OutputStream outputStream = Files.newOutputStream(protoOut);
70             usages.writeDelimitedTo(outputStream);
71         } catch (IOException e) {
72             System.err.println("Error writing proto output to: " + protoOut);
73             throw new RuntimeException(e);
74         }
75     }
76 
listClassesInJar(Path classesJarPath)77     public static Set<String> listClassesInJar(Path classesJarPath) {
78         Set<String> classes = new HashSet<>();
79         try (JarFile jarFile = new JarFile(classesJarPath.toFile())) {
80             Enumeration<JarEntry> entries = jarFile.entries();
81             while (entries.hasMoreElements()) {
82                 JarEntry entry = entries.nextElement();
83                 if (entry.getName().endsWith(".class")) {
84                     String name = Utils.trimAndConvertToPackageBasedPath(entry.getName());
85                     classes.add(name);
86                 }
87             }
88         } catch (IOException e) {
89             System.err.println("Error reading the jar file at: " + classesJarPath);
90             throw new RuntimeException(e);
91         }
92         return classes;
93     }
94 }
95