Home | History | Annotate | Download | only in libcore
      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