| /* |
| * Copyright (C) 2025 The Android Open Source Project |
| * |
| * Licensed under the Apache License, Version 2.0 (the "License"); |
| * you may not use this file except in compliance with the License. |
| * You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| package com.android.dependencymapper; |
| |
| import static com.android.dependencymapper.Utils.listClassesInJar; |
| |
| import com.android.dependencymapper.DependencyProto; |
| |
| import java.io.IOException; |
| import java.nio.file.Files; |
| import java.nio.file.Path; |
| import java.util.List; |
| import java.util.Set; |
| |
| public class Main { |
| |
| public static void main(String[] args) throws IOException, InterruptedException { |
| try { |
| InputData input = parseAndValidateInput(args); |
| generateDependencyMap(input); |
| } catch (IllegalArgumentException e) { |
| System.err.println("Error: " + e.getMessage()); |
| showUsage(); |
| } |
| } |
| |
| private static class InputData { |
| public Path srcList; |
| public Path classesJar; |
| public Path dependencyMapProto; |
| |
| public InputData(Path srcList, Path classesJar, Path dependencyMapProto) { |
| this.srcList = srcList; |
| this.classesJar = classesJar; |
| this.dependencyMapProto = dependencyMapProto; |
| } |
| } |
| |
| private static InputData parseAndValidateInput(String[] args) { |
| for (String arg : args) { |
| if ("--help".equals(arg)) { |
| showUsage(); |
| System.exit(0); // Indicate successful exit after showing help |
| } |
| } |
| |
| if (args.length != 6) { // Explicitly check for the correct number of arguments |
| throw new IllegalArgumentException("Incorrect number of arguments"); |
| } |
| |
| Path srcList = null; |
| Path classesJar = null; |
| Path dependencyMapProto = null; |
| |
| for (int i = 0; i < args.length; i += 2) { |
| String arg = args[i].trim(); |
| String argValue = args[i + 1].trim(); |
| |
| switch (arg) { |
| case "--src-path" -> srcList = Path.of(argValue); |
| case "--jar-path" -> classesJar = Path.of(argValue); |
| case "--dependency-map-path" -> dependencyMapProto = Path.of(argValue); |
| default -> throw new IllegalArgumentException("Unknown argument: " + arg); |
| } |
| } |
| |
| // Validate file existence and readability |
| validateFile(srcList, "--src-path"); |
| validateFile(classesJar, "--jar-path"); |
| |
| return new InputData(srcList, classesJar, dependencyMapProto); |
| } |
| |
| private static void validateFile(Path path, String argName) { |
| if (path == null) { |
| throw new IllegalArgumentException(argName + " is required"); |
| } |
| if (!Files.exists(path)) { |
| throw new IllegalArgumentException(argName + " does not exist: " + path); |
| } |
| if (!Files.isReadable(path)) { |
| throw new IllegalArgumentException(argName + " is not readable: " + path); |
| } |
| } |
| |
| private static void generateDependencyMap(InputData input) { |
| // First collect all classes in the jar. |
| Set<String> classesInJar = listClassesInJar(input.classesJar); |
| // Perform dependency analysis. |
| List<ClassDependencyData> classDependencyDataList = ClassDependencyAnalyzer |
| .analyze(input.classesJar, new ClassRelevancyFilter(classesInJar)); |
| // Perform java source analysis. |
| List<JavaSourceData> javaSourceDataList = JavaSourceAnalyzer.analyze(input.srcList); |
| // Collect all dependencies and map them as DependencyProto.FileDependencyList |
| DependencyMapper dp = new DependencyMapper(classDependencyDataList, javaSourceDataList); |
| DependencyProto.FileDependencyList dependencyList = dp.buildDependencyMaps(); |
| |
| // Write the proto to output file |
| Utils.writeContentsToProto(dependencyList, input.dependencyMapProto); |
| } |
| |
| private static void showUsage() { |
| System.err.println( |
| "Usage: dependency-mapper " |
| + "--src-path [src-list.rsp] " |
| + "--jar-path [classes.jar] " |
| + "--dependency-map-path [dependency-map.proto]"); |
| } |
| |
| } |