/* * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * * Copyright (c) 2002-2011 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('*'); } } }