| /* |
| * ProGuard -- shrinking, optimization, obfuscation, and preverification |
| * of Java bytecode. |
| * |
| * Copyright (c) 2002-2014 Eric Lafortune ([email protected]) |
| * |
| * This program is free software; you can redistribute it and/or modify it |
| * under the terms of the GNU General Public License as published by the Free |
| * Software Foundation; either version 2 of the License, or (at your option) |
| * any later version. |
| * |
| * This program is distributed in the hope that it will be useful, but WITHOUT |
| * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or |
| * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for |
| * more details. |
| * |
| * You should have received a copy of the GNU General Public License along |
| * with this program; if not, write to the Free Software Foundation, Inc., |
| * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
| */ |
| package proguard; |
| |
| import java.io.*; |
| import java.util.*; |
| |
| /** |
| * This class checks and prints out information about the GPL. |
| * |
| * @author Eric Lafortune |
| */ |
| public class GPL |
| { |
| /** |
| * Prints out a note about the GPL if ProGuard is linked against unknown |
| * code. |
| */ |
| public static void check() |
| { |
| ByteArrayOutputStream out = new ByteArrayOutputStream(); |
| new Exception().printStackTrace(new PrintStream(out)); |
| LineNumberReader reader = new LineNumberReader( |
| new InputStreamReader( |
| new ByteArrayInputStream(out.toByteArray()))); |
| |
| Set unknownPackageNames = unknownPackageNames(reader); |
| |
| if (unknownPackageNames.size() > 0) |
| { |
| String uniquePackageNames = uniquePackageNames(unknownPackageNames); |
| |
| System.out.println("ProGuard is released under the GNU General Public License. You therefore"); |
| System.out.println("must ensure that programs that link to it ("+uniquePackageNames+"...)"); |
| System.out.println("carry the GNU General Public License as well. Alternatively, you can"); |
| System.out.println("apply for an exception with the author of ProGuard."); |
| } |
| } |
| |
| |
| /** |
| * Returns a set of package names from the given stack trace. |
| */ |
| private static Set unknownPackageNames(LineNumberReader reader) |
| { |
| Set packageNames = new HashSet(); |
| |
| try |
| { |
| while (true) |
| { |
| String line = reader.readLine(); |
| if (line == null) |
| { |
| break; |
| } |
| |
| line = line.trim(); |
| if (line.startsWith("at ")) |
| { |
| line = line.substring(2).trim(); |
| line = trimSuffix(line, '('); |
| line = trimSuffix(line, '.'); |
| line = trimSuffix(line, '.'); |
| |
| if (line.length() > 0 && !isKnown(line)) |
| { |
| packageNames.add(line); |
| } |
| } |
| } |
| } |
| catch (IOException ex) |
| { |
| // We'll just stop looking for more names. |
| } |
| |
| return packageNames; |
| } |
| |
| |
| /** |
| * Returns a comma-separated list of package names from the set, excluding |
| * any subpackages of packages in the set. |
| */ |
| private static String uniquePackageNames(Set packageNames) |
| { |
| StringBuffer buffer = new StringBuffer(); |
| |
| Iterator iterator = packageNames.iterator(); |
| while (iterator.hasNext()) |
| { |
| String packageName = (String)iterator.next(); |
| if (!containsPrefix(packageNames, packageName)) |
| { |
| buffer.append(packageName).append(", "); |
| } |
| } |
| |
| return buffer.toString(); |
| } |
| |
| |
| /** |
| * Returns a given string without the suffix, as defined by the given |
| * separator. |
| */ |
| private static String trimSuffix(String string, char separator) |
| { |
| int index = string.lastIndexOf(separator); |
| return index < 0 ? "" : string.substring(0, index); |
| } |
| |
| |
| /** |
| * Returns whether the given set contains a prefix of the given name. |
| */ |
| private static boolean containsPrefix(Set set, String name) |
| { |
| int index = 0; |
| |
| while (!set.contains(name.substring(0, index))) |
| { |
| index = name.indexOf('.', index + 1); |
| if (index < 0) |
| { |
| return false; |
| } |
| } |
| |
| return true; |
| } |
| |
| |
| /** |
| * Returns whether the given package name has been granted an exception |
| * against the GPL linking clause, by the copyright holder of ProGuard. |
| * This method is not legally binding, but of course the actual license is. |
| * Please contact the copyright holder if you would like an exception for |
| * your code as well. |
| */ |
| private static boolean isKnown(String packageName) |
| { |
| return packageName.startsWith("java") || |
| packageName.startsWith("sun.reflect") || |
| packageName.startsWith("proguard") || |
| packageName.startsWith("org.apache.tools.ant") || |
| packageName.startsWith("org.apache.tools.maven") || |
| packageName.startsWith("org.gradle") || |
| packageName.startsWith("org.codehaus.groovy") || |
| packageName.startsWith("org.eclipse") || |
| packageName.startsWith("org.netbeans") || |
| packageName.startsWith("com.android") || |
| packageName.startsWith("com.sun.kvem") || |
| packageName.startsWith("net.certiv.proguarddt") || |
| packageName.startsWith("groovy") || |
| packageName.startsWith("scala") || |
| packageName.startsWith("sbt") || |
| packageName.startsWith("xsbt") || |
| packageName.startsWith("eclipseme"); |
| } |
| |
| |
| public static void main(String[] args) |
| { |
| LineNumberReader reader = new LineNumberReader( |
| new InputStreamReader(System.in)); |
| |
| Set unknownPackageNames = unknownPackageNames(reader); |
| |
| if (unknownPackageNames.size() > 0) |
| { |
| String uniquePackageNames = uniquePackageNames(unknownPackageNames); |
| |
| System.out.println(uniquePackageNames); |
| } |
| } |
| } |