summaryrefslogtreecommitdiff
path: root/src/proguard/gui/FilterBuilder.java
diff options
context:
space:
mode:
Diffstat (limited to 'src/proguard/gui/FilterBuilder.java')
-rw-r--r--src/proguard/gui/FilterBuilder.java208
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('*');
+ }
+ }
+}