/* * (C) Copyright Uwe Schindler (Generics Policeman) and others. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package de.thetaphi.forbiddenapis; import java.io.BufferedWriter; import java.io.File; import java.io.FileOutputStream; import java.io.IOException; import java.io.OutputStreamWriter; import java.security.Security; import java.util.Locale; import java.util.Set; import java.util.TreeSet; /** Generates a signatures file listing all JRE-internal classes for the current runtime. */ public final class InternalApiGen { final static String NL = System.getProperty("line.separator", "\n"); final String javaVersion, header; private final File output; InternalApiGen(String javaVersion, String outputFile) { this(javaVersion, new File(outputFile)); } InternalApiGen(String javaVersion, File output) { this.javaVersion = javaVersion; this.output = output; this.header = new StringBuilder() .append("# This file contains API signatures that are marked as internal in Java.").append(NL) .append("# It is provided here for reference, but can easily regenerated by executing from the source folder of forbidden-apis:").append(NL) .append("# $ ant generate-internal").append(NL) .append(NL) .append("# This file contains all internal packages listed in Security.getProperty(\"package.access\") of Java version ").append(javaVersion) .append(" (extracted from build ").append(System.getProperty("java.version")).append(").").append(NL) .append(NL) .append("@defaultMessage non-public internal runtime class in Java ").append(javaVersion).append(NL) .append(NL) .toString(); } private void parsePackages(String packagesStr, Set<String> packages) { if (packagesStr == null || packagesStr.isEmpty()) { return; } for (String pkg : packagesStr.split(",")) { pkg = pkg.trim(); if (!pkg.endsWith(".")) { pkg = pkg.concat("."); } packages.add(pkg.concat("**")); } } @SuppressForbidden void run() throws IOException { System.err.println(String.format(Locale.ENGLISH, "Writing internal APIs to signatures file '%s'...", output)); final Set<String> packages = new TreeSet<String>(); parsePackages(Security.getProperty("package.access"), packages); // TODO: add this, too??: parsePackages(Security.getProperty("package.definition"), packages); final BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(output), "UTF-8")); try { writer.write(header); for (final String s : packages) { writer.write(s); writer.newLine(); } } finally { writer.close(); } System.err.println("Internal API signatures for Java version " + javaVersion + " written successfully."); } public static void main(String... args) throws Exception { if (args.length != 2) { throw new IllegalArgumentException("Need 2 arguments: java version, output file"); } new InternalApiGen(args[0], args[1]).run(); } }