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.nio.file.Path;
20 import java.nio.file.Paths;
21 import java.util.ArrayList;
22 import java.util.Arrays;
23 import java.util.Collections;
24 import java.util.HashSet;
25 import java.util.LinkedHashSet;
26 import java.util.List;
27 import java.util.Set;
28 import libcore.Repository.OjluniRepository;
29 
30 import static libcore.Repository.openJdk9;
31 import static libcore.Repository.openJdkLegacy;
32 
33 public class StandardRepositories {
34 
35     private final List<Repository> allUpstreams;
36     // upstreams older than what is currently the default
37     private final List<Repository> historicUpstreams;
38     private final Repository openJdk8u222;
39     private final Repository openJdk8u121;
40     private final Repository openJdk9b113;
41     private final Repository openJdk9p181;
42     private final Repository openJdk7u40;
43     private final OjluniRepository ojluni;
44 
StandardRepositories(Path buildTop, Path upstreamRoot)45     private StandardRepositories(Path buildTop, Path upstreamRoot) {
46         // allUpstreams is ordered from latest to earliest
47         Set<Repository> allUpstreams = new LinkedHashSet<>();
48         allUpstreams.add(openJdk9(upstreamRoot, "9+181"));
49         this.openJdk9b113 = addAndReturn(allUpstreams, openJdk9(upstreamRoot, "9b113+"));
50         this.openJdk8u121 = addAndReturn(allUpstreams, openJdkLegacy(upstreamRoot, "8u121-b13"));
51         this.openJdk8u222 = addAndReturn(allUpstreams, openJdkLegacy(upstreamRoot, "8u222-b01"));
52         this.openJdk9p181 = addAndReturn(allUpstreams, openJdk9(upstreamRoot, "9+181"));
53         Repository openJdk8u60 = addAndReturn(allUpstreams, openJdkLegacy(upstreamRoot, "8u60"));
54         this.openJdk7u40 = addAndReturn(allUpstreams, openJdkLegacy(upstreamRoot, "7u40"));
55         this.allUpstreams = Collections.unmodifiableList(new ArrayList<>(allUpstreams));
56         this.historicUpstreams = Collections.unmodifiableList(new ArrayList<>(
57                 Arrays.asList(openJdk8u60, openJdk7u40)
58         ));
59         this.ojluni = new OjluniRepository(buildTop);
60     }
61 
addAndReturn(Set<Repository> repositories, Repository repository)62     private static Repository addAndReturn(Set<Repository> repositories, Repository repository) {
63         repositories.add(repository);
64         return repository;
65     }
66 
historicUpstreams()67     public List<Repository> historicUpstreams() {
68         return historicUpstreams;
69     }
70 
ojluni()71     public OjluniRepository ojluni() {
72         return ojluni;
73     }
74 
75     /**
76      * Returns all upstream repository snapshots, in order from latest to earliest.
77      */
upstreams()78     public List<Repository> upstreams() {
79         return allUpstreams;
80     }
81 
fromEnv()82     public static StandardRepositories fromEnv() {
83         Path androidBuildTop = Util.pathFromEnvOrThrow("ANDROID_BUILD_TOP");
84         Path upstreamRoot = Util.pathFromEnvOrThrow("OPENJDK_HOME");
85         return new StandardRepositories(androidBuildTop, upstreamRoot);
86     }
87 
88     private static final Set<String> juFilesFromJsr166 = Collections.unmodifiableSet(
89             new HashSet<>(Arrays.asList(
90                     "AbstractQueue",
91                     "ArrayDeque",
92                     "ArrayPrefixHelpers",
93                     "Deque",
94                     "Map",
95                     "NavigableMap",
96                     "NavigableSet",
97                     "PriorityQueue",
98                     "Queue",
99                     "SplittableRandom"
100             )));
101 
isJsr166(Path relPath)102     public boolean isJsr166(Path relPath) {
103         boolean result = relPath.startsWith("java/util/concurrent/");
104         String ju = "java/util/";
105         String suffix = ".java";
106         if (!result && relPath.startsWith(ju)) {
107             String name = relPath.toString().substring(ju.length());
108             if (name.endsWith(suffix)) {
109                 name = name.substring(0, name.length() - suffix.length());
110                 result = juFilesFromJsr166.contains(name);
111             }
112         }
113         return result;
114     }
115 
116     private static final Set<String> REL_PATHS_AT_OPENJDK9_181 = Collections.unmodifiableSet(
117             new HashSet<>(Arrays.asList(
118                     "java/util/concurrent/Flow.java",
119                     "java/util/AbstractList.java",
120                     "java/util/ImmutableCollections.java",
121                     "java/util/KeyValueHolder.java",
122                     "java/util/List.java",
123                     "java/util/Map.java",
124                     "java/util/Objects.java",
125                     "java/util/Set.java",
126                     "jdk/internal/HotSpotIntrinsicCandidate.java",
127                     "jdk/internal/vm/annotation/Stable.java",
128                     "jdk/internal/util/Preconditions.java"
129                     )));
130 
131     private static final Set<String> REL_PATHS_AT_OPENJDK8_222 = Collections.unmodifiableSet(
132             new HashSet<>(Arrays.asList(
133                     "java/time/chrono/JapaneseEra.java",
134                     "java/util/JapaneseImperialCalendar.java",
135                     "sun/util/calendar/Era.java",
136                     // Tests:
137                     "java/time/tck/java/time/chrono/TCKJapaneseChronology.java",
138                     "java/time/tck/java/time/chrono/TCKJapaneseEra.java",
139                     "java/time/test/java/time/chrono/TestJapaneseChronology.java",
140                     "java/time/test/java/time/chrono/TestUmmAlQuraChronology.java",
141                     "java/time/test/java/time/format/TestNonIsoFormatter.java"
142             )));
143 
referenceUpstream(Path relPath)144     public Repository referenceUpstream(Path relPath) {
145         boolean isJsr166 = isJsr166(relPath);
146         if (REL_PATHS_AT_OPENJDK9_181.contains(relPath.toString())) {
147             return openJdk9p181;
148         } else if (REL_PATHS_AT_OPENJDK8_222.contains(relPath.toString())) {
149             return openJdk8u222;
150         } else if (isJsr166) {
151             return openJdk9b113;
152         } else if (relPath.startsWith("java/sql/") || relPath.startsWith("javax/sql/")) {
153             return openJdk7u40;
154         } else {
155             return openJdk8u121;
156         }
157     }
158 
159 }
160