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 static Map<String, Package> packages = new TreeMap<String, Package>(); 152 int maxProfile; 153 154 MakefileProfiles(Properties p) { 155 int profile = 1; 156 while (true) { 157 String inclPackages = p.getProperty("PROFILE_" + profile + "_RTJAR_INCLUDE_PACKAGES"); 158 if (inclPackages == null) 159 break; 160 for (String pkg: inclPackages.substring(1).trim().split("\\s+")) { 161 if (pkg.endsWith("/")) 162 pkg = pkg.substring(0, pkg.length() - 1); 163 includePackage(profile, pkg); 164 } 165 String inclTypes = p.getProperty("PROFILE_" + profile + "_RTJAR_INCLUDE_TYPES"); 166 if (inclTypes != null) { 167 for (String type: inclTypes.replace("$$", "$").split("\\s+")) { 168 if (type.endsWith(".class")) 169 includeType(profile, type.substring(0, type.length() - 6)); 170 } 171 } 172 String exclTypes = p.getProperty("PROFILE_" + profile + "_RTJAR_EXCLUDE_TYPES"); 173 if (exclTypes != null) { 174 for (String type: exclTypes.replace("$$", "$").split("\\s+")) { 175 if (type.endsWith(".class")) 176 excludeType(profile, type.substring(0, type.length() - 6)); 177 } 178 } 179 maxProfile = profile; 180 profile++; 181 } 182 } 183 184 @Override 185 public int getProfileCount() { 186 return maxProfile; 187 } 188 189 @Override 190 public int getProfile(String typeName) { 191 int sep = typeName.lastIndexOf("/"); 192 String packageName = typeName.substring(0, sep); 193 String simpleName = typeName.substring(sep + 1); 194 195 Package p = getPackage(packageName); 196 return p.getProfile(simpleName); 197 } 198 199 @Override 200 public Set<String> getPackages(int profile) { 201 Set<String> results = new TreeSet<String>(); 202 for (Package p: packages.values()) 203 p.getPackages(profile, results); 204 return results; 205 } 206 207 private void includePackage(int profile, String packageName) { 208 // System.err.println("include package " + packageName); 209 Package p = getPackage(packageName); 210 Assert.check(p.profile == 0); 211 p.profile = profile; 212 } 213 214 private void includeType(int profile, String typeName) { 215 // System.err.println("include type " + typeName); 216 int sep = typeName.lastIndexOf("/"); 217 String packageName = typeName.substring(0, sep); 218 String simpleName = typeName.substring(sep + 1); 219 220 Package p = getPackage(packageName); 221 Assert.check(!p.includedTypes.containsKey(simpleName)); 222 p.includedTypes.put(simpleName, profile); 223 } 224 225 private void excludeType(int profile, String typeName) { 226 // System.err.println("exclude type " + typeName); 227 int sep = typeName.lastIndexOf("/"); 228 String packageName = typeName.substring(0, sep); 229 String simpleName = typeName.substring(sep + 1); 230 231 Package p = getPackage(packageName); 232 Assert.check(!p.excludedTypes.containsKey(simpleName)); 233 p.excludedTypes.put(simpleName, profile); 234 } 235 236 private Package getPackage(String packageName) { 237 int sep = packageName.lastIndexOf("/"); 238 Package parent; 239 Map<String, Package> parentSubpackages; 240 String simpleName; 241 if (sep == -1) { 242 parent = null; 243 parentSubpackages = packages; 244 simpleName = packageName; 245 } else { 246 parent = getPackage(packageName.substring(0, sep)); 247 parentSubpackages = parent.subpackages; 248 simpleName = packageName.substring(sep + 1); 249 } 250 251 Package p = parentSubpackages.get(simpleName); 252 if (p == null) { 253 parentSubpackages.put(simpleName, p = new Package(parent, simpleName)); 254 } 255 return p; 256 } 257 } 258 259 private static class SimpleProfiles extends Profiles { 260 private final Map<String, Integer> map; 261 private final int profileCount; 262 263 SimpleProfiles(Properties p) { 264 int max = 0; 265 map = new HashMap<String, Integer>(); 266 for (Map.Entry<Object,Object> e: p.entrySet()) { 267 String typeName = (String) e.getKey(); 268 int profile = Integer.valueOf((String) e.getValue()); 269 map.put(typeName, profile); 270 max = Math.max(max, profile); 271 } 272 profileCount = max; 273 } 274 275 @Override 276 public int getProfileCount() { 277 return profileCount; 278 } 279 280 @Override 281 public int getProfile(String typeName) { 282 return map.get(typeName); 283 } 284 285 @Override 286 public Set<String> getPackages(int profile) { 287 Set<String> results = new TreeSet<String>(); 288 for (Map.Entry<String,Integer> e: map.entrySet()) { 289 String tn = e.getKey(); 290 int prf = e.getValue(); 291 int sep = tn.lastIndexOf("/"); 292 if (sep > 0 && profile >= prf) 293 results.add(tn); 294 } 295 return results; 296 } 297 } 298 }