langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/sym/Profiles.java
changeset 36526 3b41f1c69604
parent 36525 4caf88912b7f
child 36527 e2de042a3820
equal deleted inserted replaced
36525:4caf88912b7f 36526:3b41f1c69604
     1 /*
       
     2  * Copyright (c) 2006, 2014, 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 
       
    26 package com.sun.tools.javac.sym;
       
    27 
       
    28 import java.io.BufferedInputStream;
       
    29 import java.io.BufferedWriter;
       
    30 import java.io.File;
       
    31 import java.io.FileInputStream;
       
    32 import java.io.FileWriter;
       
    33 import java.io.IOException;
       
    34 import java.nio.charset.Charset;
       
    35 import java.nio.file.Files;
       
    36 import java.util.HashMap;
       
    37 import java.util.Map;
       
    38 import java.util.Properties;
       
    39 import java.util.Set;
       
    40 import java.util.TreeMap;
       
    41 import java.util.TreeSet;
       
    42 
       
    43 import com.sun.tools.javac.util.Assert;
       
    44 
       
    45 /**
       
    46  * Provide details about profile contents.
       
    47  *
       
    48  * <p><b>This is NOT part of any supported API.
       
    49  * If you write code that depends on this, you do so at your own
       
    50  * risk.  This code and its internal interfaces are subject to change
       
    51  * or deletion without notice.</b></p>
       
    52  */
       
    53 public abstract class Profiles {
       
    54     // for debugging
       
    55     public static void main(String[] args) throws IOException {
       
    56         Profiles p = Profiles.read(new File(args[0]));
       
    57         if (args.length >= 2) {
       
    58             Map<Integer,Set<String>> lists = new TreeMap<>();
       
    59             for (int i = 1; i <= 4; i++)
       
    60                 lists.put(i, new TreeSet<String>());
       
    61 
       
    62             File rt_jar_lst = new File(args[1]);
       
    63             for (String line: Files.readAllLines(rt_jar_lst.toPath(), Charset.defaultCharset())) {
       
    64                 if (line.endsWith(".class")) {
       
    65                     String type = line.substring(0, line.length() - 6);
       
    66                     int profile = p.getProfile(type);
       
    67                     for (int i = profile; i <= 4; i++)
       
    68                         lists.get(i).add(type);
       
    69                 }
       
    70             }
       
    71 
       
    72             for (int i = 1; i <= 4; i++) {
       
    73                 try (BufferedWriter out = new BufferedWriter(new FileWriter(i + ".txt"))) {
       
    74                     for (String type : lists.get(i)) {
       
    75                         out.write(type);
       
    76                         out.newLine();
       
    77                     }
       
    78                 }
       
    79             }
       
    80         }
       
    81     }
       
    82 
       
    83     public static Profiles read(File file) throws IOException {
       
    84         try (BufferedInputStream in = new BufferedInputStream(new FileInputStream(file))) {
       
    85             Properties p = new Properties();
       
    86             p.load(in);
       
    87             if (p.containsKey("java/lang/Object"))
       
    88                 return new SimpleProfiles(p);
       
    89             else
       
    90                 return new MakefileProfiles(p);
       
    91         }
       
    92     }
       
    93 
       
    94     public abstract int getProfileCount();
       
    95 
       
    96     public abstract int getProfile(String typeName);
       
    97 
       
    98     public abstract Set<String> getPackages(int profile);
       
    99 
       
   100     private static class MakefileProfiles extends Profiles {
       
   101         static class Package {
       
   102             final Package parent;
       
   103             final String name;
       
   104 
       
   105             Map<String, Package> subpackages = new TreeMap<>();
       
   106 
       
   107             int profile;
       
   108             Map<String, Integer> includedTypes = new TreeMap<>();
       
   109             Map<String, Integer> excludedTypes = new TreeMap<>();
       
   110 
       
   111             Package(Package parent, String name) {
       
   112                 this.parent = parent;
       
   113                 this.name = name;
       
   114             }
       
   115 
       
   116             int getProfile() {
       
   117                 return (parent == null) ? profile : Math.max(parent.getProfile(), profile);
       
   118             }
       
   119 
       
   120             int getProfile(String simpleTypeName) {
       
   121                 Integer i;
       
   122                 if ((i = includedTypes.get(simpleTypeName)) != null)
       
   123                     return i;
       
   124                 if ((i = includedTypes.get("*")) != null)
       
   125                     return i;
       
   126                 if ((i = excludedTypes.get(simpleTypeName)) != null)
       
   127                     return i + 1;
       
   128                 if ((i = excludedTypes.get("*")) != null)
       
   129                     return i + 1;
       
   130                 return getProfile();
       
   131             }
       
   132 
       
   133             String getName() {
       
   134                 return (parent == null) ? name : (parent.getName() + "/" + name);
       
   135             }
       
   136 
       
   137             void getPackages(int profile, Set<String> results) {
       
   138                 int prf = getProfile();
       
   139                 if (prf != 0 && profile >= prf)
       
   140                     results.add(getName());
       
   141                 for (Package pkg: subpackages.values())
       
   142                     pkg.getPackages(profile, results);
       
   143             }
       
   144         }
       
   145 
       
   146         final Map<String, Package> packages = new TreeMap<>();
       
   147 
       
   148         final int maxProfile = 4;  // Three compact profiles plus full JRE
       
   149 
       
   150         MakefileProfiles(Properties p) {
       
   151             // consider crypto, only if java/lang package exists
       
   152             boolean foundJavaLang = false;
       
   153             for (int profile = 1; profile <= maxProfile; profile++) {
       
   154                 String prefix = (profile < maxProfile ? "PROFILE_" + profile : "FULL_JRE");
       
   155                 String inclPackages = p.getProperty(prefix + "_RTJAR_INCLUDE_PACKAGES");
       
   156                 if (inclPackages == null)
       
   157                     break;
       
   158                 for (String pkg: inclPackages.substring(1).trim().split("\\s+")) {
       
   159                     if (pkg.endsWith("/"))
       
   160                         pkg = pkg.substring(0, pkg.length() - 1);
       
   161                     if (foundJavaLang == false && pkg.equals("java/lang"))
       
   162                         foundJavaLang = true;
       
   163                     includePackage(profile, pkg);
       
   164                 }
       
   165                 String inclTypes =  p.getProperty(prefix + "_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(prefix + "_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             }
       
   180             /*
       
   181              * A hack to force javax/crypto package into the compact1 profile,
       
   182              * because this package exists in jce.jar, and therefore not in
       
   183              * ct.sym. Note javax/crypto should exist in a profile along with
       
   184              * javax/net/ssl package. Thus, this package is added to compact1,
       
   185              * implying that it should exist in all three profiles.
       
   186              */
       
   187             if (foundJavaLang)
       
   188                 includePackage(1, "javax/crypto");
       
   189         }
       
   190 
       
   191         @Override
       
   192         public int getProfileCount() {
       
   193             return maxProfile;
       
   194         }
       
   195 
       
   196         @Override
       
   197         public int getProfile(String typeName) {
       
   198             int sep = typeName.lastIndexOf("/");
       
   199             String packageName = typeName.substring(0, sep);
       
   200             String simpleName = typeName.substring(sep + 1);
       
   201 
       
   202             Package p = getPackage(packageName);
       
   203             return p.getProfile(simpleName);
       
   204         }
       
   205 
       
   206         @Override
       
   207         public Set<String> getPackages(int profile) {
       
   208             Set<String> results = new TreeSet<>();
       
   209             for (Package p: packages.values())
       
   210                 p.getPackages(profile, results);
       
   211             return results;
       
   212         }
       
   213 
       
   214         private void includePackage(int profile, String packageName) {
       
   215 //            System.err.println("include package " + packageName);
       
   216             Package p = getPackage(packageName);
       
   217             Assert.check(p.profile == 0);
       
   218             p.profile = profile;
       
   219         }
       
   220 
       
   221         private void includeType(int profile, String typeName) {
       
   222 //            System.err.println("include type " + typeName);
       
   223             int sep = typeName.lastIndexOf("/");
       
   224             String packageName = typeName.substring(0, sep);
       
   225             String simpleName = typeName.substring(sep + 1);
       
   226 
       
   227             Package p = getPackage(packageName);
       
   228             Assert.check(!p.includedTypes.containsKey(simpleName));
       
   229             p.includedTypes.put(simpleName, profile);
       
   230         }
       
   231 
       
   232         private void excludeType(int profile, String typeName) {
       
   233 //            System.err.println("exclude type " + typeName);
       
   234             int sep = typeName.lastIndexOf("/");
       
   235             String packageName = typeName.substring(0, sep);
       
   236             String simpleName = typeName.substring(sep + 1);
       
   237 
       
   238             Package p = getPackage(packageName);
       
   239             Assert.check(!p.excludedTypes.containsKey(simpleName));
       
   240             p.excludedTypes.put(simpleName, profile);
       
   241         }
       
   242 
       
   243         private Package getPackage(String packageName) {
       
   244             int sep = packageName.lastIndexOf("/");
       
   245             Package parent;
       
   246             Map<String, Package> parentSubpackages;
       
   247             String simpleName;
       
   248             if (sep == -1) {
       
   249                 parent = null;
       
   250                 parentSubpackages = packages;
       
   251                 simpleName = packageName;
       
   252             } else {
       
   253                 parent = getPackage(packageName.substring(0, sep));
       
   254                 parentSubpackages = parent.subpackages;
       
   255                 simpleName = packageName.substring(sep + 1);
       
   256             }
       
   257 
       
   258             Package p = parentSubpackages.get(simpleName);
       
   259             if (p == null) {
       
   260                 parentSubpackages.put(simpleName, p = new Package(parent, simpleName));
       
   261             }
       
   262             return p;
       
   263         }
       
   264     }
       
   265 
       
   266     private static class SimpleProfiles extends Profiles {
       
   267         private final Map<String, Integer> map;
       
   268         private final int profileCount;
       
   269 
       
   270         SimpleProfiles(Properties p) {
       
   271             int max = 0;
       
   272             map = new HashMap<>();
       
   273             for (Map.Entry<Object,Object> e: p.entrySet()) {
       
   274                 String typeName = (String) e.getKey();
       
   275                 int profile = Integer.valueOf((String) e.getValue());
       
   276                 map.put(typeName, profile);
       
   277                 max = Math.max(max, profile);
       
   278             }
       
   279             profileCount = max;
       
   280         }
       
   281 
       
   282         @Override
       
   283         public int getProfileCount() {
       
   284             return profileCount;
       
   285         }
       
   286 
       
   287         @Override
       
   288         public int getProfile(String typeName) {
       
   289             return map.get(typeName);
       
   290         }
       
   291 
       
   292         @Override
       
   293         public Set<String> getPackages(int profile) {
       
   294             Set<String> results = new TreeSet<>();
       
   295             for (Map.Entry<String,Integer> e: map.entrySet()) {
       
   296                 String tn = e.getKey();
       
   297                 int prf = e.getValue();
       
   298                 int sep = tn.lastIndexOf("/");
       
   299                 if (sep > 0 && profile >= prf)
       
   300                     results.add(tn);
       
   301             }
       
   302             return results;
       
   303         }
       
   304     }
       
   305 }