1 /* 2 * Copyright (C) 2017 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 17 package libcore; 18 19 import java.io.File; 20 import java.io.IOException; 21 import java.nio.file.Path; 22 import java.nio.file.Paths; 23 import java.util.ArrayList; 24 import java.util.Arrays; 25 import java.util.Collections; 26 import java.util.List; 27 import java.util.Objects; 28 import java.util.regex.Matcher; 29 import java.util.regex.Pattern; 30 31 /** 32 * A set of .java files (either from ojluni or from an upstream). 33 */ 34 abstract class Repository { 35 36 protected final Path rootPath; 37 protected final String name; 38 39 protected Repository(Path rootPath, String name) { 40 this.rootPath = Objects.requireNonNull(rootPath); 41 this.name = Objects.requireNonNull(name); 42 if (!rootPath.toFile().isDirectory()) { 43 throw new IllegalArgumentException("Missing or not a directory: " + rootPath); 44 } 45 } 46 47 /** 48 * @param relPath a relative path of a .java file in the repository, e.g. 49 * "java/util/ArrayList.java". 50 * @return the path of the indicated file (either absolute, or relative to the current 51 * working directory), or null if the file does not exist in this Repository. 52 */ 53 public final Path absolutePath(Path relPath) { 54 Path p = pathFromRepository(relPath); 55 return p == null ? null : rootPath.resolve(p).toAbsolutePath(); 56 } 57 58 public abstract Path pathFromRepository(Path relPath); 59 60 /** 61 * @return A human readable name to identify this repository, suitable for use as a 62 * directory name. 63 */ 64 public final String name() { 65 return name; 66 } 67 68 @Override 69 public String toString() { 70 return name() + " repository"; 71 } 72 73 /** 74 * A checkout of the hg repository of OpenJDK 9 or higher, located in the 75 * subdirectory {@code upstreamName} under the directory {@code upstreamRoot}. 76 */ 77 public static Repository openJdk9(Path upstreamRoot, String upstreamName) { 78 List<String> sourceDirs = Arrays.asList( 79 "jdk/src/java.base/share/classes", 80 "jdk/src/java.logging/share/classes", 81 "jdk/src/java.prefs/share/classes", 82 "jdk/src/java.sql/share/classes", 83 "jdk/src/java.desktop/share/classes", 84 "jdk/src/java.base/solaris/classes", 85 "jdk/src/java.base/unix/classes", 86 "jdk/src/java.prefs/unix/classes", 87 "jdk/src/jdk.unsupported/share/classes", 88 "jdk/src/jdk.net/share/classes", 89 "jdk/src/java.base/linux/classes", 90 "build/linux-x86_64-normal-server-release/support/gensrc/java.base" 91 ); 92 return new OpenJdkRepository(upstreamRoot, upstreamName, sourceDirs); 93 } 94 95 /** 96 * A checkout of the hg repository of OpenJDK 8 or earlier, located in the 97 * subdirectory {@code upstreamName} under the directory {@code upstreamRoot}. 98 */ 99 public static Repository openJdkLegacy(Path upstreamRoot, String upstreamName) { 100 List<String> sourceDirs = Arrays.asList( 101 "jdk/src/share/classes", 102 "jdk/src/solaris/classes", 103 "build/linux-x86_64-normal-server-release/jdk/gensrc" 104 ); 105 106 return new OpenJdkRepository(upstreamRoot, upstreamName, sourceDirs); 107 } 108 109 /** 110 * Checkouts of hg repositories of OpenJDK 8 or earlier, located in the 111 * respective {@code upstreamNames} subdirectories under the join parent 112 * directory {@code upstreamRoot}. 113 */ 114 public static List<Repository> openJdkLegacy(Path upstreamRoot, List<String> upstreamNames) { 115 List<Repository> result = new ArrayList<>(); 116 for (String upstreamName : upstreamNames) { 117 result.add(openJdkLegacy(upstreamRoot, upstreamName)); 118 } 119 return Collections.unmodifiableList(result); 120 } 121 122 static class OjluniRepository extends Repository { 123 124 /** 125 * The repository of ojluni java files belonging to the Android sources under 126 * {@code buildTop}. 127 * 128 * @param buildTop The root path of an Android checkout, as identified by the 129 * {@quote ANDROID_BUILD_TOP} environment variable. 130 */ 131 public OjluniRepository(Path buildTop) { 132 super(buildTop.resolve("libcore"), "ojluni"); 133 } 134 135 136 @Override 137 public Path pathFromRepository(Path relPath) { 138 return Paths.get("ojluni/src/main/java").resolve(relPath); 139 } 140 141 /** 142 * Returns the list of relative paths to .java files parsed from openjdk_java_files.mk 143 */ 144 public List<Path> loadRelPathsFromMakefile() throws IOException { 145 List<Path> result = new ArrayList<>(); 146 Path makefile = rootPath.resolve("openjdk_java_files.bp"); 147 Pattern pattern = Pattern.compile("\"ojluni/src/main/java/(.+\\.java)\""); 148 for (String line : Util.readLines(makefile)) { 149 Matcher matcher = pattern.matcher(line); 150 while (matcher.find()) { 151 Path path = new File(matcher.group(1)).toPath(); 152 result.add(path); 153 } 154 } 155 return result; 156 } 157 158 @Override 159 public String toString() { 160 return "libcore ojluni"; 161 } 162 } 163 164 static class OpenJdkRepository extends Repository { 165 private final List<String> sourceDirs; 166 167 public OpenJdkRepository(Path upstreamRoot, String name, List<String> sourceDirs) { 168 super(upstreamRoot.resolve(name), name); 169 this.sourceDirs = Objects.requireNonNull(sourceDirs); 170 } 171 172 @Override 173 public Path pathFromRepository(Path relPath) { 174 for (String sourceDir : sourceDirs) { 175 Path repositoryRelativePath = Paths.get(sourceDir).resolve(relPath); 176 Path file = rootPath.resolve(repositoryRelativePath); 177 if (file.toFile().exists()) { 178 return repositoryRelativePath; 179 } 180 } 181 return null; 182 } 183 184 @Override 185 public String toString() { 186 return "OpenJDK " + name; 187 } 188 } 189 190 191 } 192