diff options
Diffstat (limited to 'src/proguard/gui/FilterBuilder.java')
-rw-r--r-- | src/proguard/gui/FilterBuilder.java | 208 |
1 files changed, 208 insertions, 0 deletions
diff --git a/src/proguard/gui/FilterBuilder.java b/src/proguard/gui/FilterBuilder.java new file mode 100644 index 0000000..e46193f --- /dev/null +++ b/src/proguard/gui/FilterBuilder.java @@ -0,0 +1,208 @@ +/* + * 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('*'); + } + } +} |