blob: e46193f43c7d78e130758985c792665d24810286 [file] [log] [blame]
/*
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
* Copyright (c) 2002-2009 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.gui;
import javax.swing.*;
/**
* This class builds filters corresponding to the selections and names of a
* given list of check boxes.
*/
public class FilterBuilder
{
private JCheckBox[] checkBoxes;
private char separator;
/**
* Creates a new FilterBuilder.
* @param checkBoxes the check boxes with names and selections that should
* be reflected in the output filter.
* @param separator the separator for the names in the check boxes.
*/
public FilterBuilder(JCheckBox[] checkBoxes, char separator)
{
this.checkBoxes = checkBoxes;
this.separator = separator;
}
/**
* Builds a filter for the current names and selections of the check boxes.
*/
public String buildFilter()
{
StringBuffer positive = new StringBuffer();
StringBuffer negative = new StringBuffer();
buildFilter("", positive, negative);
return positive.length() <= negative.length() ?
positive.toString() :
negative.toString();
}
/**
* Builds two versions of the filter for the given prefix.
* @param prefix the prefix.
* @param positive the filter to be extended, assuming the matching
* strings are accepted.
* @param negative the filter to be extended, assuming the matching
* strings are rejected.
*/
private void buildFilter(String prefix,
StringBuffer positive,
StringBuffer negative)
{
int positiveCount = 0;
int negativeCount = 0;
// Count all selected and unselected check boxes with the prefix.
for (int index = 0; index < checkBoxes.length; index++)
{
JCheckBox checkBox = checkBoxes[index];
String name = checkBox.getText();
if (name.startsWith(prefix))
{
if (checkBox.isSelected())
{
positiveCount++;
}
else
{
negativeCount++;
}
}
}
// Are there only unselected check boxes?
if (positiveCount == 0)
{
// Extend the positive filter with exceptions and return.
if (positive.length() > 0)
{
positive.append(',');
}
positive.append('!').append(prefix);
if (prefix.length() == 0 ||
prefix.charAt(prefix.length()-1) == separator)
{
positive.append('*');
}
return;
}
// Are there only selected check boxes?
if (negativeCount == 0)
{
// Extend the negative filter with exceptions and return.
if (negative.length() > 0)
{
negative.append(',');
}
negative.append(prefix);
if (prefix.length() == 0 ||
prefix.charAt(prefix.length()-1) == separator)
{
negative.append('*');
}
return;
}
// Create new positive and negative filters for names starting with the
// prefix only.
StringBuffer positiveFilter = new StringBuffer();
StringBuffer negativeFilter = new StringBuffer();
String newPrefix = null;
for (int index = 0; index < checkBoxes.length; index++)
{
String name = checkBoxes[index].getText();
if (name.startsWith(prefix))
{
if (newPrefix == null ||
!name.startsWith(newPrefix))
{
int prefixIndex =
name.indexOf(separator, prefix.length()+1);
newPrefix = prefixIndex >= 0 ?
name.substring(0, prefixIndex+1) :
name;
buildFilter(newPrefix,
positiveFilter,
negativeFilter);
}
}
}
// Extend the positive filter.
if (positiveFilter.length() <= negativeFilter.length() + prefix.length() + 3)
{
if (positive.length() > 0 &&
positiveFilter.length() > 0)
{
positive.append(',');
}
positive.append(positiveFilter);
}
else
{
if (positive.length() > 0 &&
negativeFilter.length() > 0)
{
positive.append(',');
}
positive.append(negativeFilter).append(",!").append(prefix).append('*');
}
// Extend the negative filter.
if (negativeFilter.length() <= positiveFilter.length() + prefix.length() + 4)
{
if (negative.length() > 0 &&
negativeFilter.length() > 0)
{
negative.append(',');
}
negative.append(negativeFilter);
}
else
{
if (negative.length() > 0 &&
positiveFilter.length() > 0)
{
negative.append(',');
}
negative.append(positiveFilter).append(',').append(prefix).append('*');
}
}
}