/*
|
* ProGuard -- shrinking, optimization, obfuscation, and preverification
|
* of Java bytecode.
|
*
|
* Copyright (c) 2002-2014 Eric Lafortune (eric@graphics.cornell.edu)
|
*
|
* 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);
|
}
|
}
|
}
|