View Javadoc
1   /*
2    * Copyright (c) 2006, 2013, Oracle and/or its affiliates. All rights reserved.
3    * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4    *
5    * This code is free software; you can redistribute it and/or modify it
6    * under the terms of the GNU General Public License version 2 only, as
7    * published by the Free Software Foundation.  Oracle designates this
8    * particular file as subject to the "Classpath" exception as provided
9    * by Oracle in the LICENSE file that accompanied this code.
10   *
11   * This code is distributed in the hope that it will be useful, but WITHOUT
12   * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13   * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
14   * version 2 for more details (a copy is included in the LICENSE file that
15   * accompanied this code).
16   *
17   * You should have received a copy of the GNU General Public License version
18   * 2 along with this work; if not, write to the Free Software Foundation,
19   * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20   *
21   * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22   * or visit www.oracle.com if you need additional information or have any
23   * questions.
24   */
25  package com.sun.tools.javac.sym;
26  
27  import java.io.BufferedInputStream;
28  import java.io.BufferedWriter;
29  import java.io.File;
30  import java.io.FileInputStream;
31  import java.io.FileWriter;
32  import java.io.IOException;
33  import java.nio.charset.Charset;
34  import java.nio.file.Files;
35  import java.util.HashMap;
36  import java.util.Map;
37  import java.util.Properties;
38  import java.util.Set;
39  import java.util.TreeMap;
40  import java.util.TreeSet;
41  
42  import com.sun.tools.javac.util.Assert;
43  
44  /**
45   * Provide details about profile contents.
46   *
47   * <p><b>This is NOT part of any supported API.
48   * If you write code that depends on this, you do so at your own
49   * risk.  This code and its internal interfaces are subject to change
50   * or deletion without notice.</b></p>
51   */
52  public abstract class Profiles {
53      // for debugging
54      public static void main(String[] args) throws IOException {
55          Profiles p = Profiles.read(new File(args[0]));
56          if (args.length >= 2) {
57              Map<Integer,Set<String>> lists = new TreeMap<Integer,Set<String>>();
58              for (int i = 1; i <= 4; i++)
59                  lists.put(i, new TreeSet<String>());
60  
61              File rt_jar_lst = new File(args[1]);
62              for (String line: Files.readAllLines(rt_jar_lst.toPath(), Charset.defaultCharset())) {
63                  if (line.endsWith(".class")) {
64                      String type = line.substring(0, line.length() - 6);
65                      int profile = p.getProfile(type);
66                      for (int i = profile; i <= 4; i++)
67                          lists.get(i).add(type);
68                  }
69              }
70  
71              for (int i = 1; i <= 4; i++) {
72                  BufferedWriter out = new BufferedWriter(new FileWriter(i + ".txt"));
73                  try {
74                      for (String type: lists.get(i)) {
75                          out.write(type);
76                          out.newLine();
77                      }
78                  } finally {
79                      out.close();
80                  }
81              }
82          }
83      }
84  
85      public static Profiles read(File file) throws IOException {
86          BufferedInputStream in = new BufferedInputStream(new FileInputStream(file));
87          try {
88              Properties p = new Properties();
89              p.load(in);
90              if (p.containsKey("java/lang/Object"))
91                  return new SimpleProfiles(p);
92              else
93                  return new MakefileProfiles(p);
94          } finally {
95              in.close();
96          }
97      }
98  
99      public abstract int getProfileCount();
100 
101     public abstract int getProfile(String typeName);
102 
103     public abstract Set<String> getPackages(int profile);
104 
105     private static class MakefileProfiles extends Profiles {
106         static class Package {
107             final Package parent;
108             final String name;
109 
110             Map<String, Package> subpackages = new TreeMap<String, Package>();
111 
112             int profile;
113             Map<String, Integer> includedTypes = new TreeMap<String,Integer>();
114             Map<String, Integer> excludedTypes = new TreeMap<String,Integer>();
115 
116             Package(Package parent, String name) {
117                 this.parent = parent;
118                 this.name = name;
119             }
120 
121             int getProfile() {
122                 return (parent == null) ? profile : Math.max(parent.getProfile(), profile);
123             }
124 
125             int getProfile(String simpleTypeName) {
126                 Integer i;
127                 if ((i = includedTypes.get(simpleTypeName)) != null)
128                     return i;
129                 if ((i = includedTypes.get("*")) != null)
130                     return i;
131                 if ((i = excludedTypes.get(simpleTypeName)) != null)
132                     return i + 1;
133                 if ((i = excludedTypes.get("*")) != null)
134                     return i + 1;
135                 return getProfile();
136             }
137 
138             String getName() {
139                 return (parent == null) ? name : (parent.getName() + "/" + name);
140             }
141 
142             void getPackages(int profile, Set<String> results) {
143                 int prf = getProfile();
144                 if (prf != 0 && profile >= prf)
145                     results.add(getName());
146                 for (Package pkg: subpackages.values())
147                     pkg.getPackages(profile, results);
148             }
149         }
150 
151         final Map<String, Package> packages = new TreeMap<String, Package>();
152 
153         final int maxProfile = 4;  // Three compact profiles plus full JRE
154 
155         MakefileProfiles(Properties p) {
156             for (int profile = 1; profile <= maxProfile; profile++) {
157                 String prefix = (profile < maxProfile ? "PROFILE_" + profile : "FULL_JRE");
158                 String inclPackages = p.getProperty(prefix + "_RTJAR_INCLUDE_PACKAGES");
159                 if (inclPackages == null)
160                     break;
161                 for (String pkg: inclPackages.substring(1).trim().split("\\s+")) {
162                     if (pkg.endsWith("/"))
163                         pkg = pkg.substring(0, pkg.length() - 1);
164                     includePackage(profile, pkg);
165                 }
166                 String inclTypes =  p.getProperty(prefix + "_RTJAR_INCLUDE_TYPES");
167                 if (inclTypes != null) {
168                     for (String type: inclTypes.replace("$$", "$").split("\\s+")) {
169                         if (type.endsWith(".class"))
170                             includeType(profile, type.substring(0, type.length() - 6));
171                     }
172                 }
173                 String exclTypes =  p.getProperty(prefix + "_RTJAR_EXCLUDE_TYPES");
174                 if (exclTypes != null) {
175                     for (String type: exclTypes.replace("$$", "$").split("\\s+")) {
176                         if (type.endsWith(".class"))
177                             excludeType(profile, type.substring(0, type.length() - 6));
178                     }
179                 }
180             }
181         }
182 
183         @Override
184         public int getProfileCount() {
185             return maxProfile;
186         }
187 
188         @Override
189         public int getProfile(String typeName) {
190             int sep = typeName.lastIndexOf("/");
191             String packageName = typeName.substring(0, sep);
192             String simpleName = typeName.substring(sep + 1);
193 
194             Package p = getPackage(packageName);
195             return p.getProfile(simpleName);
196         }
197 
198         @Override
199         public Set<String> getPackages(int profile) {
200             Set<String> results = new TreeSet<String>();
201             for (Package p: packages.values())
202                 p.getPackages(profile, results);
203             return results;
204         }
205 
206         private void includePackage(int profile, String packageName) {
207 //            System.err.println("include package " + packageName);
208             Package p = getPackage(packageName);
209             Assert.check(p.profile == 0);
210             p.profile = profile;
211         }
212 
213         private void includeType(int profile, String typeName) {
214 //            System.err.println("include type " + typeName);
215             int sep = typeName.lastIndexOf("/");
216             String packageName = typeName.substring(0, sep);
217             String simpleName = typeName.substring(sep + 1);
218 
219             Package p = getPackage(packageName);
220             Assert.check(!p.includedTypes.containsKey(simpleName));
221             p.includedTypes.put(simpleName, profile);
222         }
223 
224         private void excludeType(int profile, String typeName) {
225 //            System.err.println("exclude type " + typeName);
226             int sep = typeName.lastIndexOf("/");
227             String packageName = typeName.substring(0, sep);
228             String simpleName = typeName.substring(sep + 1);
229 
230             Package p = getPackage(packageName);
231             Assert.check(!p.excludedTypes.containsKey(simpleName));
232             p.excludedTypes.put(simpleName, profile);
233         }
234 
235         private Package getPackage(String packageName) {
236             int sep = packageName.lastIndexOf("/");
237             Package parent;
238             Map<String, Package> parentSubpackages;
239             String simpleName;
240             if (sep == -1) {
241                 parent = null;
242                 parentSubpackages = packages;
243                 simpleName = packageName;
244             } else {
245                 parent = getPackage(packageName.substring(0, sep));
246                 parentSubpackages = parent.subpackages;
247                 simpleName = packageName.substring(sep + 1);
248             }
249 
250             Package p = parentSubpackages.get(simpleName);
251             if (p == null) {
252                 parentSubpackages.put(simpleName, p = new Package(parent, simpleName));
253             }
254             return p;
255         }
256     }
257 
258     private static class SimpleProfiles extends Profiles {
259         private final Map<String, Integer> map;
260         private final int profileCount;
261 
262         SimpleProfiles(Properties p) {
263             int max = 0;
264             map = new HashMap<String, Integer>();
265             for (Map.Entry<Object,Object> e: p.entrySet()) {
266                 String typeName = (String) e.getKey();
267                 int profile = Integer.valueOf((String) e.getValue());
268                 map.put(typeName, profile);
269                 max = Math.max(max, profile);
270             }
271             profileCount = max;
272         }
273 
274         @Override
275         public int getProfileCount() {
276             return profileCount;
277         }
278 
279         @Override
280         public int getProfile(String typeName) {
281             return map.get(typeName);
282         }
283 
284         @Override
285         public Set<String> getPackages(int profile) {
286             Set<String> results = new TreeSet<String>();
287             for (Map.Entry<String,Integer> e: map.entrySet()) {
288                 String tn = e.getKey();
289                 int prf = e.getValue();
290                 int sep = tn.lastIndexOf("/");
291                 if (sep > 0 && profile >= prf)
292                     results.add(tn);
293             }
294             return results;
295         }
296     }
297 }